1 3e0d8fb3 2005-12-27 devnull #include <u.h>
2 3e0d8fb3 2005-12-27 devnull #include <libc.h>
3 3e0d8fb3 2005-12-27 devnull #include <ip.h>
4 3e0d8fb3 2005-12-27 devnull #include <bio.h>
5 3e0d8fb3 2005-12-27 devnull #include <ndb.h>
6 3e0d8fb3 2005-12-27 devnull #include "dns.h"
8 3e0d8fb3 2005-12-27 devnull /* get a notification from another system of a changed zone */
10 3e0d8fb3 2005-12-27 devnull dnnotify(DNSmsg *reqp, DNSmsg *repp, Request *r)
16 3e0d8fb3 2005-12-27 devnull /* move one question from reqp to repp */
17 3e0d8fb3 2005-12-27 devnull memset(repp, 0, sizeof(*repp));
18 3e0d8fb3 2005-12-27 devnull tp = reqp->qd;
19 3e0d8fb3 2005-12-27 devnull reqp->qd = tp->next;
20 3e0d8fb3 2005-12-27 devnull tp->next = 0;
21 3e0d8fb3 2005-12-27 devnull repp->qd = tp;
22 3e0d8fb3 2005-12-27 devnull repp->id = reqp->id;
23 3e0d8fb3 2005-12-27 devnull repp->flags = Fresp | Onotify | Fauth;
25 3e0d8fb3 2005-12-27 devnull /* anything to do? */
26 3e0d8fb3 2005-12-27 devnull if(zonerefreshprogram == nil)
29 3e0d8fb3 2005-12-27 devnull /* make sure its the right type */
30 3e0d8fb3 2005-12-27 devnull if(repp->qd->type != Tsoa)
33 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "notification for %s", repp->qd->owner->name);
35 3e0d8fb3 2005-12-27 devnull /* is it something we care about? */
36 3e0d8fb3 2005-12-27 devnull a = inmyarea(repp->qd->owner->name);
37 3e0d8fb3 2005-12-27 devnull if(a == nil)
40 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "serial old %lud new %lud", a->soarr->soa->serial, repp->qd->soa->serial);
42 3e0d8fb3 2005-12-27 devnull /* do nothing if it didn't change */
43 3e0d8fb3 2005-12-27 devnull if(a->soarr->soa->serial== repp->qd->soa->serial)
46 3e0d8fb3 2005-12-27 devnull a->needrefresh = 1;
49 3e0d8fb3 2005-12-27 devnull static void
50 3e0d8fb3 2005-12-27 devnull ding(void *u, char *msg)
54 3e0d8fb3 2005-12-27 devnull if(strstr(msg, "alarm"))
55 3e0d8fb3 2005-12-27 devnull noted(NCONT);
57 3e0d8fb3 2005-12-27 devnull noted(NDFLT);
60 3e0d8fb3 2005-12-27 devnull /* notify a slave that an area has changed. */
61 3e0d8fb3 2005-12-27 devnull static void
62 3e0d8fb3 2005-12-27 devnull send_notify(char *slave, RR *soa, Request *req)
64 3e0d8fb3 2005-12-27 devnull int i, len, n, reqno, status, fd;
65 3e0d8fb3 2005-12-27 devnull uchar obuf[Maxudp+OUdphdrsize];
66 3e0d8fb3 2005-12-27 devnull uchar ibuf[Maxudp+OUdphdrsize];
68 3e0d8fb3 2005-12-27 devnull OUdphdr *up = (OUdphdr*)obuf;
69 3e0d8fb3 2005-12-27 devnull char *err;
70 3e0d8fb3 2005-12-27 devnull DNSmsg repmsg;
72 3e0d8fb3 2005-12-27 devnull /* create the request */
73 3e0d8fb3 2005-12-27 devnull reqno = rand();
74 3e0d8fb3 2005-12-27 devnull n = mkreq(soa->owner, Cin, obuf, Fauth | Onotify, reqno);
76 3e0d8fb3 2005-12-27 devnull /* get an address */
77 3e0d8fb3 2005-12-27 devnull if(strcmp(ipattr(slave), "ip") == 0) {
78 3e0d8fb3 2005-12-27 devnull parseip(up->raddr, slave);
80 3e0d8fb3 2005-12-27 devnull rp = dnresolve(slave, Cin, Ta, req, nil, 0, 1, 1, &status);
81 3e0d8fb3 2005-12-27 devnull if(rp == nil)
83 3e0d8fb3 2005-12-27 devnull parseip(up->raddr, rp->ip->name);
84 3e0d8fb3 2005-12-27 devnull rrfree(rp);
87 3e0d8fb3 2005-12-27 devnull fd = udpport();
88 3e0d8fb3 2005-12-27 devnull if(fd < 0)
91 3e0d8fb3 2005-12-27 devnull notify(ding);
93 3e0d8fb3 2005-12-27 devnull /* send 3 times or until we get anything back */
94 3e0d8fb3 2005-12-27 devnull for(i = 0; i < 3; i++){
95 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "sending %d byte notify to %s/%I.%d about %s", n, slave, up->raddr, nhgets(up->rport), soa->owner->name);
96 3e0d8fb3 2005-12-27 devnull if(udpwrite(fd, (OUdphdr*)obuf, obuf+OUdphdrsize, n) != n)
98 3e0d8fb3 2005-12-27 devnull alarm(2*1000);
99 3e0d8fb3 2005-12-27 devnull len = udpread(fd, (Udphdr*)ibuf, ibuf+OUdphdrsize, Maxudp);
100 3e0d8fb3 2005-12-27 devnull alarm(0);
101 3e0d8fb3 2005-12-27 devnull if(len <= OUdphdrsize)
102 3e0d8fb3 2005-12-27 devnull continue;
103 3e0d8fb3 2005-12-27 devnull err = convM2DNS(&ibuf[OUdphdrsize], len, &repmsg);
104 3e0d8fb3 2005-12-27 devnull if(err != nil)
105 3e0d8fb3 2005-12-27 devnull continue;
106 3e0d8fb3 2005-12-27 devnull if(repmsg.id == reqno && (repmsg.flags & Omask) == Onotify)
110 3e0d8fb3 2005-12-27 devnull close(fd);
113 3e0d8fb3 2005-12-27 devnull /* send notifies for any updated areas */
114 3e0d8fb3 2005-12-27 devnull static void
115 3e0d8fb3 2005-12-27 devnull notify_areas(Area *a, Request *req)
117 3e0d8fb3 2005-12-27 devnull Server *s;
119 3e0d8fb3 2005-12-27 devnull for(; a != nil; a = a->next){
120 3e0d8fb3 2005-12-27 devnull if(!a->neednotify)
121 3e0d8fb3 2005-12-27 devnull continue;
123 3e0d8fb3 2005-12-27 devnull /* send notifies to all slaves */
124 3e0d8fb3 2005-12-27 devnull for(s = a->soarr->soa->slaves; s != nil; s = s->next)
125 3e0d8fb3 2005-12-27 devnull send_notify(s->name, a->soarr, req);
126 3e0d8fb3 2005-12-27 devnull a->neednotify = 0;
131 3e0d8fb3 2005-12-27 devnull * process to notify other servers of changes
132 3e0d8fb3 2005-12-27 devnull * (also reads in new databases)
135 3e0d8fb3 2005-12-27 devnull notifyproc(void)
137 3e0d8fb3 2005-12-27 devnull Request req;
138 3e0d8fb3 2005-12-27 devnull static int already;
140 3e0d8fb3 2005-12-27 devnull if(already)
143 3e0d8fb3 2005-12-27 devnull switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
144 3e0d8fb3 2005-12-27 devnull case -1:
148 3e0d8fb3 2005-12-27 devnull default:
152 3e0d8fb3 2005-12-27 devnull req.isslave = 1; /* son't fork off subprocesses */
154 3e0d8fb3 2005-12-27 devnull for(;;){
155 3e0d8fb3 2005-12-27 devnull getactivity(&req);
156 3e0d8fb3 2005-12-27 devnull notify_areas(owned, &req);
157 3e0d8fb3 2005-12-27 devnull putactivity();
158 3e0d8fb3 2005-12-27 devnull sleep(60*1000);