dnarea.c 2.6 KB

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