summaryrefslogtreecommitdiff
path: root/sys/src/cmd/ndb/dnarea.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /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-xsys/src/cmd/ndb/dnarea.c137
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);
+ }
+}