Commit Diff
Diff:
26a7272464db1ebf3cb69c1c3c01f51f71cd8269
f199772ae75419e09da38055b9611e6a0bab8882
Commit:
f199772ae75419e09da38055b9611e6a0bab8882
Tree:
3e9ad3a0f47053100374d1480e0eb460c9383ec0
Author:
pjp <pjp@delphinusdns.org>
Committer:
pjp <pjp@delphinusdns.org>
Date:
Tue Jul 14 14:46:23 2020 UTC
Message:
convert struct fwdpq to the name struct pkt_imsg and make it 16384 bytes large this means it will always be on a page-aligned boundary, meaning to me it will be faster. Also convert values that may or may not be on a 16 bytes aligned offset to use pack32() functions. Also this fixes a case where a lock could be held indefiniately due to an error condition.
blob - 885300cbdde79cd1cb062ad089df437438cc3efc
blob + 1e0d350e6cef2ecb323d98fd0173b40776f591f7
--- ddd-db.h
+++ ddd-db.h
@@ -27,7 +27,7 @@
*/
/*
- * $Id: ddd-db.h,v 1.45 2020/07/14 07:00:18 pjp Exp $
+ * $Id: ddd-db.h,v 1.46 2020/07/14 14:46:23 pjp Exp $
*/
#ifndef _DB_H
@@ -506,18 +506,24 @@ struct rr_imsg {
#define rri_rr u.s.rr
}; /* end of struct rr_imsg */
-struct fwdpq {
- int read; /* 4 */
- int rc; /* 8 */
- int istcp; /* 12 */
- int cache; /* 16 */
- int tsigcheck; /* 20 */
- struct tsig tsig; /* 600 */
- char mac[32]; /* 632 */
- int buflen; /* 636 */
+struct pkt_imsg {
+ union {
+ struct {
+ int read;
+ int rc;
+ int istcp;
+ int cache;
+ int tsigcheck;
+ struct tsig tsig;
+ char mac[32];
+ int buflen;
+ char buf[0];
+ } s;
- char buf[16384];
-};
+ char buf[16384];
+ } u;
+#define pkt_s u.s
+}; /* 16384 */
#define SHAREDMEMSIZE 400
blob - a61da49abba2459b1350f9cba0d8db7fe42218de
blob + f4303a0b0feb1cd0707435f32566aefe249961ff
--- delphinusdnsd.c
+++ delphinusdnsd.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: delphinusdnsd.c,v 1.124 2020/07/13 22:02:26 pjp Exp $
+ * $Id: delphinusdnsd.c,v 1.125 2020/07/14 14:46:23 pjp Exp $
*/
@@ -334,7 +334,7 @@ main(int argc, char *argv[], char *environ[])
struct imsgbuf *ibuf;
struct rr_imsg *ri = NULL;
struct sf_imsg *sf = NULL;
- struct fwdpq *fwdpq = NULL;
+ struct pkt_imsg *pi = NULL;
static ddDB *db;
@@ -1047,7 +1047,7 @@ main(int argc, char *argv[], char *environ[])
cfg->shptr2 = shptr;
cfg->shptr2size = shsize;
- shsize = 16 + (SHAREDMEMSIZE3 * sizeof(struct fwdpq));
+ shsize = 16 + (SHAREDMEMSIZE3 * sizeof(struct pkt_imsg));
shptr = mmap(NULL, shsize, PROT_READ | PROT_WRITE, MAP_SHARED |\
MAP_ANON, -1, 0);
@@ -1058,8 +1058,8 @@ main(int argc, char *argv[], char *environ[])
}
/* initialize */
- for (fwdpq = (struct fwdpq *)&shptr[16], j = 0; j < SHAREDMEMSIZE3; j++, fwdpq++) {
- pack32((char *)&fwdpq->read, 1);
+ for (pi = (struct pkt_imsg *)&shptr[0], j = 0; j < SHAREDMEMSIZE3; j++, pi++) {
+ pack32((char *)&pi->pkt_s.read, 1);
}
cfg->shptr3 = shptr;
blob - adb20cf5cddc290a0519f1e98a1a7e30e7b7d5ac
blob + e5c168e55b55084931d925c4e59bc27742d60964
--- forward.c
+++ forward.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: forward.c,v 1.22 2020/07/13 22:02:26 pjp Exp $
+ * $Id: forward.c,v 1.23 2020/07/14 14:46:23 pjp Exp $
*/
#include <sys/types.h>
@@ -1139,7 +1139,8 @@ returnit(ddDB *db, struct cfg *cfg, struct forwardqueu
struct timeval tv;
struct dns_header *dh;
struct question *q;
- struct fwdpq *fwdpq, *fwdpq0;
+ static struct pkt_imsg *pi = NULL;
+ struct pkt_imsg *pi0;
struct imsg imsg;
static char *buf = NULL;
@@ -1193,65 +1194,68 @@ returnit(ddDB *db, struct cfg *cfg, struct forwardqueu
}
/* send it on to our sandbox */
- fwdpq = (struct fwdpq *)calloc(1, sizeof(struct fwdpq));
- if (fwdpq == NULL) {
- dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
- return;
+ if (pi == NULL) {
+ pi = (struct pkt_imsg *)calloc(1, sizeof(struct pkt_imsg));
+ if (pi == NULL) {
+ dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
+ return;
+ }
+ } else {
+ memset(pi, 0, sizeof(struct pkt_imsg));
}
- memcpy(&fwdpq->mac, &fwq->mac, sizeof(fwdpq->mac));
+ memcpy(&pi->pkt_s.mac, &fwq->mac, sizeof(pi->pkt_s.mac));
if (fwq->istcp) {
- fwdpq->buflen = rlen;
+ pack32((char *)&pi->pkt_s.buflen, rlen);
} else {
- if (rlen > sizeof(fwdpq->buf)) {
- dolog(LOG_INFO, "can't send packet to parser, too big\n");
+ if (rlen > (sizeof(struct pkt_imsg) - sizeof(pi->pkt_s))) {
+ dolog(LOG_INFO, "can't send UDP packet to parser, too big\n");
return;
}
- memcpy(&fwdpq->buf[0], p, rlen);
- fwdpq->buflen = rlen;
-
+ memcpy(&pi->pkt_s.buf, p, rlen);
+ pack32((char *)&pi->pkt_s.buflen, rlen);
}
if (fwq->tsigkey)
- fwdpq->tsigcheck = 1;
+ pack32((char *)&pi->pkt_s.tsigcheck, 1);
else
- fwdpq->tsigcheck = 0;
+ pack32((char *)&pi->pkt_s.tsigcheck, 0);
if (cache)
- fwdpq->cache = 1;
+ pack32((char *)&pi->pkt_s.cache, 1);
else
- fwdpq->cache = 0;
+ pack32((char *)&pi->pkt_s.cache, 0);
if (fwq->istcp)
- fwdpq->istcp = 1;
+ pack32((char *)&pi->pkt_s.istcp, 1);
else
- fwdpq->istcp = 0;
+ pack32((char *)&pi->pkt_s.istcp, 0);
/* lock */
- while (cfg->shptr3[0] == '*')
+ while (cfg->shptr3[cfg->shptr3size - 16] == '*')
usleep(arc4random() % 300);
- cfg->shptr3[0] = '*';
+ cfg->shptr3[cfg->shptr3size - 16] = '*';
- fwdpq0 = (struct fwdpq *)&cfg->shptr3[16];
- for (i = 0; i < SHAREDMEMSIZE3; i++, fwdpq0++) {
- if (unpack32((char *)&fwdpq0->read) == 1) {
- memcpy(fwdpq0, fwdpq, sizeof(struct fwdpq));
- pack32((char *)&fwdpq0->read, 0);
+ pi0 = (struct pkt_imsg *)&cfg->shptr3[0];
+ for (i = 0; i < SHAREDMEMSIZE3; i++, pi0++) {
+ if (unpack32((char *)&pi0->pkt_s.read) == 1) {
+ memcpy(pi0, pi, sizeof(struct pkt_imsg));
+ pack32((char *)&pi0->pkt_s.read, 0);
break;
}
}
if (imsg_compose(ibuf, IMSG_PARSE_MESSAGE, 0, 0, (fwq->istcp == 1) ? fwq->so : -1, &i, sizeof(i)) < 0) {
dolog(LOG_INFO, "imsg_compose: %s\n", strerror(errno));
- free(fwdpq);
+ cfg->shptr3[cfg->shptr3size - 16] = ' ';
return;
}
msgbuf_write(&ibuf->w);
- cfg->shptr3[0] = ' ';
+ cfg->shptr3[cfg->shptr3size - 16] = ' ';
for (;;) {
FD_ZERO(&rset);
@@ -1317,7 +1321,6 @@ returnit(ddDB *db, struct cfg *cfg, struct forwardqueu
if (datalen != sizeof(int)) {
dolog(LOG_ERR, "bad parsereply message, drop\n");
imsg_free(&imsg);
- free(fwdpq);
return;
}
@@ -1326,7 +1329,6 @@ returnit(ddDB *db, struct cfg *cfg, struct forwardqueu
if (rc != PARSE_RETURN_ACK) {
dolog(LOG_ERR, "returnit parser did not ACK this (%d), drop\n", rc);
imsg_free(&imsg);
- free(fwdpq);
return;
}
@@ -1337,25 +1339,24 @@ returnit(ddDB *db, struct cfg *cfg, struct forwardqueu
if (datalen != sizeof(int)) {
dolog(LOG_ERR, "bad parsereply message, drop\n");
imsg_free(&imsg);
- free(fwdpq);
return;
}
memcpy(&i, imsg.data, sizeof(int));
/* lock */
- while (cfg->shptr3[0] == '*')
+ while (cfg->shptr3[cfg->shptr3size - 16] == '*')
usleep(arc4random() % 300);
- cfg->shptr3[0] = '*';
+ cfg->shptr3[cfg->shptr3size - 16] = '*';
- fwdpq0 = (struct fwdpq *)&cfg->shptr3[16];
- fwdpq0 = &fwdpq0[i];
+ pi0 = (struct pkt_imsg *)&cfg->shptr3[0];
+ pi0 = &pi0[i];
- memcpy(fwdpq, fwdpq0, sizeof(struct fwdpq));
+ memcpy(pi, pi0, sizeof(struct pkt_imsg));
- pack32((char *)&fwdpq0->read, 1);
- cfg->shptr3[0] = ' ';
+ pack32((char *)&pi0->pkt_s.read, 1);
+ cfg->shptr3[cfg->shptr3size - 16] = ' ';
if (fwq->istcp == 1)
fwq->so = imsg.fd;
@@ -1376,23 +1377,22 @@ returnit(ddDB *db, struct cfg *cfg, struct forwardqueu
endimsg:
- if (fwq->tsigkey && (fwdpq->tsig.have_tsig == 0 || fwdpq->tsig.tsigverified == 0)) {
- dolog(LOG_INFO, "FORWARD returnit, TSIG didn't check out error code = %d\n", fwdpq->tsig.tsigerrorcode);
- free(fwdpq);
+ if (fwq->tsigkey && (unpack32((char *)&pi->pkt_s.tsig.have_tsig) == 0 \
+ || unpack32((char *)&pi->pkt_s.tsig.tsigverified) == 0)) {
+ dolog(LOG_INFO, "FORWARD returnit, TSIG didn't check out error code = %d\n", unpack32((char *)&pi->pkt_s.tsig.tsigerrorcode));
return;
}
- if (fwdpq->tsig.have_tsig) {
+ if (unpack32((char *)&pi->pkt_s.tsig.have_tsig) == 1) {
NTOHS(dh->additional);
if (dh->additional > 0)
dh->additional--;
HTONS(dh->additional);
}
- if (fwdpq->tsigcheck)
- rlen = fwdpq->tsig.tsigoffset;
+ if (unpack32((char *)&pi->pkt_s.tsigcheck) == 1)
+ rlen = unpack32((char *)&pi->pkt_s.tsig.tsigoffset);
- free(fwdpq);
/* add new tsig if needed */
pack16((char *)&dh->id, fwq->oldid);
@@ -1885,7 +1885,7 @@ fwdparseloop(struct imsgbuf *ibuf, struct imsgbuf *bib
int rlen, tmp, rc, i;
struct tsig *stsig = NULL;
- struct fwdpq *fwdpq, *fwdpq0;
+ struct pkt_imsg *pi, *pi0;
struct imsg imsg;
struct dns_header *dh;
@@ -1914,8 +1914,8 @@ fwdparseloop(struct imsgbuf *ibuf, struct imsgbuf *bib
#endif
- fwdpq = (struct fwdpq *)calloc(1, sizeof(struct fwdpq));
- if (fwdpq == NULL) {
+ pi = (struct pkt_imsg *)calloc(1, sizeof(struct pkt_imsg));
+ if (pi == NULL) {
dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
ddd_shutdown();
exit(1);
@@ -1962,23 +1962,23 @@ fwdparseloop(struct imsgbuf *ibuf, struct imsgbuf *bib
memcpy(&i, imsg.data, datalen);
/* lock */
- while (cfg->shptr3[0] == '*')
+ while (cfg->shptr3[cfg->shptr3size - 16] == '*')
usleep(arc4random() % 300);
- cfg->shptr3[0] = '*';
+ cfg->shptr3[cfg->shptr3size - 16] = '*';
- fwdpq0 = (struct fwdpq *)&cfg->shptr3[16];
- fwdpq0 = &fwdpq0[i];
+ pi0 = (struct pkt_imsg *)&cfg->shptr3[0];
+ pi0 = &pi0[i];
- memcpy(fwdpq, fwdpq0, sizeof(struct fwdpq));
- pack32((char *)&fwdpq0->read, 1);
+ memcpy(pi, pi0, sizeof(struct pkt_imsg));
+ pack32((char *)&pi0->pkt_s.read, 1);
- cfg->shptr3[0] = ' '; /* unlock */
+ cfg->shptr3[cfg->shptr3size - 16] = ' ';
- istcp = fwdpq->istcp;
+ istcp = unpack32((char *)&pi->pkt_s.istcp);
if (istcp) {
- packet = malloc(fwdpq->buflen);
+ packet = malloc(unpack32((char *)&pi->pkt_s.buflen));
if (packet == NULL) {
dolog(LOG_INFO, "malloc %s\n", strerror(errno));
rc = PARSE_RETURN_NAK;
@@ -1988,7 +1988,7 @@ fwdparseloop(struct imsgbuf *ibuf, struct imsgbuf *bib
break;
}
- if (recv(imsg.fd, packet, fwdpq->buflen, MSG_WAITALL) < 0) {
+ if (recv(imsg.fd, packet, unpack32((char *)&pi->pkt_s.buflen), MSG_WAITALL) < 0) {
dolog(LOG_INFO, "recv in forward sandbox: %s\n", strerror(errno));
rc = PARSE_RETURN_NAK;
/* send the descriptor back to them */
@@ -1997,14 +1997,14 @@ fwdparseloop(struct imsgbuf *ibuf, struct imsgbuf *bib
free(packet);
break;
}
- dolog(LOG_INFO, "received %d bytes from descriptor %d\n", fwdpq->buflen, imsg.fd);
+ dolog(LOG_INFO, "received %d bytes from descriptor %d\n", unpack32((char *)&pi->pkt_s.buflen), imsg.fd);
} else
- packet = &fwdpq->buf[0];
+ packet = &pi->pkt_s.buf[0];
if (istcp) {
- tmp = fwdpq->buflen;
+ tmp = unpack32((char *)&pi->pkt_s.buflen);
} else {
- tmp = fwdpq->buflen;
+ tmp = unpack32((char *)&pi->pkt_s.buflen);
}
if (tmp < sizeof(struct dns_header)) {
@@ -2046,7 +2046,7 @@ fwdparseloop(struct imsgbuf *ibuf, struct imsgbuf *bib
/* insert parsing logic here */
/* check for cache */
- if (fwdpq->cache) {
+ if (unpack32((char *)&pi->pkt_s.cache)) {
estart = packet;
rlen = tmp;
end = &packet[rlen];
@@ -2058,9 +2058,9 @@ fwdparseloop(struct imsgbuf *ibuf, struct imsgbuf *bib
/* check to see if we tsig */
- if (fwdpq->tsigcheck) {
+ if (unpack32((char *)&pi->pkt_s.tsigcheck)) {
rlen = tmp;
- stsig = check_tsig((char *)packet, rlen, fwdpq->mac);
+ stsig = check_tsig((char *)packet, rlen, pi->pkt_s.mac);
if (stsig == NULL) {
dolog(LOG_INFO, "FORWARD parser, malformed reply packet\n");
rc = PARSE_RETURN_MALFORMED;
@@ -2073,18 +2073,21 @@ fwdparseloop(struct imsgbuf *ibuf, struct imsgbuf *bib
break;
}
- memcpy(&fwdpq->tsig, stsig, sizeof(struct tsig));
+ memcpy(&pi->pkt_s.tsig, stsig, sizeof(struct tsig));
}
- fwdpq->rc = PARSE_RETURN_ACK;
+ pack32((char *)&pi->pkt_s.rc, PARSE_RETURN_ACK);
- cfg->shptr3[0] = '*';
+ while (cfg->shptr3[cfg->shptr3size - 16] == '*')
+ usleep(arc4random() % 300);
- fwdpq0 = (struct fwdpq *)&cfg->shptr3[16];
- for (i = 0; i < SHAREDMEMSIZE3; i++, fwdpq0++) {
- if (unpack32((char *)&fwdpq0->read) == 1) {
- memcpy(fwdpq0, fwdpq, sizeof(struct fwdpq));
- pack32((char *)&fwdpq0->read, 0);
+ cfg->shptr3[cfg->shptr3size - 16] = '*';
+
+ pi0 = (struct pkt_imsg *)&cfg->shptr3[0];
+ for (i = 0; i < SHAREDMEMSIZE3; i++, pi0++) {
+ if (unpack32((char *)&pi0->pkt_s.read) == 1) {
+ memcpy(pi0, pi, sizeof(struct pkt_imsg));
+ pack32((char *)&pi0->pkt_s.read, 0);
break;
}
}
@@ -2092,7 +2095,7 @@ fwdparseloop(struct imsgbuf *ibuf, struct imsgbuf *bib
imsg_compose(ibuf, IMSG_PARSEREPLY_MESSAGE, 0, 0, (istcp) ? imsg.fd : -1, &i, sizeof(int));
msgbuf_write(&ibuf->w);
- cfg->shptr3[0] = ' ';
+ cfg->shptr3[cfg->shptr3size - 16] = ' ';
free(stsig);
repomaster@centroid.eu