dnarea.c 3.0 KB

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