1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <ndb.h> 5 #include <ip.h> 6 #include "dns.h" 7 8 Area *owned, *delegated; 9 10 /* 11 * true if a name is in our area 12 */ 13 Area* 14 inmyarea(char *name) 15 { 16 int len; 17 Area *s, *d; 18 19 len = strlen(name); 20 for(s = owned; s; s = s->next){ 21 if(s->len > len) 22 continue; 23 if(cistrcmp(s->soarr->owner->name, name + len - s->len) == 0) 24 if(len == s->len || name[len - s->len - 1] == '.') 25 break; 26 } 27 if(s == nil) 28 return nil; 29 30 /* name is in area `s' */ 31 for(d = delegated; d; d = d->next){ 32 if(d->len > len) 33 continue; 34 if(cistrcmp(d->soarr->owner->name, name + len - d->len) == 0) 35 if(len == d->len || name[len - d->len - 1] == '.') 36 return nil; /* name is in a delegated subarea */ 37 } 38 39 return s; /* name is in area `s' and not in a delegated subarea */ 40 } 41 42 /* 43 * our area is the part of the domain tree that 44 * we serve 45 */ 46 void 47 addarea(DN *dp, RR *rp, Ndbtuple *t) 48 { 49 Area *s; 50 Area **l; 51 52 lock(&dnlock); 53 if(t->val[0]) 54 l = &delegated; 55 else 56 l = &owned; 57 58 for (s = *l; s != nil; s = s->next) 59 if (strcmp(dp->name, s->soarr->owner->name) == 0) { 60 unlock(&dnlock); 61 return; /* we've already got one */ 62 } 63 64 /* 65 * The area contains a copy of the soa rr that created it. 66 * The owner of the the soa rr should stick around as long 67 * as the area does. 68 */ 69 s = emalloc(sizeof(*s)); 70 s->len = strlen(dp->name); 71 rrcopy(rp, &s->soarr); 72 s->soarr->owner = dp; 73 s->soarr->db = 1; 74 s->soarr->ttl = Hour; 75 s->neednotify = 1; 76 s->needrefresh = 0; 77 78 if (debug) 79 dnslog("new area %s %s", dp->name, 80 l == &delegated? "delegated": "owned"); 81 82 s->next = *l; 83 *l = s; 84 unlock(&dnlock); 85 } 86 87 void 88 freearea(Area **l) 89 { 90 Area *s; 91 92 while(s = *l){ 93 *l = s->next; 94 lock(&dnlock); 95 rrfree(s->soarr); 96 memset(s, 0, sizeof *s); /* cause trouble */ 97 unlock(&dnlock); 98 free(s); 99 } 100 } 101 102 /* 103 * refresh all areas that need it 104 * this entails running a command 'zonerefreshprogram'. This could 105 * copy over databases from elsewhere or just do a zone transfer. 106 */ 107 void 108 refresh_areas(Area *s) 109 { 110 int pid; 111 Waitmsg *w; 112 113 for(; s != nil; s = s->next){ 114 if(!s->needrefresh) 115 continue; 116 117 if(zonerefreshprogram == nil){ 118 s->needrefresh = 0; 119 continue; 120 } 121 122 pid = fork(); 123 if (pid == -1) { 124 sleep(1000); /* don't fork again immediately */ 125 continue; 126 } 127 if (pid == 0){ 128 execl(zonerefreshprogram, "zonerefresh", 129 s->soarr->owner->name, nil); 130 exits("exec zonerefresh failed"); 131 } 132 while ((w = wait()) != nil && w->pid != pid) 133 free(w); 134 if (w && w->pid == pid) 135 if(w->msg == nil || *w->msg == '\0') 136 s->needrefresh = 0; 137 free(w); 138 } 139 } 140