shithub: riscv

Download patch

ref: 48d117ed648d859f407e1314effbbec56ff867ec
parent: ac962a0ae4efcbcc44d0f3cdad5de433927511ae
author: cinap_lenrek <[email protected]>
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);
 }