summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2015-10-15 22:12:27 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2015-10-15 22:12:27 +0000
commit7231c3d0557db854c0bb1565cec8d6d205256865 (patch)
tree56e6fb3fa9197824d4d322a19e707d74298b83d2
parentd34caa49d0a4b589aa1426dd3dbd9418ecb2ef25 (diff)
better memory handling of the request/cache chain
-rw-r--r--usr.sbin/rebound/rebound.c32
1 files 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 <tedu@openbsd.org>
*
@@ -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);
}