Commit Diff
Diff:
086550901e1885bd5f5eb2e202ad8aba2fde928a
88afe3e8b7970dacfb9db3afcc2a70fc3d68505e
Commit:
88afe3e8b7970dacfb9db3afcc2a70fc3d68505e
Tree:
39cfa780559001730accabc590faf0279d3072e9
Author:
pjp <pjp@delphinusdns.org>
Committer:
pjp <pjp@delphinusdns.org>
Date:
Sat Jul 4 07:22:58 2020 UTC
Message:
change struct forwardentry to be a TAILQ so that we can move the active setting up or down. Also introduce a changeforwarder() function which will linearly go up or down the set forwarders. Sorry I don't have a better strategy right now. Also allow the questions to be selective whether to set the DO bit or not, this can decrease the size of non-DNSSEC answers, in the forwarder.
blob - 162345defa52cb524e9b82537010081775833342
blob + e68f9cc07d35f04155b60142b6d3e69d645e6293
--- ddd-dns.h
+++ ddd-dns.h
@@ -27,7 +27,7 @@
*/
/*
- * $Id: ddd-dns.h,v 1.18 2020/07/03 16:16:27 pjp Exp $
+ * $Id: ddd-dns.h,v 1.19 2020/07/04 07:22:58 pjp Exp $
*/
#ifndef _DNS_H
@@ -309,6 +309,7 @@ struct sforward {
uint16_t type;
uint16_t class;
uint16_t edns0len;
+ int dnssecok;
int havemac;
char tsigname[256];
blob - f296919549cd942532b6571e45e36e1e1a14d0d4
blob + bde90baa4837ff88081c4a469f27e5a3e299ba57
--- delphinusdnsd.c
+++ delphinusdnsd.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: delphinusdnsd.c,v 1.114 2020/07/03 18:13:49 pjp Exp $
+ * $Id: delphinusdnsd.c,v 1.115 2020/07/04 07:22:58 pjp Exp $
*/
@@ -2128,6 +2128,7 @@ forwardudp:
sforward->type = question->hdr->qtype;
sforward->class = question->hdr->qclass;
sforward->edns0len = question->edns0len;
+ sforward->dnssecok = question->dnssecok;
if (question->tsig.have_tsig && question->tsig.tsigverified) {
sforward->havemac = 1;
@@ -3167,6 +3168,7 @@ forwardtcp:
sforward->class = question->hdr->qclass;
sforward->edns0len = question->edns0len;
+ sforward->dnssecok = question->dnssecok;
if (question->tsig.have_tsig && question->tsig.tsigverified) {
sforward->havemac = 1;
blob - 8bf2e1c9d53d6d2da70c963c235366cc4d139d81
blob + 63136f068f1abc3617e46d6484dfab000a4c3df7
--- forward.c
+++ forward.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: forward.c,v 1.9 2020/07/03 17:47:32 pjp Exp $
+ * $Id: forward.c,v 1.10 2020/07/04 07:22:58 pjp Exp $
*/
#include <sys/types.h>
@@ -82,21 +82,21 @@
#include "ddd-dns.h"
#include "ddd-db.h"
-SLIST_HEAD(, forwardentry) forwardhead;
+TAILQ_HEAD(forwardentrys, forwardentry) forwardhead;
-static struct forwardentry {
+struct forwardentry {
char name[INET6_ADDRSTRLEN];
int family;
struct sockaddr_storage host;
uint16_t destport;
char *tsigkey;
int active;
- SLIST_ENTRY(forwardentry) forward_entry;
+ TAILQ_ENTRY(forwardentry) forward_entry;
} *fw2, *fwp;
SLIST_HEAD(, forwardqueue) fwqhead;
-static struct forwardqueue {
+struct forwardqueue {
uint32_t longid; /* a long identifier */
time_t time; /* time created */
struct sockaddr_storage host; /* remote host to query */
@@ -119,6 +119,7 @@ static struct forwardqueue {
char oldkeyname[256]; /* old key name */
int oldkeynamelen; /* old key name len */
char oldmac[32]; /* old mac */
+ struct forwardentry *cur_forwardentry; /* current forwardentry */
SLIST_ENTRY(forwardqueue) entries; /* next entry */
} *fwq1, *fwq2, *fwqp;
@@ -140,6 +141,7 @@ void sendit(struct forwardqueue *, struct sforward *);
void returnit(struct cfg *cfg, struct forwardqueue *, char *, int, struct imsgbuf *);
struct tsig * check_tsig(char *, int, char *);
void fwdparseloop(struct imsgbuf *);
+void changeforwarder(struct forwardqueue *);
extern void dolog(int, char *, ...);
extern void pack16(char *, u_int16_t);
@@ -163,13 +165,13 @@ extern int dnssec;
/*
- * INIT_FORWARD - initialize the forward singly linked list
+ * INIT_FORWARD - initialize the forward linked lists
*/
void
init_forward(void)
{
- SLIST_INIT(&forwardhead);
+ TAILQ_INIT(&forwardhead);
SLIST_INIT(&fwqhead);
return;
}
@@ -181,6 +183,8 @@ init_forward(void)
int
insert_forward(int family, struct sockaddr_storage *ip, uint16_t port, char *tsigkey)
{
+ static int active = 0;
+
fw2 = calloc(1, sizeof(struct forwardentry));
if (fw2 == NULL) {
dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
@@ -211,9 +215,12 @@ insert_forward(int family, struct sockaddr_storage *ip
}
}
- fw2->active = 1;
+ if (! active)
+ fw2->active = 1;
+
+ active = 1;
- SLIST_INSERT_HEAD(&forwardhead, fw2, forward_entry);
+ TAILQ_INSERT_HEAD(&forwardhead, fw2, forward_entry);
return (0);
}
@@ -443,13 +450,13 @@ forwardthis(int so, struct sforward *sforward)
if (fwq1 == NULL) {
/* create a new queue and send it */
- SLIST_FOREACH(fw2, &forwardhead, forward_entry) {
+ TAILQ_FOREACH(fw2, &forwardhead, forward_entry) {
if (fw2->active == 1)
break;
}
if (fw2 == NULL) {
- SLIST_FOREACH(fwp, &forwardhead, forward_entry) {
+ TAILQ_FOREACH(fwp, &forwardhead, forward_entry) {
if (fwp != fw2) {
fw2 = fwp;
fw2->active = 1;
@@ -485,6 +492,7 @@ forwardthis(int so, struct sforward *sforward)
fwq1->oldid = sforward->header.id;
fwq1->port = fw2->destport;
+ fwq1->cur_forwardentry = fw2;
fwq1->longid = arc4random();
fwq1->id = fwq1->longid % 0xffff;
fwq1->time = now;
@@ -523,6 +531,9 @@ forwardthis(int so, struct sforward *sforward)
if (connect(fwq1->so, (struct sockaddr *)&fwq1->host, namelen) < 0) {
dolog(LOG_ERR, "FORWARD can't connect: %s\n", strerror(errno));
+
+ changeforwarder(fwq1);
+
if (fwq1->tsigkey)
free(fwq1->tsigkey);
@@ -630,7 +641,7 @@ sendit(struct forwardqueue *fwq, struct sforward *sfor
/* additionals */
- if (dnssec)
+ if (dnssec && sforward->dnssecok)
q->dnssecok = 1;
outlen = additional_opt(q, packet, 0xffff, len);
@@ -648,9 +659,16 @@ sendit(struct forwardqueue *fwq, struct sforward *sfor
if (fwq->istcp == 1) {
pack16(buf, htons(len));
- send(fwq->so, buf, len + 2, 0);
- } else
- send(fwq->so, buf, len, 0);
+ if (send(fwq->so, buf, len + 2, 0) < 0) {
+ dolog(LOG_INFO, "send() failed changing forwarder: %s\n", strerror(errno));
+ changeforwarder(fwq);
+ }
+ } else {
+ if (send(fwq->so, buf, len, 0) < 0) {
+ dolog(LOG_INFO, "send() failed (udp) changing forwarder %s\n", strerror(errno));
+ changeforwarder(fwq);
+ }
+ }
free(buf);
@@ -1435,4 +1453,24 @@ fwdparseloop(struct imsgbuf *ibuf)
} /* for(;;) */
/* NOTREACHED */
+}
+
+void
+changeforwarder(struct forwardqueue *fwq)
+{
+ fw2 = fwq->cur_forwardentry;
+
+ if ((fwp = TAILQ_PREV(fw2, forwardentrys, forward_entry)) == NULL) {
+ if ((fwp = TAILQ_NEXT(fw2, forward_entry)) == NULL) {
+ return;
+ }
+
+ fw2->active = 0;
+ fwp->active = 1;
+ } else {
+ fw2->active = 0;
+ fwp->active = 1;
+ }
+
+ return;
}
repomaster@centroid.eu