ref: 48d117ed648d859f407e1314effbbec56ff867ec
parent: ac962a0ae4efcbcc44d0f3cdad5de433927511ae
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Apr 16 20:48:42 EDT 2018
ndb/dns: remove single-ip-address assuptions
--- a/sys/src/cmd/ndb/dblookup.c
+++ b/sys/src/cmd/ndb/dblookup.c
@@ -20,9 +20,12 @@
Ptrttl = 2*Min,
};
-static Ndb *db;
-static Lock dblock;
+static Ndb *db;
+static QLock dblock;
+static Ipifc *ipifcs;
+static QLock ipifclock;
+
static RR* addrrr(Ndbtuple*, Ndbtuple*);
static RR* cnamerr(Ndbtuple*, Ndbtuple*);
static void createptrs(void);
@@ -67,7 +70,7 @@
char netdbnm[256];
Ndb *xdb, *netdb;
- if (db)
+ if(db != nil)
return 0;
xdb = ndbopen(dbfile); /* /lib/ndb */
@@ -84,7 +87,7 @@
netdb->nohash = 1;
db = ndbcat(netdb, xdb); /* both */
- return db? 0: -1;
+ return db!=nil ? 0: -1;
}
/*
@@ -122,7 +125,7 @@
return rp;
}
- lock(&dblock);
+ qlock(&dblock);
dp = idnlookup(name, class, 1);
if(opendatabase() < 0)
@@ -166,7 +169,7 @@
dp->respcode = err;
}
- unlock(&dblock);
+ qunlock(&dblock);
return rp;
}
@@ -675,13 +678,16 @@
refresh_areas(owned);
- lock(&dblock);
-
+ qlock(&dblock);
if(opendatabase() < 0){
- unlock(&dblock);
+ qunlock(&dblock);
return;
}
+ qlock(&ipifclock);
+ ipifcs = readipifc(mntpt, ipifcs, -1);
+ qunlock(&ipifclock);
+
/*
* file may be changing as we are reading it, so loop till
* mod times are consistent.
@@ -737,11 +743,10 @@
createptrs();
}
- unlock(&dblock);
+ qunlock(&dblock);
}
extern char mntpt[Maxpath]; /* net mountpoint */
-static uchar ipaddr[IPaddrlen]; /* my ip address */
/*
* get all my xxx
@@ -750,24 +755,30 @@
Ndbtuple*
lookupinfo(char *attr)
{
- char buf[64];
- char *a[2];
- Ndbtuple *t;
+ Ndbtuple *t, *nt;
+ char ip[64];
+ Ipifc *ifc;
+ Iplifc *lifc;
- if(ipcmp(ipaddr, IPnoaddr) == 0)
- if(myipaddr(ipaddr, mntpt) < 0)
- return nil;
-
- snprint(buf, sizeof buf, "%I", ipaddr);
- a[0] = attr;
-
- lock(&dblock);
+ t = nil;
+ qlock(&dblock);
if(opendatabase() < 0){
- unlock(&dblock);
+ qunlock(&dblock);
return nil;
}
- t = ndbipinfo(db, "ip", buf, a, 1);
- unlock(&dblock);
+ qlock(&ipifclock);
+ if(ipifcs == nil)
+ ipifcs = readipifc(mntpt, ipifcs, -1);
+ for(ifc = ipifcs; ifc != nil; ifc = ifc->next){
+ for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
+ snprint(ip, sizeof(ip), "%I", lifc->ip);
+ nt = ndbipinfo(db, "ip", ip, &attr, 1);
+ t = ndbconcatenate(t, nt);
+ }
+ }
+ qunlock(&ipifclock);
+ qunlock(&dblock);
+
return t;
}
@@ -808,33 +819,20 @@
int
myip(uchar *ip)
{
- char *line, *sp;
- char buf[Maxpath];
- uchar ipa[IPaddrlen];
- Biobuf *bp;
+ Ipifc *ifc;
+ Iplifc *lifc;
- if(ipcmp(ipaddr, IPnoaddr) == 0)
- if(myipaddr(ipaddr, mntpt) < 0)
- return -1;
-
- if(ipcmp(ipaddr, ip) == 0)
- return 1;
-
- snprint(buf, sizeof buf, "%s/ipselftab", mntpt);
- bp = Bopen(buf, OREAD);
- if(bp != nil) {
- while((line = Brdline(bp, '\n')) != nil) {
- line[Blinelen(bp) - 1] = '\0';
- if((sp = strchr(line, ' ')) != nil) {
- *sp = '\0';
- if(parseip(ipa, line) != -1 && ipcmp(ipa, ip) == 0) {
- Bterm(bp);
- return 1;
- }
+ qlock(&ipifclock);
+ for(ifc = ipifcs; ifc != nil; ifc = ifc->next){
+ for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
+ if(ipcmp(ip, lifc->ip) == 0){
+ qunlock(&ipifclock);
+ return 1;
}
}
- Bterm(bp);
}
+ qunlock(&ipifclock);
+
return 0;
}
@@ -1170,11 +1168,11 @@
if (dom[0] == '\0' || strcmp(dom, ".") == 0) /* dns root? */
return 1; /* hack for initialisation */
- lock(&dblock);
+ qlock(&dblock);
if (indoms == nil)
loaddomsrvs();
if (indoms == nil) {
- unlock(&dblock);
+ qunlock(&dblock);
return 1; /* no "inside-dom" sys, try inside nameservers */
}
@@ -1192,7 +1190,7 @@
break;
}
}
- unlock(&dblock);
+ qunlock(&dblock);
return rv;
}
--- a/sys/src/cmd/ndb/dnsdebug.c
+++ b/sys/src/cmd/ndb/dnsdebug.c
@@ -17,7 +17,6 @@
char *dbfile;
int debug;
-uchar ipaddr[IPaddrlen]; /* my ip address */
char *logfile = "dnsdebug";
int maxage = 60*60;
char mntpt[Maxpath];
@@ -73,8 +72,6 @@
nowns = nsec();
dninit();
fmtinstall('R', prettyrrfmt);
- if(myipaddr(ipaddr, mntpt) < 0)
- sysfatal("can't read my ip address");
opendatabase();
if(cfg.resolver)
--- a/sys/src/cmd/ndb/dnstcp.c
+++ b/sys/src/cmd/ndb/dnstcp.c
@@ -11,7 +11,6 @@
char *caller = "";
char *dbfile;
int debug;
-uchar ipaddr[IPaddrlen]; /* my ip address */
char *logfile = "dns";
int maxage = 60*60;
char mntpt[Maxpath];
@@ -79,9 +78,7 @@
else
snprint(mntpt, sizeof mntpt, "/net%s", ext);
- if(myipaddr(ipaddr, mntpt) < 0)
- sysfatal("can't read my ip address");
- dnslog("dnstcp call from %s to %I", caller, ipaddr);
+ dnslog("dnstcp call from %s", caller);
memset(callip, 0, sizeof callip);
parseip(callip, caller);
--- a/sys/src/cmd/ndb/inform.c
+++ b/sys/src/cmd/ndb/inform.c
@@ -24,6 +24,25 @@
[10] "domain name not in zone",
};
+static uchar loopbacknet[IPaddrlen] = {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0xff, 0xff,
+ 127, 0, 0, 0
+};
+static uchar loopbackmask[IPaddrlen] = {
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0, 0, 0
+};
+static uchar loopback6[IPaddrlen] = {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 1
+};
+
void
usage(void)
{
@@ -91,14 +110,16 @@
void
main(int argc, char *argv[])
{
+ static char *query[] = { "dom", "dnsdomain", "ns", "inform" };
+ char *sysname, *dnsdomain, *dom, *inform, *ns, net[32];
int debug, len, fd;
uint err;
- char *sysname, *dnsdomain, *dom, *inform, *ns, net[32];
- uchar *p, buf[4096], addr[IPv4addrlen], v6addr[IPaddrlen];
+ uchar *p, buf[4096], mynet[IPaddrlen];
ushort txid;
Ndb *db;
Ndbtuple *t, *tt;
- static char *query[] = { "dom", "dnsdomain", "ns", "inform" };
+ Ipifc *ifc;
+ Iplifc *lifc;
fmtinstall('I', eipfmt);
fmtinstall('V', eipfmt);
@@ -152,11 +173,7 @@
if(!dnsdomain)
sysfatal("no relevant dnsdomain=");
- myipaddr(v6addr, net);
- memmove(addr, v6addr + IPaddrlen - IPv4addrlen, IPv4addrlen);
-
if(debug){
- print("ip=%V\n", addr);
print("ns=%s\n", ns);
print("dnsdomain=%s\n", dnsdomain);
print("dom=%s\n", dom);
@@ -180,20 +197,51 @@
p16(&p, Cin); /* zone class */
/* delete old name */
- pname(&p, dom); /* name */
+ pname(&p, dom); /* name */
p16(&p, Ta); /* type: v4 addr */
p16(&p, Call); /* class */
p32(&p, 0); /* TTL */
p16(&p, 0); /* data len */
- /* add new A record */
- pname(&p, dom); /* name */
- p16(&p, Ta); /* type: v4 addr */
- p16(&p, Cin); /* class */
- p32(&p, 60*60*25); /* TTL (25 hours) */
- p16(&p, IPv4addrlen); /* data len */
- pmem(&p, addr, IPv4addrlen); /* v4 address */
+ pname(&p, dom); /* name */
+ p16(&p, Taaaa); /* type: v6 addr */
+ p16(&p, Call); /* class */
+ p32(&p, 0); /* TTL */
+ p16(&p, 0); /* data len */
+ for(ifc = readipifc(net, nil, -1); ifc != nil; ifc = ifc->next){
+ for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
+ /* unspecified */
+ if(ipcmp(lifc->ip, IPnoaddr) == 0)
+ continue;
+
+ /* ipv6 loopback */
+ if(ipcmp(lifc->ip, loopback6) == 0)
+ continue;
+
+ /* ipv4 loopback */
+ maskip(lifc->ip, loopbackmask, mynet);
+ if(ipcmp(mynet, loopbacknet) == 0)
+ continue;
+
+ if(debug)
+ print("ip=%I\n", lifc->ip);
+
+ /* add new A record */
+ pname(&p, dom); /* name */
+ p16(&p, isv4(lifc->ip)?Ta:Taaaa);
+ p16(&p, Cin); /* class */
+ p32(&p, 60*60*25); /* TTL (25 hours) */
+ if(isv4(lifc->ip)){
+ p16(&p, IPv4addrlen);
+ pmem(&p, lifc->ip+IPv4off, IPv4addrlen);
+ } else {
+ p16(&p, IPaddrlen);
+ pmem(&p, lifc->ip, IPaddrlen);
+ }
+ }
+ }
+
len = p - buf;
if(write(fd, buf, len) != len)
sysfatal("write failed: %r");
@@ -207,8 +255,6 @@
}while(g16(&p) != txid);
alarm(0);
- close(fd);
-
err = g16(&p) & 7;
if(err != 0 && err != 7) /* err==7 is just a "yes, I know" warning */
if(err < nelem(errmsgs))
@@ -215,5 +261,5 @@
sysfatal("%s", errmsgs[err]);
else
sysfatal("unknown dns server error %d", err);
- exits(0);
+ exits(nil);
}