diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2018-12-06 16:51:20 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2018-12-06 16:51:20 +0000 |
commit | 60fd556224f9606e4ccc8be299ef73e5458551a4 (patch) | |
tree | 672454234cc92626186a262eafe7ce7b4e1754c0 /usr.sbin/rebound/rebound.c | |
parent | e441d9f5046bfc459ef3d11f034a1283935e01ec (diff) |
add very experimental support for dns over https. (RFC 8484)
performance may be less than great.
ok anton
Diffstat (limited to 'usr.sbin/rebound/rebound.c')
-rw-r--r-- | usr.sbin/rebound/rebound.c | 64 |
1 files changed, 55 insertions, 9 deletions
diff --git a/usr.sbin/rebound/rebound.c b/usr.sbin/rebound/rebound.c index 311607ccd6f..e3b97a16737 100644 --- a/usr.sbin/rebound/rebound.c +++ b/usr.sbin/rebound/rebound.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rebound.c,v 1.102 2018/11/20 03:42:56 tedu Exp $ */ +/* $OpenBSD: rebound.c,v 1.103 2018/12/06 16:51:19 tedu Exp $ */ /* * Copyright (c) 2015 Ted Unangst <tedu@openbsd.org> * @@ -51,6 +51,14 @@ uint16_t randomid(void); +int https_init(void); +int https_connect(const char *ip, const char *name); +int https_query(uint8_t *query, size_t qlen, uint8_t *resp, size_t *resplen); + +static int https; +static char https_ip[256]; +static char https_name[256]; + union sockun { struct sockaddr a; struct sockaddr_storage s; @@ -122,7 +130,9 @@ static int connmax; static uint64_t conntotal; static int stopaccepting; -static void +static void sendreply(struct request *req, uint8_t *buf, size_t r); + +void logmsg(int prio, const char *msg, ...) { va_list ap; @@ -140,7 +150,7 @@ logmsg(int prio, const char *msg, ...) } } -static void __dead +void __dead logerr(const char *msg, ...) { va_list ap; @@ -418,6 +428,26 @@ newrequest(int ud, struct sockaddr *remoteaddr) req->cacheent = hit; } + if (https) { + int rv; + char resp[65536]; + size_t resplen; + + rv = https_query(buf, r, resp, &resplen); + if (rv != 0) { + rv = https_connect(https_ip, https_name); + if (rv == 0) + rv = https_query(buf, r, buf, &resplen); + } + if (rv != 0) { + logmsg(LOG_NOTICE, "failed to make https query"); + goto fail; + } + sendreply(req, resp, resplen); + freerequest(req); + return NULL; + } + req->s = socket(remoteaddr->sa_family, SOCK_DGRAM, 0); if (req->s == -1) goto fail; @@ -485,17 +515,13 @@ minttl(struct dnspacket *resp, u_int rlen) } static void -sendreply(struct request *req) +sendreply(struct request *req, uint8_t *buf, size_t r) { - uint8_t buf[65536]; struct dnspacket *resp; struct dnscache *ent; - size_t r; uint32_t ttl; resp = (struct dnspacket *)buf; - - r = recv(req->s, buf, sizeof(buf), 0); if (r == 0 || r == -1 || r < sizeof(struct dnspacket)) return; if (resp->id != req->reqid) @@ -540,6 +566,16 @@ sendreply(struct request *req) } } +static void +handlereply(struct request *req) +{ + uint8_t buf[65536]; + size_t r; + + r = recv(req->s, buf, sizeof(buf), 0); + sendreply(req, buf, r); +} + static struct request * tcpphasetwo(struct request *req) { @@ -743,6 +779,7 @@ readconfig(int conffd, union sockun *remoteaddr) { const char ns[] = "nameserver"; const char rc[] = "record"; + const char doh[] = "https"; char buf[1024]; char *p; struct sockaddr_in *sin = &remoteaddr->i; @@ -791,6 +828,13 @@ readconfig(int conffd, union sockun *remoteaddr) preloadA(name, value); preloadPTR(value, name); } + } else if (strncmp(buf, doh, strlen(doh)) == 0) { + p = buf + strlen(doh) + 1; + if (sscanf(p, "%255s %255s", https_ip, https_name) != 2) + logerr("do not like https line"); + https = 1; + if (rv == -1) + rv = 0; } } fclose(conf); @@ -934,7 +978,7 @@ workerloop(int conffd, int ud, int ld, int ud6, int ld6) } else { req = ke->udata; if (req->tcp == 0) - sendreply(req); + handlereply(req); freerequest(req); } break; @@ -1149,6 +1193,8 @@ main(int argc, char **argv) signal(SIGPIPE, SIG_IGN); signal(SIGUSR1, SIG_IGN); + https_init(); + while ((ch = getopt(argc, argv, "c:dl:W")) != -1) { switch (ch) { case 'c': |