131 lines
2.1 KiB
C
131 lines
2.1 KiB
C
|
|
#include <u.h>
|
||
|
|
#include <libc.h>
|
||
|
|
#include <bio.h>
|
||
|
|
#include <ndb.h>
|
||
|
|
#include <ip.h>
|
||
|
|
#include "dns.h"
|
||
|
|
|
||
|
|
Area *owned;
|
||
|
|
Area *delegated;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* true if a name is in our area
|
||
|
|
*/
|
||
|
|
Area*
|
||
|
|
inmyarea(char *name)
|
||
|
|
{
|
||
|
|
int len;
|
||
|
|
Area *s, *d;
|
||
|
|
|
||
|
|
len = strlen(name);
|
||
|
|
for(s = owned; s; s = s->next){
|
||
|
|
if(s->len > len)
|
||
|
|
continue;
|
||
|
|
if(cistrcmp(s->soarr->owner->name, name + len - s->len) == 0)
|
||
|
|
if(len == s->len || name[len - s->len - 1] == '.')
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
if(s == 0)
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
for(d = delegated; d; d = d->next){
|
||
|
|
if(d->len > len)
|
||
|
|
continue;
|
||
|
|
if(cistrcmp(d->soarr->owner->name, name + len - d->len) == 0)
|
||
|
|
if(len == d->len || name[len - d->len - 1] == '.')
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return s;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
* our area is the part of the domain tree that
|
||
|
|
* we serve
|
||
|
|
*/
|
||
|
|
void
|
||
|
|
addarea(DN *dp, RR *rp, Ndbtuple *t)
|
||
|
|
{
|
||
|
|
Area **l, *s;
|
||
|
|
|
||
|
|
if(t->val[0])
|
||
|
|
l = &delegated;
|
||
|
|
else
|
||
|
|
l = &owned;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* The area contains a copy of the soa rr that created it.
|
||
|
|
* The owner of the the soa rr should stick around as long
|
||
|
|
* as the area does.
|
||
|
|
*/
|
||
|
|
s = emalloc(sizeof(*s));
|
||
|
|
s->len = strlen(dp->name);
|
||
|
|
rrcopy(rp, &s->soarr);
|
||
|
|
s->soarr->owner = dp;
|
||
|
|
s->soarr->db = 1;
|
||
|
|
s->soarr->ttl = Hour;
|
||
|
|
s->neednotify = 1;
|
||
|
|
s->needrefresh = 0;
|
||
|
|
|
||
|
|
syslog(0, logfile, "new area %s", dp->name);
|
||
|
|
|
||
|
|
s->next = *l;
|
||
|
|
*l = s;
|
||
|
|
}
|
||
|
|
|
||
|
|
void
|
||
|
|
freearea(Area **l)
|
||
|
|
{
|
||
|
|
Area *s;
|
||
|
|
|
||
|
|
while(s = *l){
|
||
|
|
*l = s->next;
|
||
|
|
rrfree(s->soarr);
|
||
|
|
free(s);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
* refresh all areas that need it
|
||
|
|
* this entails running a command 'zonerefreshprogram'. This could
|
||
|
|
* copy over databases from elsewhere or just do a zone transfer.
|
||
|
|
*/
|
||
|
|
void
|
||
|
|
refresh_areas(Area *s)
|
||
|
|
{
|
||
|
|
int pid;
|
||
|
|
Waitmsg *w;
|
||
|
|
|
||
|
|
for(; s != nil; s = s->next){
|
||
|
|
if(!s->needrefresh)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
if(zonerefreshprogram == nil){
|
||
|
|
s->needrefresh = 0;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch(pid = fork()){
|
||
|
|
case -1:
|
||
|
|
break;
|
||
|
|
case 0:
|
||
|
|
execl(zonerefreshprogram, "zonerefresh", s->soarr->owner->name, 0);
|
||
|
|
exits(0);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
for(;;){
|
||
|
|
w = wait();
|
||
|
|
if(w == nil)
|
||
|
|
break;
|
||
|
|
if(w->pid == pid){
|
||
|
|
if(w->msg == nil || *w->msg == 0)
|
||
|
|
s->needrefresh = 0;
|
||
|
|
free(w);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
free(w);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|