From 8ef28c6244f3bac327174bd72e9a899f45244f00 Mon Sep 17 00:00:00 2001 From: tedu Date: Thu, 15 Oct 2015 22:12:26 +0000 Subject: [PATCH] better memory handling of the request/cache chain --- usr.sbin/rebound/rebound.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/usr.sbin/rebound/rebound.c b/usr.sbin/rebound/rebound.c index 28ea943ecff..a6ee07e8726 100644 --- a/usr.sbin/rebound/rebound.c +++ b/usr.sbin/rebound/rebound.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rebound.c,v 1.11 2015/10/15 21:59:54 tedu Exp $ */ +/* $OpenBSD: rebound.c,v 1.12 2015/10/15 22:12:26 tedu Exp $ */ /* * Copyright (c) 2015 Ted Unangst * @@ -59,6 +59,12 @@ struct dnsrr { /* ... */ }; +/* + * requests will point to cache entries until a response is received. + * until then, the request owns the entry and must free it. + * after it's on the list, the request must not free it. + */ + struct dnscache { TAILQ_ENTRY(dnscache) cache; struct dnspacket *req; @@ -194,6 +200,7 @@ newrequest(int ud, struct sockaddr *remoteaddr) return req; fail: + free(hit); close(req->s); free(req); return NULL; @@ -204,6 +211,7 @@ sendreply(int ud, struct request *req) { uint8_t buf[65536]; struct dnspacket *resp; + struct dnscache *ent; size_t r; resp = (struct dnspacket *)buf; @@ -215,24 +223,30 @@ sendreply(int ud, struct request *req) return; resp->id = req->clientid; sendto(ud, buf, r, 0, &req->from, req->fromlen); - if (req->cacheent) { - req->cacheent->ts = now; - req->cacheent->ts.tv_sec += 10; - req->cacheent->resp = malloc(r); - if (!req->cacheent->resp) + if ((ent = req->cacheent)) { + ent->ts = now; + ent->ts.tv_sec += 10; + ent->resp = malloc(r); + if (!ent->resp) return; - memcpy(req->cacheent->resp, buf, r); - req->cacheent->resplen = r; - TAILQ_INSERT_TAIL(&cache, req->cacheent, cache); + memcpy(ent->resp, buf, r); + ent->resplen = r; + TAILQ_INSERT_TAIL(&cache, ent, cache); } } void freerequest(struct request *req) { + struct dnscache *ent; + TAILQ_REMOVE(&reqfifo, req, fifo); close(req->client); close(req->s); + if ((ent = req->cacheent) && !ent->resp) { + free(ent->req); + free(ent); + } free(req); } -- 2.20.1