xref: /plan9/sys/src/cmd/ndb/dnarea.c (revision c361718002866812b3dd559475f979bcacdb2c1e)
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