Blame


1 3e0d8fb3 2005-12-27 devnull #include <u.h>
2 3e0d8fb3 2005-12-27 devnull #include <libc.h>
3 3e0d8fb3 2005-12-27 devnull #include <ip.h>
4 3e0d8fb3 2005-12-27 devnull #include <ctype.h>
5 3e0d8fb3 2005-12-27 devnull #include <bio.h>
6 3e0d8fb3 2005-12-27 devnull #include <ndb.h>
7 5c9f76b5 2006-02-14 devnull #include <thread.h>
8 3e0d8fb3 2005-12-27 devnull #include "dns.h"
9 3e0d8fb3 2005-12-27 devnull
10 3e0d8fb3 2005-12-27 devnull /*
11 3e0d8fb3 2005-12-27 devnull * Hash table for domain names. The hash is based only on the
12 3e0d8fb3 2005-12-27 devnull * first element of the domain name.
13 3e0d8fb3 2005-12-27 devnull */
14 3e0d8fb3 2005-12-27 devnull DN *ht[HTLEN];
15 3e0d8fb3 2005-12-27 devnull
16 3e0d8fb3 2005-12-27 devnull
17 3e0d8fb3 2005-12-27 devnull static struct
18 3e0d8fb3 2005-12-27 devnull {
19 3e0d8fb3 2005-12-27 devnull Lock lk;
20 3e0d8fb3 2005-12-27 devnull ulong names; /* names allocated */
21 3e0d8fb3 2005-12-27 devnull ulong oldest; /* longest we'll leave a name around */
22 3e0d8fb3 2005-12-27 devnull int active;
23 3e0d8fb3 2005-12-27 devnull int mutex;
24 3e0d8fb3 2005-12-27 devnull int id;
25 3e0d8fb3 2005-12-27 devnull } dnvars;
26 3e0d8fb3 2005-12-27 devnull
27 3e0d8fb3 2005-12-27 devnull /* names of RR types */
28 226d80b8 2006-04-01 devnull char *rrtname[Tall+2] =
29 3e0d8fb3 2005-12-27 devnull {
30 226d80b8 2006-04-01 devnull nil,
31 226d80b8 2006-04-01 devnull "ip",
32 226d80b8 2006-04-01 devnull "ns",
33 226d80b8 2006-04-01 devnull "md",
34 226d80b8 2006-04-01 devnull "mf",
35 226d80b8 2006-04-01 devnull "cname",
36 226d80b8 2006-04-01 devnull "soa",
37 226d80b8 2006-04-01 devnull "mb",
38 226d80b8 2006-04-01 devnull "mg",
39 226d80b8 2006-04-01 devnull "mr",
40 226d80b8 2006-04-01 devnull "null",
41 226d80b8 2006-04-01 devnull "wks",
42 226d80b8 2006-04-01 devnull "ptr",
43 226d80b8 2006-04-01 devnull "hinfo",
44 226d80b8 2006-04-01 devnull "minfo",
45 226d80b8 2006-04-01 devnull "mx",
46 226d80b8 2006-04-01 devnull "txt",
47 226d80b8 2006-04-01 devnull "rp",
48 226d80b8 2006-04-01 devnull nil,
49 226d80b8 2006-04-01 devnull nil,
50 226d80b8 2006-04-01 devnull nil,
51 226d80b8 2006-04-01 devnull nil,
52 226d80b8 2006-04-01 devnull nil,
53 226d80b8 2006-04-01 devnull nil,
54 226d80b8 2006-04-01 devnull "sig",
55 226d80b8 2006-04-01 devnull "key",
56 226d80b8 2006-04-01 devnull nil,
57 226d80b8 2006-04-01 devnull nil,
58 226d80b8 2006-04-01 devnull "aaaa",
59 226d80b8 2006-04-01 devnull nil,
60 226d80b8 2006-04-01 devnull nil,
61 226d80b8 2006-04-01 devnull nil,
62 226d80b8 2006-04-01 devnull nil,
63 226d80b8 2006-04-01 devnull nil,
64 226d80b8 2006-04-01 devnull nil,
65 226d80b8 2006-04-01 devnull nil,
66 226d80b8 2006-04-01 devnull nil,
67 226d80b8 2006-04-01 devnull "cert",
68 226d80b8 2006-04-01 devnull nil,
69 226d80b8 2006-04-01 devnull nil,
70 226d80b8 2006-04-01 devnull
71 226d80b8 2006-04-01 devnull /* 40 */ nil, nil, nil, nil, nil, nil, nil, nil,
72 226d80b8 2006-04-01 devnull /* 48 */ nil, nil, nil, nil, nil, nil, nil, nil,
73 226d80b8 2006-04-01 devnull /* 56 */ nil, nil, nil, nil, nil, nil, nil, nil,
74 226d80b8 2006-04-01 devnull /* 64 */ nil, nil, nil, nil, nil, nil, nil, nil,
75 226d80b8 2006-04-01 devnull /* 72 */ nil, nil, nil, nil, nil, nil, nil, nil,
76 226d80b8 2006-04-01 devnull /* 80 */ nil, nil, nil, nil, nil, nil, nil, nil,
77 226d80b8 2006-04-01 devnull /* 88 */ nil, nil, nil, nil, nil, nil, nil, nil,
78 226d80b8 2006-04-01 devnull /* 96 */ nil, nil, nil, nil, nil, nil, nil, nil,
79 226d80b8 2006-04-01 devnull /* 104 */ nil, nil, nil, nil, nil, nil, nil, nil,
80 226d80b8 2006-04-01 devnull /* 112 */ nil, nil, nil, nil, nil, nil, nil, nil,
81 226d80b8 2006-04-01 devnull /* 120 */ nil, nil, nil, nil, nil, nil, nil, nil,
82 226d80b8 2006-04-01 devnull /* 128 */ nil, nil, nil, nil, nil, nil, nil, nil,
83 226d80b8 2006-04-01 devnull /* 136 */ nil, nil, nil, nil, nil, nil, nil, nil,
84 226d80b8 2006-04-01 devnull /* 144 */ nil, nil, nil, nil, nil, nil, nil, nil,
85 226d80b8 2006-04-01 devnull /* 152 */ nil, nil, nil, nil, nil, nil, nil, nil,
86 226d80b8 2006-04-01 devnull /* 160 */ nil, nil, nil, nil, nil, nil, nil, nil,
87 226d80b8 2006-04-01 devnull /* 168 */ nil, nil, nil, nil, nil, nil, nil, nil,
88 226d80b8 2006-04-01 devnull /* 176 */ nil, nil, nil, nil, nil, nil, nil, nil,
89 226d80b8 2006-04-01 devnull /* 184 */ nil, nil, nil, nil, nil, nil, nil, nil,
90 226d80b8 2006-04-01 devnull /* 192 */ nil, nil, nil, nil, nil, nil, nil, nil,
91 226d80b8 2006-04-01 devnull /* 200 */ nil, nil, nil, nil, nil, nil, nil, nil,
92 226d80b8 2006-04-01 devnull /* 208 */ nil, nil, nil, nil, nil, nil, nil, nil,
93 226d80b8 2006-04-01 devnull /* 216 */ nil, nil, nil, nil, nil, nil, nil, nil,
94 226d80b8 2006-04-01 devnull /* 224 */ nil, nil, nil, nil, nil, nil, nil, nil,
95 226d80b8 2006-04-01 devnull /* 232 */ nil, nil, nil, nil, nil, nil, nil, nil,
96 226d80b8 2006-04-01 devnull /* 240 */ nil, nil, nil, nil, nil, nil, nil, nil,
97 226d80b8 2006-04-01 devnull /* 248 */ nil, nil, nil,
98 226d80b8 2006-04-01 devnull
99 226d80b8 2006-04-01 devnull "ixfr",
100 226d80b8 2006-04-01 devnull "axfr",
101 226d80b8 2006-04-01 devnull "mailb",
102 226d80b8 2006-04-01 devnull nil,
103 226d80b8 2006-04-01 devnull "all",
104 226d80b8 2006-04-01 devnull nil
105 3e0d8fb3 2005-12-27 devnull };
106 3e0d8fb3 2005-12-27 devnull
107 3e0d8fb3 2005-12-27 devnull /* names of response codes */
108 3e0d8fb3 2005-12-27 devnull char *rname[Rmask+1] =
109 3e0d8fb3 2005-12-27 devnull {
110 226d80b8 2006-04-01 devnull "ok",
111 226d80b8 2006-04-01 devnull "format error",
112 226d80b8 2006-04-01 devnull "server failure",
113 226d80b8 2006-04-01 devnull "bad name",
114 226d80b8 2006-04-01 devnull "unimplemented",
115 cbeb0b26 2006-04-01 devnull "we don't like you"
116 3e0d8fb3 2005-12-27 devnull };
117 3e0d8fb3 2005-12-27 devnull
118 3e0d8fb3 2005-12-27 devnull Lock dnlock;
119 3e0d8fb3 2005-12-27 devnull
120 3e0d8fb3 2005-12-27 devnull static int sencodefmt(Fmt*);
121 3e0d8fb3 2005-12-27 devnull
122 3e0d8fb3 2005-12-27 devnull /*
123 3e0d8fb3 2005-12-27 devnull * set up a pipe to use as a lock
124 3e0d8fb3 2005-12-27 devnull */
125 3e0d8fb3 2005-12-27 devnull void
126 3e0d8fb3 2005-12-27 devnull dninit(void)
127 3e0d8fb3 2005-12-27 devnull {
128 3e0d8fb3 2005-12-27 devnull fmtinstall('E', eipfmt);
129 3e0d8fb3 2005-12-27 devnull fmtinstall('I', eipfmt);
130 3e0d8fb3 2005-12-27 devnull fmtinstall('V', eipfmt);
131 3e0d8fb3 2005-12-27 devnull fmtinstall('R', rrfmt);
132 3e0d8fb3 2005-12-27 devnull fmtinstall('Q', rravfmt);
133 3e0d8fb3 2005-12-27 devnull fmtinstall('H', sencodefmt);
134 3e0d8fb3 2005-12-27 devnull
135 3e0d8fb3 2005-12-27 devnull dnvars.oldest = maxage;
136 3e0d8fb3 2005-12-27 devnull dnvars.names = 0;
137 3e0d8fb3 2005-12-27 devnull }
138 3e0d8fb3 2005-12-27 devnull
139 3e0d8fb3 2005-12-27 devnull /*
140 3e0d8fb3 2005-12-27 devnull * hash for a domain name
141 3e0d8fb3 2005-12-27 devnull */
142 3e0d8fb3 2005-12-27 devnull static ulong
143 3e0d8fb3 2005-12-27 devnull dnhash(char *name)
144 3e0d8fb3 2005-12-27 devnull {
145 3e0d8fb3 2005-12-27 devnull ulong hash;
146 3e0d8fb3 2005-12-27 devnull uchar *val = (uchar*)name;
147 3e0d8fb3 2005-12-27 devnull
148 3e0d8fb3 2005-12-27 devnull for(hash = 0; *val; val++)
149 3e0d8fb3 2005-12-27 devnull hash = (hash*13) + tolower(*val)-'a';
150 3e0d8fb3 2005-12-27 devnull return hash % HTLEN;
151 3e0d8fb3 2005-12-27 devnull }
152 3e0d8fb3 2005-12-27 devnull
153 3e0d8fb3 2005-12-27 devnull /*
154 3e0d8fb3 2005-12-27 devnull * lookup a symbol. if enter is not zero and the name is
155 3e0d8fb3 2005-12-27 devnull * not found, create it.
156 3e0d8fb3 2005-12-27 devnull */
157 3e0d8fb3 2005-12-27 devnull DN*
158 3e0d8fb3 2005-12-27 devnull dnlookup(char *name, int class, int enter)
159 3e0d8fb3 2005-12-27 devnull {
160 3e0d8fb3 2005-12-27 devnull DN **l;
161 3e0d8fb3 2005-12-27 devnull DN *dp;
162 3e0d8fb3 2005-12-27 devnull
163 3e0d8fb3 2005-12-27 devnull l = &ht[dnhash(name)];
164 3e0d8fb3 2005-12-27 devnull lock(&dnlock);
165 3e0d8fb3 2005-12-27 devnull for(dp = *l; dp; dp = dp->next) {
166 3e0d8fb3 2005-12-27 devnull assert(dp->magic == DNmagic);
167 3e0d8fb3 2005-12-27 devnull if(dp->class == class && cistrcmp(dp->name, name) == 0){
168 3e0d8fb3 2005-12-27 devnull dp->referenced = now;
169 3e0d8fb3 2005-12-27 devnull unlock(&dnlock);
170 3e0d8fb3 2005-12-27 devnull return dp;
171 3e0d8fb3 2005-12-27 devnull }
172 3e0d8fb3 2005-12-27 devnull l = &dp->next;
173 3e0d8fb3 2005-12-27 devnull }
174 3e0d8fb3 2005-12-27 devnull if(enter == 0){
175 3e0d8fb3 2005-12-27 devnull unlock(&dnlock);
176 3e0d8fb3 2005-12-27 devnull return 0;
177 3e0d8fb3 2005-12-27 devnull }
178 3e0d8fb3 2005-12-27 devnull dnvars.names++;
179 3e0d8fb3 2005-12-27 devnull dp = emalloc(sizeof(*dp));
180 3e0d8fb3 2005-12-27 devnull dp->magic = DNmagic;
181 3e0d8fb3 2005-12-27 devnull dp->name = estrdup(name);
182 3e0d8fb3 2005-12-27 devnull assert(dp->name != 0);
183 3e0d8fb3 2005-12-27 devnull dp->class = class;
184 3e0d8fb3 2005-12-27 devnull dp->rr = 0;
185 3e0d8fb3 2005-12-27 devnull dp->next = 0;
186 3e0d8fb3 2005-12-27 devnull dp->referenced = now;
187 3e0d8fb3 2005-12-27 devnull *l = dp;
188 3e0d8fb3 2005-12-27 devnull unlock(&dnlock);
189 3e0d8fb3 2005-12-27 devnull
190 3e0d8fb3 2005-12-27 devnull return dp;
191 3e0d8fb3 2005-12-27 devnull }
192 3e0d8fb3 2005-12-27 devnull
193 3e0d8fb3 2005-12-27 devnull /*
194 3e0d8fb3 2005-12-27 devnull * dump the cache
195 3e0d8fb3 2005-12-27 devnull */
196 3e0d8fb3 2005-12-27 devnull void
197 3e0d8fb3 2005-12-27 devnull dndump(char *file)
198 3e0d8fb3 2005-12-27 devnull {
199 3e0d8fb3 2005-12-27 devnull DN *dp;
200 3e0d8fb3 2005-12-27 devnull int i, fd;
201 3e0d8fb3 2005-12-27 devnull RR *rp;
202 3e0d8fb3 2005-12-27 devnull
203 3e0d8fb3 2005-12-27 devnull fd = open(file, OWRITE|OTRUNC);
204 3e0d8fb3 2005-12-27 devnull if(fd < 0)
205 3e0d8fb3 2005-12-27 devnull return;
206 3e0d8fb3 2005-12-27 devnull lock(&dnlock);
207 3e0d8fb3 2005-12-27 devnull for(i = 0; i < HTLEN; i++){
208 3e0d8fb3 2005-12-27 devnull for(dp = ht[i]; dp; dp = dp->next){
209 3e0d8fb3 2005-12-27 devnull fprint(fd, "%s\n", dp->name);
210 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = rp->next)
211 3e0d8fb3 2005-12-27 devnull fprint(fd, " %R %c%c %lud/%lud\n", rp, rp->auth?'A':'U',
212 3e0d8fb3 2005-12-27 devnull rp->db?'D':'N', rp->expire, rp->ttl);
213 3e0d8fb3 2005-12-27 devnull }
214 3e0d8fb3 2005-12-27 devnull }
215 3e0d8fb3 2005-12-27 devnull unlock(&dnlock);
216 3e0d8fb3 2005-12-27 devnull close(fd);
217 3e0d8fb3 2005-12-27 devnull }
218 3e0d8fb3 2005-12-27 devnull
219 3e0d8fb3 2005-12-27 devnull /*
220 3e0d8fb3 2005-12-27 devnull * purge all records
221 3e0d8fb3 2005-12-27 devnull */
222 3e0d8fb3 2005-12-27 devnull void
223 3e0d8fb3 2005-12-27 devnull dnpurge(void)
224 3e0d8fb3 2005-12-27 devnull {
225 3e0d8fb3 2005-12-27 devnull DN *dp;
226 3e0d8fb3 2005-12-27 devnull RR *rp, *srp;
227 3e0d8fb3 2005-12-27 devnull int i;
228 3e0d8fb3 2005-12-27 devnull
229 3e0d8fb3 2005-12-27 devnull lock(&dnlock);
230 3e0d8fb3 2005-12-27 devnull
231 3e0d8fb3 2005-12-27 devnull for(i = 0; i < HTLEN; i++)
232 3e0d8fb3 2005-12-27 devnull for(dp = ht[i]; dp; dp = dp->next){
233 3e0d8fb3 2005-12-27 devnull srp = rp = dp->rr;
234 3e0d8fb3 2005-12-27 devnull dp->rr = nil;
235 3e0d8fb3 2005-12-27 devnull for(; rp != nil; rp = rp->next)
236 3e0d8fb3 2005-12-27 devnull rp->cached = 0;
237 3e0d8fb3 2005-12-27 devnull rrfreelist(srp);
238 3e0d8fb3 2005-12-27 devnull }
239 3e0d8fb3 2005-12-27 devnull
240 3e0d8fb3 2005-12-27 devnull unlock(&dnlock);
241 3e0d8fb3 2005-12-27 devnull }
242 3e0d8fb3 2005-12-27 devnull
243 3e0d8fb3 2005-12-27 devnull /*
244 3e0d8fb3 2005-12-27 devnull * check the age of resource records, free any that have timed out
245 3e0d8fb3 2005-12-27 devnull */
246 3e0d8fb3 2005-12-27 devnull void
247 3e0d8fb3 2005-12-27 devnull dnage(DN *dp)
248 3e0d8fb3 2005-12-27 devnull {
249 3e0d8fb3 2005-12-27 devnull RR **l;
250 3e0d8fb3 2005-12-27 devnull RR *rp, *next;
251 3e0d8fb3 2005-12-27 devnull ulong diff;
252 3e0d8fb3 2005-12-27 devnull
253 3e0d8fb3 2005-12-27 devnull diff = now - dp->referenced;
254 3e0d8fb3 2005-12-27 devnull if(diff < Reserved)
255 3e0d8fb3 2005-12-27 devnull return;
256 3e0d8fb3 2005-12-27 devnull
257 3e0d8fb3 2005-12-27 devnull l = &dp->rr;
258 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = next){
259 3e0d8fb3 2005-12-27 devnull assert(rp->magic == RRmagic && rp->cached);
260 3e0d8fb3 2005-12-27 devnull next = rp->next;
261 3e0d8fb3 2005-12-27 devnull if(!rp->db)
262 3e0d8fb3 2005-12-27 devnull if(rp->expire < now || diff > dnvars.oldest){
263 3e0d8fb3 2005-12-27 devnull *l = next;
264 3e0d8fb3 2005-12-27 devnull rp->cached = 0;
265 3e0d8fb3 2005-12-27 devnull rrfree(rp);
266 3e0d8fb3 2005-12-27 devnull continue;
267 3e0d8fb3 2005-12-27 devnull }
268 3e0d8fb3 2005-12-27 devnull l = &rp->next;
269 3e0d8fb3 2005-12-27 devnull }
270 3e0d8fb3 2005-12-27 devnull }
271 3e0d8fb3 2005-12-27 devnull
272 3e0d8fb3 2005-12-27 devnull #define REF(x) if(x) x->refs++
273 3e0d8fb3 2005-12-27 devnull
274 3e0d8fb3 2005-12-27 devnull /*
275 3e0d8fb3 2005-12-27 devnull * our target is 4000 names cached, this should be larger on large servers
276 3e0d8fb3 2005-12-27 devnull */
277 3e0d8fb3 2005-12-27 devnull #define TARGET 4000
278 3e0d8fb3 2005-12-27 devnull
279 3e0d8fb3 2005-12-27 devnull /*
280 3e0d8fb3 2005-12-27 devnull * periodicly sweep for old records and remove unreferenced domain names
281 3e0d8fb3 2005-12-27 devnull *
282 3e0d8fb3 2005-12-27 devnull * only called when all other threads are locked out
283 3e0d8fb3 2005-12-27 devnull */
284 3e0d8fb3 2005-12-27 devnull void
285 3e0d8fb3 2005-12-27 devnull dnageall(int doit)
286 3e0d8fb3 2005-12-27 devnull {
287 3e0d8fb3 2005-12-27 devnull DN *dp, **l;
288 3e0d8fb3 2005-12-27 devnull int i;
289 3e0d8fb3 2005-12-27 devnull RR *rp;
290 3e0d8fb3 2005-12-27 devnull static ulong nextage;
291 3e0d8fb3 2005-12-27 devnull
292 3e0d8fb3 2005-12-27 devnull if(dnvars.names < TARGET && now < nextage && !doit){
293 3e0d8fb3 2005-12-27 devnull dnvars.oldest = maxage;
294 3e0d8fb3 2005-12-27 devnull return;
295 3e0d8fb3 2005-12-27 devnull }
296 3e0d8fb3 2005-12-27 devnull
297 3e0d8fb3 2005-12-27 devnull if(dnvars.names > TARGET)
298 3e0d8fb3 2005-12-27 devnull dnvars.oldest /= 2;
299 3e0d8fb3 2005-12-27 devnull nextage = now + maxage;
300 3e0d8fb3 2005-12-27 devnull
301 3e0d8fb3 2005-12-27 devnull lock(&dnlock);
302 3e0d8fb3 2005-12-27 devnull
303 3e0d8fb3 2005-12-27 devnull /* time out all old entries (and set refs to 0) */
304 3e0d8fb3 2005-12-27 devnull for(i = 0; i < HTLEN; i++)
305 3e0d8fb3 2005-12-27 devnull for(dp = ht[i]; dp; dp = dp->next){
306 3e0d8fb3 2005-12-27 devnull dp->refs = 0;
307 3e0d8fb3 2005-12-27 devnull dnage(dp);
308 3e0d8fb3 2005-12-27 devnull }
309 3e0d8fb3 2005-12-27 devnull
310 3e0d8fb3 2005-12-27 devnull /* mark all referenced domain names */
311 3e0d8fb3 2005-12-27 devnull for(i = 0; i < HTLEN; i++)
312 3e0d8fb3 2005-12-27 devnull for(dp = ht[i]; dp; dp = dp->next)
313 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = rp->next){
314 3e0d8fb3 2005-12-27 devnull REF(rp->owner);
315 3e0d8fb3 2005-12-27 devnull if(rp->negative){
316 3e0d8fb3 2005-12-27 devnull REF(rp->negsoaowner);
317 3e0d8fb3 2005-12-27 devnull continue;
318 3e0d8fb3 2005-12-27 devnull }
319 3e0d8fb3 2005-12-27 devnull switch(rp->type){
320 3e0d8fb3 2005-12-27 devnull case Thinfo:
321 3e0d8fb3 2005-12-27 devnull REF(rp->cpu);
322 3e0d8fb3 2005-12-27 devnull REF(rp->os);
323 3e0d8fb3 2005-12-27 devnull break;
324 3e0d8fb3 2005-12-27 devnull case Ttxt:
325 3e0d8fb3 2005-12-27 devnull break;
326 3e0d8fb3 2005-12-27 devnull case Tcname:
327 3e0d8fb3 2005-12-27 devnull case Tmb:
328 3e0d8fb3 2005-12-27 devnull case Tmd:
329 3e0d8fb3 2005-12-27 devnull case Tmf:
330 3e0d8fb3 2005-12-27 devnull case Tns:
331 3e0d8fb3 2005-12-27 devnull REF(rp->host);
332 3e0d8fb3 2005-12-27 devnull break;
333 3e0d8fb3 2005-12-27 devnull case Tmg:
334 3e0d8fb3 2005-12-27 devnull case Tmr:
335 3e0d8fb3 2005-12-27 devnull REF(rp->mb);
336 3e0d8fb3 2005-12-27 devnull break;
337 3e0d8fb3 2005-12-27 devnull case Tminfo:
338 3e0d8fb3 2005-12-27 devnull REF(rp->rmb);
339 3e0d8fb3 2005-12-27 devnull REF(rp->mb);
340 3e0d8fb3 2005-12-27 devnull break;
341 3e0d8fb3 2005-12-27 devnull case Trp:
342 3e0d8fb3 2005-12-27 devnull REF(rp->rmb);
343 3e0d8fb3 2005-12-27 devnull REF(rp->rp);
344 3e0d8fb3 2005-12-27 devnull break;
345 3e0d8fb3 2005-12-27 devnull case Tmx:
346 3e0d8fb3 2005-12-27 devnull REF(rp->host);
347 3e0d8fb3 2005-12-27 devnull break;
348 3e0d8fb3 2005-12-27 devnull case Ta:
349 3e0d8fb3 2005-12-27 devnull case Taaaa:
350 3e0d8fb3 2005-12-27 devnull REF(rp->ip);
351 3e0d8fb3 2005-12-27 devnull break;
352 3e0d8fb3 2005-12-27 devnull case Tptr:
353 3e0d8fb3 2005-12-27 devnull REF(rp->ptr);
354 3e0d8fb3 2005-12-27 devnull break;
355 3e0d8fb3 2005-12-27 devnull case Tsoa:
356 3e0d8fb3 2005-12-27 devnull REF(rp->host);
357 3e0d8fb3 2005-12-27 devnull REF(rp->rmb);
358 3e0d8fb3 2005-12-27 devnull break;
359 3e0d8fb3 2005-12-27 devnull }
360 3e0d8fb3 2005-12-27 devnull }
361 3e0d8fb3 2005-12-27 devnull
362 3e0d8fb3 2005-12-27 devnull /* sweep and remove unreferenced domain names */
363 3e0d8fb3 2005-12-27 devnull for(i = 0; i < HTLEN; i++){
364 3e0d8fb3 2005-12-27 devnull l = &ht[i];
365 3e0d8fb3 2005-12-27 devnull for(dp = *l; dp; dp = *l){
366 3e0d8fb3 2005-12-27 devnull if(dp->rr == 0 && dp->refs == 0){
367 3e0d8fb3 2005-12-27 devnull assert(dp->magic == DNmagic);
368 3e0d8fb3 2005-12-27 devnull *l = dp->next;
369 3e0d8fb3 2005-12-27 devnull if(dp->name)
370 3e0d8fb3 2005-12-27 devnull free(dp->name);
371 3e0d8fb3 2005-12-27 devnull dp->magic = ~dp->magic;
372 3e0d8fb3 2005-12-27 devnull dnvars.names--;
373 3e0d8fb3 2005-12-27 devnull free(dp);
374 3e0d8fb3 2005-12-27 devnull continue;
375 3e0d8fb3 2005-12-27 devnull }
376 3e0d8fb3 2005-12-27 devnull l = &dp->next;
377 3e0d8fb3 2005-12-27 devnull }
378 3e0d8fb3 2005-12-27 devnull }
379 3e0d8fb3 2005-12-27 devnull
380 3e0d8fb3 2005-12-27 devnull unlock(&dnlock);
381 3e0d8fb3 2005-12-27 devnull }
382 3e0d8fb3 2005-12-27 devnull
383 3e0d8fb3 2005-12-27 devnull /*
384 3e0d8fb3 2005-12-27 devnull * timeout all database records (used when rereading db)
385 3e0d8fb3 2005-12-27 devnull */
386 3e0d8fb3 2005-12-27 devnull void
387 3e0d8fb3 2005-12-27 devnull dnagedb(void)
388 3e0d8fb3 2005-12-27 devnull {
389 3e0d8fb3 2005-12-27 devnull DN *dp;
390 3e0d8fb3 2005-12-27 devnull int i;
391 3e0d8fb3 2005-12-27 devnull RR *rp;
392 3e0d8fb3 2005-12-27 devnull
393 3e0d8fb3 2005-12-27 devnull lock(&dnlock);
394 3e0d8fb3 2005-12-27 devnull
395 3e0d8fb3 2005-12-27 devnull /* time out all database entries */
396 3e0d8fb3 2005-12-27 devnull for(i = 0; i < HTLEN; i++)
397 3e0d8fb3 2005-12-27 devnull for(dp = ht[i]; dp; dp = dp->next)
398 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = rp->next)
399 3e0d8fb3 2005-12-27 devnull if(rp->db)
400 3e0d8fb3 2005-12-27 devnull rp->expire = 0;
401 3e0d8fb3 2005-12-27 devnull
402 3e0d8fb3 2005-12-27 devnull unlock(&dnlock);
403 3e0d8fb3 2005-12-27 devnull }
404 3e0d8fb3 2005-12-27 devnull
405 3e0d8fb3 2005-12-27 devnull /*
406 3e0d8fb3 2005-12-27 devnull * mark all local db records about my area as authoritative, time out any others
407 3e0d8fb3 2005-12-27 devnull */
408 3e0d8fb3 2005-12-27 devnull void
409 3e0d8fb3 2005-12-27 devnull dnauthdb(void)
410 3e0d8fb3 2005-12-27 devnull {
411 3e0d8fb3 2005-12-27 devnull DN *dp;
412 3e0d8fb3 2005-12-27 devnull int i;
413 3e0d8fb3 2005-12-27 devnull Area *area;
414 3e0d8fb3 2005-12-27 devnull RR *rp;
415 3e0d8fb3 2005-12-27 devnull
416 3e0d8fb3 2005-12-27 devnull lock(&dnlock);
417 3e0d8fb3 2005-12-27 devnull
418 3e0d8fb3 2005-12-27 devnull /* time out all database entries */
419 3e0d8fb3 2005-12-27 devnull for(i = 0; i < HTLEN; i++)
420 3e0d8fb3 2005-12-27 devnull for(dp = ht[i]; dp; dp = dp->next){
421 3e0d8fb3 2005-12-27 devnull area = inmyarea(dp->name);
422 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = rp->next)
423 3e0d8fb3 2005-12-27 devnull if(rp->db){
424 3e0d8fb3 2005-12-27 devnull if(area){
425 3e0d8fb3 2005-12-27 devnull if(rp->ttl < area->soarr->soa->minttl)
426 3e0d8fb3 2005-12-27 devnull rp->ttl = area->soarr->soa->minttl;
427 3e0d8fb3 2005-12-27 devnull rp->auth = 1;
428 3e0d8fb3 2005-12-27 devnull }
429 3e0d8fb3 2005-12-27 devnull if(rp->expire == 0){
430 3e0d8fb3 2005-12-27 devnull rp->db = 0;
431 3e0d8fb3 2005-12-27 devnull dp->referenced = now - Reserved - 1;
432 3e0d8fb3 2005-12-27 devnull }
433 3e0d8fb3 2005-12-27 devnull }
434 3e0d8fb3 2005-12-27 devnull }
435 3e0d8fb3 2005-12-27 devnull
436 3e0d8fb3 2005-12-27 devnull unlock(&dnlock);
437 3e0d8fb3 2005-12-27 devnull }
438 3e0d8fb3 2005-12-27 devnull
439 3e0d8fb3 2005-12-27 devnull /*
440 3e0d8fb3 2005-12-27 devnull * keep track of other processes to know if we can
441 3e0d8fb3 2005-12-27 devnull * garbage collect. block while garbage collecting.
442 3e0d8fb3 2005-12-27 devnull */
443 3e0d8fb3 2005-12-27 devnull int
444 3e0d8fb3 2005-12-27 devnull getactivity(Request *req)
445 3e0d8fb3 2005-12-27 devnull {
446 3e0d8fb3 2005-12-27 devnull int rv;
447 3e0d8fb3 2005-12-27 devnull
448 5c9f76b5 2006-02-14 devnull if(traceactivity) syslog(0, "dns", "get %d by %d.%d", dnvars.active, getpid(), threadid());
449 3e0d8fb3 2005-12-27 devnull lock(&dnvars.lk);
450 3e0d8fb3 2005-12-27 devnull while(dnvars.mutex){
451 3e0d8fb3 2005-12-27 devnull unlock(&dnvars.lk);
452 3e0d8fb3 2005-12-27 devnull sleep(200);
453 3e0d8fb3 2005-12-27 devnull lock(&dnvars.lk);
454 3e0d8fb3 2005-12-27 devnull }
455 3e0d8fb3 2005-12-27 devnull rv = ++dnvars.active;
456 3e0d8fb3 2005-12-27 devnull now = time(0);
457 3e0d8fb3 2005-12-27 devnull req->id = ++dnvars.id;
458 3e0d8fb3 2005-12-27 devnull unlock(&dnvars.lk);
459 3e0d8fb3 2005-12-27 devnull
460 3e0d8fb3 2005-12-27 devnull return rv;
461 3e0d8fb3 2005-12-27 devnull }
462 3e0d8fb3 2005-12-27 devnull void
463 3e0d8fb3 2005-12-27 devnull putactivity(void)
464 3e0d8fb3 2005-12-27 devnull {
465 3e0d8fb3 2005-12-27 devnull static ulong lastclean;
466 3e0d8fb3 2005-12-27 devnull
467 5c9f76b5 2006-02-14 devnull if(traceactivity) syslog(0, "dns", "put %d by %d.%d", dnvars.active, getpid(), threadid());
468 3e0d8fb3 2005-12-27 devnull lock(&dnvars.lk);
469 3e0d8fb3 2005-12-27 devnull dnvars.active--;
470 3e0d8fb3 2005-12-27 devnull assert(dnvars.active >= 0); /* "dnvars.active %d", dnvars.active */;
471 3e0d8fb3 2005-12-27 devnull
472 3e0d8fb3 2005-12-27 devnull /*
473 3e0d8fb3 2005-12-27 devnull * clean out old entries and check for new db periodicly
474 3e0d8fb3 2005-12-27 devnull */
475 3e0d8fb3 2005-12-27 devnull if(dnvars.mutex || (needrefresh == 0 && dnvars.active > 0)){
476 3e0d8fb3 2005-12-27 devnull unlock(&dnvars.lk);
477 3e0d8fb3 2005-12-27 devnull return;
478 3e0d8fb3 2005-12-27 devnull }
479 3e0d8fb3 2005-12-27 devnull
480 3e0d8fb3 2005-12-27 devnull /* wait till we're alone */
481 3e0d8fb3 2005-12-27 devnull dnvars.mutex = 1;
482 3e0d8fb3 2005-12-27 devnull while(dnvars.active > 0){
483 3e0d8fb3 2005-12-27 devnull unlock(&dnvars.lk);
484 3e0d8fb3 2005-12-27 devnull sleep(100);
485 3e0d8fb3 2005-12-27 devnull lock(&dnvars.lk);
486 3e0d8fb3 2005-12-27 devnull }
487 3e0d8fb3 2005-12-27 devnull unlock(&dnvars.lk);
488 3e0d8fb3 2005-12-27 devnull
489 3e0d8fb3 2005-12-27 devnull db2cache(needrefresh);
490 3e0d8fb3 2005-12-27 devnull dnageall(0);
491 3e0d8fb3 2005-12-27 devnull
492 3e0d8fb3 2005-12-27 devnull /* let others back in */
493 3e0d8fb3 2005-12-27 devnull lastclean = now;
494 3e0d8fb3 2005-12-27 devnull needrefresh = 0;
495 3e0d8fb3 2005-12-27 devnull dnvars.mutex = 0;
496 3e0d8fb3 2005-12-27 devnull }
497 3e0d8fb3 2005-12-27 devnull
498 3e0d8fb3 2005-12-27 devnull /*
499 3e0d8fb3 2005-12-27 devnull * Attach a single resource record to a domain name.
500 3e0d8fb3 2005-12-27 devnull * - Avoid duplicates with already present RR's
501 3e0d8fb3 2005-12-27 devnull * - Chain all RR's of the same type adjacent to one another
502 3e0d8fb3 2005-12-27 devnull * - chain authoritative RR's ahead of non-authoritative ones
503 3e0d8fb3 2005-12-27 devnull */
504 3e0d8fb3 2005-12-27 devnull static void
505 3e0d8fb3 2005-12-27 devnull rrattach1(RR *new, int auth)
506 3e0d8fb3 2005-12-27 devnull {
507 3e0d8fb3 2005-12-27 devnull RR **l;
508 3e0d8fb3 2005-12-27 devnull RR *rp;
509 3e0d8fb3 2005-12-27 devnull DN *dp;
510 3e0d8fb3 2005-12-27 devnull
511 3e0d8fb3 2005-12-27 devnull assert(new->magic == RRmagic && !new->cached);
512 3e0d8fb3 2005-12-27 devnull
513 3e0d8fb3 2005-12-27 devnull if(!new->db)
514 3e0d8fb3 2005-12-27 devnull new->expire = new->ttl;
515 3e0d8fb3 2005-12-27 devnull else
516 3e0d8fb3 2005-12-27 devnull new->expire = now + Year;
517 3e0d8fb3 2005-12-27 devnull dp = new->owner;
518 3e0d8fb3 2005-12-27 devnull assert(dp->magic == DNmagic);
519 3e0d8fb3 2005-12-27 devnull new->auth |= auth;
520 3e0d8fb3 2005-12-27 devnull new->next = 0;
521 3e0d8fb3 2005-12-27 devnull
522 3e0d8fb3 2005-12-27 devnull /*
523 3e0d8fb3 2005-12-27 devnull * find first rr of the right type
524 3e0d8fb3 2005-12-27 devnull */
525 3e0d8fb3 2005-12-27 devnull l = &dp->rr;
526 3e0d8fb3 2005-12-27 devnull for(rp = *l; rp; rp = *l){
527 3e0d8fb3 2005-12-27 devnull assert(rp->magic == RRmagic && rp->cached);
528 3e0d8fb3 2005-12-27 devnull if(rp->type == new->type)
529 3e0d8fb3 2005-12-27 devnull break;
530 3e0d8fb3 2005-12-27 devnull l = &rp->next;
531 3e0d8fb3 2005-12-27 devnull }
532 3e0d8fb3 2005-12-27 devnull
533 3e0d8fb3 2005-12-27 devnull /*
534 3e0d8fb3 2005-12-27 devnull * negative entries replace positive entries
535 3e0d8fb3 2005-12-27 devnull * positive entries replace negative entries
536 3e0d8fb3 2005-12-27 devnull * newer entries replace older entries with the same fields
537 3e0d8fb3 2005-12-27 devnull */
538 3e0d8fb3 2005-12-27 devnull for(rp = *l; rp; rp = *l){
539 3e0d8fb3 2005-12-27 devnull assert(rp->magic == RRmagic && rp->cached);
540 3e0d8fb3 2005-12-27 devnull if(rp->type != new->type)
541 3e0d8fb3 2005-12-27 devnull break;
542 3e0d8fb3 2005-12-27 devnull
543 3e0d8fb3 2005-12-27 devnull if(rp->db == new->db && rp->auth == new->auth){
544 3e0d8fb3 2005-12-27 devnull /* negative drives out positive and vice versa */
545 3e0d8fb3 2005-12-27 devnull if(rp->negative != new->negative){
546 3e0d8fb3 2005-12-27 devnull *l = rp->next;
547 3e0d8fb3 2005-12-27 devnull rp->cached = 0;
548 3e0d8fb3 2005-12-27 devnull rrfree(rp);
549 3e0d8fb3 2005-12-27 devnull continue;
550 3e0d8fb3 2005-12-27 devnull }
551 3e0d8fb3 2005-12-27 devnull
552 3e0d8fb3 2005-12-27 devnull /* all things equal, pick the newer one */
553 3e0d8fb3 2005-12-27 devnull if(rp->arg0 == new->arg0 && rp->arg1 == new->arg1){
554 3e0d8fb3 2005-12-27 devnull /* new drives out old */
555 3e0d8fb3 2005-12-27 devnull if(new->ttl > rp->ttl || new->expire > rp->expire){
556 3e0d8fb3 2005-12-27 devnull *l = rp->next;
557 3e0d8fb3 2005-12-27 devnull rp->cached = 0;
558 3e0d8fb3 2005-12-27 devnull rrfree(rp);
559 3e0d8fb3 2005-12-27 devnull continue;
560 3e0d8fb3 2005-12-27 devnull } else {
561 3e0d8fb3 2005-12-27 devnull rrfree(new);
562 3e0d8fb3 2005-12-27 devnull return;
563 3e0d8fb3 2005-12-27 devnull }
564 3e0d8fb3 2005-12-27 devnull }
565 3e0d8fb3 2005-12-27 devnull
566 3e0d8fb3 2005-12-27 devnull /* Hack for pointer records. This makes sure
567 3e0d8fb3 2005-12-27 devnull * the ordering in the list reflects the ordering
568 3e0d8fb3 2005-12-27 devnull * received or read from the database
569 3e0d8fb3 2005-12-27 devnull */
570 3e0d8fb3 2005-12-27 devnull if(rp->type == Tptr){
571 3e0d8fb3 2005-12-27 devnull if(!rp->negative && !new->negative
572 3e0d8fb3 2005-12-27 devnull && rp->ptr->ordinal > new->ptr->ordinal)
573 3e0d8fb3 2005-12-27 devnull break;
574 3e0d8fb3 2005-12-27 devnull }
575 3e0d8fb3 2005-12-27 devnull }
576 3e0d8fb3 2005-12-27 devnull l = &rp->next;
577 3e0d8fb3 2005-12-27 devnull }
578 3e0d8fb3 2005-12-27 devnull
579 3e0d8fb3 2005-12-27 devnull /*
580 3e0d8fb3 2005-12-27 devnull * add to chain
581 3e0d8fb3 2005-12-27 devnull */
582 3e0d8fb3 2005-12-27 devnull new->cached = 1;
583 3e0d8fb3 2005-12-27 devnull new->next = *l;
584 3e0d8fb3 2005-12-27 devnull *l = new;
585 3e0d8fb3 2005-12-27 devnull }
586 3e0d8fb3 2005-12-27 devnull
587 3e0d8fb3 2005-12-27 devnull /*
588 3e0d8fb3 2005-12-27 devnull * Attach a list of resource records to a domain name.
589 3e0d8fb3 2005-12-27 devnull * - Avoid duplicates with already present RR's
590 3e0d8fb3 2005-12-27 devnull * - Chain all RR's of the same type adjacent to one another
591 3e0d8fb3 2005-12-27 devnull * - chain authoritative RR's ahead of non-authoritative ones
592 3e0d8fb3 2005-12-27 devnull * - remove any expired RR's
593 3e0d8fb3 2005-12-27 devnull */
594 3e0d8fb3 2005-12-27 devnull void
595 3e0d8fb3 2005-12-27 devnull rrattach(RR *rp, int auth)
596 3e0d8fb3 2005-12-27 devnull {
597 3e0d8fb3 2005-12-27 devnull RR *next;
598 3e0d8fb3 2005-12-27 devnull
599 3e0d8fb3 2005-12-27 devnull lock(&dnlock);
600 3e0d8fb3 2005-12-27 devnull for(; rp; rp = next){
601 3e0d8fb3 2005-12-27 devnull next = rp->next;
602 3e0d8fb3 2005-12-27 devnull rp->next = 0;
603 3e0d8fb3 2005-12-27 devnull
604 3e0d8fb3 2005-12-27 devnull /* avoid any outside spoofing */
605 3e0d8fb3 2005-12-27 devnull if(cachedb && !rp->db && inmyarea(rp->owner->name))
606 3e0d8fb3 2005-12-27 devnull rrfree(rp);
607 3e0d8fb3 2005-12-27 devnull else
608 3e0d8fb3 2005-12-27 devnull rrattach1(rp, auth);
609 3e0d8fb3 2005-12-27 devnull }
610 3e0d8fb3 2005-12-27 devnull unlock(&dnlock);
611 3e0d8fb3 2005-12-27 devnull }
612 3e0d8fb3 2005-12-27 devnull
613 3e0d8fb3 2005-12-27 devnull /*
614 3e0d8fb3 2005-12-27 devnull * allocate a resource record of a given type
615 3e0d8fb3 2005-12-27 devnull */
616 3e0d8fb3 2005-12-27 devnull RR*
617 3e0d8fb3 2005-12-27 devnull rralloc(int type)
618 3e0d8fb3 2005-12-27 devnull {
619 3e0d8fb3 2005-12-27 devnull RR *rp;
620 3e0d8fb3 2005-12-27 devnull
621 3e0d8fb3 2005-12-27 devnull rp = emalloc(sizeof(*rp));
622 3e0d8fb3 2005-12-27 devnull rp->magic = RRmagic;
623 3e0d8fb3 2005-12-27 devnull rp->pc = getcallerpc(&type);
624 3e0d8fb3 2005-12-27 devnull rp->type = type;
625 3e0d8fb3 2005-12-27 devnull switch(type){
626 3e0d8fb3 2005-12-27 devnull case Tsoa:
627 3e0d8fb3 2005-12-27 devnull rp->soa = emalloc(sizeof(*rp->soa));
628 3e0d8fb3 2005-12-27 devnull rp->soa->slaves = nil;
629 3e0d8fb3 2005-12-27 devnull break;
630 3e0d8fb3 2005-12-27 devnull case Tkey:
631 3e0d8fb3 2005-12-27 devnull rp->key = emalloc(sizeof(*rp->key));
632 3e0d8fb3 2005-12-27 devnull break;
633 3e0d8fb3 2005-12-27 devnull case Tcert:
634 3e0d8fb3 2005-12-27 devnull rp->cert = emalloc(sizeof(*rp->cert));
635 3e0d8fb3 2005-12-27 devnull break;
636 3e0d8fb3 2005-12-27 devnull case Tsig:
637 3e0d8fb3 2005-12-27 devnull rp->sig = emalloc(sizeof(*rp->sig));
638 3e0d8fb3 2005-12-27 devnull break;
639 3e0d8fb3 2005-12-27 devnull case Tnull:
640 3e0d8fb3 2005-12-27 devnull rp->null = emalloc(sizeof(*rp->null));
641 3e0d8fb3 2005-12-27 devnull break;
642 3e0d8fb3 2005-12-27 devnull }
643 3e0d8fb3 2005-12-27 devnull rp->ttl = 0;
644 3e0d8fb3 2005-12-27 devnull rp->expire = 0;
645 3e0d8fb3 2005-12-27 devnull rp->next = 0;
646 3e0d8fb3 2005-12-27 devnull return rp;
647 3e0d8fb3 2005-12-27 devnull }
648 3e0d8fb3 2005-12-27 devnull
649 3e0d8fb3 2005-12-27 devnull /*
650 3e0d8fb3 2005-12-27 devnull * free a resource record and any related structs
651 3e0d8fb3 2005-12-27 devnull */
652 3e0d8fb3 2005-12-27 devnull void
653 3e0d8fb3 2005-12-27 devnull rrfree(RR *rp)
654 3e0d8fb3 2005-12-27 devnull {
655 3e0d8fb3 2005-12-27 devnull DN *dp;
656 3e0d8fb3 2005-12-27 devnull RR *nrp;
657 3e0d8fb3 2005-12-27 devnull Txt *t;
658 3e0d8fb3 2005-12-27 devnull
659 3e0d8fb3 2005-12-27 devnull assert(rp->magic = RRmagic);
660 3e0d8fb3 2005-12-27 devnull assert(!rp->cached);
661 3e0d8fb3 2005-12-27 devnull
662 3e0d8fb3 2005-12-27 devnull dp = rp->owner;
663 3e0d8fb3 2005-12-27 devnull if(dp){
664 3e0d8fb3 2005-12-27 devnull assert(dp->magic == DNmagic);
665 3e0d8fb3 2005-12-27 devnull for(nrp = dp->rr; nrp; nrp = nrp->next)
666 3e0d8fb3 2005-12-27 devnull assert(nrp != rp); /* "rrfree of live rr" */;
667 3e0d8fb3 2005-12-27 devnull }
668 3e0d8fb3 2005-12-27 devnull
669 3e0d8fb3 2005-12-27 devnull switch(rp->type){
670 3e0d8fb3 2005-12-27 devnull case Tsoa:
671 3e0d8fb3 2005-12-27 devnull freeserverlist(rp->soa->slaves);
672 3e0d8fb3 2005-12-27 devnull free(rp->soa);
673 3e0d8fb3 2005-12-27 devnull break;
674 3e0d8fb3 2005-12-27 devnull case Tkey:
675 3e0d8fb3 2005-12-27 devnull free(rp->key->data);
676 3e0d8fb3 2005-12-27 devnull free(rp->key);
677 3e0d8fb3 2005-12-27 devnull break;
678 3e0d8fb3 2005-12-27 devnull case Tcert:
679 3e0d8fb3 2005-12-27 devnull free(rp->cert->data);
680 3e0d8fb3 2005-12-27 devnull free(rp->cert);
681 3e0d8fb3 2005-12-27 devnull break;
682 3e0d8fb3 2005-12-27 devnull case Tsig:
683 3e0d8fb3 2005-12-27 devnull free(rp->sig->data);
684 3e0d8fb3 2005-12-27 devnull free(rp->sig);
685 3e0d8fb3 2005-12-27 devnull break;
686 3e0d8fb3 2005-12-27 devnull case Tnull:
687 3e0d8fb3 2005-12-27 devnull free(rp->null->data);
688 3e0d8fb3 2005-12-27 devnull free(rp->null);
689 3e0d8fb3 2005-12-27 devnull break;
690 3e0d8fb3 2005-12-27 devnull case Ttxt:
691 3e0d8fb3 2005-12-27 devnull while(rp->txt != nil){
692 3e0d8fb3 2005-12-27 devnull t = rp->txt;
693 3e0d8fb3 2005-12-27 devnull rp->txt = t->next;
694 3e0d8fb3 2005-12-27 devnull free(t->p);
695 3e0d8fb3 2005-12-27 devnull free(t);
696 3e0d8fb3 2005-12-27 devnull }
697 3e0d8fb3 2005-12-27 devnull break;
698 3e0d8fb3 2005-12-27 devnull }
699 3e0d8fb3 2005-12-27 devnull
700 3e0d8fb3 2005-12-27 devnull rp->magic = ~rp->magic;
701 3e0d8fb3 2005-12-27 devnull free(rp);
702 3e0d8fb3 2005-12-27 devnull }
703 3e0d8fb3 2005-12-27 devnull
704 3e0d8fb3 2005-12-27 devnull /*
705 3e0d8fb3 2005-12-27 devnull * free a list of resource records and any related structs
706 3e0d8fb3 2005-12-27 devnull */
707 3e0d8fb3 2005-12-27 devnull void
708 3e0d8fb3 2005-12-27 devnull rrfreelist(RR *rp)
709 3e0d8fb3 2005-12-27 devnull {
710 3e0d8fb3 2005-12-27 devnull RR *next;
711 3e0d8fb3 2005-12-27 devnull
712 3e0d8fb3 2005-12-27 devnull for(; rp; rp = next){
713 3e0d8fb3 2005-12-27 devnull next = rp->next;
714 3e0d8fb3 2005-12-27 devnull rrfree(rp);
715 3e0d8fb3 2005-12-27 devnull }
716 3e0d8fb3 2005-12-27 devnull }
717 3e0d8fb3 2005-12-27 devnull
718 3e0d8fb3 2005-12-27 devnull extern RR**
719 3e0d8fb3 2005-12-27 devnull rrcopy(RR *rp, RR **last)
720 3e0d8fb3 2005-12-27 devnull {
721 3e0d8fb3 2005-12-27 devnull RR *nrp;
722 3e0d8fb3 2005-12-27 devnull SOA *soa;
723 3e0d8fb3 2005-12-27 devnull Key *key;
724 3e0d8fb3 2005-12-27 devnull Cert *cert;
725 3e0d8fb3 2005-12-27 devnull Sig *sig;
726 3e0d8fb3 2005-12-27 devnull Null *null;
727 3e0d8fb3 2005-12-27 devnull Txt *t, *nt, **l;
728 3e0d8fb3 2005-12-27 devnull
729 3e0d8fb3 2005-12-27 devnull nrp = rralloc(rp->type);
730 3e0d8fb3 2005-12-27 devnull switch(rp->type){
731 3e0d8fb3 2005-12-27 devnull case Ttxt:
732 3e0d8fb3 2005-12-27 devnull *nrp = *rp;
733 3e0d8fb3 2005-12-27 devnull l = &nrp->txt;
734 3e0d8fb3 2005-12-27 devnull *l = nil;
735 3e0d8fb3 2005-12-27 devnull for(t = rp->txt; t != nil; t = t->next){
736 3e0d8fb3 2005-12-27 devnull nt = emalloc(sizeof(*nt));
737 3e0d8fb3 2005-12-27 devnull nt->p = estrdup(t->p);
738 3e0d8fb3 2005-12-27 devnull nt->next = nil;
739 3e0d8fb3 2005-12-27 devnull *l = nt;
740 3e0d8fb3 2005-12-27 devnull l = &nt->next;
741 3e0d8fb3 2005-12-27 devnull }
742 3e0d8fb3 2005-12-27 devnull break;
743 3e0d8fb3 2005-12-27 devnull case Tsoa:
744 3e0d8fb3 2005-12-27 devnull soa = nrp->soa;
745 3e0d8fb3 2005-12-27 devnull *nrp = *rp;
746 3e0d8fb3 2005-12-27 devnull nrp->soa = soa;
747 3e0d8fb3 2005-12-27 devnull *nrp->soa = *rp->soa;
748 3e0d8fb3 2005-12-27 devnull nrp->soa->slaves = copyserverlist(rp->soa->slaves);
749 3e0d8fb3 2005-12-27 devnull break;
750 3e0d8fb3 2005-12-27 devnull case Tkey:
751 3e0d8fb3 2005-12-27 devnull key = nrp->key;
752 3e0d8fb3 2005-12-27 devnull *nrp = *rp;
753 3e0d8fb3 2005-12-27 devnull nrp->key = key;
754 3e0d8fb3 2005-12-27 devnull *key = *rp->key;
755 3e0d8fb3 2005-12-27 devnull key->data = emalloc(key->dlen);
756 3e0d8fb3 2005-12-27 devnull memmove(key->data, rp->key->data, rp->key->dlen);
757 3e0d8fb3 2005-12-27 devnull break;
758 3e0d8fb3 2005-12-27 devnull case Tsig:
759 3e0d8fb3 2005-12-27 devnull sig = nrp->sig;
760 3e0d8fb3 2005-12-27 devnull *nrp = *rp;
761 3e0d8fb3 2005-12-27 devnull nrp->sig = sig;
762 3e0d8fb3 2005-12-27 devnull *sig = *rp->sig;
763 3e0d8fb3 2005-12-27 devnull sig->data = emalloc(sig->dlen);
764 3e0d8fb3 2005-12-27 devnull memmove(sig->data, rp->sig->data, rp->sig->dlen);
765 3e0d8fb3 2005-12-27 devnull break;
766 3e0d8fb3 2005-12-27 devnull case Tcert:
767 3e0d8fb3 2005-12-27 devnull cert = nrp->cert;
768 3e0d8fb3 2005-12-27 devnull *nrp = *rp;
769 3e0d8fb3 2005-12-27 devnull nrp->cert = cert;
770 3e0d8fb3 2005-12-27 devnull *cert = *rp->cert;
771 3e0d8fb3 2005-12-27 devnull cert->data = emalloc(cert->dlen);
772 3e0d8fb3 2005-12-27 devnull memmove(cert->data, rp->cert->data, rp->cert->dlen);
773 3e0d8fb3 2005-12-27 devnull break;
774 3e0d8fb3 2005-12-27 devnull case Tnull:
775 3e0d8fb3 2005-12-27 devnull null = nrp->null;
776 3e0d8fb3 2005-12-27 devnull *nrp = *rp;
777 3e0d8fb3 2005-12-27 devnull nrp->null = null;
778 3e0d8fb3 2005-12-27 devnull *null = *rp->null;
779 3e0d8fb3 2005-12-27 devnull null->data = emalloc(null->dlen);
780 3e0d8fb3 2005-12-27 devnull memmove(null->data, rp->null->data, rp->null->dlen);
781 3e0d8fb3 2005-12-27 devnull break;
782 3e0d8fb3 2005-12-27 devnull default:
783 3e0d8fb3 2005-12-27 devnull *nrp = *rp;
784 3e0d8fb3 2005-12-27 devnull break;
785 3e0d8fb3 2005-12-27 devnull }
786 3e0d8fb3 2005-12-27 devnull nrp->cached = 0;
787 3e0d8fb3 2005-12-27 devnull nrp->next = 0;
788 3e0d8fb3 2005-12-27 devnull *last = nrp;
789 3e0d8fb3 2005-12-27 devnull return &nrp->next;
790 3e0d8fb3 2005-12-27 devnull }
791 3e0d8fb3 2005-12-27 devnull
792 3e0d8fb3 2005-12-27 devnull /*
793 3e0d8fb3 2005-12-27 devnull * lookup a resource record of a particular type and
794 3e0d8fb3 2005-12-27 devnull * class attached to a domain name. Return copies.
795 3e0d8fb3 2005-12-27 devnull *
796 3e0d8fb3 2005-12-27 devnull * Priority ordering is:
797 3e0d8fb3 2005-12-27 devnull * db authoritative
798 3e0d8fb3 2005-12-27 devnull * not timed out network authoritative
799 3e0d8fb3 2005-12-27 devnull * not timed out network unauthoritative
800 3e0d8fb3 2005-12-27 devnull * unauthoritative db
801 3e0d8fb3 2005-12-27 devnull *
802 3e0d8fb3 2005-12-27 devnull * if flag NOneg is set, don't return negative cached entries.
803 3e0d8fb3 2005-12-27 devnull * return nothing instead.
804 3e0d8fb3 2005-12-27 devnull */
805 3e0d8fb3 2005-12-27 devnull RR*
806 3e0d8fb3 2005-12-27 devnull rrlookup(DN *dp, int type, int flag)
807 3e0d8fb3 2005-12-27 devnull {
808 3e0d8fb3 2005-12-27 devnull RR *rp, *first, **last;
809 3e0d8fb3 2005-12-27 devnull
810 3e0d8fb3 2005-12-27 devnull assert(dp->magic == DNmagic);
811 3e0d8fb3 2005-12-27 devnull
812 3e0d8fb3 2005-12-27 devnull first = 0;
813 3e0d8fb3 2005-12-27 devnull last = &first;
814 3e0d8fb3 2005-12-27 devnull lock(&dnlock);
815 3e0d8fb3 2005-12-27 devnull
816 3e0d8fb3 2005-12-27 devnull /* try for an authoritative db entry */
817 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = rp->next){
818 3e0d8fb3 2005-12-27 devnull assert(rp->magic == RRmagic && rp->cached);
819 3e0d8fb3 2005-12-27 devnull if(rp->db)
820 3e0d8fb3 2005-12-27 devnull if(rp->auth)
821 3e0d8fb3 2005-12-27 devnull if(tsame(type, rp->type))
822 3e0d8fb3 2005-12-27 devnull last = rrcopy(rp, last);
823 3e0d8fb3 2005-12-27 devnull }
824 3e0d8fb3 2005-12-27 devnull if(first)
825 3e0d8fb3 2005-12-27 devnull goto out;
826 3e0d8fb3 2005-12-27 devnull
827 3e0d8fb3 2005-12-27 devnull /* try for an living authoritative network entry */
828 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = rp->next){
829 3e0d8fb3 2005-12-27 devnull if(!rp->db)
830 3e0d8fb3 2005-12-27 devnull if(rp->auth)
831 3e0d8fb3 2005-12-27 devnull if(rp->ttl + 60 > now)
832 3e0d8fb3 2005-12-27 devnull if(tsame(type, rp->type)){
833 3e0d8fb3 2005-12-27 devnull if(flag == NOneg && rp->negative)
834 3e0d8fb3 2005-12-27 devnull goto out;
835 3e0d8fb3 2005-12-27 devnull last = rrcopy(rp, last);
836 3e0d8fb3 2005-12-27 devnull }
837 3e0d8fb3 2005-12-27 devnull }
838 3e0d8fb3 2005-12-27 devnull if(first)
839 3e0d8fb3 2005-12-27 devnull goto out;
840 3e0d8fb3 2005-12-27 devnull
841 3e0d8fb3 2005-12-27 devnull /* try for an living unauthoritative network entry */
842 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = rp->next){
843 3e0d8fb3 2005-12-27 devnull if(!rp->db)
844 3e0d8fb3 2005-12-27 devnull if(rp->ttl + 60 > now)
845 3e0d8fb3 2005-12-27 devnull if(tsame(type, rp->type)){
846 3e0d8fb3 2005-12-27 devnull if(flag == NOneg && rp->negative)
847 3e0d8fb3 2005-12-27 devnull goto out;
848 3e0d8fb3 2005-12-27 devnull last = rrcopy(rp, last);
849 3e0d8fb3 2005-12-27 devnull }
850 3e0d8fb3 2005-12-27 devnull }
851 3e0d8fb3 2005-12-27 devnull if(first)
852 3e0d8fb3 2005-12-27 devnull goto out;
853 3e0d8fb3 2005-12-27 devnull
854 3e0d8fb3 2005-12-27 devnull /* try for an unauthoritative db entry */
855 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = rp->next){
856 3e0d8fb3 2005-12-27 devnull if(rp->db)
857 3e0d8fb3 2005-12-27 devnull if(tsame(type, rp->type))
858 3e0d8fb3 2005-12-27 devnull last = rrcopy(rp, last);
859 3e0d8fb3 2005-12-27 devnull }
860 3e0d8fb3 2005-12-27 devnull if(first)
861 3e0d8fb3 2005-12-27 devnull goto out;
862 3e0d8fb3 2005-12-27 devnull
863 3e0d8fb3 2005-12-27 devnull /* otherwise, settle for anything we got (except for negative caches) */
864 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = rp->next){
865 3e0d8fb3 2005-12-27 devnull if(tsame(type, rp->type)){
866 3e0d8fb3 2005-12-27 devnull if(rp->negative)
867 3e0d8fb3 2005-12-27 devnull goto out;
868 3e0d8fb3 2005-12-27 devnull last = rrcopy(rp, last);
869 3e0d8fb3 2005-12-27 devnull }
870 3e0d8fb3 2005-12-27 devnull }
871 3e0d8fb3 2005-12-27 devnull
872 3e0d8fb3 2005-12-27 devnull out:
873 3e0d8fb3 2005-12-27 devnull unlock(&dnlock);
874 3e0d8fb3 2005-12-27 devnull unique(first);
875 3e0d8fb3 2005-12-27 devnull return first;
876 3e0d8fb3 2005-12-27 devnull }
877 3e0d8fb3 2005-12-27 devnull
878 3e0d8fb3 2005-12-27 devnull /*
879 3e0d8fb3 2005-12-27 devnull * convert an ascii RR type name to its integer representation
880 3e0d8fb3 2005-12-27 devnull */
881 3e0d8fb3 2005-12-27 devnull int
882 3e0d8fb3 2005-12-27 devnull rrtype(char *atype)
883 3e0d8fb3 2005-12-27 devnull {
884 3e0d8fb3 2005-12-27 devnull int i;
885 3e0d8fb3 2005-12-27 devnull
886 3e0d8fb3 2005-12-27 devnull for(i = 0; i <= Tall; i++)
887 3e0d8fb3 2005-12-27 devnull if(rrtname[i] && strcmp(rrtname[i], atype) == 0)
888 3e0d8fb3 2005-12-27 devnull return i;
889 3e0d8fb3 2005-12-27 devnull
890 226d80b8 2006-04-01 devnull /* make any a synonym for all */
891 3e0d8fb3 2005-12-27 devnull if(strcmp(atype, "any") == 0)
892 3e0d8fb3 2005-12-27 devnull return Tall;
893 3e0d8fb3 2005-12-27 devnull return atoi(atype);
894 3e0d8fb3 2005-12-27 devnull }
895 3e0d8fb3 2005-12-27 devnull
896 3e0d8fb3 2005-12-27 devnull /*
897 3e0d8fb3 2005-12-27 devnull * convert an integer RR type to it's ascii name
898 3e0d8fb3 2005-12-27 devnull */
899 3e0d8fb3 2005-12-27 devnull char*
900 3e0d8fb3 2005-12-27 devnull rrname(int type, char *buf, int len)
901 3e0d8fb3 2005-12-27 devnull {
902 3e0d8fb3 2005-12-27 devnull char *t;
903 3e0d8fb3 2005-12-27 devnull
904 3e0d8fb3 2005-12-27 devnull t = 0;
905 3e0d8fb3 2005-12-27 devnull if(type <= Tall)
906 3e0d8fb3 2005-12-27 devnull t = rrtname[type];
907 3e0d8fb3 2005-12-27 devnull if(t==0){
908 3e0d8fb3 2005-12-27 devnull snprint(buf, len, "%d", type);
909 3e0d8fb3 2005-12-27 devnull t = buf;
910 3e0d8fb3 2005-12-27 devnull }
911 3e0d8fb3 2005-12-27 devnull return t;
912 3e0d8fb3 2005-12-27 devnull }
913 3e0d8fb3 2005-12-27 devnull
914 3e0d8fb3 2005-12-27 devnull /*
915 3e0d8fb3 2005-12-27 devnull * return 0 if not a supported rr type
916 3e0d8fb3 2005-12-27 devnull */
917 3e0d8fb3 2005-12-27 devnull int
918 3e0d8fb3 2005-12-27 devnull rrsupported(int type)
919 3e0d8fb3 2005-12-27 devnull {
920 3e0d8fb3 2005-12-27 devnull if(type < 0 || type >Tall)
921 3e0d8fb3 2005-12-27 devnull return 0;
922 3e0d8fb3 2005-12-27 devnull return rrtname[type] != 0;
923 3e0d8fb3 2005-12-27 devnull }
924 3e0d8fb3 2005-12-27 devnull
925 3e0d8fb3 2005-12-27 devnull /*
926 3e0d8fb3 2005-12-27 devnull * compare 2 types
927 3e0d8fb3 2005-12-27 devnull */
928 3e0d8fb3 2005-12-27 devnull int
929 3e0d8fb3 2005-12-27 devnull tsame(int t1, int t2)
930 3e0d8fb3 2005-12-27 devnull {
931 3e0d8fb3 2005-12-27 devnull return t1 == t2 || t1 == Tall;
932 3e0d8fb3 2005-12-27 devnull }
933 3e0d8fb3 2005-12-27 devnull
934 3e0d8fb3 2005-12-27 devnull /*
935 3e0d8fb3 2005-12-27 devnull * Add resource records to a list, duplicate them if they are cached
936 3e0d8fb3 2005-12-27 devnull * RR's since these are shared.
937 3e0d8fb3 2005-12-27 devnull */
938 3e0d8fb3 2005-12-27 devnull RR*
939 3e0d8fb3 2005-12-27 devnull rrcat(RR **start, RR *rp)
940 3e0d8fb3 2005-12-27 devnull {
941 3e0d8fb3 2005-12-27 devnull RR **last;
942 3e0d8fb3 2005-12-27 devnull
943 3e0d8fb3 2005-12-27 devnull last = start;
944 3e0d8fb3 2005-12-27 devnull while(*last != 0)
945 3e0d8fb3 2005-12-27 devnull last = &(*last)->next;
946 3e0d8fb3 2005-12-27 devnull
947 3e0d8fb3 2005-12-27 devnull *last = rp;
948 3e0d8fb3 2005-12-27 devnull return *start;
949 3e0d8fb3 2005-12-27 devnull }
950 3e0d8fb3 2005-12-27 devnull
951 3e0d8fb3 2005-12-27 devnull /*
952 3e0d8fb3 2005-12-27 devnull * remove negative cache rr's from an rr list
953 3e0d8fb3 2005-12-27 devnull */
954 3e0d8fb3 2005-12-27 devnull RR*
955 3e0d8fb3 2005-12-27 devnull rrremneg(RR **l)
956 3e0d8fb3 2005-12-27 devnull {
957 3e0d8fb3 2005-12-27 devnull RR **nl, *rp;
958 3e0d8fb3 2005-12-27 devnull RR *first;
959 3e0d8fb3 2005-12-27 devnull
960 3e0d8fb3 2005-12-27 devnull first = nil;
961 3e0d8fb3 2005-12-27 devnull nl = &first;
962 3e0d8fb3 2005-12-27 devnull while(*l != nil){
963 3e0d8fb3 2005-12-27 devnull rp = *l;
964 3e0d8fb3 2005-12-27 devnull if(rp->negative){
965 3e0d8fb3 2005-12-27 devnull *l = rp->next;
966 3e0d8fb3 2005-12-27 devnull *nl = rp;
967 3e0d8fb3 2005-12-27 devnull nl = &rp->next;
968 3e0d8fb3 2005-12-27 devnull *nl = nil;
969 3e0d8fb3 2005-12-27 devnull } else
970 3e0d8fb3 2005-12-27 devnull l = &rp->next;
971 3e0d8fb3 2005-12-27 devnull }
972 3e0d8fb3 2005-12-27 devnull
973 3e0d8fb3 2005-12-27 devnull return first;
974 3e0d8fb3 2005-12-27 devnull }
975 3e0d8fb3 2005-12-27 devnull
976 3e0d8fb3 2005-12-27 devnull /*
977 3e0d8fb3 2005-12-27 devnull * remove rr's of a particular type from an rr list
978 3e0d8fb3 2005-12-27 devnull */
979 3e0d8fb3 2005-12-27 devnull RR*
980 3e0d8fb3 2005-12-27 devnull rrremtype(RR **l, int type)
981 3e0d8fb3 2005-12-27 devnull {
982 3e0d8fb3 2005-12-27 devnull RR **nl, *rp;
983 3e0d8fb3 2005-12-27 devnull RR *first;
984 3e0d8fb3 2005-12-27 devnull
985 3e0d8fb3 2005-12-27 devnull first = nil;
986 3e0d8fb3 2005-12-27 devnull nl = &first;
987 3e0d8fb3 2005-12-27 devnull while(*l != nil){
988 3e0d8fb3 2005-12-27 devnull rp = *l;
989 3e0d8fb3 2005-12-27 devnull if(rp->type == type){
990 3e0d8fb3 2005-12-27 devnull *l = rp->next;
991 3e0d8fb3 2005-12-27 devnull *nl = rp;
992 3e0d8fb3 2005-12-27 devnull nl = &rp->next;
993 3e0d8fb3 2005-12-27 devnull *nl = nil;
994 3e0d8fb3 2005-12-27 devnull } else
995 3e0d8fb3 2005-12-27 devnull l = &(*l)->next;
996 3e0d8fb3 2005-12-27 devnull }
997 3e0d8fb3 2005-12-27 devnull
998 3e0d8fb3 2005-12-27 devnull return first;
999 3e0d8fb3 2005-12-27 devnull }
1000 3e0d8fb3 2005-12-27 devnull
1001 3e0d8fb3 2005-12-27 devnull /*
1002 3e0d8fb3 2005-12-27 devnull * print conversion for rr records
1003 3e0d8fb3 2005-12-27 devnull */
1004 3e0d8fb3 2005-12-27 devnull int
1005 3e0d8fb3 2005-12-27 devnull rrfmt(Fmt *f)
1006 3e0d8fb3 2005-12-27 devnull {
1007 3e0d8fb3 2005-12-27 devnull RR *rp;
1008 3e0d8fb3 2005-12-27 devnull char *strp;
1009 3e0d8fb3 2005-12-27 devnull Fmt fstr;
1010 3e0d8fb3 2005-12-27 devnull int rv;
1011 3e0d8fb3 2005-12-27 devnull char buf[Domlen];
1012 3e0d8fb3 2005-12-27 devnull Server *s;
1013 3e0d8fb3 2005-12-27 devnull Txt *t;
1014 3e0d8fb3 2005-12-27 devnull
1015 3e0d8fb3 2005-12-27 devnull fmtstrinit(&fstr);
1016 3e0d8fb3 2005-12-27 devnull
1017 3e0d8fb3 2005-12-27 devnull rp = va_arg(f->args, RR*);
1018 3e0d8fb3 2005-12-27 devnull if(rp == 0){
1019 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "<null>");
1020 3e0d8fb3 2005-12-27 devnull goto out;
1021 3e0d8fb3 2005-12-27 devnull }
1022 3e0d8fb3 2005-12-27 devnull
1023 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "%s %s", rp->owner->name,
1024 3e0d8fb3 2005-12-27 devnull rrname(rp->type, buf, sizeof buf));
1025 3e0d8fb3 2005-12-27 devnull
1026 3e0d8fb3 2005-12-27 devnull if(rp->negative){
1027 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\tnegative - rcode %d", rp->negrcode);
1028 3e0d8fb3 2005-12-27 devnull goto out;
1029 3e0d8fb3 2005-12-27 devnull }
1030 3e0d8fb3 2005-12-27 devnull
1031 3e0d8fb3 2005-12-27 devnull switch(rp->type){
1032 3e0d8fb3 2005-12-27 devnull case Thinfo:
1033 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%s %s", rp->cpu->name, rp->os->name);
1034 3e0d8fb3 2005-12-27 devnull break;
1035 3e0d8fb3 2005-12-27 devnull case Tcname:
1036 3e0d8fb3 2005-12-27 devnull case Tmb:
1037 3e0d8fb3 2005-12-27 devnull case Tmd:
1038 3e0d8fb3 2005-12-27 devnull case Tmf:
1039 3e0d8fb3 2005-12-27 devnull case Tns:
1040 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%s", rp->host->name);
1041 3e0d8fb3 2005-12-27 devnull break;
1042 3e0d8fb3 2005-12-27 devnull case Tmg:
1043 3e0d8fb3 2005-12-27 devnull case Tmr:
1044 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%s", rp->mb->name);
1045 3e0d8fb3 2005-12-27 devnull break;
1046 3e0d8fb3 2005-12-27 devnull case Tminfo:
1047 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%s %s", rp->mb->name, rp->rmb->name);
1048 3e0d8fb3 2005-12-27 devnull break;
1049 3e0d8fb3 2005-12-27 devnull case Tmx:
1050 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%lud %s", rp->pref, rp->host->name);
1051 3e0d8fb3 2005-12-27 devnull break;
1052 3e0d8fb3 2005-12-27 devnull case Ta:
1053 3e0d8fb3 2005-12-27 devnull case Taaaa:
1054 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%s", rp->ip->name);
1055 3e0d8fb3 2005-12-27 devnull break;
1056 3e0d8fb3 2005-12-27 devnull case Tptr:
1057 226d80b8 2006-04-01 devnull /* fmtprint(&fstr, "\t%s(%lud)", rp->ptr->name, rp->ptr->ordinal); */
1058 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%s", rp->ptr->name);
1059 3e0d8fb3 2005-12-27 devnull break;
1060 3e0d8fb3 2005-12-27 devnull case Tsoa:
1061 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%s %s %lud %lud %lud %lud %lud", rp->host->name,
1062 3e0d8fb3 2005-12-27 devnull rp->rmb->name, rp->soa->serial, rp->soa->refresh, rp->soa->retry,
1063 3e0d8fb3 2005-12-27 devnull rp->soa->expire, rp->soa->minttl);
1064 3e0d8fb3 2005-12-27 devnull for(s = rp->soa->slaves; s != nil; s = s->next)
1065 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " %s", s->name);
1066 3e0d8fb3 2005-12-27 devnull break;
1067 3e0d8fb3 2005-12-27 devnull case Tnull:
1068 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%.*H", rp->null->dlen, rp->null->data);
1069 3e0d8fb3 2005-12-27 devnull break;
1070 3e0d8fb3 2005-12-27 devnull case Ttxt:
1071 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t");
1072 3e0d8fb3 2005-12-27 devnull for(t = rp->txt; t != nil; t = t->next)
1073 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "%s", t->p);
1074 3e0d8fb3 2005-12-27 devnull break;
1075 3e0d8fb3 2005-12-27 devnull case Trp:
1076 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%s %s", rp->rmb->name, rp->rp->name);
1077 3e0d8fb3 2005-12-27 devnull break;
1078 3e0d8fb3 2005-12-27 devnull case Tkey:
1079 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%d %d %d", rp->key->flags, rp->key->proto,
1080 3e0d8fb3 2005-12-27 devnull rp->key->alg);
1081 3e0d8fb3 2005-12-27 devnull break;
1082 3e0d8fb3 2005-12-27 devnull case Tsig:
1083 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%d %d %d %lud %lud %lud %d %s",
1084 3e0d8fb3 2005-12-27 devnull rp->sig->type, rp->sig->alg, rp->sig->labels, rp->sig->ttl,
1085 3e0d8fb3 2005-12-27 devnull rp->sig->exp, rp->sig->incep, rp->sig->tag, rp->sig->signer->name);
1086 3e0d8fb3 2005-12-27 devnull break;
1087 3e0d8fb3 2005-12-27 devnull case Tcert:
1088 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\t%d %d %d",
1089 3e0d8fb3 2005-12-27 devnull rp->sig->type, rp->sig->tag, rp->sig->alg);
1090 3e0d8fb3 2005-12-27 devnull break;
1091 3e0d8fb3 2005-12-27 devnull default:
1092 3e0d8fb3 2005-12-27 devnull break;
1093 3e0d8fb3 2005-12-27 devnull }
1094 3e0d8fb3 2005-12-27 devnull out:
1095 3e0d8fb3 2005-12-27 devnull strp = fmtstrflush(&fstr);
1096 3e0d8fb3 2005-12-27 devnull rv = fmtstrcpy(f, strp);
1097 3e0d8fb3 2005-12-27 devnull free(strp);
1098 3e0d8fb3 2005-12-27 devnull return rv;
1099 3e0d8fb3 2005-12-27 devnull }
1100 3e0d8fb3 2005-12-27 devnull
1101 3e0d8fb3 2005-12-27 devnull /*
1102 3e0d8fb3 2005-12-27 devnull * print conversion for rr records in attribute value form
1103 3e0d8fb3 2005-12-27 devnull */
1104 3e0d8fb3 2005-12-27 devnull int
1105 3e0d8fb3 2005-12-27 devnull rravfmt(Fmt *f)
1106 3e0d8fb3 2005-12-27 devnull {
1107 3e0d8fb3 2005-12-27 devnull RR *rp;
1108 3e0d8fb3 2005-12-27 devnull char *strp;
1109 3e0d8fb3 2005-12-27 devnull Fmt fstr;
1110 3e0d8fb3 2005-12-27 devnull int rv;
1111 3e0d8fb3 2005-12-27 devnull Server *s;
1112 3e0d8fb3 2005-12-27 devnull Txt *t;
1113 3e0d8fb3 2005-12-27 devnull int quote;
1114 3e0d8fb3 2005-12-27 devnull
1115 3e0d8fb3 2005-12-27 devnull fmtstrinit(&fstr);
1116 3e0d8fb3 2005-12-27 devnull
1117 3e0d8fb3 2005-12-27 devnull rp = va_arg(f->args, RR*);
1118 3e0d8fb3 2005-12-27 devnull if(rp == 0){
1119 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "<null>");
1120 3e0d8fb3 2005-12-27 devnull goto out;
1121 3e0d8fb3 2005-12-27 devnull }
1122 3e0d8fb3 2005-12-27 devnull
1123 3e0d8fb3 2005-12-27 devnull if(rp->type == Tptr)
1124 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "ptr=%s", rp->owner->name);
1125 3e0d8fb3 2005-12-27 devnull else
1126 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "dom=%s", rp->owner->name);
1127 3e0d8fb3 2005-12-27 devnull
1128 3e0d8fb3 2005-12-27 devnull switch(rp->type){
1129 3e0d8fb3 2005-12-27 devnull case Thinfo:
1130 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " cpu=%s os=%s", rp->cpu->name, rp->os->name);
1131 3e0d8fb3 2005-12-27 devnull break;
1132 3e0d8fb3 2005-12-27 devnull case Tcname:
1133 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " cname=%s", rp->host->name);
1134 3e0d8fb3 2005-12-27 devnull break;
1135 3e0d8fb3 2005-12-27 devnull case Tmb:
1136 3e0d8fb3 2005-12-27 devnull case Tmd:
1137 3e0d8fb3 2005-12-27 devnull case Tmf:
1138 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " mbox=%s", rp->host->name);
1139 3e0d8fb3 2005-12-27 devnull break;
1140 3e0d8fb3 2005-12-27 devnull case Tns:
1141 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " ns=%s", rp->host->name);
1142 3e0d8fb3 2005-12-27 devnull break;
1143 3e0d8fb3 2005-12-27 devnull case Tmg:
1144 3e0d8fb3 2005-12-27 devnull case Tmr:
1145 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " mbox=%s", rp->mb->name);
1146 3e0d8fb3 2005-12-27 devnull break;
1147 3e0d8fb3 2005-12-27 devnull case Tminfo:
1148 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " mbox=%s mbox=%s", rp->mb->name, rp->rmb->name);
1149 3e0d8fb3 2005-12-27 devnull break;
1150 3e0d8fb3 2005-12-27 devnull case Tmx:
1151 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " pref=%lud mx=%s", rp->pref, rp->host->name);
1152 3e0d8fb3 2005-12-27 devnull break;
1153 3e0d8fb3 2005-12-27 devnull case Ta:
1154 3e0d8fb3 2005-12-27 devnull case Taaaa:
1155 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " ip=%s", rp->ip->name);
1156 3e0d8fb3 2005-12-27 devnull break;
1157 3e0d8fb3 2005-12-27 devnull case Tptr:
1158 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " dom=%s", rp->ptr->name);
1159 3e0d8fb3 2005-12-27 devnull break;
1160 3e0d8fb3 2005-12-27 devnull case Tsoa:
1161 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " ns=%s mbox=%s serial=%lud refresh=%lud retry=%lud expire=%lud ttl=%lud",
1162 3e0d8fb3 2005-12-27 devnull rp->host->name, rp->rmb->name, rp->soa->serial,
1163 3e0d8fb3 2005-12-27 devnull rp->soa->refresh, rp->soa->retry,
1164 3e0d8fb3 2005-12-27 devnull rp->soa->expire, rp->soa->minttl);
1165 3e0d8fb3 2005-12-27 devnull for(s = rp->soa->slaves; s != nil; s = s->next)
1166 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " dnsslave=%s", s->name);
1167 3e0d8fb3 2005-12-27 devnull break;
1168 3e0d8fb3 2005-12-27 devnull case Tnull:
1169 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " null=%.*H", rp->null->dlen, rp->null->data);
1170 3e0d8fb3 2005-12-27 devnull break;
1171 3e0d8fb3 2005-12-27 devnull case Ttxt:
1172 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " txt=");
1173 3e0d8fb3 2005-12-27 devnull quote = 0;
1174 3e0d8fb3 2005-12-27 devnull for(t = rp->txt; t != nil; t = t->next)
1175 3e0d8fb3 2005-12-27 devnull if(strchr(t->p, ' '))
1176 3e0d8fb3 2005-12-27 devnull quote = 1;
1177 3e0d8fb3 2005-12-27 devnull if(quote)
1178 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\"");
1179 3e0d8fb3 2005-12-27 devnull for(t = rp->txt; t != nil; t = t->next)
1180 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "%s", t->p);
1181 3e0d8fb3 2005-12-27 devnull if(quote)
1182 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, "\"");
1183 3e0d8fb3 2005-12-27 devnull break;
1184 3e0d8fb3 2005-12-27 devnull case Trp:
1185 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " rp=%s txt=%s", rp->rmb->name, rp->rp->name);
1186 3e0d8fb3 2005-12-27 devnull break;
1187 3e0d8fb3 2005-12-27 devnull case Tkey:
1188 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " flags=%d proto=%d alg=%d",
1189 3e0d8fb3 2005-12-27 devnull rp->key->flags, rp->key->proto, rp->key->alg);
1190 3e0d8fb3 2005-12-27 devnull break;
1191 3e0d8fb3 2005-12-27 devnull case Tsig:
1192 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " type=%d alg=%d labels=%d ttl=%lud exp=%lud incep=%lud tag=%d signer=%s",
1193 3e0d8fb3 2005-12-27 devnull rp->sig->type, rp->sig->alg, rp->sig->labels, rp->sig->ttl,
1194 3e0d8fb3 2005-12-27 devnull rp->sig->exp, rp->sig->incep, rp->sig->tag, rp->sig->signer->name);
1195 3e0d8fb3 2005-12-27 devnull break;
1196 3e0d8fb3 2005-12-27 devnull case Tcert:
1197 3e0d8fb3 2005-12-27 devnull fmtprint(&fstr, " type=%d tag=%d alg=%d",
1198 3e0d8fb3 2005-12-27 devnull rp->sig->type, rp->sig->tag, rp->sig->alg);
1199 3e0d8fb3 2005-12-27 devnull break;
1200 3e0d8fb3 2005-12-27 devnull default:
1201 3e0d8fb3 2005-12-27 devnull break;
1202 3e0d8fb3 2005-12-27 devnull }
1203 3e0d8fb3 2005-12-27 devnull out:
1204 3e0d8fb3 2005-12-27 devnull strp = fmtstrflush(&fstr);
1205 3e0d8fb3 2005-12-27 devnull rv = fmtstrcpy(f, strp);
1206 3e0d8fb3 2005-12-27 devnull free(strp);
1207 3e0d8fb3 2005-12-27 devnull return rv;
1208 3e0d8fb3 2005-12-27 devnull }
1209 3e0d8fb3 2005-12-27 devnull
1210 3e0d8fb3 2005-12-27 devnull void
1211 3e0d8fb3 2005-12-27 devnull warning(char *fmt, ...)
1212 3e0d8fb3 2005-12-27 devnull {
1213 3e0d8fb3 2005-12-27 devnull char dnserr[128];
1214 3e0d8fb3 2005-12-27 devnull va_list arg;
1215 3e0d8fb3 2005-12-27 devnull
1216 3e0d8fb3 2005-12-27 devnull va_start(arg, fmt);
1217 3e0d8fb3 2005-12-27 devnull vseprint(dnserr, dnserr+sizeof(dnserr), fmt, arg);
1218 3e0d8fb3 2005-12-27 devnull va_end(arg);
1219 3e0d8fb3 2005-12-27 devnull syslog(1, "dns", dnserr);
1220 3e0d8fb3 2005-12-27 devnull }
1221 3e0d8fb3 2005-12-27 devnull
1222 3e0d8fb3 2005-12-27 devnull /*
1223 3e0d8fb3 2005-12-27 devnull * chasing down double free's
1224 3e0d8fb3 2005-12-27 devnull */
1225 3e0d8fb3 2005-12-27 devnull void
1226 3e0d8fb3 2005-12-27 devnull dncheck(void *p, int dolock)
1227 3e0d8fb3 2005-12-27 devnull {
1228 3e0d8fb3 2005-12-27 devnull DN *dp;
1229 49a1496c 2006-02-20 devnull int i;
1230 3e0d8fb3 2005-12-27 devnull RR *rp;
1231 3e0d8fb3 2005-12-27 devnull
1232 3e0d8fb3 2005-12-27 devnull if(p != nil){
1233 3e0d8fb3 2005-12-27 devnull dp = p;
1234 3e0d8fb3 2005-12-27 devnull assert(dp->magic == DNmagic);
1235 3e0d8fb3 2005-12-27 devnull }
1236 3e0d8fb3 2005-12-27 devnull
1237 3e0d8fb3 2005-12-27 devnull if(!testing)
1238 3e0d8fb3 2005-12-27 devnull return;
1239 3e0d8fb3 2005-12-27 devnull
1240 3e0d8fb3 2005-12-27 devnull if(dolock)
1241 3e0d8fb3 2005-12-27 devnull lock(&dnlock);
1242 3e0d8fb3 2005-12-27 devnull for(i = 0; i < HTLEN; i++)
1243 3e0d8fb3 2005-12-27 devnull for(dp = ht[i]; dp; dp = dp->next){
1244 3e0d8fb3 2005-12-27 devnull assert(dp != p);
1245 3e0d8fb3 2005-12-27 devnull assert(dp->magic == DNmagic);
1246 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = rp->next){
1247 3e0d8fb3 2005-12-27 devnull assert(rp->magic == RRmagic);
1248 3e0d8fb3 2005-12-27 devnull assert(rp->cached);
1249 3e0d8fb3 2005-12-27 devnull assert(rp->owner == dp);
1250 3e0d8fb3 2005-12-27 devnull }
1251 3e0d8fb3 2005-12-27 devnull }
1252 3e0d8fb3 2005-12-27 devnull if(dolock)
1253 3e0d8fb3 2005-12-27 devnull unlock(&dnlock);
1254 3e0d8fb3 2005-12-27 devnull }
1255 3e0d8fb3 2005-12-27 devnull
1256 3e0d8fb3 2005-12-27 devnull static int
1257 3e0d8fb3 2005-12-27 devnull rrequiv(RR *r1, RR *r2)
1258 3e0d8fb3 2005-12-27 devnull {
1259 3e0d8fb3 2005-12-27 devnull return r1->owner == r2->owner
1260 3e0d8fb3 2005-12-27 devnull && r1->type == r2->type
1261 3e0d8fb3 2005-12-27 devnull && r1->arg0 == r2->arg0
1262 3e0d8fb3 2005-12-27 devnull && r1->arg1 == r2->arg1;
1263 3e0d8fb3 2005-12-27 devnull }
1264 3e0d8fb3 2005-12-27 devnull
1265 3e0d8fb3 2005-12-27 devnull void
1266 3e0d8fb3 2005-12-27 devnull unique(RR *rp)
1267 3e0d8fb3 2005-12-27 devnull {
1268 3e0d8fb3 2005-12-27 devnull RR **l, *nrp;
1269 3e0d8fb3 2005-12-27 devnull
1270 3e0d8fb3 2005-12-27 devnull for(; rp; rp = rp->next){
1271 3e0d8fb3 2005-12-27 devnull l = &rp->next;
1272 3e0d8fb3 2005-12-27 devnull for(nrp = *l; nrp; nrp = *l){
1273 3e0d8fb3 2005-12-27 devnull if(rrequiv(rp, nrp)){
1274 3e0d8fb3 2005-12-27 devnull *l = nrp->next;
1275 3e0d8fb3 2005-12-27 devnull rrfree(nrp);
1276 3e0d8fb3 2005-12-27 devnull } else
1277 3e0d8fb3 2005-12-27 devnull l = &nrp->next;
1278 3e0d8fb3 2005-12-27 devnull }
1279 3e0d8fb3 2005-12-27 devnull }
1280 3e0d8fb3 2005-12-27 devnull }
1281 3e0d8fb3 2005-12-27 devnull
1282 3e0d8fb3 2005-12-27 devnull /*
1283 3e0d8fb3 2005-12-27 devnull * true if second domain is subsumed by the first
1284 3e0d8fb3 2005-12-27 devnull */
1285 3e0d8fb3 2005-12-27 devnull int
1286 3e0d8fb3 2005-12-27 devnull subsume(char *higher, char *lower)
1287 3e0d8fb3 2005-12-27 devnull {
1288 3e0d8fb3 2005-12-27 devnull int hn, ln;
1289 3e0d8fb3 2005-12-27 devnull
1290 3e0d8fb3 2005-12-27 devnull ln = strlen(lower);
1291 3e0d8fb3 2005-12-27 devnull hn = strlen(higher);
1292 3e0d8fb3 2005-12-27 devnull if(ln < hn)
1293 3e0d8fb3 2005-12-27 devnull return 0;
1294 3e0d8fb3 2005-12-27 devnull
1295 3e0d8fb3 2005-12-27 devnull if(cistrcmp(lower + ln - hn, higher) != 0)
1296 3e0d8fb3 2005-12-27 devnull return 0;
1297 3e0d8fb3 2005-12-27 devnull
1298 3e0d8fb3 2005-12-27 devnull if(ln > hn && hn != 0 && lower[ln - hn - 1] != '.')
1299 3e0d8fb3 2005-12-27 devnull return 0;
1300 3e0d8fb3 2005-12-27 devnull
1301 3e0d8fb3 2005-12-27 devnull return 1;
1302 3e0d8fb3 2005-12-27 devnull }
1303 3e0d8fb3 2005-12-27 devnull
1304 3e0d8fb3 2005-12-27 devnull /*
1305 3e0d8fb3 2005-12-27 devnull * randomize the order we return items to provide some
1306 3e0d8fb3 2005-12-27 devnull * load balancing for servers.
1307 3e0d8fb3 2005-12-27 devnull *
1308 3e0d8fb3 2005-12-27 devnull * only randomize the first class of entries
1309 3e0d8fb3 2005-12-27 devnull */
1310 3e0d8fb3 2005-12-27 devnull RR*
1311 3e0d8fb3 2005-12-27 devnull randomize(RR *rp)
1312 3e0d8fb3 2005-12-27 devnull {
1313 3e0d8fb3 2005-12-27 devnull RR *first, *last, *x, *base;
1314 3e0d8fb3 2005-12-27 devnull ulong n;
1315 3e0d8fb3 2005-12-27 devnull
1316 3e0d8fb3 2005-12-27 devnull if(rp == nil || rp->next == nil)
1317 3e0d8fb3 2005-12-27 devnull return rp;
1318 3e0d8fb3 2005-12-27 devnull
1319 3e0d8fb3 2005-12-27 devnull /* just randomize addresses and mx's */
1320 3e0d8fb3 2005-12-27 devnull for(x = rp; x; x = x->next)
1321 3e0d8fb3 2005-12-27 devnull if(x->type != Ta && x->type != Tmx && x->type != Tns)
1322 3e0d8fb3 2005-12-27 devnull return rp;
1323 3e0d8fb3 2005-12-27 devnull
1324 3e0d8fb3 2005-12-27 devnull base = rp;
1325 3e0d8fb3 2005-12-27 devnull
1326 3e0d8fb3 2005-12-27 devnull n = rand();
1327 3e0d8fb3 2005-12-27 devnull last = first = nil;
1328 3e0d8fb3 2005-12-27 devnull while(rp != nil){
1329 3e0d8fb3 2005-12-27 devnull /* stop randomizing if we've moved past our class */
1330 3e0d8fb3 2005-12-27 devnull if(base->auth != rp->auth || base->db != rp->db){
1331 3e0d8fb3 2005-12-27 devnull last->next = rp;
1332 3e0d8fb3 2005-12-27 devnull break;
1333 3e0d8fb3 2005-12-27 devnull }
1334 3e0d8fb3 2005-12-27 devnull
1335 3e0d8fb3 2005-12-27 devnull /* unchain */
1336 3e0d8fb3 2005-12-27 devnull x = rp;
1337 3e0d8fb3 2005-12-27 devnull rp = x->next;
1338 3e0d8fb3 2005-12-27 devnull x->next = nil;
1339 3e0d8fb3 2005-12-27 devnull
1340 3e0d8fb3 2005-12-27 devnull if(n&1){
1341 3e0d8fb3 2005-12-27 devnull /* add to tail */
1342 3e0d8fb3 2005-12-27 devnull if(last == nil)
1343 3e0d8fb3 2005-12-27 devnull first = x;
1344 3e0d8fb3 2005-12-27 devnull else
1345 3e0d8fb3 2005-12-27 devnull last->next = x;
1346 3e0d8fb3 2005-12-27 devnull last = x;
1347 3e0d8fb3 2005-12-27 devnull } else {
1348 3e0d8fb3 2005-12-27 devnull /* add to head */
1349 3e0d8fb3 2005-12-27 devnull if(last == nil)
1350 3e0d8fb3 2005-12-27 devnull last = x;
1351 3e0d8fb3 2005-12-27 devnull x->next = first;
1352 3e0d8fb3 2005-12-27 devnull first = x;
1353 3e0d8fb3 2005-12-27 devnull }
1354 3e0d8fb3 2005-12-27 devnull
1355 3e0d8fb3 2005-12-27 devnull /* reroll the dice */
1356 3e0d8fb3 2005-12-27 devnull n >>= 1;
1357 3e0d8fb3 2005-12-27 devnull }
1358 3e0d8fb3 2005-12-27 devnull return first;
1359 3e0d8fb3 2005-12-27 devnull }
1360 3e0d8fb3 2005-12-27 devnull
1361 3e0d8fb3 2005-12-27 devnull static int
1362 3e0d8fb3 2005-12-27 devnull sencodefmt(Fmt *f)
1363 3e0d8fb3 2005-12-27 devnull {
1364 3e0d8fb3 2005-12-27 devnull char *out;
1365 3e0d8fb3 2005-12-27 devnull char *buf;
1366 3e0d8fb3 2005-12-27 devnull int i, len;
1367 3e0d8fb3 2005-12-27 devnull int ilen;
1368 3e0d8fb3 2005-12-27 devnull int rv;
1369 3e0d8fb3 2005-12-27 devnull uchar *b;
1370 226d80b8 2006-04-01 devnull char obuf[64]; /* rsc optimization */
1371 3e0d8fb3 2005-12-27 devnull
1372 3e0d8fb3 2005-12-27 devnull if(!(f->flags&FmtPrec) || f->prec < 1)
1373 3e0d8fb3 2005-12-27 devnull goto error;
1374 3e0d8fb3 2005-12-27 devnull
1375 3e0d8fb3 2005-12-27 devnull b = va_arg(f->args, uchar*);
1376 3e0d8fb3 2005-12-27 devnull if(b == nil)
1377 3e0d8fb3 2005-12-27 devnull goto error;
1378 3e0d8fb3 2005-12-27 devnull
1379 3e0d8fb3 2005-12-27 devnull /* if it's a printable, go for it */
1380 3e0d8fb3 2005-12-27 devnull len = f->prec;
1381 3e0d8fb3 2005-12-27 devnull for(i = 0; i < len; i++)
1382 3e0d8fb3 2005-12-27 devnull if(!isprint(b[i]))
1383 3e0d8fb3 2005-12-27 devnull break;
1384 3e0d8fb3 2005-12-27 devnull if(i == len){
1385 3e0d8fb3 2005-12-27 devnull if(len >= sizeof obuf)
1386 3e0d8fb3 2005-12-27 devnull len = sizeof(obuf)-1;
1387 3e0d8fb3 2005-12-27 devnull memmove(obuf, b, len);
1388 3e0d8fb3 2005-12-27 devnull obuf[len] = 0;
1389 3e0d8fb3 2005-12-27 devnull fmtstrcpy(f, obuf);
1390 3e0d8fb3 2005-12-27 devnull return 0;
1391 3e0d8fb3 2005-12-27 devnull }
1392 3e0d8fb3 2005-12-27 devnull
1393 3e0d8fb3 2005-12-27 devnull ilen = f->prec;
1394 3e0d8fb3 2005-12-27 devnull f->prec = 0;
1395 3e0d8fb3 2005-12-27 devnull f->flags &= ~FmtPrec;
1396 3e0d8fb3 2005-12-27 devnull switch(f->r){
1397 3e0d8fb3 2005-12-27 devnull case '<':
1398 3e0d8fb3 2005-12-27 devnull len = (8*ilen+4)/5 + 3;
1399 3e0d8fb3 2005-12-27 devnull break;
1400 3e0d8fb3 2005-12-27 devnull case '[':
1401 3e0d8fb3 2005-12-27 devnull len = (8*ilen+5)/6 + 4;
1402 3e0d8fb3 2005-12-27 devnull break;
1403 3e0d8fb3 2005-12-27 devnull case 'H':
1404 3e0d8fb3 2005-12-27 devnull len = 2*ilen + 1;
1405 3e0d8fb3 2005-12-27 devnull break;
1406 3e0d8fb3 2005-12-27 devnull default:
1407 3e0d8fb3 2005-12-27 devnull goto error;
1408 3e0d8fb3 2005-12-27 devnull }
1409 3e0d8fb3 2005-12-27 devnull
1410 3e0d8fb3 2005-12-27 devnull if(len > sizeof(obuf)){
1411 3e0d8fb3 2005-12-27 devnull buf = malloc(len);
1412 3e0d8fb3 2005-12-27 devnull if(buf == nil)
1413 3e0d8fb3 2005-12-27 devnull goto error;
1414 3e0d8fb3 2005-12-27 devnull } else
1415 3e0d8fb3 2005-12-27 devnull buf = obuf;
1416 3e0d8fb3 2005-12-27 devnull
1417 226d80b8 2006-04-01 devnull /* convert */
1418 3e0d8fb3 2005-12-27 devnull out = buf;
1419 3e0d8fb3 2005-12-27 devnull switch(f->r){
1420 3e0d8fb3 2005-12-27 devnull case '<':
1421 3e0d8fb3 2005-12-27 devnull rv = enc32(out, len, b, ilen);
1422 3e0d8fb3 2005-12-27 devnull break;
1423 3e0d8fb3 2005-12-27 devnull case '[':
1424 3e0d8fb3 2005-12-27 devnull rv = enc64(out, len, b, ilen);
1425 3e0d8fb3 2005-12-27 devnull break;
1426 3e0d8fb3 2005-12-27 devnull case 'H':
1427 3e0d8fb3 2005-12-27 devnull rv = enc16(out, len, b, ilen);
1428 3e0d8fb3 2005-12-27 devnull break;
1429 3e0d8fb3 2005-12-27 devnull default:
1430 3e0d8fb3 2005-12-27 devnull rv = -1;
1431 3e0d8fb3 2005-12-27 devnull break;
1432 3e0d8fb3 2005-12-27 devnull }
1433 3e0d8fb3 2005-12-27 devnull if(rv < 0)
1434 3e0d8fb3 2005-12-27 devnull goto error;
1435 3e0d8fb3 2005-12-27 devnull
1436 3e0d8fb3 2005-12-27 devnull fmtstrcpy(f, buf);
1437 3e0d8fb3 2005-12-27 devnull if(buf != obuf)
1438 3e0d8fb3 2005-12-27 devnull free(buf);
1439 3e0d8fb3 2005-12-27 devnull return 0;
1440 3e0d8fb3 2005-12-27 devnull
1441 3e0d8fb3 2005-12-27 devnull error:
1442 3e0d8fb3 2005-12-27 devnull return fmtstrcpy(f, "<encodefmt>");
1443 3e0d8fb3 2005-12-27 devnull
1444 3e0d8fb3 2005-12-27 devnull }
1445 3e0d8fb3 2005-12-27 devnull
1446 3e0d8fb3 2005-12-27 devnull void*
1447 3e0d8fb3 2005-12-27 devnull emalloc(int size)
1448 3e0d8fb3 2005-12-27 devnull {
1449 3e0d8fb3 2005-12-27 devnull char *x;
1450 3e0d8fb3 2005-12-27 devnull
1451 3e0d8fb3 2005-12-27 devnull x = mallocz(size, 1);
1452 3e0d8fb3 2005-12-27 devnull if(x == nil)
1453 3e0d8fb3 2005-12-27 devnull abort();
1454 3e0d8fb3 2005-12-27 devnull setmalloctag(x, getcallerpc(&size));
1455 3e0d8fb3 2005-12-27 devnull return x;
1456 3e0d8fb3 2005-12-27 devnull }
1457 3e0d8fb3 2005-12-27 devnull
1458 3e0d8fb3 2005-12-27 devnull char*
1459 3e0d8fb3 2005-12-27 devnull estrdup(char *s)
1460 3e0d8fb3 2005-12-27 devnull {
1461 3e0d8fb3 2005-12-27 devnull int size;
1462 3e0d8fb3 2005-12-27 devnull char *p;
1463 3e0d8fb3 2005-12-27 devnull
1464 3e0d8fb3 2005-12-27 devnull size = strlen(s)+1;
1465 3e0d8fb3 2005-12-27 devnull p = mallocz(size, 0);
1466 3e0d8fb3 2005-12-27 devnull if(p == nil)
1467 3e0d8fb3 2005-12-27 devnull abort();
1468 3e0d8fb3 2005-12-27 devnull memmove(p, s, size);
1469 3e0d8fb3 2005-12-27 devnull setmalloctag(p, getcallerpc(&s));
1470 3e0d8fb3 2005-12-27 devnull return p;
1471 3e0d8fb3 2005-12-27 devnull }
1472 3e0d8fb3 2005-12-27 devnull
1473 3e0d8fb3 2005-12-27 devnull /*
1474 3e0d8fb3 2005-12-27 devnull * create a pointer record
1475 3e0d8fb3 2005-12-27 devnull */
1476 3e0d8fb3 2005-12-27 devnull static RR*
1477 3e0d8fb3 2005-12-27 devnull mkptr(DN *dp, char *ptr, ulong ttl)
1478 3e0d8fb3 2005-12-27 devnull {
1479 3e0d8fb3 2005-12-27 devnull DN *ipdp;
1480 3e0d8fb3 2005-12-27 devnull RR *rp;
1481 3e0d8fb3 2005-12-27 devnull
1482 3e0d8fb3 2005-12-27 devnull ipdp = dnlookup(ptr, Cin, 1);
1483 3e0d8fb3 2005-12-27 devnull
1484 3e0d8fb3 2005-12-27 devnull rp = rralloc(Tptr);
1485 3e0d8fb3 2005-12-27 devnull rp->ptr = dp;
1486 3e0d8fb3 2005-12-27 devnull rp->owner = ipdp;
1487 3e0d8fb3 2005-12-27 devnull rp->db = 1;
1488 3e0d8fb3 2005-12-27 devnull if(ttl)
1489 3e0d8fb3 2005-12-27 devnull rp->ttl = ttl;
1490 3e0d8fb3 2005-12-27 devnull return rp;
1491 3e0d8fb3 2005-12-27 devnull }
1492 3e0d8fb3 2005-12-27 devnull
1493 3e0d8fb3 2005-12-27 devnull /*
1494 3e0d8fb3 2005-12-27 devnull * look for all ip addresses in this network and make
1495 3e0d8fb3 2005-12-27 devnull * pointer records for them.
1496 3e0d8fb3 2005-12-27 devnull */
1497 3e0d8fb3 2005-12-27 devnull void
1498 3e0d8fb3 2005-12-27 devnull dnptr(uchar *net, uchar *mask, char *dom, int bytes, int ttl)
1499 3e0d8fb3 2005-12-27 devnull {
1500 3e0d8fb3 2005-12-27 devnull int i, j;
1501 3e0d8fb3 2005-12-27 devnull DN *dp;
1502 3e0d8fb3 2005-12-27 devnull RR *rp, *nrp, *first, **l;
1503 3e0d8fb3 2005-12-27 devnull uchar ip[IPaddrlen];
1504 3e0d8fb3 2005-12-27 devnull uchar nnet[IPaddrlen];
1505 3e0d8fb3 2005-12-27 devnull char ptr[Domlen];
1506 3e0d8fb3 2005-12-27 devnull char *p, *e;
1507 3e0d8fb3 2005-12-27 devnull
1508 3e0d8fb3 2005-12-27 devnull l = &first;
1509 3e0d8fb3 2005-12-27 devnull first = nil;
1510 3e0d8fb3 2005-12-27 devnull for(i = 0; i < HTLEN; i++){
1511 3e0d8fb3 2005-12-27 devnull for(dp = ht[i]; dp; dp = dp->next){
1512 3e0d8fb3 2005-12-27 devnull for(rp = dp->rr; rp; rp = rp->next){
1513 3e0d8fb3 2005-12-27 devnull if(rp->type != Ta || rp->negative)
1514 3e0d8fb3 2005-12-27 devnull continue;
1515 3e0d8fb3 2005-12-27 devnull parseip(ip, rp->ip->name);
1516 3e0d8fb3 2005-12-27 devnull maskip(ip, mask, nnet);
1517 3e0d8fb3 2005-12-27 devnull if(ipcmp(net, nnet) != 0)
1518 3e0d8fb3 2005-12-27 devnull continue;
1519 3e0d8fb3 2005-12-27 devnull p = ptr;
1520 3e0d8fb3 2005-12-27 devnull e = ptr+sizeof(ptr);
1521 3e0d8fb3 2005-12-27 devnull for(j = IPaddrlen-1; j >= IPaddrlen-bytes; j--)
1522 3e0d8fb3 2005-12-27 devnull p = seprint(p, e, "%d.", ip[j]);
1523 3e0d8fb3 2005-12-27 devnull seprint(p, e, "%s", dom);
1524 3e0d8fb3 2005-12-27 devnull nrp = mkptr(dp, ptr, ttl);
1525 3e0d8fb3 2005-12-27 devnull *l = nrp;
1526 3e0d8fb3 2005-12-27 devnull l = &nrp->next;
1527 3e0d8fb3 2005-12-27 devnull }
1528 3e0d8fb3 2005-12-27 devnull }
1529 3e0d8fb3 2005-12-27 devnull }
1530 3e0d8fb3 2005-12-27 devnull
1531 3e0d8fb3 2005-12-27 devnull for(rp = first; rp != nil; rp = nrp){
1532 3e0d8fb3 2005-12-27 devnull nrp = rp->next;
1533 3e0d8fb3 2005-12-27 devnull rp->next = nil;
1534 3e0d8fb3 2005-12-27 devnull rrattach(rp, 1);
1535 3e0d8fb3 2005-12-27 devnull }
1536 3e0d8fb3 2005-12-27 devnull }
1537 3e0d8fb3 2005-12-27 devnull
1538 3e0d8fb3 2005-12-27 devnull void
1539 3e0d8fb3 2005-12-27 devnull freeserverlist(Server *s)
1540 3e0d8fb3 2005-12-27 devnull {
1541 3e0d8fb3 2005-12-27 devnull Server *next;
1542 3e0d8fb3 2005-12-27 devnull
1543 3e0d8fb3 2005-12-27 devnull for(; s != nil; s = next){
1544 3e0d8fb3 2005-12-27 devnull next = s->next;
1545 3e0d8fb3 2005-12-27 devnull free(s);
1546 3e0d8fb3 2005-12-27 devnull }
1547 3e0d8fb3 2005-12-27 devnull }
1548 3e0d8fb3 2005-12-27 devnull
1549 3e0d8fb3 2005-12-27 devnull void
1550 3e0d8fb3 2005-12-27 devnull addserver(Server **l, char *name)
1551 3e0d8fb3 2005-12-27 devnull {
1552 3e0d8fb3 2005-12-27 devnull Server *s;
1553 3e0d8fb3 2005-12-27 devnull
1554 3e0d8fb3 2005-12-27 devnull while(*l)
1555 3e0d8fb3 2005-12-27 devnull l = &(*l)->next;
1556 3e0d8fb3 2005-12-27 devnull s = malloc(sizeof(Server)+strlen(name)+1);
1557 3e0d8fb3 2005-12-27 devnull if(s == nil)
1558 3e0d8fb3 2005-12-27 devnull return;
1559 3e0d8fb3 2005-12-27 devnull s->name = (char*)(s+1);
1560 3e0d8fb3 2005-12-27 devnull strcpy(s->name, name);
1561 3e0d8fb3 2005-12-27 devnull s->next = nil;
1562 3e0d8fb3 2005-12-27 devnull *l = s;
1563 3e0d8fb3 2005-12-27 devnull }
1564 3e0d8fb3 2005-12-27 devnull
1565 3e0d8fb3 2005-12-27 devnull Server*
1566 3e0d8fb3 2005-12-27 devnull copyserverlist(Server *s)
1567 3e0d8fb3 2005-12-27 devnull {
1568 3e0d8fb3 2005-12-27 devnull Server *ns;
1569 3e0d8fb3 2005-12-27 devnull
1570 3e0d8fb3 2005-12-27 devnull
1571 3e0d8fb3 2005-12-27 devnull for(ns = nil; s != nil; s = s->next)
1572 3e0d8fb3 2005-12-27 devnull addserver(&ns, s->name);
1573 3e0d8fb3 2005-12-27 devnull return ns;
1574 3e0d8fb3 2005-12-27 devnull }