aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ndb/dnarea.c
blob: bb4d050cb8c13bfc8850f77043b0592ec7c1cf11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ndb.h>
#include <ip.h>
#include <thread.h>
#include "dns.h"

Area *owned;
Area *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 == 0)
		return 0;

	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 0;
	}

	return s;
}

/*
 *  our area is the part of the domain tree that
 *  we serve
 */
void
addarea(DN *dp, RR *rp, Ndbtuple *t)
{
	Area **l, *s;

	if(t->val[0])
		l = &delegated;
	else
		l = &owned;

	/*
	 *  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;

syslog(0, logfile, "new area %s", dp->name);

	s->next = *l;
	*l = s;
}

void
freearea(Area **l)
{
	Area *s;

	while(s = *l){
		*l = s->next;
		rrfree(s->soarr);
		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)
{
	Waitmsg *w;
	char *argv[3];

	argv[0] = zonerefreshprogram;
	argv[1] = "XXX";
	argv[2] = nil;

	for(; s != nil; s = s->next){
		if(!s->needrefresh)
			continue;

		if(zonerefreshprogram == nil){
			s->needrefresh = 0;
			continue;
		}

		argv[1] = s->soarr->owner->name;
		w = runproc(argv[0], argv, 0);
		free(w);
	}
}