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 <bio.h>
4 3e0d8fb3 2005-12-27 devnull #include <ndb.h>
5 3e0d8fb3 2005-12-27 devnull #include <ip.h>
6 3e0d8fb3 2005-12-27 devnull #include "dns.h"
7 3e0d8fb3 2005-12-27 devnull
8 3e0d8fb3 2005-12-27 devnull static Ndb *db;
9 3e0d8fb3 2005-12-27 devnull
10 3e0d8fb3 2005-12-27 devnull static RR* dblookup1(char*, int, int, int);
11 3e0d8fb3 2005-12-27 devnull static RR* addrrr(Ndbtuple*, Ndbtuple*);
12 3e0d8fb3 2005-12-27 devnull static RR* nsrr(Ndbtuple*, Ndbtuple*);
13 3e0d8fb3 2005-12-27 devnull static RR* cnamerr(Ndbtuple*, Ndbtuple*);
14 3e0d8fb3 2005-12-27 devnull static RR* mxrr(Ndbtuple*, Ndbtuple*);
15 3e0d8fb3 2005-12-27 devnull static RR* soarr(Ndbtuple*, Ndbtuple*);
16 3e0d8fb3 2005-12-27 devnull static RR* ptrrr(Ndbtuple*, Ndbtuple*);
17 3e0d8fb3 2005-12-27 devnull static Ndbtuple* look(Ndbtuple*, Ndbtuple*, char*);
18 3e0d8fb3 2005-12-27 devnull static RR* doaxfr(Ndb*, char*);
19 3e0d8fb3 2005-12-27 devnull static RR* nullrr(Ndbtuple *entry, Ndbtuple *pair);
20 3e0d8fb3 2005-12-27 devnull static RR* txtrr(Ndbtuple *entry, Ndbtuple *pair);
21 3e0d8fb3 2005-12-27 devnull static Lock dblock;
22 3e0d8fb3 2005-12-27 devnull static void createptrs(void);
23 3e0d8fb3 2005-12-27 devnull
24 3e0d8fb3 2005-12-27 devnull static int implemented[Tall] =
25 3e0d8fb3 2005-12-27 devnull {
26 3e0d8fb3 2005-12-27 devnull [Ta] 1,
27 3e0d8fb3 2005-12-27 devnull [Tns] 1,
28 3e0d8fb3 2005-12-27 devnull [Tsoa] 1,
29 3e0d8fb3 2005-12-27 devnull [Tmx] 1,
30 3e0d8fb3 2005-12-27 devnull [Tptr] 1,
31 3e0d8fb3 2005-12-27 devnull [Tcname] 1,
32 3e0d8fb3 2005-12-27 devnull [Tnull] 1,
33 3e0d8fb3 2005-12-27 devnull [Ttxt] 1,
34 3e0d8fb3 2005-12-27 devnull };
35 3e0d8fb3 2005-12-27 devnull
36 3e0d8fb3 2005-12-27 devnull static void
37 3e0d8fb3 2005-12-27 devnull nstrcpy(char *to, char *from, int len)
38 3e0d8fb3 2005-12-27 devnull {
39 3e0d8fb3 2005-12-27 devnull strncpy(to, from, len);
40 3e0d8fb3 2005-12-27 devnull to[len-1] = 0;
41 3e0d8fb3 2005-12-27 devnull }
42 3e0d8fb3 2005-12-27 devnull
43 3e0d8fb3 2005-12-27 devnull int
44 3e0d8fb3 2005-12-27 devnull opendatabase(void)
45 3e0d8fb3 2005-12-27 devnull {
46 3e0d8fb3 2005-12-27 devnull char buf[256];
47 3e0d8fb3 2005-12-27 devnull Ndb *xdb;
48 3e0d8fb3 2005-12-27 devnull
49 3e0d8fb3 2005-12-27 devnull if(db == nil){
50 3e0d8fb3 2005-12-27 devnull snprint(buf, sizeof(buf), "%s/ndb", mntpt);
51 3e0d8fb3 2005-12-27 devnull xdb = ndbopen(dbfile);
52 3e0d8fb3 2005-12-27 devnull if(xdb != nil)
53 3e0d8fb3 2005-12-27 devnull xdb->nohash = 1;
54 3e0d8fb3 2005-12-27 devnull db = ndbcat(ndbopen(buf), xdb);
55 3e0d8fb3 2005-12-27 devnull }
56 3e0d8fb3 2005-12-27 devnull if(db == nil)
57 3e0d8fb3 2005-12-27 devnull return -1;
58 3e0d8fb3 2005-12-27 devnull else
59 3e0d8fb3 2005-12-27 devnull return 0;
60 3e0d8fb3 2005-12-27 devnull }
61 3e0d8fb3 2005-12-27 devnull
62 3e0d8fb3 2005-12-27 devnull /*
63 3e0d8fb3 2005-12-27 devnull * lookup an RR in the network database, look for matches
64 3e0d8fb3 2005-12-27 devnull * against both the domain name and the wildcarded domain name.
65 3e0d8fb3 2005-12-27 devnull *
66 3e0d8fb3 2005-12-27 devnull * the lock makes sure only one process can be accessing the data
67 3e0d8fb3 2005-12-27 devnull * base at a time. This is important since there's a lot of
68 3e0d8fb3 2005-12-27 devnull * shared state there.
69 3e0d8fb3 2005-12-27 devnull *
70 3e0d8fb3 2005-12-27 devnull * e.g. for x.research.bell-labs.com, first look for a match against
71 3e0d8fb3 2005-12-27 devnull * the x.research.bell-labs.com. If nothing matches, try *.research.bell-labs.com.
72 3e0d8fb3 2005-12-27 devnull */
73 3e0d8fb3 2005-12-27 devnull RR*
74 3e0d8fb3 2005-12-27 devnull dblookup(char *name, int class, int type, int auth, int ttl)
75 3e0d8fb3 2005-12-27 devnull {
76 3e0d8fb3 2005-12-27 devnull RR *rp, *tp;
77 3e0d8fb3 2005-12-27 devnull char buf[256];
78 3e0d8fb3 2005-12-27 devnull char *wild, *cp;
79 3e0d8fb3 2005-12-27 devnull DN *dp, *ndp;
80 3e0d8fb3 2005-12-27 devnull int err;
81 3e0d8fb3 2005-12-27 devnull static int parallel;
82 3e0d8fb3 2005-12-27 devnull static int parfd[2];
83 3e0d8fb3 2005-12-27 devnull static char token[1];
84 3e0d8fb3 2005-12-27 devnull
85 3e0d8fb3 2005-12-27 devnull /* so far only internet lookups are implemented */
86 3e0d8fb3 2005-12-27 devnull if(class != Cin)
87 3e0d8fb3 2005-12-27 devnull return 0;
88 3e0d8fb3 2005-12-27 devnull
89 3e0d8fb3 2005-12-27 devnull err = Rname;
90 3e0d8fb3 2005-12-27 devnull
91 3e0d8fb3 2005-12-27 devnull if(type == Tall){
92 3e0d8fb3 2005-12-27 devnull rp = 0;
93 3e0d8fb3 2005-12-27 devnull for (type = Ta; type < Tall; type++)
94 3e0d8fb3 2005-12-27 devnull if(implemented[type])
95 3e0d8fb3 2005-12-27 devnull rrcat(&rp, dblookup(name, class, type, auth, ttl));
96 3e0d8fb3 2005-12-27 devnull return rp;
97 3e0d8fb3 2005-12-27 devnull }
98 3e0d8fb3 2005-12-27 devnull
99 3e0d8fb3 2005-12-27 devnull lock(&dblock);
100 3e0d8fb3 2005-12-27 devnull dp = dnlookup(name, class, 1);
101 3e0d8fb3 2005-12-27 devnull if(opendatabase() < 0)
102 3e0d8fb3 2005-12-27 devnull goto out;
103 3e0d8fb3 2005-12-27 devnull if(dp->rr)
104 3e0d8fb3 2005-12-27 devnull err = 0;
105 3e0d8fb3 2005-12-27 devnull
106 3e0d8fb3 2005-12-27 devnull /* first try the given name */
107 3e0d8fb3 2005-12-27 devnull rp = 0;
108 3e0d8fb3 2005-12-27 devnull if(cachedb)
109 3e0d8fb3 2005-12-27 devnull rp = rrlookup(dp, type, NOneg);
110 3e0d8fb3 2005-12-27 devnull else
111 3e0d8fb3 2005-12-27 devnull rp = dblookup1(name, type, auth, ttl);
112 3e0d8fb3 2005-12-27 devnull if(rp)
113 3e0d8fb3 2005-12-27 devnull goto out;
114 3e0d8fb3 2005-12-27 devnull
115 3e0d8fb3 2005-12-27 devnull /* try lower case version */
116 3e0d8fb3 2005-12-27 devnull for(cp = name; *cp; cp++)
117 3e0d8fb3 2005-12-27 devnull *cp = tolower(*cp);
118 3e0d8fb3 2005-12-27 devnull if(cachedb)
119 3e0d8fb3 2005-12-27 devnull rp = rrlookup(dp, type, NOneg);
120 3e0d8fb3 2005-12-27 devnull else
121 3e0d8fb3 2005-12-27 devnull rp = dblookup1(name, type, auth, ttl);
122 3e0d8fb3 2005-12-27 devnull if(rp)
123 3e0d8fb3 2005-12-27 devnull goto out;
124 3e0d8fb3 2005-12-27 devnull
125 3e0d8fb3 2005-12-27 devnull /* walk the domain name trying the wildcard '*' at each position */
126 3e0d8fb3 2005-12-27 devnull for(wild = strchr(name, '.'); wild; wild = strchr(wild+1, '.')){
127 3e0d8fb3 2005-12-27 devnull snprint(buf, sizeof(buf), "*%s", wild);
128 3e0d8fb3 2005-12-27 devnull ndp = dnlookup(buf, class, 1);
129 3e0d8fb3 2005-12-27 devnull if(ndp->rr)
130 3e0d8fb3 2005-12-27 devnull err = 0;
131 3e0d8fb3 2005-12-27 devnull if(cachedb)
132 3e0d8fb3 2005-12-27 devnull rp = rrlookup(ndp, type, NOneg);
133 3e0d8fb3 2005-12-27 devnull else
134 3e0d8fb3 2005-12-27 devnull rp = dblookup1(buf, type, auth, ttl);
135 3e0d8fb3 2005-12-27 devnull if(rp)
136 3e0d8fb3 2005-12-27 devnull break;
137 3e0d8fb3 2005-12-27 devnull }
138 3e0d8fb3 2005-12-27 devnull out:
139 3e0d8fb3 2005-12-27 devnull /* add owner to uncached records */
140 3e0d8fb3 2005-12-27 devnull if(rp){
141 3e0d8fb3 2005-12-27 devnull for(tp = rp; tp; tp = tp->next)
142 3e0d8fb3 2005-12-27 devnull tp->owner = dp;
143 3e0d8fb3 2005-12-27 devnull } else {
144 3e0d8fb3 2005-12-27 devnull /* don't call it non-existent if it's not ours */
145 3e0d8fb3 2005-12-27 devnull if(err == Rname && !inmyarea(name))
146 3e0d8fb3 2005-12-27 devnull err = Rserver;
147 3e0d8fb3 2005-12-27 devnull dp->nonexistent = err;
148 3e0d8fb3 2005-12-27 devnull }
149 3e0d8fb3 2005-12-27 devnull
150 3e0d8fb3 2005-12-27 devnull unlock(&dblock);
151 3e0d8fb3 2005-12-27 devnull return rp;
152 3e0d8fb3 2005-12-27 devnull }
153 3e0d8fb3 2005-12-27 devnull
154 3e0d8fb3 2005-12-27 devnull /*
155 3e0d8fb3 2005-12-27 devnull * lookup an RR in the network database
156 3e0d8fb3 2005-12-27 devnull */
157 3e0d8fb3 2005-12-27 devnull static RR*
158 3e0d8fb3 2005-12-27 devnull dblookup1(char *name, int type, int auth, int ttl)
159 3e0d8fb3 2005-12-27 devnull {
160 3e0d8fb3 2005-12-27 devnull Ndbtuple *t, *nt;
161 3e0d8fb3 2005-12-27 devnull RR *rp, *list, **l;
162 3e0d8fb3 2005-12-27 devnull Ndbs s;
163 3e0d8fb3 2005-12-27 devnull char dname[Domlen];
164 3e0d8fb3 2005-12-27 devnull char *attr;
165 3e0d8fb3 2005-12-27 devnull DN *dp;
166 3e0d8fb3 2005-12-27 devnull RR *(*f)(Ndbtuple*, Ndbtuple*);
167 3e0d8fb3 2005-12-27 devnull int found, x;
168 3e0d8fb3 2005-12-27 devnull
169 3e0d8fb3 2005-12-27 devnull dp = 0;
170 3e0d8fb3 2005-12-27 devnull switch(type){
171 3e0d8fb3 2005-12-27 devnull case Tptr:
172 3e0d8fb3 2005-12-27 devnull attr = "ptr";
173 3e0d8fb3 2005-12-27 devnull f = ptrrr;
174 3e0d8fb3 2005-12-27 devnull break;
175 3e0d8fb3 2005-12-27 devnull case Ta:
176 3e0d8fb3 2005-12-27 devnull attr = "ip";
177 3e0d8fb3 2005-12-27 devnull f = addrrr;
178 3e0d8fb3 2005-12-27 devnull break;
179 3e0d8fb3 2005-12-27 devnull case Tnull:
180 3e0d8fb3 2005-12-27 devnull attr = "nullrr";
181 3e0d8fb3 2005-12-27 devnull f = nullrr;
182 3e0d8fb3 2005-12-27 devnull break;
183 3e0d8fb3 2005-12-27 devnull case Tns:
184 3e0d8fb3 2005-12-27 devnull attr = "ns";
185 3e0d8fb3 2005-12-27 devnull f = nsrr;
186 3e0d8fb3 2005-12-27 devnull break;
187 3e0d8fb3 2005-12-27 devnull case Tsoa:
188 3e0d8fb3 2005-12-27 devnull attr = "soa";
189 3e0d8fb3 2005-12-27 devnull f = soarr;
190 3e0d8fb3 2005-12-27 devnull break;
191 3e0d8fb3 2005-12-27 devnull case Tmx:
192 3e0d8fb3 2005-12-27 devnull attr = "mx";
193 3e0d8fb3 2005-12-27 devnull f = mxrr;
194 3e0d8fb3 2005-12-27 devnull break;
195 3e0d8fb3 2005-12-27 devnull case Tcname:
196 3e0d8fb3 2005-12-27 devnull attr = "cname";
197 3e0d8fb3 2005-12-27 devnull f = cnamerr;
198 3e0d8fb3 2005-12-27 devnull break;
199 3e0d8fb3 2005-12-27 devnull case Taxfr:
200 3e0d8fb3 2005-12-27 devnull case Tixfr:
201 3e0d8fb3 2005-12-27 devnull return doaxfr(db, name);
202 3e0d8fb3 2005-12-27 devnull default:
203 3e0d8fb3 2005-12-27 devnull return nil;
204 3e0d8fb3 2005-12-27 devnull }
205 3e0d8fb3 2005-12-27 devnull
206 3e0d8fb3 2005-12-27 devnull /*
207 3e0d8fb3 2005-12-27 devnull * find a matching entry in the database
208 3e0d8fb3 2005-12-27 devnull */
209 3e0d8fb3 2005-12-27 devnull free(ndbgetvalue(db, &s, "dom", name, attr, &t));
210 3e0d8fb3 2005-12-27 devnull
211 3e0d8fb3 2005-12-27 devnull /*
212 3e0d8fb3 2005-12-27 devnull * hack for local names
213 3e0d8fb3 2005-12-27 devnull */
214 3e0d8fb3 2005-12-27 devnull if(t == 0 && strchr(name, '.') == 0)
215 3e0d8fb3 2005-12-27 devnull free(ndbgetvalue(db, &s, "sys", name, attr, &t));
216 3e0d8fb3 2005-12-27 devnull if(t == 0)
217 3e0d8fb3 2005-12-27 devnull return nil;
218 3e0d8fb3 2005-12-27 devnull
219 3e0d8fb3 2005-12-27 devnull /* search whole entry for default domain name */
220 3e0d8fb3 2005-12-27 devnull strncpy(dname, name, sizeof dname);
221 3e0d8fb3 2005-12-27 devnull for(nt = t; nt; nt = nt->entry)
222 3e0d8fb3 2005-12-27 devnull if(strcmp(nt->attr, "dom") == 0){
223 3e0d8fb3 2005-12-27 devnull nstrcpy(dname, nt->val, sizeof dname);
224 3e0d8fb3 2005-12-27 devnull break;
225 3e0d8fb3 2005-12-27 devnull }
226 3e0d8fb3 2005-12-27 devnull
227 3e0d8fb3 2005-12-27 devnull /* ttl is maximum of soa minttl and entry's ttl ala rfc883 */
228 3e0d8fb3 2005-12-27 devnull nt = look(t, s.t, "ttl");
229 3e0d8fb3 2005-12-27 devnull if(nt){
230 3e0d8fb3 2005-12-27 devnull x = atoi(nt->val);
231 3e0d8fb3 2005-12-27 devnull if(x > ttl)
232 3e0d8fb3 2005-12-27 devnull ttl = x;
233 3e0d8fb3 2005-12-27 devnull }
234 3e0d8fb3 2005-12-27 devnull
235 3e0d8fb3 2005-12-27 devnull /* default ttl is one day */
236 3e0d8fb3 2005-12-27 devnull if(ttl < 0)
237 3e0d8fb3 2005-12-27 devnull ttl = DEFTTL;
238 3e0d8fb3 2005-12-27 devnull
239 3e0d8fb3 2005-12-27 devnull /*
240 3e0d8fb3 2005-12-27 devnull * The database has 2 levels of precedence; line and entry.
241 3e0d8fb3 2005-12-27 devnull * Pairs on the same line bind tighter than pairs in the
242 3e0d8fb3 2005-12-27 devnull * same entry, so we search the line first.
243 3e0d8fb3 2005-12-27 devnull */
244 3e0d8fb3 2005-12-27 devnull found = 0;
245 3e0d8fb3 2005-12-27 devnull list = 0;
246 3e0d8fb3 2005-12-27 devnull l = &list;
247 3e0d8fb3 2005-12-27 devnull for(nt = s.t;; ){
248 3e0d8fb3 2005-12-27 devnull if(found == 0 && strcmp(nt->attr, "dom") == 0){
249 3e0d8fb3 2005-12-27 devnull nstrcpy(dname, nt->val, sizeof dname);
250 3e0d8fb3 2005-12-27 devnull found = 1;
251 3e0d8fb3 2005-12-27 devnull }
252 3e0d8fb3 2005-12-27 devnull if(cistrcmp(attr, nt->attr) == 0){
253 3e0d8fb3 2005-12-27 devnull rp = (*f)(t, nt);
254 3e0d8fb3 2005-12-27 devnull rp->auth = auth;
255 3e0d8fb3 2005-12-27 devnull rp->db = 1;
256 3e0d8fb3 2005-12-27 devnull if(ttl)
257 3e0d8fb3 2005-12-27 devnull rp->ttl = ttl;
258 3e0d8fb3 2005-12-27 devnull if(dp == 0)
259 3e0d8fb3 2005-12-27 devnull dp = dnlookup(dname, Cin, 1);
260 3e0d8fb3 2005-12-27 devnull rp->owner = dp;
261 3e0d8fb3 2005-12-27 devnull *l = rp;
262 3e0d8fb3 2005-12-27 devnull l = &rp->next;
263 3e0d8fb3 2005-12-27 devnull nt->ptr = 1;
264 3e0d8fb3 2005-12-27 devnull }
265 3e0d8fb3 2005-12-27 devnull nt = nt->line;
266 3e0d8fb3 2005-12-27 devnull if(nt == s.t)
267 3e0d8fb3 2005-12-27 devnull break;
268 3e0d8fb3 2005-12-27 devnull }
269 3e0d8fb3 2005-12-27 devnull
270 3e0d8fb3 2005-12-27 devnull /* search whole entry */
271 3e0d8fb3 2005-12-27 devnull for(nt = t; nt; nt = nt->entry)
272 3e0d8fb3 2005-12-27 devnull if(nt->ptr == 0 && cistrcmp(attr, nt->attr) == 0){
273 3e0d8fb3 2005-12-27 devnull rp = (*f)(t, nt);
274 3e0d8fb3 2005-12-27 devnull rp->db = 1;
275 3e0d8fb3 2005-12-27 devnull if(ttl)
276 3e0d8fb3 2005-12-27 devnull rp->ttl = ttl;
277 3e0d8fb3 2005-12-27 devnull rp->auth = auth;
278 3e0d8fb3 2005-12-27 devnull if(dp == 0)
279 3e0d8fb3 2005-12-27 devnull dp = dnlookup(dname, Cin, 1);
280 3e0d8fb3 2005-12-27 devnull rp->owner = dp;
281 3e0d8fb3 2005-12-27 devnull *l = rp;
282 3e0d8fb3 2005-12-27 devnull l = &rp->next;
283 3e0d8fb3 2005-12-27 devnull }
284 3e0d8fb3 2005-12-27 devnull ndbfree(t);
285 3e0d8fb3 2005-12-27 devnull
286 3e0d8fb3 2005-12-27 devnull return list;
287 3e0d8fb3 2005-12-27 devnull }
288 3e0d8fb3 2005-12-27 devnull
289 3e0d8fb3 2005-12-27 devnull /*
290 3e0d8fb3 2005-12-27 devnull * make various types of resource records from a database entry
291 3e0d8fb3 2005-12-27 devnull */
292 3e0d8fb3 2005-12-27 devnull static RR*
293 3e0d8fb3 2005-12-27 devnull addrrr(Ndbtuple *entry, Ndbtuple *pair)
294 3e0d8fb3 2005-12-27 devnull {
295 3e0d8fb3 2005-12-27 devnull RR *rp;
296 3e0d8fb3 2005-12-27 devnull uchar addr[IPaddrlen];
297 3e0d8fb3 2005-12-27 devnull
298 3e0d8fb3 2005-12-27 devnull USED(entry);
299 3e0d8fb3 2005-12-27 devnull parseip(addr, pair->val);
300 3e0d8fb3 2005-12-27 devnull if(isv4(addr))
301 3e0d8fb3 2005-12-27 devnull rp = rralloc(Ta);
302 3e0d8fb3 2005-12-27 devnull else
303 3e0d8fb3 2005-12-27 devnull rp = rralloc(Taaaa);
304 3e0d8fb3 2005-12-27 devnull rp->ip = dnlookup(pair->val, Cin, 1);
305 3e0d8fb3 2005-12-27 devnull return rp;
306 3e0d8fb3 2005-12-27 devnull }
307 3e0d8fb3 2005-12-27 devnull static RR*
308 3e0d8fb3 2005-12-27 devnull nullrr(Ndbtuple *entry, Ndbtuple *pair)
309 3e0d8fb3 2005-12-27 devnull {
310 3e0d8fb3 2005-12-27 devnull RR *rp;
311 3e0d8fb3 2005-12-27 devnull
312 3e0d8fb3 2005-12-27 devnull USED(entry);
313 3e0d8fb3 2005-12-27 devnull rp = rralloc(Tnull);
314 3e0d8fb3 2005-12-27 devnull rp->null->data = (uchar*)estrdup(pair->val);
315 3e0d8fb3 2005-12-27 devnull rp->null->dlen = strlen((char*)rp->null->data);
316 3e0d8fb3 2005-12-27 devnull return rp;
317 3e0d8fb3 2005-12-27 devnull }
318 3e0d8fb3 2005-12-27 devnull /*
319 3e0d8fb3 2005-12-27 devnull * txt rr strings are at most 255 bytes long. one
320 3e0d8fb3 2005-12-27 devnull * can represent longer strings by multiple concatenated
321 3e0d8fb3 2005-12-27 devnull * <= 255 byte ones.
322 3e0d8fb3 2005-12-27 devnull */
323 3e0d8fb3 2005-12-27 devnull static RR*
324 3e0d8fb3 2005-12-27 devnull txtrr(Ndbtuple *entry, Ndbtuple *pair)
325 3e0d8fb3 2005-12-27 devnull {
326 3e0d8fb3 2005-12-27 devnull RR *rp;
327 3e0d8fb3 2005-12-27 devnull Txt *t, **l;
328 3e0d8fb3 2005-12-27 devnull int i, len, sofar;
329 3e0d8fb3 2005-12-27 devnull
330 3e0d8fb3 2005-12-27 devnull USED(entry);
331 3e0d8fb3 2005-12-27 devnull rp = rralloc(Ttxt);
332 3e0d8fb3 2005-12-27 devnull l = &rp->txt;
333 3e0d8fb3 2005-12-27 devnull rp->txt = nil;
334 3e0d8fb3 2005-12-27 devnull len = strlen(pair->val);
335 3e0d8fb3 2005-12-27 devnull sofar = 0;
336 3e0d8fb3 2005-12-27 devnull while(len > sofar){
337 3e0d8fb3 2005-12-27 devnull t = emalloc(sizeof(*t));
338 3e0d8fb3 2005-12-27 devnull t->next = nil;
339 3e0d8fb3 2005-12-27 devnull
340 3e0d8fb3 2005-12-27 devnull i = len-sofar;
341 3e0d8fb3 2005-12-27 devnull if(i > 255)
342 3e0d8fb3 2005-12-27 devnull i = 255;
343 3e0d8fb3 2005-12-27 devnull
344 3e0d8fb3 2005-12-27 devnull t->p = emalloc(i+1);
345 3e0d8fb3 2005-12-27 devnull memmove(t->p, pair->val+sofar, i);
346 3e0d8fb3 2005-12-27 devnull t->p[i] = 0;
347 3e0d8fb3 2005-12-27 devnull sofar += i;
348 3e0d8fb3 2005-12-27 devnull
349 3e0d8fb3 2005-12-27 devnull *l = t;
350 3e0d8fb3 2005-12-27 devnull l = &t->next;
351 3e0d8fb3 2005-12-27 devnull }
352 3e0d8fb3 2005-12-27 devnull return rp;
353 3e0d8fb3 2005-12-27 devnull }
354 3e0d8fb3 2005-12-27 devnull static RR*
355 3e0d8fb3 2005-12-27 devnull cnamerr(Ndbtuple *entry, Ndbtuple *pair)
356 3e0d8fb3 2005-12-27 devnull {
357 3e0d8fb3 2005-12-27 devnull RR *rp;
358 3e0d8fb3 2005-12-27 devnull
359 3e0d8fb3 2005-12-27 devnull USED(entry);
360 3e0d8fb3 2005-12-27 devnull rp = rralloc(Tcname);
361 3e0d8fb3 2005-12-27 devnull rp->host = dnlookup(pair->val, Cin, 1);
362 3e0d8fb3 2005-12-27 devnull return rp;
363 3e0d8fb3 2005-12-27 devnull }
364 3e0d8fb3 2005-12-27 devnull static RR*
365 3e0d8fb3 2005-12-27 devnull mxrr(Ndbtuple *entry, Ndbtuple *pair)
366 3e0d8fb3 2005-12-27 devnull {
367 3e0d8fb3 2005-12-27 devnull RR * rp;
368 3e0d8fb3 2005-12-27 devnull
369 3e0d8fb3 2005-12-27 devnull rp = rralloc(Tmx);
370 3e0d8fb3 2005-12-27 devnull rp->host = dnlookup(pair->val, Cin, 1);
371 3e0d8fb3 2005-12-27 devnull pair = look(entry, pair, "pref");
372 3e0d8fb3 2005-12-27 devnull if(pair)
373 3e0d8fb3 2005-12-27 devnull rp->pref = atoi(pair->val);
374 3e0d8fb3 2005-12-27 devnull else
375 3e0d8fb3 2005-12-27 devnull rp->pref = 1;
376 3e0d8fb3 2005-12-27 devnull return rp;
377 3e0d8fb3 2005-12-27 devnull }
378 3e0d8fb3 2005-12-27 devnull static RR*
379 3e0d8fb3 2005-12-27 devnull nsrr(Ndbtuple *entry, Ndbtuple *pair)
380 3e0d8fb3 2005-12-27 devnull {
381 3e0d8fb3 2005-12-27 devnull RR *rp;
382 3e0d8fb3 2005-12-27 devnull Ndbtuple *t;
383 3e0d8fb3 2005-12-27 devnull
384 3e0d8fb3 2005-12-27 devnull rp = rralloc(Tns);
385 3e0d8fb3 2005-12-27 devnull rp->host = dnlookup(pair->val, Cin, 1);
386 3e0d8fb3 2005-12-27 devnull t = look(entry, pair, "soa");
387 3e0d8fb3 2005-12-27 devnull if(t && t->val[0] == 0)
388 3e0d8fb3 2005-12-27 devnull rp->local = 1;
389 3e0d8fb3 2005-12-27 devnull return rp;
390 3e0d8fb3 2005-12-27 devnull }
391 3e0d8fb3 2005-12-27 devnull static RR*
392 3e0d8fb3 2005-12-27 devnull ptrrr(Ndbtuple *entry, Ndbtuple *pair)
393 3e0d8fb3 2005-12-27 devnull {
394 3e0d8fb3 2005-12-27 devnull RR *rp;
395 3e0d8fb3 2005-12-27 devnull
396 3e0d8fb3 2005-12-27 devnull USED(entry);
397 3e0d8fb3 2005-12-27 devnull rp = rralloc(Tns);
398 3e0d8fb3 2005-12-27 devnull rp->ptr = dnlookup(pair->val, Cin, 1);
399 3e0d8fb3 2005-12-27 devnull return rp;
400 3e0d8fb3 2005-12-27 devnull }
401 3e0d8fb3 2005-12-27 devnull static RR*
402 3e0d8fb3 2005-12-27 devnull soarr(Ndbtuple *entry, Ndbtuple *pair)
403 3e0d8fb3 2005-12-27 devnull {
404 3e0d8fb3 2005-12-27 devnull RR *rp;
405 3e0d8fb3 2005-12-27 devnull Ndbtuple *ns, *mb, *t;
406 3e0d8fb3 2005-12-27 devnull char mailbox[Domlen];
407 3e0d8fb3 2005-12-27 devnull Ndb *ndb;
408 3e0d8fb3 2005-12-27 devnull char *p;
409 3e0d8fb3 2005-12-27 devnull
410 3e0d8fb3 2005-12-27 devnull rp = rralloc(Tsoa);
411 3e0d8fb3 2005-12-27 devnull rp->soa->serial = 1;
412 3e0d8fb3 2005-12-27 devnull for(ndb = db; ndb; ndb = ndb->next)
413 3e0d8fb3 2005-12-27 devnull if(ndb->mtime > rp->soa->serial)
414 3e0d8fb3 2005-12-27 devnull rp->soa->serial = ndb->mtime;
415 3e0d8fb3 2005-12-27 devnull rp->soa->refresh = Day;
416 3e0d8fb3 2005-12-27 devnull rp->soa->retry = Hour;
417 3e0d8fb3 2005-12-27 devnull rp->soa->expire = Day;
418 3e0d8fb3 2005-12-27 devnull rp->soa->minttl = Day;
419 3e0d8fb3 2005-12-27 devnull t = look(entry, pair, "ttl");
420 3e0d8fb3 2005-12-27 devnull if(t)
421 3e0d8fb3 2005-12-27 devnull rp->soa->minttl = atoi(t->val);
422 3e0d8fb3 2005-12-27 devnull t = look(entry, pair, "refresh");
423 3e0d8fb3 2005-12-27 devnull if(t)
424 3e0d8fb3 2005-12-27 devnull rp->soa->refresh = atoi(t->val);
425 3e0d8fb3 2005-12-27 devnull t = look(entry, pair, "serial");
426 3e0d8fb3 2005-12-27 devnull if(t)
427 3e0d8fb3 2005-12-27 devnull rp->soa->serial = strtoul(t->val, 0, 10);
428 3e0d8fb3 2005-12-27 devnull
429 3e0d8fb3 2005-12-27 devnull ns = look(entry, pair, "ns");
430 3e0d8fb3 2005-12-27 devnull if(ns == 0)
431 3e0d8fb3 2005-12-27 devnull ns = look(entry, pair, "dom");
432 3e0d8fb3 2005-12-27 devnull rp->host = dnlookup(ns->val, Cin, 1);
433 3e0d8fb3 2005-12-27 devnull
434 3e0d8fb3 2005-12-27 devnull /* accept all of:
435 3e0d8fb3 2005-12-27 devnull * mbox=person
436 3e0d8fb3 2005-12-27 devnull * mbox=person@machine.dom
437 3e0d8fb3 2005-12-27 devnull * mbox=person.machine.dom
438 3e0d8fb3 2005-12-27 devnull */
439 3e0d8fb3 2005-12-27 devnull mb = look(entry, pair, "mbox");
440 3e0d8fb3 2005-12-27 devnull if(mb == nil)
441 3e0d8fb3 2005-12-27 devnull mb = look(entry, pair, "mb");
442 3e0d8fb3 2005-12-27 devnull if(mb){
443 3e0d8fb3 2005-12-27 devnull if(strchr(mb->val, '.')) {
444 3e0d8fb3 2005-12-27 devnull p = strchr(mb->val, '@');
445 3e0d8fb3 2005-12-27 devnull if(p != nil)
446 3e0d8fb3 2005-12-27 devnull *p = '.';
447 3e0d8fb3 2005-12-27 devnull rp->rmb = dnlookup(mb->val, Cin, 1);
448 3e0d8fb3 2005-12-27 devnull } else {
449 3e0d8fb3 2005-12-27 devnull snprint(mailbox, sizeof(mailbox), "%s.%s",
450 3e0d8fb3 2005-12-27 devnull mb->val, ns->val);
451 3e0d8fb3 2005-12-27 devnull rp->rmb = dnlookup(mailbox, Cin, 1);
452 3e0d8fb3 2005-12-27 devnull }
453 3e0d8fb3 2005-12-27 devnull } else {
454 3e0d8fb3 2005-12-27 devnull snprint(mailbox, sizeof(mailbox), "postmaster.%s",
455 3e0d8fb3 2005-12-27 devnull ns->val);
456 3e0d8fb3 2005-12-27 devnull rp->rmb = dnlookup(mailbox, Cin, 1);
457 3e0d8fb3 2005-12-27 devnull }
458 3e0d8fb3 2005-12-27 devnull
459 3e0d8fb3 2005-12-27 devnull /* hang dns slaves off of the soa. this is
460 3e0d8fb3 2005-12-27 devnull * for managing the area.
461 3e0d8fb3 2005-12-27 devnull */
462 3e0d8fb3 2005-12-27 devnull for(t = entry; t != nil; t = t->entry)
463 3e0d8fb3 2005-12-27 devnull if(strcmp(t->attr, "dnsslave") == 0)
464 3e0d8fb3 2005-12-27 devnull addserver(&rp->soa->slaves, t->val);
465 3e0d8fb3 2005-12-27 devnull
466 3e0d8fb3 2005-12-27 devnull return rp;
467 3e0d8fb3 2005-12-27 devnull }
468 3e0d8fb3 2005-12-27 devnull
469 3e0d8fb3 2005-12-27 devnull /*
470 3e0d8fb3 2005-12-27 devnull * Look for a pair with the given attribute. look first on the same line,
471 3e0d8fb3 2005-12-27 devnull * then in the whole entry.
472 3e0d8fb3 2005-12-27 devnull */
473 3e0d8fb3 2005-12-27 devnull static Ndbtuple*
474 3e0d8fb3 2005-12-27 devnull look(Ndbtuple *entry, Ndbtuple *line, char *attr)
475 3e0d8fb3 2005-12-27 devnull {
476 3e0d8fb3 2005-12-27 devnull Ndbtuple *nt;
477 3e0d8fb3 2005-12-27 devnull
478 3e0d8fb3 2005-12-27 devnull /* first look on same line (closer binding) */
479 3e0d8fb3 2005-12-27 devnull for(nt = line;;){
480 3e0d8fb3 2005-12-27 devnull if(cistrcmp(attr, nt->attr) == 0)
481 3e0d8fb3 2005-12-27 devnull return nt;
482 3e0d8fb3 2005-12-27 devnull nt = nt->line;
483 3e0d8fb3 2005-12-27 devnull if(nt == line)
484 3e0d8fb3 2005-12-27 devnull break;
485 3e0d8fb3 2005-12-27 devnull }
486 3e0d8fb3 2005-12-27 devnull /* search whole tuple */
487 3e0d8fb3 2005-12-27 devnull for(nt = entry; nt; nt = nt->entry)
488 3e0d8fb3 2005-12-27 devnull if(cistrcmp(attr, nt->attr) == 0)
489 3e0d8fb3 2005-12-27 devnull return nt;
490 3e0d8fb3 2005-12-27 devnull return 0;
491 3e0d8fb3 2005-12-27 devnull }
492 3e0d8fb3 2005-12-27 devnull
493 3e0d8fb3 2005-12-27 devnull static RR**
494 3e0d8fb3 2005-12-27 devnull linkrr(RR *rp, DN *dp, RR **l)
495 3e0d8fb3 2005-12-27 devnull {
496 3e0d8fb3 2005-12-27 devnull rp->owner = dp;
497 3e0d8fb3 2005-12-27 devnull rp->auth = 1;
498 3e0d8fb3 2005-12-27 devnull rp->db = 1;
499 3e0d8fb3 2005-12-27 devnull *l = rp;
500 3e0d8fb3 2005-12-27 devnull return &rp->next;
501 3e0d8fb3 2005-12-27 devnull }
502 3e0d8fb3 2005-12-27 devnull
503 3e0d8fb3 2005-12-27 devnull /* these are answered specially by the tcp version */
504 3e0d8fb3 2005-12-27 devnull static RR*
505 3e0d8fb3 2005-12-27 devnull doaxfr(Ndb *db, char *name)
506 3e0d8fb3 2005-12-27 devnull {
507 3e0d8fb3 2005-12-27 devnull USED(db);
508 3e0d8fb3 2005-12-27 devnull USED(name);
509 3e0d8fb3 2005-12-27 devnull return 0;
510 3e0d8fb3 2005-12-27 devnull }
511 3e0d8fb3 2005-12-27 devnull
512 3e0d8fb3 2005-12-27 devnull
513 3e0d8fb3 2005-12-27 devnull /*
514 3e0d8fb3 2005-12-27 devnull * read the all the soa's from the database to determine area's.
515 3e0d8fb3 2005-12-27 devnull * this is only used when we're not caching the database.
516 3e0d8fb3 2005-12-27 devnull */
517 3e0d8fb3 2005-12-27 devnull static void
518 3e0d8fb3 2005-12-27 devnull dbfile2area(Ndb *db)
519 3e0d8fb3 2005-12-27 devnull {
520 3e0d8fb3 2005-12-27 devnull Ndbtuple *t;
521 3e0d8fb3 2005-12-27 devnull
522 3e0d8fb3 2005-12-27 devnull if(debug)
523 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "rereading %s", db->file);
524 3e0d8fb3 2005-12-27 devnull Bseek(&db->b, 0, 0);
525 3e0d8fb3 2005-12-27 devnull while(t = ndbparse(db)){
526 3e0d8fb3 2005-12-27 devnull ndbfree(t);
527 3e0d8fb3 2005-12-27 devnull }
528 3e0d8fb3 2005-12-27 devnull }
529 3e0d8fb3 2005-12-27 devnull
530 3e0d8fb3 2005-12-27 devnull /*
531 3e0d8fb3 2005-12-27 devnull * read the database into the cache
532 3e0d8fb3 2005-12-27 devnull */
533 3e0d8fb3 2005-12-27 devnull static void
534 3e0d8fb3 2005-12-27 devnull dbpair2cache(DN *dp, Ndbtuple *entry, Ndbtuple *pair)
535 3e0d8fb3 2005-12-27 devnull {
536 3e0d8fb3 2005-12-27 devnull RR *rp;
537 3e0d8fb3 2005-12-27 devnull Ndbtuple *t;
538 3e0d8fb3 2005-12-27 devnull static ulong ord;
539 3e0d8fb3 2005-12-27 devnull
540 3e0d8fb3 2005-12-27 devnull rp = 0;
541 3e0d8fb3 2005-12-27 devnull if(cistrcmp(pair->attr, "ip") == 0){
542 3e0d8fb3 2005-12-27 devnull dp->ordinal = ord++;
543 3e0d8fb3 2005-12-27 devnull rp = addrrr(entry, pair);
544 3e0d8fb3 2005-12-27 devnull } else if(cistrcmp(pair->attr, "ns") == 0){
545 3e0d8fb3 2005-12-27 devnull rp = nsrr(entry, pair);
546 3e0d8fb3 2005-12-27 devnull } else if(cistrcmp(pair->attr, "soa") == 0){
547 3e0d8fb3 2005-12-27 devnull rp = soarr(entry, pair);
548 3e0d8fb3 2005-12-27 devnull addarea(dp, rp, pair);
549 3e0d8fb3 2005-12-27 devnull } else if(cistrcmp(pair->attr, "mx") == 0){
550 3e0d8fb3 2005-12-27 devnull rp = mxrr(entry, pair);
551 3e0d8fb3 2005-12-27 devnull } else if(cistrcmp(pair->attr, "cname") == 0){
552 3e0d8fb3 2005-12-27 devnull rp = cnamerr(entry, pair);
553 3e0d8fb3 2005-12-27 devnull } else if(cistrcmp(pair->attr, "nullrr") == 0){
554 3e0d8fb3 2005-12-27 devnull rp = nullrr(entry, pair);
555 3e0d8fb3 2005-12-27 devnull } else if(cistrcmp(pair->attr, "txtrr") == 0){
556 3e0d8fb3 2005-12-27 devnull rp = txtrr(entry, pair);
557 3e0d8fb3 2005-12-27 devnull }
558 3e0d8fb3 2005-12-27 devnull
559 3e0d8fb3 2005-12-27 devnull if(rp == 0)
560 3e0d8fb3 2005-12-27 devnull return;
561 3e0d8fb3 2005-12-27 devnull
562 3e0d8fb3 2005-12-27 devnull rp->owner = dp;
563 3e0d8fb3 2005-12-27 devnull rp->db = 1;
564 3e0d8fb3 2005-12-27 devnull t = look(entry, pair, "ttl");
565 3e0d8fb3 2005-12-27 devnull if(t)
566 3e0d8fb3 2005-12-27 devnull rp->ttl = atoi(t->val);
567 3e0d8fb3 2005-12-27 devnull rrattach(rp, 0);
568 3e0d8fb3 2005-12-27 devnull }
569 3e0d8fb3 2005-12-27 devnull static void
570 3e0d8fb3 2005-12-27 devnull dbtuple2cache(Ndbtuple *t)
571 3e0d8fb3 2005-12-27 devnull {
572 3e0d8fb3 2005-12-27 devnull Ndbtuple *et, *nt;
573 3e0d8fb3 2005-12-27 devnull DN *dp;
574 3e0d8fb3 2005-12-27 devnull
575 3e0d8fb3 2005-12-27 devnull for(et = t; et; et = et->entry){
576 3e0d8fb3 2005-12-27 devnull if(strcmp(et->attr, "dom") == 0){
577 3e0d8fb3 2005-12-27 devnull dp = dnlookup(et->val, Cin, 1);
578 3e0d8fb3 2005-12-27 devnull
579 3e0d8fb3 2005-12-27 devnull /* first same line */
580 3e0d8fb3 2005-12-27 devnull for(nt = et->line; nt != et; nt = nt->line){
581 3e0d8fb3 2005-12-27 devnull dbpair2cache(dp, t, nt);
582 3e0d8fb3 2005-12-27 devnull nt->ptr = 1;
583 3e0d8fb3 2005-12-27 devnull }
584 3e0d8fb3 2005-12-27 devnull
585 3e0d8fb3 2005-12-27 devnull /* then rest of entry */
586 3e0d8fb3 2005-12-27 devnull for(nt = t; nt; nt = nt->entry){
587 3e0d8fb3 2005-12-27 devnull if(nt->ptr == 0)
588 3e0d8fb3 2005-12-27 devnull dbpair2cache(dp, t, nt);
589 3e0d8fb3 2005-12-27 devnull nt->ptr = 0;
590 3e0d8fb3 2005-12-27 devnull }
591 3e0d8fb3 2005-12-27 devnull }
592 3e0d8fb3 2005-12-27 devnull }
593 3e0d8fb3 2005-12-27 devnull }
594 3e0d8fb3 2005-12-27 devnull static void
595 3e0d8fb3 2005-12-27 devnull dbfile2cache(Ndb *db)
596 3e0d8fb3 2005-12-27 devnull {
597 3e0d8fb3 2005-12-27 devnull Ndbtuple *t;
598 3e0d8fb3 2005-12-27 devnull
599 3e0d8fb3 2005-12-27 devnull if(debug)
600 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "rereading %s", db->file);
601 3e0d8fb3 2005-12-27 devnull Bseek(&db->b, 0, 0);
602 3e0d8fb3 2005-12-27 devnull while(t = ndbparse(db)){
603 3e0d8fb3 2005-12-27 devnull dbtuple2cache(t);
604 3e0d8fb3 2005-12-27 devnull ndbfree(t);
605 3e0d8fb3 2005-12-27 devnull }
606 3e0d8fb3 2005-12-27 devnull }
607 3e0d8fb3 2005-12-27 devnull void
608 3e0d8fb3 2005-12-27 devnull db2cache(int doit)
609 3e0d8fb3 2005-12-27 devnull {
610 3e0d8fb3 2005-12-27 devnull Ndb *ndb;
611 3e0d8fb3 2005-12-27 devnull Dir *d;
612 3e0d8fb3 2005-12-27 devnull ulong youngest, temp;
613 3e0d8fb3 2005-12-27 devnull static ulong lastcheck;
614 3e0d8fb3 2005-12-27 devnull static ulong lastyoungest;
615 3e0d8fb3 2005-12-27 devnull
616 3e0d8fb3 2005-12-27 devnull /* no faster than once every 2 minutes */
617 3e0d8fb3 2005-12-27 devnull if(now < lastcheck + 2*Min && !doit)
618 3e0d8fb3 2005-12-27 devnull return;
619 3e0d8fb3 2005-12-27 devnull
620 3e0d8fb3 2005-12-27 devnull refresh_areas(owned);
621 3e0d8fb3 2005-12-27 devnull
622 3e0d8fb3 2005-12-27 devnull lock(&dblock);
623 3e0d8fb3 2005-12-27 devnull
624 3e0d8fb3 2005-12-27 devnull if(opendatabase() < 0){
625 3e0d8fb3 2005-12-27 devnull unlock(&dblock);
626 3e0d8fb3 2005-12-27 devnull return;
627 3e0d8fb3 2005-12-27 devnull }
628 3e0d8fb3 2005-12-27 devnull
629 3e0d8fb3 2005-12-27 devnull /*
630 3e0d8fb3 2005-12-27 devnull * file may be changing as we are reading it, so loop till
631 3e0d8fb3 2005-12-27 devnull * mod times are consistent.
632 3e0d8fb3 2005-12-27 devnull *
633 3e0d8fb3 2005-12-27 devnull * we don't use the times in the ndb records because they may
634 3e0d8fb3 2005-12-27 devnull * change outside of refreshing our cached knowledge.
635 3e0d8fb3 2005-12-27 devnull */
636 3e0d8fb3 2005-12-27 devnull for(;;){
637 3e0d8fb3 2005-12-27 devnull lastcheck = now;
638 3e0d8fb3 2005-12-27 devnull youngest = 0;
639 3e0d8fb3 2005-12-27 devnull for(ndb = db; ndb; ndb = ndb->next){
640 3e0d8fb3 2005-12-27 devnull /* the dirfstat avoids walking the mount table each time */
641 3e0d8fb3 2005-12-27 devnull if((d = dirfstat(Bfildes(&ndb->b))) != nil ||
642 3e0d8fb3 2005-12-27 devnull (d = dirstat(ndb->file)) != nil){
643 3e0d8fb3 2005-12-27 devnull temp = d->mtime; /* ulong vs int crap */
644 3e0d8fb3 2005-12-27 devnull if(temp > youngest)
645 3e0d8fb3 2005-12-27 devnull youngest = temp;
646 3e0d8fb3 2005-12-27 devnull free(d);
647 3e0d8fb3 2005-12-27 devnull }
648 3e0d8fb3 2005-12-27 devnull }
649 3e0d8fb3 2005-12-27 devnull if(!doit && youngest == lastyoungest){
650 3e0d8fb3 2005-12-27 devnull unlock(&dblock);
651 3e0d8fb3 2005-12-27 devnull return;
652 3e0d8fb3 2005-12-27 devnull }
653 3e0d8fb3 2005-12-27 devnull
654 3e0d8fb3 2005-12-27 devnull /* forget our area definition */
655 3e0d8fb3 2005-12-27 devnull freearea(&owned);
656 3e0d8fb3 2005-12-27 devnull freearea(&delegated);
657 3e0d8fb3 2005-12-27 devnull
658 3e0d8fb3 2005-12-27 devnull /* reopen all the files (to get oldest for time stamp) */
659 3e0d8fb3 2005-12-27 devnull for(ndb = db; ndb; ndb = ndb->next)
660 3e0d8fb3 2005-12-27 devnull ndbreopen(ndb);
661 3e0d8fb3 2005-12-27 devnull
662 3e0d8fb3 2005-12-27 devnull if(cachedb){
663 3e0d8fb3 2005-12-27 devnull /* mark all db records as timed out */
664 3e0d8fb3 2005-12-27 devnull dnagedb();
665 3e0d8fb3 2005-12-27 devnull
666 3e0d8fb3 2005-12-27 devnull /* read in new entries */
667 3e0d8fb3 2005-12-27 devnull for(ndb = db; ndb; ndb = ndb->next)
668 3e0d8fb3 2005-12-27 devnull dbfile2cache(ndb);
669 3e0d8fb3 2005-12-27 devnull
670 3e0d8fb3 2005-12-27 devnull /* mark as authentic anything in our domain */
671 3e0d8fb3 2005-12-27 devnull dnauthdb();
672 3e0d8fb3 2005-12-27 devnull
673 3e0d8fb3 2005-12-27 devnull /* remove old entries */
674 3e0d8fb3 2005-12-27 devnull dnageall(1);
675 3e0d8fb3 2005-12-27 devnull } else {
676 3e0d8fb3 2005-12-27 devnull /* read all the soa's to get database defaults */
677 3e0d8fb3 2005-12-27 devnull for(ndb = db; ndb; ndb = ndb->next)
678 3e0d8fb3 2005-12-27 devnull dbfile2area(ndb);
679 3e0d8fb3 2005-12-27 devnull }
680 3e0d8fb3 2005-12-27 devnull
681 3e0d8fb3 2005-12-27 devnull doit = 0;
682 3e0d8fb3 2005-12-27 devnull lastyoungest = youngest;
683 3e0d8fb3 2005-12-27 devnull createptrs();
684 3e0d8fb3 2005-12-27 devnull }
685 3e0d8fb3 2005-12-27 devnull
686 3e0d8fb3 2005-12-27 devnull unlock(&dblock);
687 3e0d8fb3 2005-12-27 devnull }
688 3e0d8fb3 2005-12-27 devnull
689 3e0d8fb3 2005-12-27 devnull extern uchar ipaddr[IPaddrlen];
690 3e0d8fb3 2005-12-27 devnull
691 3e0d8fb3 2005-12-27 devnull /*
692 3e0d8fb3 2005-12-27 devnull * get all my xxx
693 3e0d8fb3 2005-12-27 devnull */
694 3e0d8fb3 2005-12-27 devnull Ndbtuple*
695 3e0d8fb3 2005-12-27 devnull lookupinfo(char *attr)
696 3e0d8fb3 2005-12-27 devnull {
697 3e0d8fb3 2005-12-27 devnull char buf[64];
698 3e0d8fb3 2005-12-27 devnull char *a[2];
699 3e0d8fb3 2005-12-27 devnull static Ndbtuple *t;
700 3e0d8fb3 2005-12-27 devnull
701 3e0d8fb3 2005-12-27 devnull snprint(buf, sizeof buf, "%I", ipaddr);
702 3e0d8fb3 2005-12-27 devnull a[0] = attr;
703 3e0d8fb3 2005-12-27 devnull
704 3e0d8fb3 2005-12-27 devnull lock(&dblock);
705 3e0d8fb3 2005-12-27 devnull if(opendatabase() < 0){
706 3e0d8fb3 2005-12-27 devnull unlock(&dblock);
707 3e0d8fb3 2005-12-27 devnull return nil;
708 3e0d8fb3 2005-12-27 devnull }
709 3e0d8fb3 2005-12-27 devnull t = ndbipinfo(db, "ip", buf, a, 1);
710 3e0d8fb3 2005-12-27 devnull unlock(&dblock);
711 3e0d8fb3 2005-12-27 devnull return t;
712 3e0d8fb3 2005-12-27 devnull }
713 3e0d8fb3 2005-12-27 devnull
714 3e0d8fb3 2005-12-27 devnull char *localservers = "local#dns#servers";
715 3e0d8fb3 2005-12-27 devnull char *localserverprefix = "local#dns#server";
716 3e0d8fb3 2005-12-27 devnull
717 3e0d8fb3 2005-12-27 devnull /*
718 3e0d8fb3 2005-12-27 devnull * return non-zero is this is a bad delegation
719 3e0d8fb3 2005-12-27 devnull */
720 3e0d8fb3 2005-12-27 devnull int
721 3e0d8fb3 2005-12-27 devnull baddelegation(RR *rp, RR *nsrp, uchar *addr)
722 3e0d8fb3 2005-12-27 devnull {
723 3e0d8fb3 2005-12-27 devnull Ndbtuple *nt;
724 3e0d8fb3 2005-12-27 devnull static Ndbtuple *t;
725 3e0d8fb3 2005-12-27 devnull
726 3e0d8fb3 2005-12-27 devnull if(t == nil)
727 3e0d8fb3 2005-12-27 devnull t = lookupinfo("dom");
728 3e0d8fb3 2005-12-27 devnull if(t == nil)
729 3e0d8fb3 2005-12-27 devnull return 0;
730 3e0d8fb3 2005-12-27 devnull
731 3e0d8fb3 2005-12-27 devnull for(; rp; rp = rp->next){
732 3e0d8fb3 2005-12-27 devnull if(rp->type != Tns)
733 3e0d8fb3 2005-12-27 devnull continue;
734 3e0d8fb3 2005-12-27 devnull
735 3e0d8fb3 2005-12-27 devnull /* see if delegation is looping */
736 3e0d8fb3 2005-12-27 devnull if(nsrp)
737 3e0d8fb3 2005-12-27 devnull if(rp->owner != nsrp->owner)
738 3e0d8fb3 2005-12-27 devnull if(subsume(rp->owner->name, nsrp->owner->name) &&
739 3e0d8fb3 2005-12-27 devnull strcmp(nsrp->owner->name, localservers) != 0){
740 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "delegation loop %R -> %R from %I", nsrp, rp, addr);
741 3e0d8fb3 2005-12-27 devnull return 1;
742 3e0d8fb3 2005-12-27 devnull }
743 3e0d8fb3 2005-12-27 devnull
744 3e0d8fb3 2005-12-27 devnull /* see if delegating to us what we don't own */
745 3e0d8fb3 2005-12-27 devnull for(nt = t; nt != nil; nt = nt->entry)
746 3e0d8fb3 2005-12-27 devnull if(rp->host && cistrcmp(rp->host->name, nt->val) == 0)
747 3e0d8fb3 2005-12-27 devnull break;
748 3e0d8fb3 2005-12-27 devnull if(nt != nil && !inmyarea(rp->owner->name)){
749 3e0d8fb3 2005-12-27 devnull syslog(0, logfile, "bad delegation %R from %I", rp, addr);
750 3e0d8fb3 2005-12-27 devnull return 1;
751 3e0d8fb3 2005-12-27 devnull }
752 3e0d8fb3 2005-12-27 devnull }
753 3e0d8fb3 2005-12-27 devnull
754 3e0d8fb3 2005-12-27 devnull return 0;
755 3e0d8fb3 2005-12-27 devnull }
756 3e0d8fb3 2005-12-27 devnull
757 3e0d8fb3 2005-12-27 devnull static void
758 3e0d8fb3 2005-12-27 devnull addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
759 3e0d8fb3 2005-12-27 devnull {
760 3e0d8fb3 2005-12-27 devnull DN *nsdp;
761 3e0d8fb3 2005-12-27 devnull RR *rp;
762 3e0d8fb3 2005-12-27 devnull char buf[32];
763 3e0d8fb3 2005-12-27 devnull
764 3e0d8fb3 2005-12-27 devnull /* ns record for name server, make up an impossible name */
765 3e0d8fb3 2005-12-27 devnull rp = rralloc(Tns);
766 3e0d8fb3 2005-12-27 devnull snprint(buf, sizeof(buf), "%s%d", localserverprefix, i);
767 3e0d8fb3 2005-12-27 devnull nsdp = dnlookup(buf, class, 1);
768 3e0d8fb3 2005-12-27 devnull rp->host = nsdp;
769 3e0d8fb3 2005-12-27 devnull rp->owner = dp;
770 3e0d8fb3 2005-12-27 devnull rp->local = 1;
771 3e0d8fb3 2005-12-27 devnull rp->db = 1;
772 3e0d8fb3 2005-12-27 devnull rp->ttl = 10*Min;
773 3e0d8fb3 2005-12-27 devnull rrattach(rp, 1);
774 3e0d8fb3 2005-12-27 devnull
775 3e0d8fb3 2005-12-27 devnull print("dns %s\n", ipaddr);
776 3e0d8fb3 2005-12-27 devnull /* A record */
777 3e0d8fb3 2005-12-27 devnull rp = rralloc(Ta);
778 3e0d8fb3 2005-12-27 devnull rp->ip = dnlookup(ipaddr, class, 1);
779 3e0d8fb3 2005-12-27 devnull rp->owner = nsdp;
780 3e0d8fb3 2005-12-27 devnull rp->local = 1;
781 3e0d8fb3 2005-12-27 devnull rp->db = 1;
782 3e0d8fb3 2005-12-27 devnull rp->ttl = 10*Min;
783 3e0d8fb3 2005-12-27 devnull rrattach(rp, 1);
784 3e0d8fb3 2005-12-27 devnull }
785 3e0d8fb3 2005-12-27 devnull
786 3e0d8fb3 2005-12-27 devnull /*
787 3e0d8fb3 2005-12-27 devnull * return list of dns server addresses to use when
788 3e0d8fb3 2005-12-27 devnull * acting just as a resolver.
789 3e0d8fb3 2005-12-27 devnull */
790 3e0d8fb3 2005-12-27 devnull RR*
791 3e0d8fb3 2005-12-27 devnull dnsservers(int class)
792 3e0d8fb3 2005-12-27 devnull {
793 3e0d8fb3 2005-12-27 devnull Ndbtuple *t, *nt;
794 3e0d8fb3 2005-12-27 devnull RR *nsrp;
795 3e0d8fb3 2005-12-27 devnull DN *dp;
796 3e0d8fb3 2005-12-27 devnull char *p;
797 3e0d8fb3 2005-12-27 devnull int i, n;
798 3e0d8fb3 2005-12-27 devnull char *buf, *args[5];
799 3e0d8fb3 2005-12-27 devnull
800 3e0d8fb3 2005-12-27 devnull dp = dnlookup(localservers, class, 1);
801 3e0d8fb3 2005-12-27 devnull nsrp = rrlookup(dp, Tns, NOneg);
802 3e0d8fb3 2005-12-27 devnull if(nsrp != nil)
803 3e0d8fb3 2005-12-27 devnull return nsrp;
804 3e0d8fb3 2005-12-27 devnull
805 3e0d8fb3 2005-12-27 devnull p = getenv("DNSSERVER");
806 3e0d8fb3 2005-12-27 devnull if(p != nil){
807 3e0d8fb3 2005-12-27 devnull buf = estrdup(p);
808 3e0d8fb3 2005-12-27 devnull n = tokenize(buf, args, nelem(args));
809 3e0d8fb3 2005-12-27 devnull for(i = 0; i < n; i++)
810 3e0d8fb3 2005-12-27 devnull addlocaldnsserver(dp, class, args[i], i);
811 3e0d8fb3 2005-12-27 devnull free(buf);
812 3e0d8fb3 2005-12-27 devnull } else {
813 3e0d8fb3 2005-12-27 devnull t = lookupinfo("@dns");
814 3e0d8fb3 2005-12-27 devnull if(t == nil)
815 3e0d8fb3 2005-12-27 devnull return nil;
816 3e0d8fb3 2005-12-27 devnull i = 0;
817 3e0d8fb3 2005-12-27 devnull for(nt = t; nt != nil; nt = nt->entry){
818 3e0d8fb3 2005-12-27 devnull addlocaldnsserver(dp, class, nt->val, i);
819 3e0d8fb3 2005-12-27 devnull i++;
820 3e0d8fb3 2005-12-27 devnull }
821 3e0d8fb3 2005-12-27 devnull ndbfree(t);
822 3e0d8fb3 2005-12-27 devnull }
823 3e0d8fb3 2005-12-27 devnull
824 3e0d8fb3 2005-12-27 devnull return rrlookup(dp, Tns, NOneg);
825 3e0d8fb3 2005-12-27 devnull }
826 3e0d8fb3 2005-12-27 devnull
827 3e0d8fb3 2005-12-27 devnull static void
828 3e0d8fb3 2005-12-27 devnull addlocaldnsdomain(DN *dp, int class, char *domain)
829 3e0d8fb3 2005-12-27 devnull {
830 3e0d8fb3 2005-12-27 devnull RR *rp;
831 3e0d8fb3 2005-12-27 devnull
832 3e0d8fb3 2005-12-27 devnull /* A record */
833 3e0d8fb3 2005-12-27 devnull rp = rralloc(Tptr);
834 3e0d8fb3 2005-12-27 devnull rp->ptr = dnlookup(domain, class, 1);
835 3e0d8fb3 2005-12-27 devnull rp->owner = dp;
836 3e0d8fb3 2005-12-27 devnull rp->db = 1;
837 3e0d8fb3 2005-12-27 devnull rp->ttl = 10*Min;
838 3e0d8fb3 2005-12-27 devnull rrattach(rp, 1);
839 3e0d8fb3 2005-12-27 devnull }
840 3e0d8fb3 2005-12-27 devnull
841 3e0d8fb3 2005-12-27 devnull /*
842 3e0d8fb3 2005-12-27 devnull * return list of domains to use when resolving names without '.'s
843 3e0d8fb3 2005-12-27 devnull */
844 3e0d8fb3 2005-12-27 devnull RR*
845 3e0d8fb3 2005-12-27 devnull domainlist(int class)
846 3e0d8fb3 2005-12-27 devnull {
847 3e0d8fb3 2005-12-27 devnull Ndbtuple *t, *nt;
848 3e0d8fb3 2005-12-27 devnull RR *rp;
849 3e0d8fb3 2005-12-27 devnull DN *dp;
850 3e0d8fb3 2005-12-27 devnull
851 3e0d8fb3 2005-12-27 devnull dp = dnlookup("local#dns#domains", class, 1);
852 3e0d8fb3 2005-12-27 devnull rp = rrlookup(dp, Tptr, NOneg);
853 3e0d8fb3 2005-12-27 devnull if(rp != nil)
854 3e0d8fb3 2005-12-27 devnull return rp;
855 3e0d8fb3 2005-12-27 devnull
856 3e0d8fb3 2005-12-27 devnull t = lookupinfo("dnsdomain");
857 3e0d8fb3 2005-12-27 devnull if(t == nil)
858 3e0d8fb3 2005-12-27 devnull return nil;
859 3e0d8fb3 2005-12-27 devnull for(nt = t; nt != nil; nt = nt->entry)
860 3e0d8fb3 2005-12-27 devnull addlocaldnsdomain(dp, class, nt->val);
861 3e0d8fb3 2005-12-27 devnull ndbfree(t);
862 3e0d8fb3 2005-12-27 devnull
863 3e0d8fb3 2005-12-27 devnull return rrlookup(dp, Tptr, NOneg);
864 3e0d8fb3 2005-12-27 devnull }
865 3e0d8fb3 2005-12-27 devnull
866 3e0d8fb3 2005-12-27 devnull char *v4ptrdom = ".in-addr.arpa";
867 3e0d8fb3 2005-12-27 devnull char *v6ptrdom = ".ip6.arpa"; /* ip6.int deprecated, rfc 3152 */
868 3e0d8fb3 2005-12-27 devnull
869 3e0d8fb3 2005-12-27 devnull char *attribs[] = {
870 3e0d8fb3 2005-12-27 devnull "ipmask",
871 3e0d8fb3 2005-12-27 devnull 0
872 3e0d8fb3 2005-12-27 devnull };
873 3e0d8fb3 2005-12-27 devnull
874 3e0d8fb3 2005-12-27 devnull /*
875 3e0d8fb3 2005-12-27 devnull * create ptrs that are in our areas
876 3e0d8fb3 2005-12-27 devnull */
877 3e0d8fb3 2005-12-27 devnull static void
878 3e0d8fb3 2005-12-27 devnull createptrs(void)
879 3e0d8fb3 2005-12-27 devnull {
880 3e0d8fb3 2005-12-27 devnull int len, dlen, n;
881 3e0d8fb3 2005-12-27 devnull Area *s;
882 3e0d8fb3 2005-12-27 devnull char *f[40];
883 3e0d8fb3 2005-12-27 devnull char buf[Domlen+1];
884 3e0d8fb3 2005-12-27 devnull uchar net[IPaddrlen];
885 3e0d8fb3 2005-12-27 devnull uchar mask[IPaddrlen];
886 3e0d8fb3 2005-12-27 devnull char ipa[48];
887 3e0d8fb3 2005-12-27 devnull Ndbtuple *t, *nt;
888 3e0d8fb3 2005-12-27 devnull
889 3e0d8fb3 2005-12-27 devnull dlen = strlen(v4ptrdom);
890 3e0d8fb3 2005-12-27 devnull for(s = owned; s; s = s->next){
891 3e0d8fb3 2005-12-27 devnull len = strlen(s->soarr->owner->name);
892 3e0d8fb3 2005-12-27 devnull if(len <= dlen)
893 3e0d8fb3 2005-12-27 devnull continue;
894 3e0d8fb3 2005-12-27 devnull if(cistrcmp(s->soarr->owner->name+len-dlen, v4ptrdom) != 0)
895 3e0d8fb3 2005-12-27 devnull continue;
896 3e0d8fb3 2005-12-27 devnull
897 3e0d8fb3 2005-12-27 devnull /* get mask and net value */
898 3e0d8fb3 2005-12-27 devnull strncpy(buf, s->soarr->owner->name, sizeof(buf));
899 3e0d8fb3 2005-12-27 devnull buf[sizeof(buf)-1] = 0;
900 3e0d8fb3 2005-12-27 devnull n = getfields(buf, f, nelem(f), 0, ".");
901 3e0d8fb3 2005-12-27 devnull memset(mask, 0xff, IPaddrlen);
902 3e0d8fb3 2005-12-27 devnull ipmove(net, v4prefix);
903 3e0d8fb3 2005-12-27 devnull switch(n){
904 3e0d8fb3 2005-12-27 devnull case 3: /* /8 */
905 3e0d8fb3 2005-12-27 devnull net[IPv4off] = atoi(f[0]);
906 3e0d8fb3 2005-12-27 devnull mask[IPv4off+1] = 0;
907 3e0d8fb3 2005-12-27 devnull mask[IPv4off+2] = 0;
908 3e0d8fb3 2005-12-27 devnull mask[IPv4off+3] = 0;
909 3e0d8fb3 2005-12-27 devnull break;
910 3e0d8fb3 2005-12-27 devnull case 4: /* /16 */
911 3e0d8fb3 2005-12-27 devnull net[IPv4off] = atoi(f[1]);
912 3e0d8fb3 2005-12-27 devnull net[IPv4off+1] = atoi(f[0]);
913 3e0d8fb3 2005-12-27 devnull mask[IPv4off+2] = 0;
914 3e0d8fb3 2005-12-27 devnull mask[IPv4off+3] = 0;
915 3e0d8fb3 2005-12-27 devnull break;
916 3e0d8fb3 2005-12-27 devnull case 5: /* /24 */
917 3e0d8fb3 2005-12-27 devnull net[IPv4off] = atoi(f[2]);
918 3e0d8fb3 2005-12-27 devnull net[IPv4off+1] = atoi(f[1]);
919 3e0d8fb3 2005-12-27 devnull net[IPv4off+2] = atoi(f[0]);
920 3e0d8fb3 2005-12-27 devnull mask[IPv4off+3] = 0;
921 3e0d8fb3 2005-12-27 devnull break;
922 3e0d8fb3 2005-12-27 devnull case 6: /* rfc2317 */
923 3e0d8fb3 2005-12-27 devnull net[IPv4off] = atoi(f[3]);
924 3e0d8fb3 2005-12-27 devnull net[IPv4off+1] = atoi(f[2]);
925 3e0d8fb3 2005-12-27 devnull net[IPv4off+2] = atoi(f[1]);
926 3e0d8fb3 2005-12-27 devnull net[IPv4off+3] = atoi(f[0]);
927 3e0d8fb3 2005-12-27 devnull sprint(ipa, "%I", net);
928 3e0d8fb3 2005-12-27 devnull t = ndbipinfo(db, "ip", ipa, attribs, 1);
929 3e0d8fb3 2005-12-27 devnull if(t == nil) /* could be a reverse with no forward */
930 3e0d8fb3 2005-12-27 devnull continue;
931 3e0d8fb3 2005-12-27 devnull nt = look(t, t, "ipmask");
932 3e0d8fb3 2005-12-27 devnull if(nt == nil){ /* we're confused */
933 3e0d8fb3 2005-12-27 devnull ndbfree(t);
934 3e0d8fb3 2005-12-27 devnull continue;
935 3e0d8fb3 2005-12-27 devnull }
936 3e0d8fb3 2005-12-27 devnull parseipmask(mask, nt->val);
937 3e0d8fb3 2005-12-27 devnull n = 5;
938 3e0d8fb3 2005-12-27 devnull break;
939 3e0d8fb3 2005-12-27 devnull default:
940 3e0d8fb3 2005-12-27 devnull continue;
941 3e0d8fb3 2005-12-27 devnull }
942 3e0d8fb3 2005-12-27 devnull
943 3e0d8fb3 2005-12-27 devnull /* go through all domain entries looking for RR's in this network and create ptrs */
944 3e0d8fb3 2005-12-27 devnull dnptr(net, mask, s->soarr->owner->name, 6-n, 0);
945 3e0d8fb3 2005-12-27 devnull }
946 3e0d8fb3 2005-12-27 devnull }