From 48d117ed648d859f407e1314effbbec56ff867ec Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Tue, 17 Apr 2018 00:48:42 +0200 Subject: [PATCH] ndb/dns: remove single-ip-address assuptions --- sys/src/cmd/ndb/dblookup.c | 100 ++++++++++++++++++------------------- sys/src/cmd/ndb/dnsdebug.c | 3 -- sys/src/cmd/ndb/dnstcp.c | 5 +- sys/src/cmd/ndb/inform.c | 82 +++++++++++++++++++++++------- 4 files changed, 114 insertions(+), 76 deletions(-) diff --git a/sys/src/cmd/ndb/dblookup.c b/sys/src/cmd/ndb/dblookup.c index 14537f251..b7bb9097e 100644 --- a/sys/src/cmd/ndb/dblookup.c +++ b/sys/src/cmd/ndb/dblookup.c @@ -20,8 +20,11 @@ enum { 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*); @@ -67,7 +70,7 @@ opendatabase(void) char netdbnm[256]; Ndb *xdb, *netdb; - if (db) + if(db != nil) return 0; xdb = ndbopen(dbfile); /* /lib/ndb */ @@ -84,7 +87,7 @@ opendatabase(void) netdb->nohash = 1; db = ndbcat(netdb, xdb); /* both */ - return db? 0: -1; + return db!=nil ? 0: -1; } /* @@ -122,7 +125,7 @@ dblookup(char *name, int class, int type, int auth, int ttl) return rp; } - lock(&dblock); + qlock(&dblock); dp = idnlookup(name, class, 1); if(opendatabase() < 0) @@ -166,7 +169,7 @@ out: dp->respcode = err; } - unlock(&dblock); + qunlock(&dblock); return rp; } @@ -675,13 +678,16 @@ db2cache(int doit) 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 @@ db2cache(int doit) 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 @@ static uchar ipaddr[IPaddrlen]; /* my ip address */ 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 @@ baddelegation(RR *rp, RR *nsrp, uchar *addr) 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 @@ insideaddr(char *dom) 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 @@ insideaddr(char *dom) break; } } - unlock(&dblock); + qunlock(&dblock); return rv; } diff --git a/sys/src/cmd/ndb/dnsdebug.c b/sys/src/cmd/ndb/dnsdebug.c index e31ea8ce5..300434cff 100644 --- a/sys/src/cmd/ndb/dnsdebug.c +++ b/sys/src/cmd/ndb/dnsdebug.c @@ -17,7 +17,6 @@ static RR *serveraddrs; char *dbfile; int debug; -uchar ipaddr[IPaddrlen]; /* my ip address */ char *logfile = "dnsdebug"; int maxage = 60*60; char mntpt[Maxpath]; @@ -73,8 +72,6 @@ main(int argc, char *argv[]) nowns = nsec(); dninit(); fmtinstall('R', prettyrrfmt); - if(myipaddr(ipaddr, mntpt) < 0) - sysfatal("can't read my ip address"); opendatabase(); if(cfg.resolver) diff --git a/sys/src/cmd/ndb/dnstcp.c b/sys/src/cmd/ndb/dnstcp.c index 475c30fd3..4ba125983 100644 --- a/sys/src/cmd/ndb/dnstcp.c +++ b/sys/src/cmd/ndb/dnstcp.c @@ -11,7 +11,6 @@ Cfg cfg; 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 @@ main(int argc, char *argv[]) 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); diff --git a/sys/src/cmd/ndb/inform.c b/sys/src/cmd/ndb/inform.c index 58e3936fd..299b0cb2f 100644 --- a/sys/src/cmd/ndb/inform.c +++ b/sys/src/cmd/ndb/inform.c @@ -24,6 +24,25 @@ char *errmsgs[] = { [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 @@ pname(uchar **p, char *s) 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 @@ main(int argc, char *argv[]) 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,19 +197,50 @@ main(int argc, char *argv[]) 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) @@ -207,13 +255,11 @@ main(int argc, char *argv[]) }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)) sysfatal("%s", errmsgs[err]); else sysfatal("unknown dns server error %d", err); - exits(0); + exits(nil); }