From 84154d027ddfd6b1d65d84ebd315437a843a4913 Mon Sep 17 00:00:00 2001 From: Ted Unangst Date: Thu, 1 Sep 2016 10:54:37 +0000 Subject: scan responses for minimum ttl, and cache for min(ttl, 300) instead of a fixed amount --- usr.sbin/rebound/rebound.c | 63 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 10 deletions(-) (limited to 'usr.sbin/rebound') diff --git a/usr.sbin/rebound/rebound.c b/usr.sbin/rebound/rebound.c index 0f560e9f771..aabfdeb9bf8 100644 --- a/usr.sbin/rebound/rebound.c +++ b/usr.sbin/rebound/rebound.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rebound.c,v 1.67 2016/08/21 21:23:48 tedu Exp $ */ +/* $OpenBSD: rebound.c,v 1.68 2016/09/01 10:54:36 tedu Exp $ */ /* * Copyright (c) 2015 Ted Unangst * @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,8 @@ #include #include +#define MINIMUM(a,b) (((a)<(b))?(a):(b)) + uint16_t randomid(void); union sockthing { @@ -60,14 +63,6 @@ struct dnspacket { /* ... */ }; -struct dnsrr { - uint16_t type; - uint16_t class; - uint32_t ttl; - uint16_t rdatalen; - /* ... */ -}; - /* * requests will point to cache entries until a response is received. * until then, the request owns the entry and must free it. @@ -302,6 +297,50 @@ fail: return NULL; } +static uint32_t +minttl(struct dnspacket *resp, size_t rlen) +{ + uint32_t minttl = UINT_MAX, ttl, cnt, i; + uint16_t len; + char *p = (char *)resp; + char *end = p + rlen; + + /* skip past packet header */ + p += sizeof(struct dnspacket); + if (p >= end) + return -1; + if (ntohs(resp->qdcount) != 1) + return -1; + /* skip past query name, type, and class */ + p += strnlen(p, end - p); + p += 2; + p += 2; + cnt = ntohs(resp->ancount); + for (i = 0; i < cnt; i++) { + if (p >= end) + return -1; + /* skip past answer name, type, and class */ + p += strnlen(p, end - p); + p += 2; + p += 2; + if (p + 4 >= end) + return -1; + memcpy(&ttl, p, 4); + p += 4; + if (p + 2 >= end) + return -1; + ttl = ntohl(ttl); + if (ttl < minttl) + minttl = ttl; + memcpy(&len, p, 2); + p += 2; + p += ntohs(len); + } + return minttl; +} + + + static void sendreply(int ud, struct request *req) { @@ -309,6 +348,7 @@ sendreply(int ud, struct request *req) struct dnspacket *resp; struct dnscache *ent; size_t r; + uint32_t ttl; resp = (struct dnspacket *)buf; @@ -327,8 +367,11 @@ sendreply(int ud, struct request *req) */ if (RB_INSERT(cachetree, &cachetree, ent)) return; + ttl = minttl(resp, r); + if (ttl == -1) + ttl = 0; ent->ts = now; - ent->ts.tv_sec += 10; + ent->ts.tv_sec += MINIMUM(ttl, 300); ent->resp = malloc(r); if (!ent->resp) { RB_REMOVE(cachetree, &cachetree, ent); -- cgit v1.2.3