Commit Diff
Diff:
fef6b099649fff857e85cd54cee9e4ed6af6c8fd
d774e9584a08eb515b70fd4085d78edb445e770f
Commit:
d774e9584a08eb515b70fd4085d78edb445e770f
Tree:
9760b1f4b9b576729c19595982677071c4579372
Author:
pjp <pjp@delphinusdns.org>
Committer:
pjp <pjp@delphinusdns.org>
Date:
Tue Jun 30 14:06:21 2020 UTC
Message:
basic forwarding stuff, I had to break it off at around 11AM due to migraine I'm hoping by thursday or friday there will be more to fill
blob - 74d9c8f4cef5e8d45ce00e4aa9450816387dc260
blob + 632dd9bce43b3f18adc72ffbc01718207433a1c3
--- ddd-db.h
+++ ddd-db.h
@@ -27,7 +27,7 @@
*/
/*
- * $Id: ddd-db.h,v 1.35 2020/06/30 07:09:46 pjp Exp $
+ * $Id: ddd-db.h,v 1.36 2020/06/30 14:06:21 pjp Exp $
*/
#ifndef _DB_H
@@ -61,6 +61,8 @@
#define IMSG_NOTIFY_MESSAGE 9 /* notify our replicant engine */
#define IMSG_SETUP_NEURON 10 /* set up a new imsg via fd passing */
#define IMSG_CRIPPLE_NEURON 11 /* no new neurons are needed */
+#define IMSG_FORWARD_UDP 12 /* forward a UDP packet */
+#define IMSG_FORWARD_TCP 13 /* forward a TCP packet (with fd) */
#define ERR_DROP 0x1
#define ERR_NXDOMAIN 0x2
@@ -417,6 +419,12 @@ struct raxfr_logic {
int rrtype;
int dnssec;
int (*raxfr)(FILE *, u_char *, u_char *, u_char *, struct soa *, u_int16_t, HMAC_CTX *);
+};
+
+struct forward {
+ struct sockaddr_in from;
+ char buf[4000]; /* the maximum payload of an imsg is 0xffff */
+ int buflen;
};
#endif /* _DB_H */
blob - 8120ea5739628e087ad59c397794e34f26ab67cd
blob + 8b27b9b0c553ff5d28878480eb4e50d029206c1a
--- delphinusdnsd.c
+++ delphinusdnsd.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: delphinusdnsd.c,v 1.107 2020/06/30 07:30:36 pjp Exp $
+ * $Id: delphinusdnsd.c,v 1.108 2020/06/30 14:06:21 pjp Exp $
*/
@@ -104,7 +104,7 @@ extern void unpack(char *, char *, int);
extern void add_rrlimit(int, u_int16_t *, int, char *);
extern void axfrloop(int *, int, char **, ddDB *, struct imsgbuf *);
-extern void forwardloop(ddDB *, struct imsgbuf *);
+extern void forwardloop(ddDB *, struct cfg *, struct imsgbuf *);
extern void replicantloop(ddDB *, struct imsgbuf *);
extern struct question *build_fake_question(char *, int, u_int16_t, char *, int);
extern int check_ent(char *, int);
@@ -626,10 +626,16 @@ main(int argc, char *argv[], char *environ[])
}
if (res->ai_family == AF_INET) {
+ on = 1;
if (setsockopt(udp[i], IPPROTO_IP, IP_RECVTTL,
&on, sizeof(on)) < 0) {
- dolog(LOG_INFO, "setsockopt: %s\n", strerror(errno));
+ dolog(LOG_INFO, "setsockopt: %s\n", strerror(errno));
}
+ on = 1;
+ if (setsockopt(udp[i], SOL_SOCKET, SO_REUSEPORT,
+ &on, sizeof(on)) < 0) {
+ dolog(LOG_INFO, "setsockopt: %s\n", strerror(errno));
+ }
} else if (res->ai_family == AF_INET6) {
/* RFC 3542 page 30 */
on = 1;
@@ -637,6 +643,11 @@ main(int argc, char *argv[], char *environ[])
IPV6_RECVHOPLIMIT, &on, sizeof(on)) < 0) {
dolog(LOG_INFO, "setsockopt: %s\n", strerror(errno));
}
+ on = 1;
+ if (setsockopt(udp[i], SOL_SOCKET, SO_REUSEPORT,
+ &on, sizeof(on)) < 0) {
+ dolog(LOG_INFO, "setsockopt: %s\n", strerror(errno));
+ }
}
ident[i] = bind_list[i];
@@ -771,7 +782,6 @@ main(int argc, char *argv[], char *environ[])
i--;
continue;
}
-
if ((udp[i] = socket(pifap->ifa_addr->sa_family, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
dolog(LOG_INFO, "socket: %s\n", strerror(errno));
@@ -786,10 +796,16 @@ main(int argc, char *argv[], char *environ[])
}
if (pifap->ifa_addr->sa_family == AF_INET) {
+ on = 1;
if (setsockopt(udp[i], IPPROTO_IP, IP_RECVTTL,
&on, sizeof(on)) < 0) {
dolog(LOG_INFO, "setsockopt: %s\n", strerror(errno));
}
+ on = 1;
+ if (setsockopt(udp[i], SOL_SOCKET, SO_REUSEPORT,
+ &on, sizeof(on)) < 0) {
+ dolog(LOG_INFO, "setsockopt: %s\n", strerror(errno));
+ }
} else if (pifap->ifa_addr->sa_family == AF_INET6) {
/* RFC 3542 page 30 */
on = 1;
@@ -797,6 +813,11 @@ main(int argc, char *argv[], char *environ[])
IPV6_RECVHOPLIMIT, &on, sizeof(on)) < 0) {
dolog(LOG_INFO, "setsockopt: %s\n", strerror(errno));
}
+ on = 1;
+ if (setsockopt(udp[i], SOL_SOCKET, SO_REUSEPORT,
+ &on, sizeof(on)) < 0) {
+ dolog(LOG_INFO, "setsockopt: %s\n", strerror(errno));
+ }
}
@@ -940,7 +961,7 @@ main(int argc, char *argv[], char *environ[])
}
setproctitle("FORWARD engine");
- forwardloop(db, ibuf);
+ forwardloop(db, cfg, ibuf);
/* NOTREACHED */
exit(1);
default:
@@ -1135,6 +1156,7 @@ main(int argc, char *argv[], char *environ[])
cfg->axfr[i] = uafd[i];
cfg->ident[i] = strdup(ident[i]);
+
}
(void)mainloop(cfg, &cortex_ibuf);
@@ -1481,15 +1503,24 @@ mainloop(struct cfg *cfg, struct imsgbuf *ibuf)
struct imsgbuf *pibuf;
struct imsg imsg;
+ struct forward *forward;
+
ssize_t n, datalen;
+ forward = calloc(1, sizeof(struct forward));
+ if (forward == NULL) {
+ dolog(LOG_ERR, "calloc: %s\n", strerror(errno));
+ ddd_shutdown();
+ exit(1);
+ }
+
replybuf = calloc(1, 65536);
if (replybuf == NULL) {
dolog(LOG_ERR, "calloc: %s\n", strerror(errno));
ddd_shutdown();
exit(1);
- }
+ }
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, PF_UNSPEC, &cfg->my_imsg[MY_IMSG_PARSER].imsg_fds[0]) < 0) {
dolog(LOG_INFO, "socketpair() failed\n");
@@ -1563,7 +1594,6 @@ mainloop(struct cfg *cfg, struct imsgbuf *ibuf)
}
#endif
-
sp = cfg->recurse;
for (;;) {
@@ -1994,6 +2024,20 @@ axfrentry:
case ERR_FORWARD:
snprintf(replystring, DNS_MAXNAME, "FORWARD");
/* send query to forward process/cortex */
+
+ if (len > 4000) {
+ dolog(LOG_INFO, "question is larger than 4000 bytes, not forwarding\n");
+ goto udpout;
+ }
+
+ forward->from.sin_addr.s_addr = sin->sin_addr.s_addr;
+ memcpy(&forward->buf, buf, len);
+ forward->buflen = len;
+
+ imsg_compose(ibuf, IMSG_FORWARD_UDP,
+ 0, 0, -1, forward, sizeof(struct forward));
+
+ msgbuf_write(&ibuf->w);
goto udpout;
break;
@@ -2966,6 +3010,10 @@ tcploop(struct cfg *cfg, struct imsgbuf *ibuf)
case ERR_FORWARD:
snprintf(replystring, DNS_MAXNAME, "FORWARD");
/* send query to forward process/cortex */
+ imsg_compose(ibuf, IMSG_FORWARD_TCP,
+ 0, 0, tcpnp->so, &tcpnp->buf, tcpnp->bytes_read);
+
+ msgbuf_write(&ibuf->w);
goto tcpout;
break;
@@ -3851,6 +3899,37 @@ setup_cortex(struct imsgbuf *ibuf)
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
switch(imsg.hdr.type) {
+ /* forward duplicated sockets to forward process */
+ case IMSG_FORWARD_TCP:
+ SLIST_FOREACH(neup2, &neuronhead, entries) {
+ if (neup2->desc == MY_IMSG_FORWARD)
+ break;
+ }
+ /* didn't find it? skip */
+ if (neup2 == NULL) {
+ /* XXX this can't fail but if it does, throw so out */
+ close(imsg.fd);
+ break;
+ }
+
+ imsg_compose(&neup2->ibuf, IMSG_FORWARD_TCP, 0, 0, imsg.fd, imsg.data, datalen);
+ msgbuf_write(&neup2->ibuf.w);
+
+ break;
+ case IMSG_FORWARD_UDP:
+ SLIST_FOREACH(neup2, &neuronhead, entries) {
+ if (neup2->desc == MY_IMSG_FORWARD)
+ break;
+ }
+ /* didn't find it? skip */
+ if (neup2 == NULL)
+ break;
+
+ imsg_compose(&neup2->ibuf, IMSG_FORWARD_UDP, 0, 0, -1, imsg.data, datalen);
+ msgbuf_write(&neup2->ibuf.w);
+
+ break;
+
/* hellos go to the master */
case IMSG_HELLO_MESSAGE:
case IMSG_SHUTDOWN_MESSAGE:
blob - 14739fa13440e7032da1e70aeb89c3ef85995794
blob + 6b8b830644a1e6ec18b4295a94153c588d5ff5bb
--- forward.c
+++ forward.c
@@ -27,13 +27,14 @@
*/
/*
- * $Id: forward.c,v 1.1 2020/06/30 07:09:46 pjp Exp $
+ * $Id: forward.c,v 1.2 2020/06/30 14:06:21 pjp Exp $
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <sys/uio.h>
+#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -81,7 +82,8 @@
void init_forward(void);
int insert_forward(void);
-void forwardloop(ddDB *, struct imsgbuf *);
+void forwardloop(ddDB *, struct cfg *, struct imsgbuf *);
+void forwardthis(int, struct forward *);
extern void dolog(int, char *, ...);
@@ -125,12 +127,78 @@ insert_forward(void)
}
void
-forwardloop(ddDB *db, struct imsgbuf *ibuf)
+forwardloop(ddDB *db, struct cfg *cfg, struct imsgbuf *ibuf)
{
+ struct imsg imsg;
+ int max, sel;
+ ssize_t n, datalen;
+ fd_set rset;
+ for (;;) {
+ FD_ZERO(&rset);
+ FD_SET(ibuf->fd, &rset);
+ if (ibuf->fd > max)
+ max = ibuf->fd;
+
+ sel = select(max + 1, &rset, NULL, NULL, NULL);
+ if (sel == -1) {
+ continue;
+ }
+ if (FD_ISSET(ibuf->fd, &rset)) {
+
+ if ((n = imsg_read(ibuf)) < 0 && errno != EAGAIN) {
+ dolog(LOG_ERR, "imsg read failure %s\n", strerror(errno));
+ continue;
+ }
+ if (n == 0) {
+ /* child died? */
+ dolog(LOG_INFO, "sigpipe on child? exiting.\n");
+ exit(1);
+ }
+
+ for (;;) {
+ if ((n = imsg_get(ibuf, &imsg)) < 0) {
+ dolog(LOG_ERR, "imsg read error: %s\n", strerror(errno));
+ break;
+ } else {
+ if (n == 0)
+ break;
+
+ datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
+ if (datalen != sizeof(struct forward)) {
+ imsg_free(&imsg);
+ continue;
+ }
+
+ switch(imsg.hdr.type) {
+ case IMSG_FORWARD_UDP:
+ dolog(LOG_INFO, "received UDP message from mainloop\n");
+ forwardthis(-1, imsg.data);
+ break;
+
+ case IMSG_FORWARD_TCP:
+ dolog(LOG_INFO, "received TCP message and descriptor\n");
+ forwardthis(imsg.fd, imsg.data);
+ break;
+ }
+
+ imsg_free(&imsg);
+ }
+ } /* for (;;) */
+ } /* FD_ISSET... */
+ }
+
while (1)
sleep(10);
/* NOTREACHED */
+
+}
+
+void
+forwardthis(int so, struct forward *forward)
+{
+
+
}
repomaster@centroid.eu