ref: 45e71cb72869a4adbff53154a2f6c75d7b404a1d
parent: 7ddda493c0c5370902148e20c579dd2d213f0a69
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);
}