ndb/dns: remove single-ip-address assuptions

This commit is contained in:
cinap_lenrek 2018-04-17 00:48:42 +02:00
parent ac962a0ae4
commit 48d117ed64
4 changed files with 114 additions and 76 deletions

View file

@ -20,8 +20,11 @@ enum {
Ptrttl = 2*Min, Ptrttl = 2*Min,
}; };
static Ndb *db; static Ndb *db;
static Lock dblock; static QLock dblock;
static Ipifc *ipifcs;
static QLock ipifclock;
static RR* addrrr(Ndbtuple*, Ndbtuple*); static RR* addrrr(Ndbtuple*, Ndbtuple*);
static RR* cnamerr(Ndbtuple*, Ndbtuple*); static RR* cnamerr(Ndbtuple*, Ndbtuple*);
@ -67,7 +70,7 @@ opendatabase(void)
char netdbnm[256]; char netdbnm[256];
Ndb *xdb, *netdb; Ndb *xdb, *netdb;
if (db) if(db != nil)
return 0; return 0;
xdb = ndbopen(dbfile); /* /lib/ndb */ xdb = ndbopen(dbfile); /* /lib/ndb */
@ -84,7 +87,7 @@ opendatabase(void)
netdb->nohash = 1; netdb->nohash = 1;
db = ndbcat(netdb, xdb); /* both */ 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; return rp;
} }
lock(&dblock); qlock(&dblock);
dp = idnlookup(name, class, 1); dp = idnlookup(name, class, 1);
if(opendatabase() < 0) if(opendatabase() < 0)
@ -166,7 +169,7 @@ out:
dp->respcode = err; dp->respcode = err;
} }
unlock(&dblock); qunlock(&dblock);
return rp; return rp;
} }
@ -675,13 +678,16 @@ db2cache(int doit)
refresh_areas(owned); refresh_areas(owned);
lock(&dblock); qlock(&dblock);
if(opendatabase() < 0){ if(opendatabase() < 0){
unlock(&dblock); qunlock(&dblock);
return; return;
} }
qlock(&ipifclock);
ipifcs = readipifc(mntpt, ipifcs, -1);
qunlock(&ipifclock);
/* /*
* file may be changing as we are reading it, so loop till * file may be changing as we are reading it, so loop till
* mod times are consistent. * mod times are consistent.
@ -737,11 +743,10 @@ db2cache(int doit)
createptrs(); createptrs();
} }
unlock(&dblock); qunlock(&dblock);
} }
extern char mntpt[Maxpath]; /* net mountpoint */ extern char mntpt[Maxpath]; /* net mountpoint */
static uchar ipaddr[IPaddrlen]; /* my ip address */
/* /*
* get all my xxx * get all my xxx
@ -750,24 +755,30 @@ static uchar ipaddr[IPaddrlen]; /* my ip address */
Ndbtuple* Ndbtuple*
lookupinfo(char *attr) lookupinfo(char *attr)
{ {
char buf[64]; Ndbtuple *t, *nt;
char *a[2]; char ip[64];
Ndbtuple *t; Ipifc *ifc;
Iplifc *lifc;
if(ipcmp(ipaddr, IPnoaddr) == 0) t = nil;
if(myipaddr(ipaddr, mntpt) < 0) qlock(&dblock);
return nil;
snprint(buf, sizeof buf, "%I", ipaddr);
a[0] = attr;
lock(&dblock);
if(opendatabase() < 0){ if(opendatabase() < 0){
unlock(&dblock); qunlock(&dblock);
return nil; return nil;
} }
t = ndbipinfo(db, "ip", buf, a, 1); qlock(&ipifclock);
unlock(&dblock); 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; return t;
} }
@ -808,33 +819,20 @@ baddelegation(RR *rp, RR *nsrp, uchar *addr)
int int
myip(uchar *ip) myip(uchar *ip)
{ {
char *line, *sp; Ipifc *ifc;
char buf[Maxpath]; Iplifc *lifc;
uchar ipa[IPaddrlen];
Biobuf *bp;
if(ipcmp(ipaddr, IPnoaddr) == 0) qlock(&ipifclock);
if(myipaddr(ipaddr, mntpt) < 0) for(ifc = ipifcs; ifc != nil; ifc = ifc->next){
return -1; for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
if(ipcmp(ip, lifc->ip) == 0){
if(ipcmp(ipaddr, ip) == 0) qunlock(&ipifclock);
return 1; 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;
}
} }
} }
Bterm(bp);
} }
qunlock(&ipifclock);
return 0; return 0;
} }
@ -1170,11 +1168,11 @@ insideaddr(char *dom)
if (dom[0] == '\0' || strcmp(dom, ".") == 0) /* dns root? */ if (dom[0] == '\0' || strcmp(dom, ".") == 0) /* dns root? */
return 1; /* hack for initialisation */ return 1; /* hack for initialisation */
lock(&dblock); qlock(&dblock);
if (indoms == nil) if (indoms == nil)
loaddomsrvs(); loaddomsrvs();
if (indoms == nil) { if (indoms == nil) {
unlock(&dblock); qunlock(&dblock);
return 1; /* no "inside-dom" sys, try inside nameservers */ return 1; /* no "inside-dom" sys, try inside nameservers */
} }
@ -1192,7 +1190,7 @@ insideaddr(char *dom)
break; break;
} }
} }
unlock(&dblock); qunlock(&dblock);
return rv; return rv;
} }

View file

@ -17,7 +17,6 @@ static RR *serveraddrs;
char *dbfile; char *dbfile;
int debug; int debug;
uchar ipaddr[IPaddrlen]; /* my ip address */
char *logfile = "dnsdebug"; char *logfile = "dnsdebug";
int maxage = 60*60; int maxage = 60*60;
char mntpt[Maxpath]; char mntpt[Maxpath];
@ -73,8 +72,6 @@ main(int argc, char *argv[])
nowns = nsec(); nowns = nsec();
dninit(); dninit();
fmtinstall('R', prettyrrfmt); fmtinstall('R', prettyrrfmt);
if(myipaddr(ipaddr, mntpt) < 0)
sysfatal("can't read my ip address");
opendatabase(); opendatabase();
if(cfg.resolver) if(cfg.resolver)

View file

@ -11,7 +11,6 @@ Cfg cfg;
char *caller = ""; char *caller = "";
char *dbfile; char *dbfile;
int debug; int debug;
uchar ipaddr[IPaddrlen]; /* my ip address */
char *logfile = "dns"; char *logfile = "dns";
int maxage = 60*60; int maxage = 60*60;
char mntpt[Maxpath]; char mntpt[Maxpath];
@ -79,9 +78,7 @@ main(int argc, char *argv[])
else else
snprint(mntpt, sizeof mntpt, "/net%s", ext); snprint(mntpt, sizeof mntpt, "/net%s", ext);
if(myipaddr(ipaddr, mntpt) < 0) dnslog("dnstcp call from %s", caller);
sysfatal("can't read my ip address");
dnslog("dnstcp call from %s to %I", caller, ipaddr);
memset(callip, 0, sizeof callip); memset(callip, 0, sizeof callip);
parseip(callip, caller); parseip(callip, caller);

View file

@ -24,6 +24,25 @@ char *errmsgs[] = {
[10] "domain name not in zone", [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 void
usage(void) usage(void)
{ {
@ -91,14 +110,16 @@ pname(uchar **p, char *s)
void void
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
static char *query[] = { "dom", "dnsdomain", "ns", "inform" };
char *sysname, *dnsdomain, *dom, *inform, *ns, net[32];
int debug, len, fd; int debug, len, fd;
uint err; uint err;
char *sysname, *dnsdomain, *dom, *inform, *ns, net[32]; uchar *p, buf[4096], mynet[IPaddrlen];
uchar *p, buf[4096], addr[IPv4addrlen], v6addr[IPaddrlen];
ushort txid; ushort txid;
Ndb *db; Ndb *db;
Ndbtuple *t, *tt; Ndbtuple *t, *tt;
static char *query[] = { "dom", "dnsdomain", "ns", "inform" }; Ipifc *ifc;
Iplifc *lifc;
fmtinstall('I', eipfmt); fmtinstall('I', eipfmt);
fmtinstall('V', eipfmt); fmtinstall('V', eipfmt);
@ -152,11 +173,7 @@ main(int argc, char *argv[])
if(!dnsdomain) if(!dnsdomain)
sysfatal("no relevant dnsdomain="); sysfatal("no relevant dnsdomain=");
myipaddr(v6addr, net);
memmove(addr, v6addr + IPaddrlen - IPv4addrlen, IPv4addrlen);
if(debug){ if(debug){
print("ip=%V\n", addr);
print("ns=%s\n", ns); print("ns=%s\n", ns);
print("dnsdomain=%s\n", dnsdomain); print("dnsdomain=%s\n", dnsdomain);
print("dom=%s\n", dom); print("dom=%s\n", dom);
@ -180,19 +197,50 @@ main(int argc, char *argv[])
p16(&p, Cin); /* zone class */ p16(&p, Cin); /* zone class */
/* delete old name */ /* delete old name */
pname(&p, dom); /* name */ pname(&p, dom); /* name */
p16(&p, Ta); /* type: v4 addr */ p16(&p, Ta); /* type: v4 addr */
p16(&p, Call); /* class */ p16(&p, Call); /* class */
p32(&p, 0); /* TTL */ p32(&p, 0); /* TTL */
p16(&p, 0); /* data len */ p16(&p, 0); /* data len */
/* add new A record */ pname(&p, dom); /* name */
pname(&p, dom); /* name */ p16(&p, Taaaa); /* type: v6 addr */
p16(&p, Ta); /* type: v4 addr */ p16(&p, Call); /* class */
p16(&p, Cin); /* class */ p32(&p, 0); /* TTL */
p32(&p, 60*60*25); /* TTL (25 hours) */ p16(&p, 0); /* data len */
p16(&p, IPv4addrlen); /* data len */
pmem(&p, addr, IPv4addrlen); /* v4 address */ 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; len = p - buf;
if(write(fd, buf, len) != len) if(write(fd, buf, len) != len)
@ -207,13 +255,11 @@ main(int argc, char *argv[])
}while(g16(&p) != txid); }while(g16(&p) != txid);
alarm(0); alarm(0);
close(fd);
err = g16(&p) & 7; err = g16(&p) & 7;
if(err != 0 && err != 7) /* err==7 is just a "yes, I know" warning */ if(err != 0 && err != 7) /* err==7 is just a "yes, I know" warning */
if(err < nelem(errmsgs)) if(err < nelem(errmsgs))
sysfatal("%s", errmsgs[err]); sysfatal("%s", errmsgs[err]);
else else
sysfatal("unknown dns server error %d", err); sysfatal("unknown dns server error %d", err);
exits(0); exits(nil);
} }