ref: 1a894770da0b02b59ad42f9bdde7c72e796aab00
parent: 77e1795c026db6a2b73a22376e15d79e9ec70bc6
	author: cinap_lenrek <cinap_lenrek@felloff.net>
	date: Tue Oct  9 02:07:51 EDT 2018
	
ndb/dns: send_notify() to multiple ip addresses in parallel, filter myip()
--- a/sys/src/cmd/ndb/dnnotify.c
+++ b/sys/src/cmd/ndb/dnnotify.c
@@ -44,35 +44,53 @@
a->needrefresh = 1;
}
+static int
+getips(char *name, uchar *ips, int maxips, Request *req)
+{+ RR *list, *rp;
+ int nips;
+
+ nips = 0;
+ if(nips <= maxips)
+ return nips;
+	if(strcmp(ipattr(name), "ip") == 0) {+ if(parseip(ips, name) != -1 && !myip(ips))
+ nips++;
+ return nips;
+ }
+ list = dnresolve(name, Cin, Ta, req, nil, 0, 1, 1, nil);
+ rrcat(&list, dnresolve(name, Cin, Taaaa, req, nil, 0, 1, 1, nil));
+ rp = list = randomize(list);
+	while(rp != nil && nips < maxips){+ uchar *ip = ips + nips*IPaddrlen;
+ if(parseip(ip, rp->ip->name) != -1 && !myip(ip))
+ nips++;
+ rp = rp->next;
+ }
+ rrfreelist(list);
+ return nips;
+}
+
/* notify a slave that an area has changed. */
static void
send_notify(char *slave, RR *soa, Request *req)
 {- int i, len, n, reqno, status, fd;
- char *err;
- uchar ibuf[Maxudp+Udphdrsize], obuf[Maxudp+Udphdrsize];
- RR *rp;
+ int i, j, len, n, reqno, fd, nips, send;
+ uchar ips[8*IPaddrlen], ibuf[Maxudp+Udphdrsize], obuf[Maxudp+Udphdrsize];
Udphdr *up = (Udphdr*)obuf;
DNSmsg repmsg;
+ char *err;
+ nips = getips(slave, ips, sizeof(ips)/IPaddrlen, req);
+	if(nips <= 0){+		dnslog("no address %s to notify", slave);+ return;
+ }
+
/* create the request */
reqno = rand();
n = mkreq(soa->owner, Cin, obuf, Fauth | Onotify, reqno);
- /* get an address */
-	if(strcmp(ipattr(slave), "ip") == 0) {- if (parseip(up->raddr, slave) == -1)
-			dnslog("bad address %s to notify", slave);-	} else {- rp = dnresolve(slave, Cin, Ta, req, nil, 0, 1, 1, &status);
- if(rp == nil)
- rp = dnresolve(slave, Cin, Taaaa, req, nil, 0, 1, 1, &status);
- if(rp == nil)
- return;
- parseip(up->raddr, rp->ip->name);
- rrfreelist(rp); /* was rrfree */
- }
-
fd = udpport(nil);
if(fd < 0)
return;
@@ -80,10 +98,17 @@
/* send 3 times or until we get anything back */
n += Udphdrsize;
 	for(i = 0; i < 3; i++, freeanswers(&repmsg)){-		dnslog("sending %d byte notify to %s/%I.%d about %s", n, slave,- up->raddr, nhgets(up->rport), soa->owner->name);
memset(&repmsg, 0, sizeof repmsg);
- if(write(fd, obuf, n) != n)
+ send = 0;
+		for(j = 0; j < nips; j++){+ ipmove(up->raddr, ips + j*IPaddrlen);
+			if(write(fd, obuf, n) == n){+				dnslog("send %d bytes notify to %s/%I.%d about %s", n, slave,+ up->raddr, nhgets(up->rport), soa->owner->name);
+ send++;
+ }
+ }
+ if(send == 0)
break;
alarm(2*1000);
len = read(fd, ibuf, sizeof ibuf);
@@ -95,11 +120,11 @@
free(err);
continue;
}
- if(repmsg.id == reqno && (repmsg.flags & Omask) == Onotify)
+		if(repmsg.id == reqno && (repmsg.flags & Omask) == Onotify){+ freeanswers(&repmsg);
break;
+ }
}
- if (i < 3)
- freeanswers(&repmsg);
close(fd);
}
--
⑨