dnarea.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. if(t->val[0])
  46. l = &delegated;
  47. else
  48. l = &owned;
  49. for (s = *l; s != nil; s = s->next)
  50. if (strcmp(dp->name, s->soarr->owner->name) == 0)
  51. return; /* we've already got one */
  52. /*
  53. * The area contains a copy of the soa rr that created it.
  54. * The owner of the the soa rr should stick around as long
  55. * as the area does.
  56. */
  57. s = emalloc(sizeof(*s));
  58. s->len = strlen(dp->name);
  59. rrcopy(rp, &s->soarr);
  60. s->soarr->owner = dp;
  61. s->soarr->db = 1;
  62. s->soarr->ttl = Hour;
  63. s->neednotify = 1;
  64. s->needrefresh = 0;
  65. if (debug)
  66. dnslog("new area %s %s", dp->name,
  67. l == &delegated? "delegated": "owned");
  68. s->next = *l;
  69. *l = s;
  70. }
  71. void
  72. freearea(Area **l)
  73. {
  74. Area *s;
  75. while(s = *l){
  76. *l = s->next;
  77. rrfree(s->soarr);
  78. memset(s, 0, sizeof *s); /* cause trouble */
  79. free(s);
  80. }
  81. }
  82. /*
  83. * refresh all areas that need it
  84. * this entails running a command 'zonerefreshprogram'. This could
  85. * copy over databases from elsewhere or just do a zone transfer.
  86. */
  87. void
  88. refresh_areas(Area *s)
  89. {
  90. int pid;
  91. Waitmsg *w;
  92. for(; s != nil; s = s->next){
  93. if(!s->needrefresh)
  94. continue;
  95. if(zonerefreshprogram == nil){
  96. s->needrefresh = 0;
  97. continue;
  98. }
  99. pid = fork();
  100. if (pid == -1) {
  101. sleep(1000); /* don't try it again immediately */
  102. continue;
  103. }
  104. if (pid == 0){
  105. execl(zonerefreshprogram, "zonerefresh",
  106. s->soarr->owner->name, nil);
  107. exits("exec zonerefresh failed");
  108. }
  109. while ((w = wait()) != nil && w->pid != pid)
  110. free(w);
  111. if (w && w->pid == pid)
  112. if(w->msg == nil || *w->msg == '\0')
  113. s->needrefresh = 0;
  114. free(w);
  115. }
  116. }