ref: 2402025982aa44c91e452fd792abdfc880461944
parent: 358551de19c9ff5bab9cd9c98769224f63fb7e94
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Jan 4 14:25:05 EST 2023
ndb/dns: allow specifying local ip addresses for serving dns Allow specifying the local IP addresses that the UDP dns server will listen on when the -s flag is given.
--- a/sys/man/8/ndb
+++ b/sys/man/8/ndb
@@ -57,7 +57,7 @@
.br
.B ndb/dns
[
-.B -norRs
+.B -norR
] [
.B -a
.I maxage
@@ -73,7 +73,12 @@
] [
.B -z
.I program
+] [
+.B -s
+[
+.I addrs...
]
+]
.br
.B ndb/dnstcp
[
@@ -390,7 +395,13 @@
Do not complete lookups on behalf of remote systems.
.TP
.B -s
-also answer domain requests sent to UDP port 53.
+also answer domain requests sent to IP
+.I addrs
+on UDP port 53.
+If no IP
+.I addrs
+are given, listen on any interface on network mount point
+.IR netmtpt .
.TP
.B -x
specifies the mount point of the
--- a/sys/src/cmd/ndb/dn.c
+++ b/sys/src/cmd/ndb/dn.c
@@ -144,7 +144,6 @@
ding(void*, char *msg)
{
if(strstr(msg, "alarm") != nil) {
- stats.alarms++;
noted(NCONT); /* resume with system call error */
} else
noted(NDFLT); /* die */
--- a/sys/src/cmd/ndb/dnnotify.c
+++ b/sys/src/cmd/ndb/dnnotify.c
@@ -73,7 +73,7 @@
/* notify a slave that an area has changed. */
static void
-send_notify(char *slave, RR *soa, Request *req)
+send_notify(char *mntpt, char *slave, RR *soa, Request *req)
{
int i, j, len, n, reqno, fd, nips, send;
uchar ips[8*IPaddrlen], ibuf[Maxudp+Udphdrsize], obuf[Maxudp+Udphdrsize];
@@ -91,7 +91,7 @@
reqno = rand();
n = mkreq(soa->owner, Cin, obuf, Fauth | Onotify, reqno);
- fd = udpport(nil);
+ fd = udpport(mntpt);
if(fd < 0)
return;
@@ -130,7 +130,7 @@
/* send notifies for any updated areas */
static void
-notify_areas(Area *a, Request *req)
+notify_areas(char *mntpt, Area *a, Request *req)
{
Server *s;
@@ -140,7 +140,7 @@
/* send notifies to all slaves */
for(s = a->soarr->soa->slaves; s != nil; s = s->next)
- send_notify(s->name, a->soarr, req);
+ send_notify(mntpt, s->name, a->soarr, req);
a->neednotify = 0;
}
}
@@ -150,7 +150,7 @@
* (also reads in new databases)
*/
void
-notifyproc(void)
+notifyproc(char *mntpt)
{
Request req;
@@ -169,7 +169,7 @@
for(;;){
getactivity(&req, 0);
- notify_areas(owned, &req);
+ notify_areas(mntpt, owned, &req);
putactivity(0);
sleep(60*1000);
}
--- a/sys/src/cmd/ndb/dnresolve.c
+++ b/sys/src/cmd/ndb/dnresolve.c
@@ -473,38 +473,40 @@
}
/*
- * Get a udp port for sending requests and reading replies. Put the port
- * into "headers" mode.
+ * Get a udp port for sending requests and reading replies.
+ * Put the port into "headers" mode.
*/
-static char *hmsg = "headers";
-
int
-udpport(char *mtpt)
+udpport(char *mntpt)
{
- int fd, ctl;
+ static char hmsg[] = "headers";
+ static char imsg[] = "ignoreadvice";
+
char ds[64], adir[64];
+ int fd, ctl;
/* get a udp port */
- snprint(ds, sizeof ds, "%s/udp!*!0", (mtpt && *mtpt) ? mtpt : "/net");
+ snprint(ds, sizeof ds, "%s/udp!*!0", mntpt);
ctl = announce(ds, adir);
- if(ctl < 0){
- /* warning("can't get udp port"); */
+ if(ctl < 0)
return -1;
- }
/* turn on header style interface */
- if(write(ctl, hmsg, strlen(hmsg)) != strlen(hmsg)){
+ if(write(ctl, hmsg, sizeof(hmsg)-1) < 0){
+ warning("can't enable %s on %s: %r", hmsg, adir);
close(ctl);
- warning(hmsg);
return -1;
}
+ /* ignore ICMP advice */
+ write(ctl, imsg, sizeof(imsg)-1);
+
/* grab the data file */
snprint(ds, sizeof ds, "%s/data", adir);
fd = open(ds, ORDWR);
- close(ctl);
if(fd < 0)
warning("can't open udp port %s: %r", ds);
+ close(ctl);
return fd;
}
--- a/sys/src/cmd/ndb/dns.c
+++ b/sys/src/cmd/ndb/dns.c
@@ -103,8 +103,8 @@
void
usage(void)
{
- fprint(2, "usage: %s [-FnorRs] [-a maxage] [-f ndb-file] [-N target] "
- "[-T forwip] [-x netmtpt] [-z refreshprog]\n", argv0);
+ fprint(2, "usage: %s [-FnorR] [-a maxage] [-f ndb-file] [-N target] "
+ "[-T forwip] [-x netmtpt] [-z refreshprog] [-s [addrs...]]\n", argv0);
exits("usage");
}
@@ -167,12 +167,13 @@
usage();
break;
}ARGEND
- if(argc != 0)
+
+ if(argc != 0 && !cfg.serve)
usage();
rfork(RFREND|RFNOTEG);
- cfg.inside = (*mntpt == '\0' || strcmp(mntpt, "/net") == 0);
+ cfg.inside = strcmp(mntpt, "/net") == 0;
/* start syslog before we fork */
fmtinstall('F', fcallfmt);
@@ -203,10 +204,16 @@
if (cfg.straddle && !seerootns())
dnslog("straddle server misconfigured; can't see root name servers");
- if(cfg.serve)
- dnudpserver(mntpt);
+ if(cfg.serve){
+ if(argc == 0)
+ dnudpserver(mntpt, "*");
+ else {
+ while(argc-- > 0)
+ dnudpserver(mntpt, *argv++);
+ }
+ }
if(sendnotifies)
- notifyproc();
+ notifyproc(mntpt);
io();
_exits(0);
--- a/sys/src/cmd/ndb/dns.h
+++ b/sys/src/cmd/ndb/dns.h
@@ -392,7 +392,6 @@
ulong qrecvdudp;
ulong qsent;
ulong qrecvd9prpc; /* packet count */
- ulong alarms;
/* reply times by count */
ulong under10ths[3*10+2]; /* under n*0.1 seconds, n is index */
ulong tmout;
@@ -527,11 +526,11 @@
/* dnserver.c */
void dnserver(DNSmsg*, DNSmsg*, Request*, uchar *, int);
-void dnudpserver(char*);
+void dnudpserver(char*, char*);
/* dnnotify.c */
void dnnotify(DNSmsg*, DNSmsg*, Request*);
-void notifyproc(void);
+void notifyproc(char*);
/* convDNS2M.c */
int convDNS2M(DNSmsg*, uchar*, int);
--- a/sys/src/cmd/ndb/dnudpserver.c
+++ b/sys/src/cmd/ndb/dnudpserver.c
@@ -7,7 +7,7 @@
Logqueries = 0,
};
-static int udpannounce(char*);
+static int udpannounce(char*, char*);
static void reply(int, uchar*, DNSmsg*, Request*);
typedef struct Inprogress Inprogress;
@@ -31,8 +31,6 @@
Forwtarg forwtarg[10];
int forwtcount;
-static char *hmsg = "headers";
-
/*
* record client id and ignore retransmissions.
* we're still single thread at this point.
@@ -129,9 +127,9 @@
* a process to act as a dns server for outside reqeusts
*/
void
-dnudpserver(char *mntpt)
+dnudpserver(char *mntpt, char *addr)
{
- volatile int fd, len, op, rcode;
+ volatile int fd, len, op, rcode, served;
char *volatile err;
volatile char tname[32];
volatile uchar buf[Udphdrsize + Maxudp + 1024];
@@ -153,15 +151,16 @@
return;
}
- fd = -1;
+ served = 0;
restart:
- procsetname("udp server announcing");
- if(fd >= 0)
- close(fd);
- while((fd = udpannounce(mntpt)) < 0)
- sleep(5000);
+ procsetname("%s: udp server announcing %s", mntpt, addr);
+ if((fd = udpannounce(mntpt, addr)) < 0){
+ warning("can't announce %s on %s: %r", addr, mntpt);
+ do {
+ sleep(5000);
+ } while((fd = udpannounce(mntpt, addr)) < 0);
+ }
-// procsetname("udp server");
memset(&req, 0, sizeof req);
if(setjmp(req.mret))
putactivity(0);
@@ -171,8 +170,7 @@
/* loop on requests */
for(;; putactivity(0)){
- procsetname("served %lud udp; %lud alarms",
- stats.qrecvdudp, stats.alarms);
+ procsetname("%s: udp server %s: served %d", mntpt, addr, served);
memset(&repmsg, 0, sizeof repmsg);
memset(&reqmsg, 0, sizeof reqmsg);
@@ -179,8 +177,10 @@
alarm(60*1000);
len = read(fd, buf, sizeof buf);
alarm(0);
- if(len <= Udphdrsize)
+ if(len <= Udphdrsize){
+ close(fd);
goto restart;
+ }
if(forwtcount > 0)
redistrib(buf, len);
@@ -194,6 +194,8 @@
req.aborttime = timems() + Maxreqtm;
req.from = smprint("%I", buf);
rcode = 0;
+
+ served++;
stats.qrecvdudp++;
err = convM2DNS(&buf[Udphdrsize], len, &reqmsg, &rcode);
@@ -279,39 +281,33 @@
* announce on well-known dns udp port and set message style interface
*/
static int
-udpannounce(char *mntpt)
+udpannounce(char *mntpt, char *addr)
{
- int data, ctl;
+ static char hmsg[] = "headers";
+ static char imsg[] = "ignoreadvice";
+
char dir[64], datafile[64+6];
- static int whined;
+ int data, ctl;
- /* get a udp port */
- sprint(datafile, "%s/udp!*!dns", mntpt);
+ snprint(datafile, sizeof(datafile), "%s/udp!%s!dns", mntpt, addr);
ctl = announce(datafile, dir);
- if(ctl < 0){
- if(!whined++)
- warning("can't announce on %s", datafile);
+ if(ctl < 0)
return -1;
- }
/* turn on header style interface */
- if(write(ctl, hmsg, strlen(hmsg)) != strlen(hmsg)){
+ if(write(ctl, hmsg, sizeof(hmsg)-1) < 0){
+ warning("can't enable %s on %s: %r", hmsg, datafile);
close(ctl);
- if(!whined++)
- warning("can't enable headers on %s", datafile);
return -1;
}
+ /* ignore ICMP advice */
+ write(ctl, imsg, sizeof(imsg)-1);
+
snprint(datafile, sizeof(datafile), "%s/data", dir);
data = open(datafile, ORDWR);
- if(data < 0){
- close(ctl);
- if(!whined++)
- warning("can't open %s to announce on dns udp port",
- datafile);
- return -1;
- }
-
+ if(data < 0)
+ warning("can't open udp port %s: %r", datafile);
close(ctl);
return data;
}