diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/ndb/dnarea.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ndb/dnarea.c')
-rwxr-xr-x | sys/src/cmd/ndb/dnarea.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/sys/src/cmd/ndb/dnarea.c b/sys/src/cmd/ndb/dnarea.c new file mode 100755 index 000000000..ca680219c --- /dev/null +++ b/sys/src/cmd/ndb/dnarea.c @@ -0,0 +1,137 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <ndb.h> +#include <ip.h> +#include "dns.h" + +Area *owned, *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 == nil) + return nil; + + /* name is in area `s' */ + 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 nil; /* name is in a delegated subarea */ + } + + return s; /* name is in area `s' and not in a delegated subarea */ +} + +/* + * our area is the part of the domain tree that + * we serve + */ +void +addarea(DN *dp, RR *rp, Ndbtuple *t) +{ + Area *s; + Area **l; + + lock(&dnlock); + if(t->val[0]) + l = &delegated; + else + l = &owned; + + for (s = *l; s != nil; s = s->next) + if (strcmp(dp->name, s->soarr->owner->name) == 0) { + unlock(&dnlock); + return; /* we've already got one */ + } + + /* + * 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; + + if (debug) + dnslog("new area %s %s", dp->name, + l == &delegated? "delegated": "owned"); + + s->next = *l; + *l = s; + unlock(&dnlock); +} + +void +freearea(Area **l) +{ + Area *s; + + while(s = *l){ + *l = s->next; + rrfree(s->soarr); + memset(s, 0, sizeof *s); /* cause trouble */ + 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; + } + + pid = fork(); + if (pid == -1) { + sleep(1000); /* don't fork again immediately */ + continue; + } + if (pid == 0){ + execl(zonerefreshprogram, "zonerefresh", + s->soarr->owner->name, nil); + exits("exec zonerefresh failed"); + } + while ((w = wait()) != nil && w->pid != pid) + free(w); + if (w && w->pid == pid) + if(w->msg == nil || *w->msg == '\0') + s->needrefresh = 0; + free(w); + } +} |