1dc5a79c1SDavid du Colombier #include <u.h>
2dc5a79c1SDavid du Colombier #include <libc.h>
3dc5a79c1SDavid du Colombier #include <bio.h>
4dc5a79c1SDavid du Colombier #include <ndb.h>
5dc5a79c1SDavid du Colombier #include <ip.h>
6dc5a79c1SDavid du Colombier #include "dns.h"
7dc5a79c1SDavid du Colombier
84f8f669cSDavid du Colombier Area *owned, *delegated;
9dc5a79c1SDavid du Colombier
10dc5a79c1SDavid du Colombier /*
11dc5a79c1SDavid du Colombier * true if a name is in our area
12dc5a79c1SDavid du Colombier */
13dc5a79c1SDavid du Colombier Area*
inmyarea(char * name)14dc5a79c1SDavid du Colombier inmyarea(char *name)
15dc5a79c1SDavid du Colombier {
16dc5a79c1SDavid du Colombier int len;
17dc5a79c1SDavid du Colombier Area *s, *d;
18dc5a79c1SDavid du Colombier
19dc5a79c1SDavid du Colombier len = strlen(name);
20dc5a79c1SDavid du Colombier for(s = owned; s; s = s->next){
21dc5a79c1SDavid du Colombier if(s->len > len)
22dc5a79c1SDavid du Colombier continue;
23dc5a79c1SDavid du Colombier if(cistrcmp(s->soarr->owner->name, name + len - s->len) == 0)
24dc5a79c1SDavid du Colombier if(len == s->len || name[len - s->len - 1] == '.')
25dc5a79c1SDavid du Colombier break;
26dc5a79c1SDavid du Colombier }
274f8f669cSDavid du Colombier if(s == nil)
284f8f669cSDavid du Colombier return nil;
29dc5a79c1SDavid du Colombier
304f8f669cSDavid du Colombier /* name is in area `s' */
31dc5a79c1SDavid du Colombier for(d = delegated; d; d = d->next){
32dc5a79c1SDavid du Colombier if(d->len > len)
33dc5a79c1SDavid du Colombier continue;
34dc5a79c1SDavid du Colombier if(cistrcmp(d->soarr->owner->name, name + len - d->len) == 0)
35dc5a79c1SDavid du Colombier if(len == d->len || name[len - d->len - 1] == '.')
364f8f669cSDavid du Colombier return nil; /* name is in a delegated subarea */
37dc5a79c1SDavid du Colombier }
38dc5a79c1SDavid du Colombier
394f8f669cSDavid du Colombier return s; /* name is in area `s' and not in a delegated subarea */
40dc5a79c1SDavid du Colombier }
41dc5a79c1SDavid du Colombier
42dc5a79c1SDavid du Colombier /*
43dc5a79c1SDavid du Colombier * our area is the part of the domain tree that
44dc5a79c1SDavid du Colombier * we serve
45dc5a79c1SDavid du Colombier */
46dc5a79c1SDavid du Colombier void
addarea(DN * dp,RR * rp,Ndbtuple * t)47dc5a79c1SDavid du Colombier addarea(DN *dp, RR *rp, Ndbtuple *t)
48dc5a79c1SDavid du Colombier {
494f8f669cSDavid du Colombier Area *s;
504f8f669cSDavid du Colombier Area **l;
51dc5a79c1SDavid du Colombier
52530fef66SDavid du Colombier lock(&dnlock);
53dc5a79c1SDavid du Colombier if(t->val[0])
54dc5a79c1SDavid du Colombier l = &delegated;
55dc5a79c1SDavid du Colombier else
56dc5a79c1SDavid du Colombier l = &owned;
57dc5a79c1SDavid du Colombier
584f8f669cSDavid du Colombier for (s = *l; s != nil; s = s->next)
59530fef66SDavid du Colombier if (strcmp(dp->name, s->soarr->owner->name) == 0) {
60530fef66SDavid du Colombier unlock(&dnlock);
614f8f669cSDavid du Colombier return; /* we've already got one */
62530fef66SDavid du Colombier }
634f8f669cSDavid du Colombier
64dc5a79c1SDavid du Colombier /*
65dc5a79c1SDavid du Colombier * The area contains a copy of the soa rr that created it.
66dc5a79c1SDavid du Colombier * The owner of the the soa rr should stick around as long
67dc5a79c1SDavid du Colombier * as the area does.
68dc5a79c1SDavid du Colombier */
69dc5a79c1SDavid du Colombier s = emalloc(sizeof(*s));
70dc5a79c1SDavid du Colombier s->len = strlen(dp->name);
71dc5a79c1SDavid du Colombier rrcopy(rp, &s->soarr);
72dc5a79c1SDavid du Colombier s->soarr->owner = dp;
73dc5a79c1SDavid du Colombier s->soarr->db = 1;
74dc5a79c1SDavid du Colombier s->soarr->ttl = Hour;
75dc5a79c1SDavid du Colombier s->neednotify = 1;
76dc5a79c1SDavid du Colombier s->needrefresh = 0;
77dc5a79c1SDavid du Colombier
78186d659cSDavid du Colombier if (debug)
794f8f669cSDavid du Colombier dnslog("new area %s %s", dp->name,
804f8f669cSDavid du Colombier l == &delegated? "delegated": "owned");
81dc5a79c1SDavid du Colombier
82dc5a79c1SDavid du Colombier s->next = *l;
83dc5a79c1SDavid du Colombier *l = s;
84530fef66SDavid du Colombier unlock(&dnlock);
85dc5a79c1SDavid du Colombier }
86dc5a79c1SDavid du Colombier
87dc5a79c1SDavid du Colombier void
freearea(Area ** l)88dc5a79c1SDavid du Colombier freearea(Area **l)
89dc5a79c1SDavid du Colombier {
90dc5a79c1SDavid du Colombier Area *s;
91dc5a79c1SDavid du Colombier
92dc5a79c1SDavid du Colombier while(s = *l){
93dc5a79c1SDavid du Colombier *l = s->next;
94*c3617180SDavid du Colombier lock(&dnlock);
95dc5a79c1SDavid du Colombier rrfree(s->soarr);
964f8f669cSDavid du Colombier memset(s, 0, sizeof *s); /* cause trouble */
97*c3617180SDavid du Colombier unlock(&dnlock);
98dc5a79c1SDavid du Colombier free(s);
99dc5a79c1SDavid du Colombier }
100dc5a79c1SDavid du Colombier }
101dc5a79c1SDavid du Colombier
102dc5a79c1SDavid du Colombier /*
103dc5a79c1SDavid du Colombier * refresh all areas that need it
104dc5a79c1SDavid du Colombier * this entails running a command 'zonerefreshprogram'. This could
105dc5a79c1SDavid du Colombier * copy over databases from elsewhere or just do a zone transfer.
106dc5a79c1SDavid du Colombier */
107dc5a79c1SDavid du Colombier void
refresh_areas(Area * s)108dc5a79c1SDavid du Colombier refresh_areas(Area *s)
109dc5a79c1SDavid du Colombier {
110dc5a79c1SDavid du Colombier int pid;
111dc5a79c1SDavid du Colombier Waitmsg *w;
112dc5a79c1SDavid du Colombier
113dc5a79c1SDavid du Colombier for(; s != nil; s = s->next){
114dc5a79c1SDavid du Colombier if(!s->needrefresh)
115dc5a79c1SDavid du Colombier continue;
116dc5a79c1SDavid du Colombier
117dc5a79c1SDavid du Colombier if(zonerefreshprogram == nil){
118dc5a79c1SDavid du Colombier s->needrefresh = 0;
119dc5a79c1SDavid du Colombier continue;
120dc5a79c1SDavid du Colombier }
121dc5a79c1SDavid du Colombier
1224f8f669cSDavid du Colombier pid = fork();
1234f8f669cSDavid du Colombier if (pid == -1) {
124e02f7f02SDavid du Colombier sleep(1000); /* don't fork again immediately */
1254f8f669cSDavid du Colombier continue;
1264f8f669cSDavid du Colombier }
1274f8f669cSDavid du Colombier if (pid == 0){
1284f8f669cSDavid du Colombier execl(zonerefreshprogram, "zonerefresh",
1294f8f669cSDavid du Colombier s->soarr->owner->name, nil);
1304f8f669cSDavid du Colombier exits("exec zonerefresh failed");
1314f8f669cSDavid du Colombier }
1324f8f669cSDavid du Colombier while ((w = wait()) != nil && w->pid != pid)
1334f8f669cSDavid du Colombier free(w);
1344f8f669cSDavid du Colombier if (w && w->pid == pid)
1354f8f669cSDavid du Colombier if(w->msg == nil || *w->msg == '\0')
136dc5a79c1SDavid du Colombier s->needrefresh = 0;
137dc5a79c1SDavid du Colombier free(w);
138dc5a79c1SDavid du Colombier }
139dc5a79c1SDavid du Colombier }
140