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;
50 5c9f76b5 2006-02-14 devnull * this isn't going to work as a thread!
53 3e0d8fb3 2005-12-27 devnull static void
54 3e0d8fb3 2005-12-27 devnull ding(void *u, char *msg)
58 3e0d8fb3 2005-12-27 devnull if(strstr(msg, "alarm"))
59 3e0d8fb3 2005-12-27 devnull noted(NCONT);
61 3e0d8fb3 2005-12-27 devnull noted(NDFLT);
64 3e0d8fb3 2005-12-27 devnull /* notify a slave that an area has changed. */
65 3e0d8fb3 2005-12-27 devnull static void
66 3e0d8fb3 2005-12-27 devnull send_notify(char *slave, RR *soa, Request *req)
68 3e0d8fb3 2005-12-27 devnull int i, len, n, reqno, status, fd;
69 5c9f76b5 2006-02-14 devnull uchar obuf[Maxudp+Udphdrsize];
70 5c9f76b5 2006-02-14 devnull uchar ibuf[Maxudp+Udphdrsize];
72 5c9f76b5 2006-02-14 devnull Udphdr *up = (Udphdr*)obuf;
73 3e0d8fb3 2005-12-27 devnull char *err;
74 3e0d8fb3 2005-12-27 devnull DNSmsg repmsg;
76 3e0d8fb3 2005-12-27 devnull /* create the request */
77 3e0d8fb3 2005-12-27 devnull reqno = rand();
78 3e0d8fb3 2005-12-27 devnull n = mkreq(soa->owner, Cin, obuf, Fauth | Onotify, reqno);
80 3e0d8fb3 2005-12-27 devnull /* get an address */
81 3e0d8fb3 2005-12-27 devnull if(strcmp(ipattr(slave), "ip") == 0) {
82 3e0d8fb3 2005-12-27 devnull parseip(up->raddr, slave);
84 3e0d8fb3 2005-12-27 devnull rp = dnresolve(slave, Cin, Ta, req, nil, 0, 1, 1, &status);
85 3e0d8fb3 2005-12-27 devnull if(rp == nil)
87 3e0d8fb3 2005-12-27 devnull parseip(up->raddr, rp->ip->name);
88 3e0d8fb3 2005-12-27 devnull rrfree(rp);
91 3e0d8fb3 2005-12-27 devnull fd = udpport();
92 3e0d8fb3 2005-12-27 devnull if(fd < 0)
95 3e0d8fb3 2005-12-27 devnull notify(ding);
97 3e0d8fb3 2005-12-27 devnull /* send 3 times or until we get anything back */
98 3e0d8fb3 2005-12-27 devnull for(i = 0; i < 3; i++){
99 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);
100 5c9f76b5 2006-02-14 devnull if(udpwrite(fd, (Udphdr*)obuf, obuf+Udphdrsize, n) != n)
102 3e0d8fb3 2005-12-27 devnull alarm(2*1000);
103 5c9f76b5 2006-02-14 devnull len = udpread(fd, (Udphdr*)ibuf, ibuf+Udphdrsize, Maxudp);
104 3e0d8fb3 2005-12-27 devnull alarm(0);
105 5c9f76b5 2006-02-14 devnull if(len <= Udphdrsize)
106 3e0d8fb3 2005-12-27 devnull continue;
107 5c9f76b5 2006-02-14 devnull err = convM2DNS(&ibuf[Udphdrsize], len, &repmsg);
108 3e0d8fb3 2005-12-27 devnull if(err != nil)
109 3e0d8fb3 2005-12-27 devnull continue;
110 3e0d8fb3 2005-12-27 devnull if(repmsg.id == reqno && (repmsg.flags & Omask) == Onotify)
114 3e0d8fb3 2005-12-27 devnull close(fd);
117 3e0d8fb3 2005-12-27 devnull /* send notifies for any updated areas */
118 3e0d8fb3 2005-12-27 devnull static void
119 3e0d8fb3 2005-12-27 devnull notify_areas(Area *a, Request *req)
121 3e0d8fb3 2005-12-27 devnull Server *s;
123 3e0d8fb3 2005-12-27 devnull for(; a != nil; a = a->next){
124 3e0d8fb3 2005-12-27 devnull if(!a->neednotify)
125 3e0d8fb3 2005-12-27 devnull continue;
127 3e0d8fb3 2005-12-27 devnull /* send notifies to all slaves */
128 3e0d8fb3 2005-12-27 devnull for(s = a->soarr->soa->slaves; s != nil; s = s->next)
129 3e0d8fb3 2005-12-27 devnull send_notify(s->name, a->soarr, req);
130 3e0d8fb3 2005-12-27 devnull a->neednotify = 0;
135 3e0d8fb3 2005-12-27 devnull * process to notify other servers of changes
136 3e0d8fb3 2005-12-27 devnull * (also reads in new databases)
139 5c9f76b5 2006-02-14 devnull notifyproc(void *v)
141 3e0d8fb3 2005-12-27 devnull Request req;
143 5c9f76b5 2006-02-14 devnull USED(v);
145 3e0d8fb3 2005-12-27 devnull for(;;){
146 3e0d8fb3 2005-12-27 devnull getactivity(&req);
147 3e0d8fb3 2005-12-27 devnull notify_areas(owned, &req);
148 3e0d8fb3 2005-12-27 devnull putactivity();
149 3e0d8fb3 2005-12-27 devnull sleep(60*1000);