Blame


1 be7ae884 2010-05-26 pbug /*
2 48603f7d 2014-04-13 pjp * Copyright (c) 2010-2014 Peter J. Philipp
3 b6dc64dc 2010-04-15 pbug * All rights reserved.
4 b6dc64dc 2010-04-15 pbug *
5 b6dc64dc 2010-04-15 pbug * Redistribution and use in source and binary forms, with or without
6 b6dc64dc 2010-04-15 pbug * modification, are permitted provided that the following conditions
7 b6dc64dc 2010-04-15 pbug * are met:
8 b6dc64dc 2010-04-15 pbug * 1. Redistributions of source code must retain the above copyright
9 b6dc64dc 2010-04-15 pbug * notice, this list of conditions and the following disclaimer.
10 b6dc64dc 2010-04-15 pbug * 2. Redistributions in binary form must reproduce the above copyright
11 b6dc64dc 2010-04-15 pbug * notice, this list of conditions and the following disclaimer in the
12 b6dc64dc 2010-04-15 pbug * documentation and/or other materials provided with the distribution.
13 b6dc64dc 2010-04-15 pbug * 3. The name of the author may not be used to endorse or promote products
14 b6dc64dc 2010-04-15 pbug * derived from this software without specific prior written permission
15 b6dc64dc 2010-04-15 pbug *
16 b6dc64dc 2010-04-15 pbug * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 b6dc64dc 2010-04-15 pbug * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 b6dc64dc 2010-04-15 pbug * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 b6dc64dc 2010-04-15 pbug * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 b6dc64dc 2010-04-15 pbug * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 b6dc64dc 2010-04-15 pbug * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 b6dc64dc 2010-04-15 pbug * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 b6dc64dc 2010-04-15 pbug * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 b6dc64dc 2010-04-15 pbug * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 b6dc64dc 2010-04-15 pbug * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 b6dc64dc 2010-04-15 pbug *
27 b6dc64dc 2010-04-15 pbug */
28 b6dc64dc 2010-04-15 pbug #include "include.h"
29 b6dc64dc 2010-04-15 pbug #include "dns.h"
30 b6dc64dc 2010-04-15 pbug #include "db.h"
31 b6dc64dc 2010-04-15 pbug
32 0e7d94ac 2014-05-18 pjp extern struct question *build_fake_question(char *, int, u_int16_t);
33 0e7d94ac 2014-05-18 pjp extern struct question *build_question(char *, int);
34 0e7d94ac 2014-05-18 pjp extern void build_reply(struct sreply *, int, char *, int, struct question *, struct sockaddr *, socklen_t, struct domain *, struct domain *, u_int8_t, int, int, struct recurses *);
35 0e7d94ac 2014-05-18 pjp extern void dolog(int, char *, ...);
36 0e7d94ac 2014-05-18 pjp extern int free_question(struct question *);
37 0e7d94ac 2014-05-18 pjp extern int get_soa(DB *, struct question *, struct domain *, int);
38 0e7d94ac 2014-05-18 pjp extern in_addr_t getmask(int);
39 0e7d94ac 2014-05-18 pjp extern int getmask6(int, struct sockaddr_in6 *);
40 0e7d94ac 2014-05-18 pjp extern int lookup_zone(DB *, struct question *, struct domain *, int *, char *, int);
41 0e7d94ac 2014-05-18 pjp extern int memcasecmp(u_char *, u_char *, int);
42 0e7d94ac 2014-05-18 pjp extern void reply_a(struct sreply *, DB *);
43 0e7d94ac 2014-05-18 pjp extern void reply_aaaa(struct sreply *, DB *);
44 0e7d94ac 2014-05-18 pjp extern void reply_cname(struct sreply *);
45 0e7d94ac 2014-05-18 pjp extern void reply_mx(struct sreply *, DB *);
46 0e7d94ac 2014-05-18 pjp extern void reply_ns(struct sreply *, DB *);
47 0e7d94ac 2014-05-18 pjp extern void reply_noerror(struct sreply *);
48 0e7d94ac 2014-05-18 pjp extern void reply_nxdomain(struct sreply *);
49 0e7d94ac 2014-05-18 pjp extern void reply_ptr(struct sreply *);
50 0e7d94ac 2014-05-18 pjp extern void reply_soa(struct sreply *);
51 0e7d94ac 2014-05-18 pjp extern void reply_txt(struct sreply *sreply);
52 0e7d94ac 2014-05-18 pjp extern void slave_shutdown(void);
53 0e7d94ac 2014-05-18 pjp extern void update_db(DB *, struct domain *);
54 5079e583 2010-11-06 pbug
55 0e7d94ac 2014-05-18 pjp int contains(u_char *, u_char *);
56 0e7d94ac 2014-05-18 pjp void init_recurse(void);
57 0e7d94ac 2014-05-18 pjp int insert_recurse(char *, char *);
58 0e7d94ac 2014-05-18 pjp int fakerecurse(DB *, struct recurses *, struct ns *, int);
59 0e7d94ac 2014-05-18 pjp int find_recurse(struct sockaddr_storage *, int);
60 0e7d94ac 2014-05-18 pjp int level(u_char *);
61 0e7d94ac 2014-05-18 pjp int lookup_a(DB *, struct recurses *, struct ns *);
62 0e7d94ac 2014-05-18 pjp int lookup_aaaa(DB *, struct recurses *, struct ns *);
63 0e7d94ac 2014-05-18 pjp int lookup_ns(DB *, struct recurses *);
64 0e7d94ac 2014-05-18 pjp int negative_cache(DB *, struct recurses *);
65 0e7d94ac 2014-05-18 pjp int netlookup(DB *, struct recurses *);
66 0e7d94ac 2014-05-18 pjp int netlookup6(DB *, struct recurses *);
67 0e7d94ac 2014-05-18 pjp void recurseloop(int, int *, DB *);
68 0e7d94ac 2014-05-18 pjp int recurse_parse(DB *, struct recurses *, u_char *, u_int16_t);
69 0e7d94ac 2014-05-18 pjp void reply_raw(DB *, struct recurses *, struct domain *, int *);
70 0e7d94ac 2014-05-18 pjp void reply_raw_cname(DB *, struct recurses *, struct domain *, int *);
71 0e7d94ac 2014-05-18 pjp void reply_raw_noerror(DB *, struct recurses *, struct domain *, int *);
72 0e7d94ac 2014-05-18 pjp void reply_raw_nxdomain(DB *, struct recurses *, struct domain *, int *);
73 0e7d94ac 2014-05-18 pjp void remove_zone(DB *, struct domain *);
74 b6dc64dc 2010-04-15 pbug
75 dd869383 2013-02-16 pjp extern int debug, verbose;
76 dd869383 2013-02-16 pjp
77 f1e825ef 2010-09-28 pbug #ifndef MIN
78 f1e825ef 2010-09-28 pbug #define MIN(a,b) ((a < b) ? a : b)
79 f1e825ef 2010-09-28 pbug #endif
80 f1e825ef 2010-09-28 pbug
81 b6dc64dc 2010-04-15 pbug SLIST_HEAD(listhead, recurseentry) recursehead;
82 b6dc64dc 2010-04-15 pbug
83 c0963faf 2014-05-01 pjp static struct recurseentry {
84 b6dc64dc 2010-04-15 pbug char name[INET6_ADDRSTRLEN];
85 b6dc64dc 2010-04-15 pbug int family;
86 b6dc64dc 2010-04-15 pbug struct sockaddr_storage hostmask;
87 b6dc64dc 2010-04-15 pbug struct sockaddr_storage netmask;
88 b6dc64dc 2010-04-15 pbug u_int8_t prefixlen;
89 c0963faf 2014-05-01 pjp SLIST_ENTRY(recurseentry) recurse_entry;
90 c0963faf 2014-05-01 pjp } *rn2, *rnp;
91 b6dc64dc 2010-04-15 pbug
92 b6dc64dc 2010-04-15 pbug
93 fedd844f 2014-09-27 pjp static const char rcsid[] = "$Id: recurse.c,v 1.45 2014/09/27 17:38:28 pjp Exp $";
94 be7ae884 2010-05-26 pbug
95 b6dc64dc 2010-04-15 pbug /*
96 b6dc64dc 2010-04-15 pbug * INIT_RECURSE - initialize the recurse singly linked list
97 b6dc64dc 2010-04-15 pbug */
98 b6dc64dc 2010-04-15 pbug
99 b6dc64dc 2010-04-15 pbug void
100 b6dc64dc 2010-04-15 pbug init_recurse(void)
101 b6dc64dc 2010-04-15 pbug {
102 b6dc64dc 2010-04-15 pbug SLIST_INIT(&recursehead);
103 b6dc64dc 2010-04-15 pbug return;
104 b6dc64dc 2010-04-15 pbug }
105 b6dc64dc 2010-04-15 pbug
106 b6dc64dc 2010-04-15 pbug /*
107 b6dc64dc 2010-04-15 pbug * INSERT_RECURSE - insert an address and prefixlen into the recurse slist
108 b6dc64dc 2010-04-15 pbug */
109 b6dc64dc 2010-04-15 pbug
110 b6dc64dc 2010-04-15 pbug int
111 b6dc64dc 2010-04-15 pbug insert_recurse(char *address, char *prefixlen)
112 b6dc64dc 2010-04-15 pbug {
113 b6dc64dc 2010-04-15 pbug struct sockaddr_in *sin;
114 b6dc64dc 2010-04-15 pbug struct sockaddr_in6 *sin6;
115 b6dc64dc 2010-04-15 pbug int pnum;
116 b6dc64dc 2010-04-15 pbug int ret;
117 b6dc64dc 2010-04-15 pbug
118 b6dc64dc 2010-04-15 pbug pnum = atoi(prefixlen);
119 b6dc64dc 2010-04-15 pbug rn2 = malloc(sizeof(struct recurseentry)); /* Insert after. */
120 b6dc64dc 2010-04-15 pbug
121 b6dc64dc 2010-04-15 pbug if (strchr(address, ':') != NULL) {
122 b6dc64dc 2010-04-15 pbug rn2->family = AF_INET6;
123 b6dc64dc 2010-04-15 pbug sin6 = (struct sockaddr_in6 *)&rn2->hostmask;
124 b6dc64dc 2010-04-15 pbug if ((ret = inet_pton(AF_INET6, address, &sin6->sin6_addr.s6_addr)) != 1)
125 b6dc64dc 2010-04-15 pbug return (-1);
126 b6dc64dc 2010-04-15 pbug sin6->sin6_family = AF_INET6;
127 b6dc64dc 2010-04-15 pbug sin6 = (struct sockaddr_in6 *)&rn2->netmask;
128 b6dc64dc 2010-04-15 pbug sin6->sin6_family = AF_INET6;
129 b6dc64dc 2010-04-15 pbug if (getmask6(pnum, sin6) < 0)
130 b6dc64dc 2010-04-15 pbug return(-1);
131 b6dc64dc 2010-04-15 pbug rn2->prefixlen = pnum;
132 b6dc64dc 2010-04-15 pbug } else {
133 b6dc64dc 2010-04-15 pbug
134 b6dc64dc 2010-04-15 pbug rn2->family = AF_INET;
135 b6dc64dc 2010-04-15 pbug sin = (struct sockaddr_in *)&rn2->hostmask;
136 b6dc64dc 2010-04-15 pbug sin->sin_family = AF_INET;
137 b6dc64dc 2010-04-15 pbug sin->sin_addr.s_addr = inet_addr(address);
138 b6dc64dc 2010-04-15 pbug sin = (struct sockaddr_in *)&rn2->netmask;
139 b6dc64dc 2010-04-15 pbug sin->sin_family = AF_INET;
140 b6dc64dc 2010-04-15 pbug sin->sin_addr.s_addr = getmask(pnum);
141 b6dc64dc 2010-04-15 pbug rn2->prefixlen = pnum;
142 b6dc64dc 2010-04-15 pbug
143 b6dc64dc 2010-04-15 pbug }
144 b6dc64dc 2010-04-15 pbug
145 c0963faf 2014-05-01 pjp SLIST_INSERT_HEAD(&recursehead, rn2, recurse_entry);
146 b6dc64dc 2010-04-15 pbug
147 b6dc64dc 2010-04-15 pbug return (0);
148 b6dc64dc 2010-04-15 pbug }
149 b6dc64dc 2010-04-15 pbug
150 b6dc64dc 2010-04-15 pbug /*
151 b6dc64dc 2010-04-15 pbug * FIND_RECURSE - walk the recurse list and find the correponding network
152 b6dc64dc 2010-04-15 pbug * if a network matches return 1, if no match is found return
153 b6dc64dc 2010-04-15 pbug * 0.
154 b6dc64dc 2010-04-15 pbug */
155 b6dc64dc 2010-04-15 pbug
156 b6dc64dc 2010-04-15 pbug int
157 b6dc64dc 2010-04-15 pbug find_recurse(struct sockaddr_storage *sst, int family)
158 b6dc64dc 2010-04-15 pbug {
159 b6dc64dc 2010-04-15 pbug struct sockaddr_in *sin, *sin0;
160 b6dc64dc 2010-04-15 pbug struct sockaddr_in6 *sin6, *sin60, *sin61;
161 b6dc64dc 2010-04-15 pbug u_int32_t hostmask, netmask;
162 b6dc64dc 2010-04-15 pbug u_int32_t a;
163 b6dc64dc 2010-04-15 pbug #ifdef __amd64
164 b6dc64dc 2010-04-15 pbug u_int64_t *hm[2], *nm[2], *a6[2];
165 b6dc64dc 2010-04-15 pbug #else
166 b6dc64dc 2010-04-15 pbug u_int32_t *hm[4], *nm[4], *a6[4];
167 b6dc64dc 2010-04-15 pbug #endif
168 b6dc64dc 2010-04-15 pbug
169 c0963faf 2014-05-01 pjp SLIST_FOREACH(rnp, &recursehead, recurse_entry) {
170 b6dc64dc 2010-04-15 pbug if (rnp->family == AF_INET) {
171 b6dc64dc 2010-04-15 pbug if (family != AF_INET)
172 b6dc64dc 2010-04-15 pbug continue;
173 b6dc64dc 2010-04-15 pbug sin = (struct sockaddr_in *)sst;
174 b6dc64dc 2010-04-15 pbug a = sin->sin_addr.s_addr;
175 b6dc64dc 2010-04-15 pbug sin = (struct sockaddr_in *)&rnp->hostmask;
176 b6dc64dc 2010-04-15 pbug sin0 = (struct sockaddr_in *)&rnp->netmask;
177 b6dc64dc 2010-04-15 pbug hostmask = sin->sin_addr.s_addr;
178 b6dc64dc 2010-04-15 pbug netmask = sin0->sin_addr.s_addr;
179 b6dc64dc 2010-04-15 pbug if ((hostmask & netmask) == (a & netmask)) {
180 b6dc64dc 2010-04-15 pbug return (1);
181 b6dc64dc 2010-04-15 pbug } /* if hostmask */
182 b6dc64dc 2010-04-15 pbug } else if (rnp->family == AF_INET6) {
183 b6dc64dc 2010-04-15 pbug if (family != AF_INET6)
184 b6dc64dc 2010-04-15 pbug continue;
185 b6dc64dc 2010-04-15 pbug sin6 = (struct sockaddr_in6 *)sst;
186 b6dc64dc 2010-04-15 pbug sin60 = (struct sockaddr_in6 *)&rnp->hostmask;
187 b6dc64dc 2010-04-15 pbug sin61 = (struct sockaddr_in6 *)&rnp->netmask;
188 b6dc64dc 2010-04-15 pbug #ifdef __amd64
189 b6dc64dc 2010-04-15 pbug /*
190 b6dc64dc 2010-04-15 pbug * If this is on a 64 bit machine, we'll benefit
191 b6dc64dc 2010-04-15 pbug * by using 64 bit registers, this should make it
192 b6dc64dc 2010-04-15 pbug * a tad faster...
193 b6dc64dc 2010-04-15 pbug */
194 b6dc64dc 2010-04-15 pbug hm[0] = (u_int64_t *)&sin60->sin6_addr.s6_addr;
195 b6dc64dc 2010-04-15 pbug hm[1] = (hm[0] + 1);
196 b6dc64dc 2010-04-15 pbug nm[0] = (u_int64_t *)&sin61->sin6_addr.s6_addr;
197 b6dc64dc 2010-04-15 pbug nm[1] = (nm[0] + 1);
198 b6dc64dc 2010-04-15 pbug a6[0] = (u_int64_t *)&sin6->sin6_addr.s6_addr;
199 b6dc64dc 2010-04-15 pbug a6[1] = (a6[0] + 1);
200 b6dc64dc 2010-04-15 pbug if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
201 b6dc64dc 2010-04-15 pbug ((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))) {
202 b6dc64dc 2010-04-15 pbug #else
203 b6dc64dc 2010-04-15 pbug hm[0] = (u_int32_t *)&sin60->sin6_addr.s6_addr;
204 b6dc64dc 2010-04-15 pbug hm[1] = (hm[0] + 1); hm[2] = (hm[1] + 1);
205 b6dc64dc 2010-04-15 pbug hm[3] = (hm[2] + 1);
206 b6dc64dc 2010-04-15 pbug nm[0] = (u_int32_t *)&sin61->sin6_addr.s6_addr;
207 b6dc64dc 2010-04-15 pbug nm[1] = (nm[0] + 1); nm[2] = (nm[1] + 1);
208 b6dc64dc 2010-04-15 pbug nm[3] = (nm[2] + 1);
209 b6dc64dc 2010-04-15 pbug a6[0] = (u_int32_t *)&sin6->sin6_addr.s6_addr;
210 b6dc64dc 2010-04-15 pbug a6[1] = (a6[0] + 1); a6[2] = (a6[1] + 1);
211 b6dc64dc 2010-04-15 pbug a6[3] = (a6[2] + 1);
212 b6dc64dc 2010-04-15 pbug
213 b6dc64dc 2010-04-15 pbug if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
214 b6dc64dc 2010-04-15 pbug ((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))&&
215 b6dc64dc 2010-04-15 pbug ((*hm[2] & *nm[2]) == (*a6[2] & *nm[2]))&&
216 b6dc64dc 2010-04-15 pbug ((*hm[3] & *nm[3]) == (*a6[3] & *nm[3]))) {
217 b6dc64dc 2010-04-15 pbug #endif
218 b6dc64dc 2010-04-15 pbug
219 b6dc64dc 2010-04-15 pbug return (1);
220 b6dc64dc 2010-04-15 pbug } /* if ip6 address */
221 b6dc64dc 2010-04-15 pbug
222 b6dc64dc 2010-04-15 pbug } /* if AF_INET6 */
223 b6dc64dc 2010-04-15 pbug } /* SLIST */
224 b6dc64dc 2010-04-15 pbug
225 b6dc64dc 2010-04-15 pbug return (0);
226 b6dc64dc 2010-04-15 pbug }
227 b6dc64dc 2010-04-15 pbug
228 b6dc64dc 2010-04-15 pbug void
229 b6dc64dc 2010-04-15 pbug recurseloop(int sp, int *raw, DB *db)
230 b6dc64dc 2010-04-15 pbug {
231 b6dc64dc 2010-04-15 pbug int sel, ret;
232 cfbdfdca 2010-09-24 pbug int maxso, len;
233 00c89913 2010-10-11 pbug socklen_t slen = sizeof(struct sockaddr_storage);
234 b6dc64dc 2010-04-15 pbug fd_set rset;
235 b6dc64dc 2010-04-15 pbug struct timeval tv;
236 b6dc64dc 2010-04-15 pbug struct srecurseheader rh;
237 aded9c80 2010-09-15 pbug struct domain sd;
238 aded9c80 2010-09-15 pbug struct dns_header *dh;
239 00c89913 2010-10-11 pbug struct sockaddr_storage ssin;
240 00c89913 2010-10-11 pbug struct sockaddr_in *sin;
241 00c89913 2010-10-11 pbug struct sockaddr_in6 *sin6;
242 b6dc64dc 2010-04-15 pbug
243 aded9c80 2010-09-15 pbug int type, lzerrno, wildcard = 0;
244 aded9c80 2010-09-15 pbug
245 aded9c80 2010-09-15 pbug char fakereplystring[DNS_MAXNAME + 1];
246 604e0a34 2010-09-15 pbug char buf[2048];
247 4d7c9557 2010-11-09 pbug char address[INET6_ADDRSTRLEN];
248 b6dc64dc 2010-04-15 pbug
249 be7ae884 2010-05-26 pbug SLIST_INIT(&recurseshead);
250 be7ae884 2010-05-26 pbug
251 b6dc64dc 2010-04-15 pbug for (;;) {
252 5528a18e 2010-09-21 pbug /*
253 5528a18e 2010-09-21 pbug * launch all fakesr requests
254 5528a18e 2010-09-21 pbug */
255 c0963faf 2014-05-01 pjp SLIST_FOREACH(sr1, &recurseshead, recurses_entry) {
256 5528a18e 2010-09-21 pbug if (sr1->isfake && !sr1->launched) {
257 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "launching question (fakesr) for %s", sr1->question->hdr->name);
258 5528a18e 2010-09-21 pbug sr1->launched = 1;
259 5528a18e 2010-09-21 pbug type = lookup_zone(db, sr1->question, &sd, &lzerrno, (char *)fakereplystring, wildcard);
260 5528a18e 2010-09-21 pbug if (type < 0) {
261 cfbdfdca 2010-09-24 pbug netlookup(db, sr1);
262 5528a18e 2010-09-21 pbug } else {
263 c0963faf 2014-05-01 pjp SLIST_REMOVE(&recurseshead, sr1, recurses, recurses_entry);
264 5528a18e 2010-09-21 pbug sr1->callback->hascallback--;
265 5528a18e 2010-09-21 pbug free_question(sr1->question);
266 5528a18e 2010-09-21 pbug free(sr1);
267 5528a18e 2010-09-21 pbug }
268 5528a18e 2010-09-21 pbug }
269 3553d5f3 2010-09-26 pbug
270 3553d5f3 2010-09-26 pbug /*
271 3553d5f3 2010-09-26 pbug * while we're going through the list to look for
272 3553d5f3 2010-09-26 pbug * fakesr launches we may as well expire recurses
273 3553d5f3 2010-09-26 pbug * that have timed out (> 10 seconds)
274 3553d5f3 2010-09-26 pbug */
275 f1e825ef 2010-09-28 pbug if (difftime(time(NULL), sr1->received) >= 30) {
276 08769151 2010-10-03 pbug /* only remove if we don't have any callbacks
277 08769151 2010-10-03 pbug * outstanding...
278 08769151 2010-10-03 pbug */
279 08769151 2010-10-03 pbug if (! sr1->hascallback) {
280 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "removing recurses struct");
281 c0963faf 2014-05-01 pjp SLIST_REMOVE(&recurseshead, sr1, recurses, recurses_entry);
282 08769151 2010-10-03 pbug if (sr1->so != -1) {
283 08769151 2010-10-03 pbug if (close(sr1->so) < 0)
284 dd869383 2013-02-16 pjp dolog(LOG_ERR, "close: %m");
285 08769151 2010-10-03 pbug sr1->so = -1;
286 08769151 2010-10-03 pbug }
287 08769151 2010-10-03 pbug
288 08769151 2010-10-03 pbug if (sr1->callback)
289 08769151 2010-10-03 pbug sr1->callback->hascallback--;
290 3553d5f3 2010-09-26 pbug
291 08769151 2010-10-03 pbug free_question(sr1->question);
292 08769151 2010-10-03 pbug free(sr1);
293 08769151 2010-10-03 pbug }
294 3553d5f3 2010-09-26 pbug }
295 5528a18e 2010-09-21 pbug }
296 b6dc64dc 2010-04-15 pbug FD_ZERO(&rset);
297 b6dc64dc 2010-04-15 pbug
298 604e0a34 2010-09-15 pbug maxso = sp;
299 b6dc64dc 2010-04-15 pbug FD_SET(sp, &rset);
300 b6dc64dc 2010-04-15 pbug
301 604e0a34 2010-09-15 pbug /* XXX remember recurseshead is for struct recurses */
302 c0963faf 2014-05-01 pjp SLIST_FOREACH(sr1, &recurseshead, recurses_entry) {
303 22893736 2010-09-19 pbug if (sr1->so != -1) {
304 22893736 2010-09-19 pbug if (maxso < sr1->so)
305 22893736 2010-09-19 pbug maxso = sr1->so;
306 604e0a34 2010-09-15 pbug
307 22893736 2010-09-19 pbug FD_SET(sr1->so, &rset);
308 22893736 2010-09-19 pbug }
309 604e0a34 2010-09-15 pbug }
310 604e0a34 2010-09-15 pbug
311 b6dc64dc 2010-04-15 pbug tv.tv_sec = 1;
312 b6dc64dc 2010-04-15 pbug tv.tv_usec = 0;
313 604e0a34 2010-09-15 pbug sel = select(maxso + 1, &rset, NULL, NULL, &tv);
314 b6dc64dc 2010-04-15 pbug if (sel < 0) {
315 dd869383 2013-02-16 pjp dolog(LOG_INFO, "select: %m");
316 b6dc64dc 2010-04-15 pbug continue;
317 b6dc64dc 2010-04-15 pbug } else if (sel == 0) {
318 b6dc64dc 2010-04-15 pbug /* timeout */
319 b6dc64dc 2010-04-15 pbug continue;
320 b6dc64dc 2010-04-15 pbug }
321 b6dc64dc 2010-04-15 pbug
322 b6dc64dc 2010-04-15 pbug if (FD_ISSET(sp, &rset)) {
323 b6dc64dc 2010-04-15 pbug ret = recv(sp, (char *)&rh, sizeof(rh), 0);
324 b6dc64dc 2010-04-15 pbug if (ret < 0) {
325 dd869383 2013-02-16 pjp dolog(LOG_INFO, "recv: %m");
326 aded9c80 2010-09-15 pbug continue;
327 aded9c80 2010-09-15 pbug }
328 aded9c80 2010-09-15 pbug
329 aded9c80 2010-09-15 pbug /* place request on struct recurses linked list */
330 aded9c80 2010-09-15 pbug
331 aded9c80 2010-09-15 pbug sr = calloc(sizeof(struct recurses), 1);
332 aded9c80 2010-09-15 pbug if (sr == NULL) {
333 dd869383 2013-02-16 pjp dolog(LOG_ERR, "calloc: %m");
334 b6dc64dc 2010-04-15 pbug continue;
335 aded9c80 2010-09-15 pbug }
336 aded9c80 2010-09-15 pbug
337 aded9c80 2010-09-15 pbug memcpy(&sr->query, &rh.buf, 512);
338 aded9c80 2010-09-15 pbug sr->len = rh.len;
339 aded9c80 2010-09-15 pbug sr->af = rh.af;
340 aded9c80 2010-09-15 pbug sr->proto = rh.proto;
341 604e0a34 2010-09-15 pbug sr->so = -1;
342 c8a9dee0 2010-09-18 pbug sr->callback = NULL;
343 22893736 2010-09-19 pbug sr->hascallback = 0;
344 c8a9dee0 2010-09-18 pbug sr->isfake = 0;
345 437140e3 2010-09-25 pbug sr->packetcount = 0;
346 f1e825ef 2010-09-28 pbug sr->lookrecord = NULL;
347 aded9c80 2010-09-15 pbug memcpy(&sr->source, &rh.source, sizeof(struct sockaddr_storage));
348 aded9c80 2010-09-15 pbug memcpy(&sr->dest, &rh.dest, sizeof(struct sockaddr_storage));
349 aded9c80 2010-09-15 pbug sr->received = time(NULL);
350 aded9c80 2010-09-15 pbug
351 aded9c80 2010-09-15 pbug sr->question = build_question(sr->query, sr->len);
352 aded9c80 2010-09-15 pbug if (sr->question == NULL) {
353 dd869383 2013-02-16 pjp dolog(LOG_ERR, "malformed question in recurse.c");
354 aded9c80 2010-09-15 pbug free(sr);
355 aded9c80 2010-09-15 pbug continue;
356 b6dc64dc 2010-04-15 pbug }
357 aded9c80 2010-09-15 pbug
358 aded9c80 2010-09-15 pbug type = lookup_zone(db, sr->question, &sd, &lzerrno, (char *)fakereplystring, wildcard);
359 aded9c80 2010-09-15 pbug if (type < 0) {
360 df7b3e7e 2010-09-25 pbug if (lzerrno == ERR_NOERROR &&
361 df7b3e7e 2010-09-25 pbug (sd.flags & DOMAIN_NEGATIVE_CACHE) ==
362 df7b3e7e 2010-09-25 pbug DOMAIN_NEGATIVE_CACHE) {
363 df7b3e7e 2010-09-25 pbug
364 df7b3e7e 2010-09-25 pbug reply_raw_nxdomain(db, sr, &sd, raw);
365 df7b3e7e 2010-09-25 pbug free_question(sr->question);
366 df7b3e7e 2010-09-25 pbug free(sr);
367 df7b3e7e 2010-09-25 pbug continue;
368 df7b3e7e 2010-09-25 pbug
369 df7b3e7e 2010-09-25 pbug }
370 cfbdfdca 2010-09-24 pbug if (netlookup(db, sr) < 0)
371 dbaa9c14 2010-09-23 pbug continue;
372 dbaa9c14 2010-09-23 pbug
373 c0963faf 2014-05-01 pjp SLIST_INSERT_HEAD(&recurseshead, sr, recurses_entry);
374 aded9c80 2010-09-15 pbug } else {
375 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "we had the record in our cache, reply action");
376 fe3d3220 2010-09-21 pbug /* check if zone is expired */
377 fe3d3220 2010-09-21 pbug
378 fe3d3220 2010-09-21 pbug if ((! (sd.flags & DOMAIN_STATIC_ZONE)) &&
379 fe3d3220 2010-09-21 pbug (sd.created + sd.ttl < time(NULL))) {
380 fe3d3220 2010-09-21 pbug remove_zone(db, &sd);
381 fe3d3220 2010-09-21 pbug
382 fe3d3220 2010-09-21 pbug /* continue with netlookup */
383 fe3d3220 2010-09-21 pbug
384 fe3d3220 2010-09-21 pbug if (netlookup(db, sr) < 0)
385 fe3d3220 2010-09-21 pbug continue;
386 22893736 2010-09-19 pbug
387 c0963faf 2014-05-01 pjp SLIST_INSERT_HEAD(&recurseshead, sr, recurses_entry);
388 fe3d3220 2010-09-21 pbug continue;
389 fe3d3220 2010-09-21 pbug }
390 fe3d3220 2010-09-21 pbug
391 b55adb0c 2010-09-26 pbug if (type == DNS_TYPE_CNAME)
392 b55adb0c 2010-09-26 pbug reply_raw_cname(db, sr, &sd, raw);
393 b55adb0c 2010-09-26 pbug else
394 b55adb0c 2010-09-26 pbug reply_raw(db, sr, &sd, raw);
395 b55adb0c 2010-09-26 pbug
396 22893736 2010-09-19 pbug free_question(sr->question);
397 22893736 2010-09-19 pbug free(sr);
398 aded9c80 2010-09-15 pbug continue;
399 aded9c80 2010-09-15 pbug }
400 aded9c80 2010-09-15 pbug
401 aded9c80 2010-09-15 pbug } /* FD_ISSET(sp) */
402 604e0a34 2010-09-15 pbug
403 c0963faf 2014-05-01 pjp SLIST_FOREACH(sr1, &recurseshead, recurses_entry) {
404 22893736 2010-09-19 pbug if (sr1->so != -1 && FD_ISSET(sr1->so, &rset)) {
405 604e0a34 2010-09-15 pbug /*
406 604e0a34 2010-09-15 pbug * we got a reply from the nameserver we
407 604e0a34 2010-09-15 pbug * queried, now we must parse the input
408 604e0a34 2010-09-15 pbug */
409 b6dc64dc 2010-04-15 pbug
410 00c89913 2010-10-11 pbug slen = sizeof(struct sockaddr_storage);
411 00c89913 2010-10-11 pbug if ((len = recvfrom(sr1->so, buf, sizeof(buf), 0, (struct sockaddr *)&ssin, &slen)) < 0) {
412 3553d5f3 2010-09-26 pbug if (errno != EWOULDBLOCK)
413 dd869383 2013-02-16 pjp dolog(LOG_ERR, "recvfrom: %m");
414 604e0a34 2010-09-15 pbug continue;
415 604e0a34 2010-09-15 pbug }
416 604e0a34 2010-09-15 pbug
417 1f906207 2010-09-17 pbug #if 1
418 604e0a34 2010-09-15 pbug /* XXX do some checking of expected IP address */
419 00c89913 2010-10-11 pbug
420 00c89913 2010-10-11 pbug switch (ssin.ss_family) {
421 00c89913 2010-10-11 pbug case AF_INET:
422 00c89913 2010-10-11 pbug sin = (struct sockaddr_in *)&ssin;
423 00c89913 2010-10-11 pbug if (sin->sin_addr.s_addr != sr1->a[0]) {
424 dd869383 2013-02-16 pjp dolog(LOG_ERR, "return address is not from right nameserver");
425 00c89913 2010-10-11 pbug continue;
426 00c89913 2010-10-11 pbug }
427 4d7c9557 2010-11-09 pbug break;
428 00c89913 2010-10-11 pbug case AF_INET6:
429 00c89913 2010-10-11 pbug sin6 = (struct sockaddr_in6*)&ssin;
430 00c89913 2010-10-11 pbug if (memcmp((char *)&sin6->sin6_addr, (char *)&sr1->aaaa[0], sizeof(struct in6_addr)) != 0) {
431 4d7c9557 2010-11-09 pbug inet_ntop(AF_INET6, &sin6->sin6_addr, address, sizeof(address));
432 00c89913 2010-10-11 pbug
433 dd869383 2013-02-16 pjp dolog(LOG_ERR, "return IPv6 address (%s) is not from right nameserver", address);
434 00c89913 2010-10-11 pbug continue;
435 00c89913 2010-10-11 pbug }
436 4d7c9557 2010-11-09 pbug break;
437 604e0a34 2010-09-15 pbug }
438 1f906207 2010-09-17 pbug #endif
439 604e0a34 2010-09-15 pbug
440 604e0a34 2010-09-15 pbug if (len < sizeof(struct dns_header)) {
441 dd869383 2013-02-16 pjp dolog(LOG_ERR, "size malformed on reply len=%d", len);
442 604e0a34 2010-09-15 pbug /* on error, we just go out and wait for the real ID, this sucks! XXX */
443 604e0a34 2010-09-15 pbug continue;
444 604e0a34 2010-09-15 pbug }
445 b6dc64dc 2010-04-15 pbug
446 604e0a34 2010-09-15 pbug dh = (struct dns_header*)&buf[0];
447 604e0a34 2010-09-15 pbug
448 604e0a34 2010-09-15 pbug if (ntohs(dh->id) != sr1->id) {
449 dd869383 2013-02-16 pjp dolog(LOG_ERR, "unexpected dns ID (%u != %u)", ntohs(dh->id), sr1->id);
450 604e0a34 2010-09-15 pbug /* on error, we just go out and wait for the real ID, this sucks! XXX */
451 604e0a34 2010-09-15 pbug continue;
452 604e0a34 2010-09-15 pbug }
453 604e0a34 2010-09-15 pbug
454 604e0a34 2010-09-15 pbug if (! (ntohs(dh->query) & DNS_REPLY)) {
455 dd869383 2013-02-16 pjp dolog(LOG_ERR, "reply is not a DNS reply");
456 604e0a34 2010-09-15 pbug continue;
457 604e0a34 2010-09-15 pbug }
458 604e0a34 2010-09-15 pbug
459 604e0a34 2010-09-15 pbug /* XXX */
460 604e0a34 2010-09-15 pbug
461 3553d5f3 2010-09-26 pbug if (close(sr1->so) < 0)
462 dd869383 2013-02-16 pjp dolog(LOG_ERR, "close: %m");
463 3553d5f3 2010-09-26 pbug
464 1c8eb9ed 2010-09-17 pbug sr1->so = -1;
465 604e0a34 2010-09-15 pbug
466 604e0a34 2010-09-15 pbug if (ntohs(dh->query) & DNS_NAMEERR) {
467 604e0a34 2010-09-15 pbug negative_cache(db, sr1);
468 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "added negative cache for domain \"%s\"", sr1->question->converted_name);
469 604e0a34 2010-09-15 pbug /* reply negatively */
470 df7b3e7e 2010-09-25 pbug reply_raw_nxdomain(db, sr1, &sd, raw);
471 604e0a34 2010-09-15 pbug goto remove;
472 604e0a34 2010-09-15 pbug }
473 604e0a34 2010-09-15 pbug
474 b36746d8 2010-09-25 pbug sr1->authoritative = 0;
475 cfbdfdca 2010-09-24 pbug recurse_parse(db, sr1, (u_char*)&buf, len);
476 437140e3 2010-09-25 pbug
477 437140e3 2010-09-25 pbug /* check if we're flooding anything */
478 437140e3 2010-09-25 pbug if (sr1->packetcount > 50) {
479 dd869383 2013-02-16 pjp dolog(LOG_ERR, "packetcount is over 50, I think I'm flooding something, abort()");
480 06aa4e57 2011-04-12 pbug slave_shutdown();
481 437140e3 2010-09-25 pbug abort();
482 437140e3 2010-09-25 pbug }
483 1c8eb9ed 2010-09-17 pbug
484 c8a9dee0 2010-09-18 pbug type = lookup_zone(db, sr1->question, &sd, &lzerrno, (char *)fakereplystring, wildcard);
485 1c8eb9ed 2010-09-17 pbug if (type < 0) {
486 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "lookup_zone failed, doing netlookup");
487 437140e3 2010-09-25 pbug
488 b36746d8 2010-09-25 pbug if (sr1->authoritative == DNS_TYPE_NS &&
489 b36746d8 2010-09-25 pbug netlookup(db, sr1) < 0) {
490 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "subsequent netlookup failed");
491 c8a9dee0 2010-09-18 pbug
492 1c8eb9ed 2010-09-17 pbug }
493 22893736 2010-09-19 pbug
494 b36746d8 2010-09-25 pbug if (sr1->authoritative == DNS_TYPE_SOA) {
495 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "got an authoritative SOA answer, we'd reply an SOA here");
496 b36746d8 2010-09-25 pbug memset(&sd, 0, sizeof(struct domain));
497 b36746d8 2010-09-25 pbug get_soa(db, sr1->question, &sd, wildcard);
498 b36746d8 2010-09-25 pbug
499 b36746d8 2010-09-25 pbug reply_raw_noerror(db, sr, &sd, raw);
500 b36746d8 2010-09-25 pbug if (sr1->callback)
501 b36746d8 2010-09-25 pbug sr1->callback->hascallback--;
502 b36746d8 2010-09-25 pbug goto remove;
503 b36746d8 2010-09-25 pbug }
504 b36746d8 2010-09-25 pbug
505 22893736 2010-09-19 pbug continue;
506 1c8eb9ed 2010-09-17 pbug } else {
507 1c8eb9ed 2010-09-17 pbug /* we've found the record we're looking
508 1c8eb9ed 2010-09-17 pbug * for do something with it..
509 1c8eb9ed 2010-09-17 pbug */
510 604e0a34 2010-09-15 pbug
511 c8a9dee0 2010-09-18 pbug if (sr1->isfake) {
512 c8a9dee0 2010-09-18 pbug /* do another netlookup with the callback */
513 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "sr is fake, doing netlookup on the callback");
514 c8a9dee0 2010-09-18 pbug
515 c8a9dee0 2010-09-18 pbug if (netlookup(db, sr1->callback) < 0) {
516 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "callback netlookup failed");
517 c8a9dee0 2010-09-18 pbug }
518 c8a9dee0 2010-09-18 pbug
519 22893736 2010-09-19 pbug sr1->callback->hascallback--;
520 22893736 2010-09-19 pbug /* XXX continue; */
521 22893736 2010-09-19 pbug
522 22893736 2010-09-19 pbug
523 22893736 2010-09-19 pbug } else {
524 b55adb0c 2010-09-26 pbug if (type == DNS_TYPE_CNAME)
525 b55adb0c 2010-09-26 pbug reply_raw_cname(db, sr, &sd, raw);
526 b55adb0c 2010-09-26 pbug else
527 b55adb0c 2010-09-26 pbug reply_raw(db, sr1, &sd, raw);
528 22893736 2010-09-19 pbug }
529 1c8eb9ed 2010-09-17 pbug }
530 604e0a34 2010-09-15 pbug remove:
531 22893736 2010-09-19 pbug /* only remove if we don't have any callbacks
532 22893736 2010-09-19 pbug * outstanding...
533 22893736 2010-09-19 pbug */
534 22893736 2010-09-19 pbug if (! sr1->hascallback) {
535 c0963faf 2014-05-01 pjp SLIST_REMOVE(&recurseshead, sr1, recurses, recurses_entry);
536 22893736 2010-09-19 pbug free_question(sr1->question);
537 22893736 2010-09-19 pbug free(sr1);
538 22893736 2010-09-19 pbug }
539 604e0a34 2010-09-15 pbug
540 604e0a34 2010-09-15 pbug } /* FD_ISSET(sr1->so */
541 604e0a34 2010-09-15 pbug } /* SLIST_FOREACH(sr... */
542 604e0a34 2010-09-15 pbug
543 604e0a34 2010-09-15 pbug #if 0
544 be7ae884 2010-05-26 pbug /*
545 be7ae884 2010-05-26 pbug I drew this on a notepad one night, I think that's supposed to how
546 be7ae884 2010-05-26 pbug it shoudl go...
547 be7ae884 2010-05-26 pbug
548 be7ae884 2010-05-26 pbug +----------------+ +--------------------------+
549 be7ae884 2010-05-26 pbug | | | |
550 be7ae884 2010-05-26 pbug | v v |
551 be7ae884 2010-05-26 pbug | -------------------- select ------------------- |
552 be7ae884 2010-05-26 pbug | || || |
553 be7ae884 2010-05-26 pbug | || || |
554 be7ae884 2010-05-26 pbug | +----+ +----+ |
555 be7ae884 2010-05-26 pbug | | | take request | | parse reply |
556 be7ae884 2010-05-26 pbug | +----+ from authoritative +----+ and insert |
557 be7ae884 2010-05-26 pbug | || side / new record |
558 be7ae884 2010-05-26 pbug | || / |
559 be7ae884 2010-05-26 pbug | || / |
560 be7ae884 2010-05-26 pbug | || +---------------+ |
561 be7ae884 2010-05-26 pbug | || / |
562 be7ae884 2010-05-26 pbug | || / bad or expired |
563 be7ae884 2010-05-26 pbug | +----+=====================>+----+ lookup record |
564 be7ae884 2010-05-26 pbug | | | lookup name in db | | on the net |
565 be7ae884 2010-05-26 pbug | +----+ +----+-------------------+
566 be7ae884 2010-05-26 pbug | ||
567 be7ae884 2010-05-26 pbug | || good
568 be7ae884 2010-05-26 pbug | ||
569 be7ae884 2010-05-26 pbug | +----+
570 be7ae884 2010-05-26 pbug | | | reply
571 be7ae884 2010-05-26 pbug | +----+
572 be7ae884 2010-05-26 pbug | ||
573 be7ae884 2010-05-26 pbug | ||
574 be7ae884 2010-05-26 pbug | ||
575 be7ae884 2010-05-26 pbug | +----+
576 be7ae884 2010-05-26 pbug +--------| | cleanup
577 be7ae884 2010-05-26 pbug +----+
578 be7ae884 2010-05-26 pbug
579 be7ae884 2010-05-26 pbug */
580 be7ae884 2010-05-26 pbug
581 b6dc64dc 2010-04-15 pbug #endif
582 b6dc64dc 2010-04-15 pbug
583 b6dc64dc 2010-04-15 pbug
584 604e0a34 2010-09-15 pbug } /* for(;;) */
585 aded9c80 2010-09-15 pbug
586 604e0a34 2010-09-15 pbug /* NOTREACHED */
587 aded9c80 2010-09-15 pbug }
588 aded9c80 2010-09-15 pbug
589 aded9c80 2010-09-15 pbug /*
590 aded9c80 2010-09-15 pbug * LOOKUP_NS - given an address try to look up the nameservers anywhere along
591 604e0a34 2010-09-15 pbug * its path. return number of servers reachable or -1 on error.
592 aded9c80 2010-09-15 pbug */
593 aded9c80 2010-09-15 pbug
594 aded9c80 2010-09-15 pbug int
595 aded9c80 2010-09-15 pbug lookup_ns(DB *db, struct recurses *sr)
596 aded9c80 2010-09-15 pbug {
597 aded9c80 2010-09-15 pbug int ret, plen, i;
598 aded9c80 2010-09-15 pbug int onemore = 0;
599 aded9c80 2010-09-15 pbug char *p;
600 b6dc64dc 2010-04-15 pbug
601 aded9c80 2010-09-15 pbug DBT key, data;
602 b6dc64dc 2010-04-15 pbug
603 aded9c80 2010-09-15 pbug struct domain *sd, mydomain;
604 aded9c80 2010-09-15 pbug
605 aded9c80 2010-09-15 pbug p = sr->question->hdr->name;
606 aded9c80 2010-09-15 pbug plen = sr->question->hdr->namelen;
607 aded9c80 2010-09-15 pbug
608 aded9c80 2010-09-15 pbug do {
609 aded9c80 2010-09-15 pbug again:
610 aded9c80 2010-09-15 pbug memset(&key, 0, sizeof(key));
611 aded9c80 2010-09-15 pbug memset(&data, 0, sizeof(data));
612 aded9c80 2010-09-15 pbug
613 aded9c80 2010-09-15 pbug key.data = (char *)p;
614 aded9c80 2010-09-15 pbug key.size = plen;
615 aded9c80 2010-09-15 pbug
616 aded9c80 2010-09-15 pbug data.data = NULL;
617 aded9c80 2010-09-15 pbug data.size = 0;
618 aded9c80 2010-09-15 pbug
619 aded9c80 2010-09-15 pbug ret = db->get(db, NULL, &key, &data, 0);
620 aded9c80 2010-09-15 pbug if (ret != 0) {
621 aded9c80 2010-09-15 pbug if (*p != 0) {
622 aded9c80 2010-09-15 pbug plen -= (*p + 1);
623 aded9c80 2010-09-15 pbug p = (p + (*p + 1));
624 aded9c80 2010-09-15 pbug sr->indicator++;
625 aded9c80 2010-09-15 pbug }
626 aded9c80 2010-09-15 pbug
627 aded9c80 2010-09-15 pbug /* XXX this is different from lookup_zone(), not
628 aded9c80 2010-09-15 pbug * sure how it even works there...
629 aded9c80 2010-09-15 pbug */
630 aded9c80 2010-09-15 pbug if (*p == 0 && ! onemore) {
631 aded9c80 2010-09-15 pbug plen = 1;
632 aded9c80 2010-09-15 pbug onemore = 1;
633 aded9c80 2010-09-15 pbug sr->indicator++;
634 aded9c80 2010-09-15 pbug goto again; /* XXX */
635 aded9c80 2010-09-15 pbug }
636 aded9c80 2010-09-15 pbug } else {
637 aded9c80 2010-09-15 pbug /* we have a lookup */
638 aded9c80 2010-09-15 pbug
639 aded9c80 2010-09-15 pbug if (data.size != sizeof(struct domain)) {
640 dd869383 2013-02-16 pjp dolog(LOG_ERR, "btree db is damaged");
641 aded9c80 2010-09-15 pbug return (-1);
642 aded9c80 2010-09-15 pbug }
643 aded9c80 2010-09-15 pbug
644 aded9c80 2010-09-15 pbug #if 0
645 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "we gots a lookup, yay!\n");
646 aded9c80 2010-09-15 pbug #endif
647 aded9c80 2010-09-15 pbug
648 f1e825ef 2010-09-28 pbug /*
649 f1e825ef 2010-09-28 pbug * record which record we used
650 f1e825ef 2010-09-28 pbug */
651 f1e825ef 2010-09-28 pbug
652 3f255a8f 2011-04-19 pbug sr->lookrecord = (u_char *)p;
653 aded9c80 2010-09-15 pbug
654 aded9c80 2010-09-15 pbug memcpy((char *)&mydomain, (char *)data.data, sizeof(struct domain));
655 aded9c80 2010-09-15 pbug sd = (struct domain *)&mydomain;
656 604e0a34 2010-09-15 pbug
657 604e0a34 2010-09-15 pbug /*
658 604e0a34 2010-09-15 pbug * If we're not a static zone (like hints) and we're
659 604e0a34 2010-09-15 pbug * expired then we go on to the next indicator..
660 fe3d3220 2010-09-21 pbug * .. but first we must remove this zone...
661 604e0a34 2010-09-15 pbug */
662 604e0a34 2010-09-15 pbug if ((! (sd->flags & DOMAIN_STATIC_ZONE)) &&
663 604e0a34 2010-09-15 pbug (time(NULL) > (sd->created + sd->ttl))) {
664 fe3d3220 2010-09-21 pbug
665 fe3d3220 2010-09-21 pbug remove_zone(db, sd);
666 604e0a34 2010-09-15 pbug
667 604e0a34 2010-09-15 pbug if (*p != 0) {
668 604e0a34 2010-09-15 pbug plen -= (*p + 1);
669 604e0a34 2010-09-15 pbug p = (p + (*p + 1));
670 604e0a34 2010-09-15 pbug sr->indicator++;
671 604e0a34 2010-09-15 pbug continue;
672 604e0a34 2010-09-15 pbug } else {
673 604e0a34 2010-09-15 pbug return (-1);
674 604e0a34 2010-09-15 pbug }
675 604e0a34 2010-09-15 pbug }
676 604e0a34 2010-09-15 pbug /*
677 604e0a34 2010-09-15 pbug * If we have a negative cache, then just return with
678 604e0a34 2010-09-15 pbug * error.
679 604e0a34 2010-09-15 pbug */
680 604e0a34 2010-09-15 pbug if ((sd->flags & DOMAIN_NEGATIVE_CACHE) &&
681 604e0a34 2010-09-15 pbug (time(NULL) <= (sd->created + sd->ttl))) {
682 604e0a34 2010-09-15 pbug return (-1);
683 604e0a34 2010-09-15 pbug }
684 604e0a34 2010-09-15 pbug
685 518aa971 2010-09-30 pbug sr->aaaa_count = 0;
686 aded9c80 2010-09-15 pbug sr->a_count = 0;
687 aded9c80 2010-09-15 pbug sr->a_ptr = 0;
688 aded9c80 2010-09-15 pbug
689 aded9c80 2010-09-15 pbug for (i = 0; i < sd->ns_count; i++) {
690 518aa971 2010-09-30 pbug if (sr->af == AF_INET6) {
691 f98bb34d 2011-09-19 pbug if (lookup_aaaa(db, sr, &sd->ns[(sd->ns_ptr + i) % sd->ns_count] ) < 0)
692 518aa971 2010-09-30 pbug continue;
693 518aa971 2010-09-30 pbug sr->aaaa_count++;
694 518aa971 2010-09-30 pbug } else {
695 f98bb34d 2011-09-19 pbug if (lookup_a(db, sr, &sd->ns[(sd->ns_ptr + i) % sd->ns_count] ) < 0)
696 518aa971 2010-09-30 pbug continue;
697 518aa971 2010-09-30 pbug sr->a_count++;
698 518aa971 2010-09-30 pbug }
699 aded9c80 2010-09-15 pbug }
700 aded9c80 2010-09-15 pbug
701 5528a18e 2010-09-21 pbug if (sd->ns_count)
702 5528a18e 2010-09-21 pbug sd->ns_ptr = (sd->ns_ptr + 1) % sd->ns_count;
703 5528a18e 2010-09-21 pbug else
704 5528a18e 2010-09-21 pbug sd->ns_ptr = 0;
705 5528a18e 2010-09-21 pbug
706 aded9c80 2010-09-15 pbug update_db(db, sd);
707 aded9c80 2010-09-15 pbug
708 aded9c80 2010-09-15 pbug break;
709 aded9c80 2010-09-15 pbug }
710 aded9c80 2010-09-15 pbug
711 aded9c80 2010-09-15 pbug } while (*p != 0 && ret != 0);
712 aded9c80 2010-09-15 pbug
713 1f906207 2010-09-17 pbug #if 1
714 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "got %d addresses for %s, indicator %d\n", sr->a_count, sr->question->hdr->name, sr->indicator);
715 aded9c80 2010-09-15 pbug
716 604e0a34 2010-09-15 pbug #endif
717 604e0a34 2010-09-15 pbug
718 518aa971 2010-09-30 pbug return ((sr->af == AF_INET6) ? sr->aaaa_count : sr->a_count);
719 b6dc64dc 2010-04-15 pbug }
720 aded9c80 2010-09-15 pbug
721 aded9c80 2010-09-15 pbug
722 aded9c80 2010-09-15 pbug /*
723 aded9c80 2010-09-15 pbug * LOOKUP_A - given a path, lookup the A record in that record
724 aded9c80 2010-09-15 pbug *
725 aded9c80 2010-09-15 pbug */
726 aded9c80 2010-09-15 pbug
727 aded9c80 2010-09-15 pbug int
728 aded9c80 2010-09-15 pbug lookup_a(DB *db, struct recurses *sr, struct ns *ns)
729 aded9c80 2010-09-15 pbug {
730 aded9c80 2010-09-15 pbug int ret, plen;
731 aded9c80 2010-09-15 pbug char *p;
732 aded9c80 2010-09-15 pbug
733 aded9c80 2010-09-15 pbug DBT key, data;
734 aded9c80 2010-09-15 pbug
735 dbd9100e 2010-09-19 pbug struct domain *sd, sdomain;
736 c8a9dee0 2010-09-18 pbug int found = 0;
737 aded9c80 2010-09-15 pbug
738 aded9c80 2010-09-15 pbug p = ns->nsserver;
739 aded9c80 2010-09-15 pbug plen = ns->nslen;
740 aded9c80 2010-09-15 pbug
741 aded9c80 2010-09-15 pbug memset(&key, 0, sizeof(key));
742 aded9c80 2010-09-15 pbug memset(&data, 0, sizeof(data));
743 aded9c80 2010-09-15 pbug
744 aded9c80 2010-09-15 pbug key.data = (char *)p;
745 aded9c80 2010-09-15 pbug key.size = plen;
746 aded9c80 2010-09-15 pbug
747 aded9c80 2010-09-15 pbug data.data = NULL;
748 aded9c80 2010-09-15 pbug data.size = 0;
749 aded9c80 2010-09-15 pbug
750 c8a9dee0 2010-09-18 pbug found = 0;
751 c8a9dee0 2010-09-18 pbug
752 aded9c80 2010-09-15 pbug ret = db->get(db, NULL, &key, &data, 0);
753 aded9c80 2010-09-15 pbug if (ret == 0) {
754 aded9c80 2010-09-15 pbug if (data.size != sizeof(struct domain)) {
755 dd869383 2013-02-16 pjp dolog(LOG_ERR, "btree db is damaged");
756 aded9c80 2010-09-15 pbug return (-1);
757 aded9c80 2010-09-15 pbug }
758 aded9c80 2010-09-15 pbug
759 dbd9100e 2010-09-19 pbug memcpy((char*)&sdomain, data.data, sizeof(struct domain));
760 dbd9100e 2010-09-19 pbug sd = &sdomain;
761 c8a9dee0 2010-09-18 pbug
762 c8a9dee0 2010-09-18 pbug if ((sd->flags & DOMAIN_HAVE_A) == DOMAIN_HAVE_A) {
763 c8a9dee0 2010-09-18 pbug memcpy((char *)&sr->a[sr->a_count], (char *)&sd->a[0], sizeof(in_addr_t));
764 dbd9100e 2010-09-19 pbug sd->a_count++;
765 c8a9dee0 2010-09-18 pbug found = 1;
766 dbd9100e 2010-09-19 pbug
767 c8a9dee0 2010-09-18 pbug }
768 c8a9dee0 2010-09-18 pbug }
769 aded9c80 2010-09-15 pbug
770 c8a9dee0 2010-09-18 pbug if (! found) {
771 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "calling fakerecurse");
772 f1e825ef 2010-09-28 pbug fakerecurse(db, sr, ns, DNS_TYPE_A);
773 aded9c80 2010-09-15 pbug return (-1);
774 c8a9dee0 2010-09-18 pbug }
775 aded9c80 2010-09-15 pbug
776 aded9c80 2010-09-15 pbug return (0);
777 aded9c80 2010-09-15 pbug }
778 604e0a34 2010-09-15 pbug
779 c7eceeba 2010-09-16 pbug /*
780 c7eceeba 2010-09-16 pbug * NEGATIVE_CACHE - cache a lookup as negative (NXDOMAIN)
781 c7eceeba 2010-09-16 pbug *
782 c7eceeba 2010-09-16 pbug */
783 604e0a34 2010-09-15 pbug
784 604e0a34 2010-09-15 pbug int
785 604e0a34 2010-09-15 pbug negative_cache(DB *db, struct recurses *sr)
786 604e0a34 2010-09-15 pbug {
787 604e0a34 2010-09-15 pbug struct domain sd;
788 604e0a34 2010-09-15 pbug
789 604e0a34 2010-09-15 pbug memset(&sd, 0, sizeof(sd));
790 604e0a34 2010-09-15 pbug
791 604e0a34 2010-09-15 pbug sd.zonelen = sr->question->hdr->namelen;
792 604e0a34 2010-09-15 pbug
793 f98bb34d 2011-09-19 pbug memcpy((char *)&sd.zone, (char *)sr->question->hdr->name, sd.zonelen);
794 604e0a34 2010-09-15 pbug
795 604e0a34 2010-09-15 pbug #if __linux__
796 f98bb34d 2011-09-19 pbug strncpy((char *)&sd.zonename, (char *)sr->question->converted_name, DNS_MAXNAME);
797 604e0a34 2010-09-15 pbug sd.zonename[DNS_MAXNAME] = 0;
798 604e0a34 2010-09-15 pbug #else
799 f98bb34d 2011-09-19 pbug strlcpy((char *)&sd.zonename, (char *)sr->question->converted_name, DNS_MAXNAME + 1);
800 604e0a34 2010-09-15 pbug #endif
801 604e0a34 2010-09-15 pbug
802 604e0a34 2010-09-15 pbug sd.created = time(NULL);
803 604e0a34 2010-09-15 pbug sd.ttl = NEGATIVE_CACHE_TIME; /* 10 minutes */
804 604e0a34 2010-09-15 pbug
805 604e0a34 2010-09-15 pbug sd.flags |= DOMAIN_NEGATIVE_CACHE;
806 604e0a34 2010-09-15 pbug
807 604e0a34 2010-09-15 pbug update_db(db, &sd);
808 c7eceeba 2010-09-16 pbug
809 c7eceeba 2010-09-16 pbug return (0);
810 c7eceeba 2010-09-16 pbug }
811 c7eceeba 2010-09-16 pbug
812 c7eceeba 2010-09-16 pbug /*
813 c7eceeba 2010-09-16 pbug * RECURSE_PARSE - based on compress_label.
814 c7eceeba 2010-09-16 pbug *
815 c7eceeba 2010-09-16 pbug */
816 c7eceeba 2010-09-16 pbug
817 c7eceeba 2010-09-16 pbug int
818 c7eceeba 2010-09-16 pbug recurse_parse(DB *db, struct recurses *sr, u_char *buf, u_int16_t offset)
819 c7eceeba 2010-09-16 pbug {
820 c7eceeba 2010-09-16 pbug u_char *label[256]; /* should be enough */
821 22893736 2010-09-19 pbug static u_char converted_name[256][256];
822 1f906207 2010-09-17 pbug u_int8_t cn_len[256];
823 c7eceeba 2010-09-16 pbug u_char *end = &buf[offset];
824 1f906207 2010-09-17 pbug int update;
825 b36746d8 2010-09-25 pbug int rrcount[3]; /* RR count answer, authoritative, additional */
826 b36746d8 2010-09-25 pbug int pointer = 0; /* default answer */
827 b55adb0c 2010-09-26 pbug int txtlen;
828 1f906207 2010-09-17 pbug
829 1f906207 2010-09-17 pbug char abuf[INET6_ADDRSTRLEN];
830 1f906207 2010-09-17 pbug
831 1f906207 2010-09-17 pbug DBT key, data;
832 1f906207 2010-09-17 pbug
833 1f906207 2010-09-17 pbug struct domain sdomain;
834 b36746d8 2010-09-25 pbug struct dns_header *dh;
835 c7eceeba 2010-09-16 pbug struct question {
836 c7eceeba 2010-09-16 pbug u_int16_t type;
837 c7eceeba 2010-09-16 pbug u_int16_t class;
838 c7eceeba 2010-09-16 pbug } __attribute__((packed));
839 c7eceeba 2010-09-16 pbug struct answer {
840 c7eceeba 2010-09-16 pbug u_int16_t type;
841 c7eceeba 2010-09-16 pbug u_int16_t class;
842 c7eceeba 2010-09-16 pbug u_int32_t ttl;
843 c7eceeba 2010-09-16 pbug u_int16_t rdlength;
844 c7eceeba 2010-09-16 pbug } __attribute__((packed));
845 dbaa9c14 2010-09-23 pbug struct mysoa {
846 c7eceeba 2010-09-16 pbug u_int32_t serial;
847 c7eceeba 2010-09-16 pbug u_int32_t refresh;
848 c7eceeba 2010-09-16 pbug u_int32_t retry;
849 c7eceeba 2010-09-16 pbug u_int32_t expire;
850 c7eceeba 2010-09-16 pbug u_int32_t minttl;
851 c7eceeba 2010-09-16 pbug } __attribute__((packed));
852 c7eceeba 2010-09-16 pbug
853 c7eceeba 2010-09-16 pbug struct answer *a;
854 dbaa9c14 2010-09-23 pbug struct mysoa *mysoa;
855 dbaa9c14 2010-09-23 pbug struct soa *soa;
856 f1e825ef 2010-09-28 pbug struct ns ns;
857 c7eceeba 2010-09-16 pbug
858 c7eceeba 2010-09-16 pbug u_int i, j, k;
859 c7eceeba 2010-09-16 pbug u_int16_t *compressor;
860 c7eceeba 2010-09-16 pbug u_int16_t c;
861 8bd942da 2010-09-26 pbug u_int16_t *preference;
862 c7eceeba 2010-09-16 pbug
863 c7eceeba 2010-09-16 pbug int found = 0;
864 c7eceeba 2010-09-16 pbug
865 c7eceeba 2010-09-16 pbug u_char *p, *q, *r;
866 c7eceeba 2010-09-16 pbug
867 b36746d8 2010-09-25 pbug dh = (struct dns_header*)&buf[0];
868 b36746d8 2010-09-25 pbug rrcount[pointer++] = ntohs(dh->answer);
869 b36746d8 2010-09-25 pbug rrcount[pointer++] = ntohs(dh->nsrr);
870 b36746d8 2010-09-25 pbug rrcount[pointer++] = ntohs(dh->additional);
871 b36746d8 2010-09-25 pbug
872 b36746d8 2010-09-25 pbug pointer = 0;
873 b36746d8 2010-09-25 pbug while (rrcount[pointer] == 0) {
874 b36746d8 2010-09-25 pbug pointer++;
875 b36746d8 2010-09-25 pbug if (pointer > 2)
876 b36746d8 2010-09-25 pbug return (-1);
877 b36746d8 2010-09-25 pbug }
878 b36746d8 2010-09-25 pbug
879 c7eceeba 2010-09-16 pbug p = &buf[sizeof(struct dns_header)];
880 c7eceeba 2010-09-16 pbug label[0] = p;
881 c7eceeba 2010-09-16 pbug
882 c7eceeba 2010-09-16 pbug while (p <= end && *p) {
883 c7eceeba 2010-09-16 pbug p += *p;
884 c7eceeba 2010-09-16 pbug p++;
885 c7eceeba 2010-09-16 pbug }
886 c7eceeba 2010-09-16 pbug
887 c7eceeba 2010-09-16 pbug /*
888 c7eceeba 2010-09-16 pbug * the question label was bogus, we'll just get out of there, return 0
889 c7eceeba 2010-09-16 pbug */
890 c7eceeba 2010-09-16 pbug
891 c7eceeba 2010-09-16 pbug if (p > end)
892 c7eceeba 2010-09-16 pbug return (-1);
893 c7eceeba 2010-09-16 pbug
894 c7eceeba 2010-09-16 pbug p += sizeof(struct question);
895 c7eceeba 2010-09-16 pbug p++; /* one more */
896 c7eceeba 2010-09-16 pbug /* start of answer/additional/authoritative */
897 c7eceeba 2010-09-16 pbug
898 c7eceeba 2010-09-16 pbug for (i = 1; i < 100; i++) {
899 c7eceeba 2010-09-16 pbug label[i] = p;
900 c7eceeba 2010-09-16 pbug
901 c7eceeba 2010-09-16 pbug while (p <= end && *p) {
902 c7eceeba 2010-09-16 pbug if ((*p & 0xc0) == 0xc0) {
903 c7eceeba 2010-09-16 pbug p++;
904 c7eceeba 2010-09-16 pbug break;
905 c7eceeba 2010-09-16 pbug }
906 c7eceeba 2010-09-16 pbug p += *p;
907 c7eceeba 2010-09-16 pbug p++;
908 c7eceeba 2010-09-16 pbug
909 c7eceeba 2010-09-16 pbug if (p > end)
910 c7eceeba 2010-09-16 pbug goto end;
911 c7eceeba 2010-09-16 pbug }
912 c7eceeba 2010-09-16 pbug
913 c7eceeba 2010-09-16 pbug p++; /* one more */
914 c7eceeba 2010-09-16 pbug
915 c7eceeba 2010-09-16 pbug
916 c7eceeba 2010-09-16 pbug a = (struct answer *)p;
917 c7eceeba 2010-09-16 pbug p += sizeof(struct answer);
918 c7eceeba 2010-09-16 pbug
919 0f65e2ee 2011-02-28 pbug if (p > end)
920 0f65e2ee 2011-02-28 pbug goto end;
921 0f65e2ee 2011-02-28 pbug
922 c7eceeba 2010-09-16 pbug switch (ntohs(a->type)) {
923 c7eceeba 2010-09-16 pbug case DNS_TYPE_A:
924 c7eceeba 2010-09-16 pbug p += sizeof(in_addr_t);
925 c7eceeba 2010-09-16 pbug break;
926 c7eceeba 2010-09-16 pbug case DNS_TYPE_AAAA:
927 c7eceeba 2010-09-16 pbug p += 16; /* sizeof 4 * 32 bit */
928 c7eceeba 2010-09-16 pbug break;
929 c7eceeba 2010-09-16 pbug case DNS_TYPE_TXT:
930 c7eceeba 2010-09-16 pbug p += *p;
931 c7eceeba 2010-09-16 pbug p++;
932 c7eceeba 2010-09-16 pbug break;
933 c7eceeba 2010-09-16 pbug case DNS_TYPE_MX:
934 c7eceeba 2010-09-16 pbug p += sizeof(u_int16_t); /* mx_priority */
935 c7eceeba 2010-09-16 pbug /* FALLTHROUGH */
936 c7eceeba 2010-09-16 pbug case DNS_TYPE_NS:
937 c7eceeba 2010-09-16 pbug case DNS_TYPE_PTR:
938 c7eceeba 2010-09-16 pbug case DNS_TYPE_CNAME:
939 c7eceeba 2010-09-16 pbug label[++i] = p;
940 c7eceeba 2010-09-16 pbug while (p <= end && *p) {
941 c7eceeba 2010-09-16 pbug if ((*p & 0xc0) == 0xc0) {
942 c7eceeba 2010-09-16 pbug p++;
943 c7eceeba 2010-09-16 pbug break;
944 c7eceeba 2010-09-16 pbug }
945 c7eceeba 2010-09-16 pbug p += *p;
946 c7eceeba 2010-09-16 pbug p++;
947 604e0a34 2010-09-15 pbug
948 c7eceeba 2010-09-16 pbug if (p > end)
949 c7eceeba 2010-09-16 pbug goto end;
950 c7eceeba 2010-09-16 pbug }
951 c7eceeba 2010-09-16 pbug
952 c7eceeba 2010-09-16 pbug p++; /* one more */
953 c7eceeba 2010-09-16 pbug break;
954 c7eceeba 2010-09-16 pbug case DNS_TYPE_SOA:
955 c7eceeba 2010-09-16 pbug /* nsserver */
956 c7eceeba 2010-09-16 pbug label[++i] = p;
957 c7eceeba 2010-09-16 pbug while (p <= end && *p) {
958 c7eceeba 2010-09-16 pbug if ((*p & 0xc0) == 0xc0) {
959 c7eceeba 2010-09-16 pbug p++;
960 c7eceeba 2010-09-16 pbug break;
961 c7eceeba 2010-09-16 pbug }
962 c7eceeba 2010-09-16 pbug p += *p;
963 c7eceeba 2010-09-16 pbug p++;
964 c7eceeba 2010-09-16 pbug if (p > end)
965 c7eceeba 2010-09-16 pbug goto end;
966 c7eceeba 2010-09-16 pbug }
967 c7eceeba 2010-09-16 pbug
968 c7eceeba 2010-09-16 pbug p++; /* one more */
969 c7eceeba 2010-09-16 pbug
970 c7eceeba 2010-09-16 pbug if (p > end)
971 c7eceeba 2010-09-16 pbug goto end;
972 c7eceeba 2010-09-16 pbug
973 c7eceeba 2010-09-16 pbug /* responsible person */
974 c7eceeba 2010-09-16 pbug label[++i] = p;
975 c7eceeba 2010-09-16 pbug while (p <= end && *p) {
976 c7eceeba 2010-09-16 pbug if ((*p & 0xc0) == 0xc0) {
977 c7eceeba 2010-09-16 pbug p++;
978 c7eceeba 2010-09-16 pbug break;
979 c7eceeba 2010-09-16 pbug }
980 c7eceeba 2010-09-16 pbug p += *p;
981 c7eceeba 2010-09-16 pbug p++;
982 c7eceeba 2010-09-16 pbug }
983 c7eceeba 2010-09-16 pbug
984 c7eceeba 2010-09-16 pbug p++; /* one more */
985 c7eceeba 2010-09-16 pbug
986 c7eceeba 2010-09-16 pbug if (p > end)
987 c7eceeba 2010-09-16 pbug goto end;
988 c7eceeba 2010-09-16 pbug
989 dbaa9c14 2010-09-23 pbug p += sizeof(struct mysoa); /* advance struct soa */
990 c7eceeba 2010-09-16 pbug
991 c7eceeba 2010-09-16 pbug break;
992 c7eceeba 2010-09-16 pbug default:
993 c7eceeba 2010-09-16 pbug break;
994 c7eceeba 2010-09-16 pbug /* XXX */
995 c7eceeba 2010-09-16 pbug } /* switch */
996 c7eceeba 2010-09-16 pbug
997 c7eceeba 2010-09-16 pbug if (p >= end)
998 c7eceeba 2010-09-16 pbug break;
999 c7eceeba 2010-09-16 pbug } /* for (i *) */
1000 c7eceeba 2010-09-16 pbug
1001 c7eceeba 2010-09-16 pbug /*
1002 c7eceeba 2010-09-16 pbug * go through our list of labels and expand them from possible
1003 c7eceeba 2010-09-16 pbug * compression, then we make our next pass..
1004 c7eceeba 2010-09-16 pbug */
1005 c7eceeba 2010-09-16 pbug
1006 c7eceeba 2010-09-16 pbug for (j = 0; j <= i; j++) {
1007 c7eceeba 2010-09-16 pbug q = converted_name[j];
1008 c7eceeba 2010-09-16 pbug p = label[j];
1009 c7eceeba 2010-09-16 pbug again:
1010 c7eceeba 2010-09-16 pbug for (; *p ; p += *p, p++) {
1011 c7eceeba 2010-09-16 pbug if ((*p & 0xc0) == 0xc0)
1012 c7eceeba 2010-09-16 pbug break;
1013 c7eceeba 2010-09-16 pbug
1014 c7eceeba 2010-09-16 pbug r = (p + 1);
1015 c7eceeba 2010-09-16 pbug
1016 c7eceeba 2010-09-16 pbug *q++ = *p;
1017 c7eceeba 2010-09-16 pbug
1018 c7eceeba 2010-09-16 pbug for (k = 0; k < *p; k++)
1019 c7eceeba 2010-09-16 pbug *q++ = tolower(r[k]);
1020 c7eceeba 2010-09-16 pbug }
1021 c7eceeba 2010-09-16 pbug
1022 c7eceeba 2010-09-16 pbug if ((*p & 0xc0) == 0xc0) {
1023 c7eceeba 2010-09-16 pbug compressor = (u_int16_t *)p;
1024 c7eceeba 2010-09-16 pbug c = (ntohs(*compressor) & ~(0xc000));
1025 c7eceeba 2010-09-16 pbug for (k = 0; k <= i; k++) {
1026 c7eceeba 2010-09-16 pbug found = 0;
1027 c7eceeba 2010-09-16 pbug for (r = label[k]; *r; r += *r, r++) {
1028 c7eceeba 2010-09-16 pbug if (r - buf == c) {
1029 c7eceeba 2010-09-16 pbug p = r;
1030 c7eceeba 2010-09-16 pbug found = 1;
1031 c7eceeba 2010-09-16 pbug }
1032 c7eceeba 2010-09-16 pbug
1033 c7eceeba 2010-09-16 pbug
1034 c7eceeba 2010-09-16 pbug /*
1035 c7eceeba 2010-09-16 pbug * we're searching for an offset in
1036 c7eceeba 2010-09-16 pbug * non-compressed form, but we
1037 c7eceeba 2010-09-16 pbug * encountered compression, so we
1038 c7eceeba 2010-09-16 pbug * break and go to the next label
1039 c7eceeba 2010-09-16 pbug */
1040 c7eceeba 2010-09-16 pbug
1041 c7eceeba 2010-09-16 pbug if ((*r & 0xc0) == 0xc0) {
1042 c7eceeba 2010-09-16 pbug break;
1043 c7eceeba 2010-09-16 pbug }
1044 c7eceeba 2010-09-16 pbug }
1045 c7eceeba 2010-09-16 pbug
1046 c7eceeba 2010-09-16 pbug if (found) {
1047 c7eceeba 2010-09-16 pbug /*
1048 c7eceeba 2010-09-16 pbug * pretend we found a match but we
1049 c7eceeba 2010-09-16 pbug * have compression inside pointing
1050 c7eceeba 2010-09-16 pbug * down, then break this, it's corrupt
1051 c7eceeba 2010-09-16 pbug * it's a possible loop attempt
1052 c7eceeba 2010-09-16 pbug */
1053 c7eceeba 2010-09-16 pbug if ((*r & 0xc0) == 0xc0) {
1054 c7eceeba 2010-09-16 pbug compressor = (u_int16_t *)r;
1055 c7eceeba 2010-09-16 pbug if ((ntohs(*compressor) & ~0xc000) >= c)
1056 c7eceeba 2010-09-16 pbug break;
1057 c7eceeba 2010-09-16 pbug }
1058 c7eceeba 2010-09-16 pbug
1059 c7eceeba 2010-09-16 pbug goto again;
1060 c7eceeba 2010-09-16 pbug }
1061 c7eceeba 2010-09-16 pbug }
1062 c7eceeba 2010-09-16 pbug
1063 c7eceeba 2010-09-16 pbug /*
1064 c7eceeba 2010-09-16 pbug * if we fall through the for loop, we didn't find the
1065 c7eceeba 2010-09-16 pbug * recursive label... corrupt.
1066 c7eceeba 2010-09-16 pbug */
1067 c7eceeba 2010-09-16 pbug
1068 dd869383 2013-02-16 pjp dolog(LOG_ERR, "corrupt compression");
1069 c7eceeba 2010-09-16 pbug return (-1);
1070 c7eceeba 2010-09-16 pbug }
1071 c7eceeba 2010-09-16 pbug
1072 c7eceeba 2010-09-16 pbug *q++ = '\0'; /* don't forget this */
1073 1f906207 2010-09-17 pbug cn_len[j] = (q - converted_name[j]);
1074 c7eceeba 2010-09-16 pbug
1075 c7eceeba 2010-09-16 pbug } /* for (j .. */
1076 c7eceeba 2010-09-16 pbug
1077 1f906207 2010-09-17 pbug #if 0
1078 c7eceeba 2010-09-16 pbug for (j = 0; j <= i; j++) {
1079 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "%s with length %u", converted_name[j], cn_len[j]);
1080 c7eceeba 2010-09-16 pbug }
1081 1f906207 2010-09-17 pbug #endif
1082 1f906207 2010-09-17 pbug
1083 1f906207 2010-09-17 pbug p = &buf[sizeof(struct dns_header)];
1084 1f906207 2010-09-17 pbug label[0] = p;
1085 1f906207 2010-09-17 pbug
1086 1f906207 2010-09-17 pbug while (p <= end && *p) {
1087 1f906207 2010-09-17 pbug p += *p;
1088 1f906207 2010-09-17 pbug p++;
1089 1f906207 2010-09-17 pbug }
1090 1f906207 2010-09-17 pbug
1091 1f906207 2010-09-17 pbug /*
1092 1f906207 2010-09-17 pbug * the question label was bogus, we'll just get out of there, return 0
1093 1f906207 2010-09-17 pbug */
1094 1f906207 2010-09-17 pbug
1095 1f906207 2010-09-17 pbug if (p > end)
1096 1f906207 2010-09-17 pbug return (-1);
1097 1f906207 2010-09-17 pbug
1098 1f906207 2010-09-17 pbug p += sizeof(struct question);
1099 1f906207 2010-09-17 pbug p++; /* one more */
1100 1f906207 2010-09-17 pbug /* start of answer/additional/authoritative */
1101 1f906207 2010-09-17 pbug
1102 1f906207 2010-09-17 pbug for (i = 1; i < 100; i++) {
1103 1f906207 2010-09-17 pbug label[i] = p;
1104 1f906207 2010-09-17 pbug
1105 1f906207 2010-09-17 pbug while (p <= end && *p) {
1106 1f906207 2010-09-17 pbug if ((*p & 0xc0) == 0xc0) {
1107 1f906207 2010-09-17 pbug p++;
1108 1f906207 2010-09-17 pbug break;
1109 1f906207 2010-09-17 pbug }
1110 1f906207 2010-09-17 pbug p += *p;
1111 1f906207 2010-09-17 pbug p++;
1112 1f906207 2010-09-17 pbug
1113 1f906207 2010-09-17 pbug if (p > end)
1114 1f906207 2010-09-17 pbug goto end;
1115 1f906207 2010-09-17 pbug }
1116 1f906207 2010-09-17 pbug
1117 1f906207 2010-09-17 pbug p++; /* one more */
1118 1f906207 2010-09-17 pbug
1119 c7eceeba 2010-09-16 pbug
1120 1f906207 2010-09-17 pbug a = (struct answer *)p;
1121 1f906207 2010-09-17 pbug p += sizeof(struct answer);
1122 1f906207 2010-09-17 pbug
1123 1f906207 2010-09-17 pbug /* load our record */
1124 1f906207 2010-09-17 pbug memset(&key, 0, sizeof(key));
1125 1f906207 2010-09-17 pbug memset(&data, 0, sizeof(data));
1126 1f906207 2010-09-17 pbug
1127 1f906207 2010-09-17 pbug key.data = (char *)converted_name[i];
1128 1f906207 2010-09-17 pbug key.size = cn_len[i];
1129 1f906207 2010-09-17 pbug
1130 1f906207 2010-09-17 pbug data.data = NULL;
1131 1f906207 2010-09-17 pbug data.size = 0;
1132 1f906207 2010-09-17 pbug
1133 1f906207 2010-09-17 pbug memset((char *)&sdomain, 0, sizeof(struct domain));
1134 1f906207 2010-09-17 pbug if (db->get(db, NULL, &key, &data, 0) == 0) {
1135 1f906207 2010-09-17 pbug if (data.size != sizeof(struct domain)) {
1136 dd869383 2013-02-16 pjp dolog(LOG_INFO, "damaged btree database");
1137 1f906207 2010-09-17 pbug return -1;
1138 1f906207 2010-09-17 pbug }
1139 1f906207 2010-09-17 pbug
1140 1f906207 2010-09-17 pbug memcpy((char *)&sdomain, (char *)data.data, data.size);
1141 1f906207 2010-09-17 pbug
1142 1f906207 2010-09-17 pbug }
1143 1f906207 2010-09-17 pbug
1144 1f906207 2010-09-17 pbug
1145 1f906207 2010-09-17 pbug if (sdomain.zone == NULL) {
1146 f98bb34d 2011-09-19 pbug memcpy(&sdomain.zone, converted_name[i], cn_len[i]);
1147 1f906207 2010-09-17 pbug sdomain.zonelen = cn_len[i];
1148 1f906207 2010-09-17 pbug }
1149 1f906207 2010-09-17 pbug
1150 1f906207 2010-09-17 pbug
1151 1f906207 2010-09-17 pbug switch (ntohs(a->type)) {
1152 1f906207 2010-09-17 pbug case DNS_TYPE_A:
1153 1f906207 2010-09-17 pbug /*
1154 1f906207 2010-09-17 pbug * scan addresses in this struct domain and check if
1155 1f906207 2010-09-17 pbug * this one exists already...
1156 1f906207 2010-09-17 pbug */
1157 1f906207 2010-09-17 pbug
1158 1f906207 2010-09-17 pbug update = 1;
1159 1f906207 2010-09-17 pbug for (j = 0; j < sdomain.a_count; j++) {
1160 1f906207 2010-09-17 pbug if (memcmp(&sdomain.a[j], p, sizeof(in_addr_t)) == 0) {
1161 22893736 2010-09-19 pbug #if 0
1162 dd869383 2013-02-16 pjp dolog(LOG_INFO, "record exists already");
1163 22893736 2010-09-19 pbug #endif
1164 1f906207 2010-09-17 pbug update = 0;
1165 1f906207 2010-09-17 pbug }
1166 1f906207 2010-09-17 pbug }
1167 1f906207 2010-09-17 pbug
1168 1f906207 2010-09-17 pbug if (j >= RECORD_COUNT) {
1169 dd869383 2013-02-16 pjp dolog(LOG_INFO, "db can't hold any more records\n");
1170 1f906207 2010-09-17 pbug update = 0;
1171 1f906207 2010-09-17 pbug }
1172 f1e825ef 2010-09-28 pbug
1173 f1e825ef 2010-09-28 pbug /*
1174 f1e825ef 2010-09-28 pbug * check if we're a 2nd level domain or higher and
1175 f1e825ef 2010-09-28 pbug * if we were directly querying the zone...
1176 f1e825ef 2010-09-28 pbug */
1177 1f906207 2010-09-17 pbug
1178 1f906207 2010-09-17 pbug if (update) {
1179 f1e825ef 2010-09-28 pbug if (level(sr->lookrecord) > 1) {
1180 f1e825ef 2010-09-28 pbug if (!contains(sr->lookrecord, converted_name[i])) {
1181 f1e825ef 2010-09-28 pbug memcpy(ns.nsserver, converted_name[i], cn_len[i]);
1182 f1e825ef 2010-09-28 pbug ns.nslen = cn_len[i];
1183 f1e825ef 2010-09-28 pbug
1184 f1e825ef 2010-09-28 pbug fakerecurse(db, sr, &ns, DNS_TYPE_A);
1185 f1e825ef 2010-09-28 pbug update = 0;
1186 f1e825ef 2010-09-28 pbug }
1187 f1e825ef 2010-09-28 pbug }
1188 f1e825ef 2010-09-28 pbug }
1189 f1e825ef 2010-09-28 pbug
1190 f1e825ef 2010-09-28 pbug
1191 f1e825ef 2010-09-28 pbug if (update) {
1192 1f906207 2010-09-17 pbug memcpy(&sdomain.a[j], p, sizeof(in_addr_t));
1193 1f906207 2010-09-17 pbug sdomain.a_count++;
1194 dbd9100e 2010-09-19 pbug sdomain.region[j] = 0xff;
1195 1f906207 2010-09-17 pbug sdomain.a_ptr = 0;
1196 1f906207 2010-09-17 pbug sdomain.flags |= DOMAIN_HAVE_A;
1197 1f906207 2010-09-17 pbug sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1198 1f906207 2010-09-17 pbug sdomain.created = time(NULL);
1199 1f906207 2010-09-17 pbug sdomain.ttl = ntohl(a->ttl);
1200 1f906207 2010-09-17 pbug
1201 1f906207 2010-09-17 pbug if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1202 1f906207 2010-09-17 pbug update_db(db, &sdomain);
1203 1f906207 2010-09-17 pbug inet_ntop(AF_INET, p, abuf, sizeof(abuf));
1204 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "updateing zone %s with address %s ttl= %u, lookrecord = %s", converted_name[i], abuf, sdomain.ttl, sr->lookrecord);
1205 1f906207 2010-09-17 pbug }
1206 08769151 2010-10-03 pbug }
1207 1f906207 2010-09-17 pbug
1208 1f906207 2010-09-17 pbug p += sizeof(in_addr_t);
1209 8c01150e 2010-09-25 pbug if (pointer > 2) {
1210 dd869383 2013-02-16 pjp dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1211 8c01150e 2010-09-25 pbug return (-1);
1212 8c01150e 2010-09-25 pbug }
1213 b36746d8 2010-09-25 pbug rrcount[pointer]--;
1214 b36746d8 2010-09-25 pbug if (rrcount[pointer] == 0)
1215 b36746d8 2010-09-25 pbug pointer++;
1216 8c01150e 2010-09-25 pbug
1217 8c01150e 2010-09-25 pbug break;
1218 8c01150e 2010-09-25 pbug case DNS_TYPE_AAAA:
1219 8c01150e 2010-09-25 pbug /*
1220 8c01150e 2010-09-25 pbug * scan addresses in this struct domain and check if
1221 8c01150e 2010-09-25 pbug * this one exists already...
1222 8c01150e 2010-09-25 pbug */
1223 8c01150e 2010-09-25 pbug
1224 8c01150e 2010-09-25 pbug update = 1;
1225 8c01150e 2010-09-25 pbug for (j = 0; j < sdomain.aaaa_count; j++) {
1226 f98bb34d 2011-09-19 pbug if (memcmp(&sdomain.aaaa[j], p, sizeof(struct in6_addr)) == 0) {
1227 8c01150e 2010-09-25 pbug #if 0
1228 dd869383 2013-02-16 pjp dolog(LOG_INFO, "record exists already");
1229 8c01150e 2010-09-25 pbug #endif
1230 8c01150e 2010-09-25 pbug update = 0;
1231 8c01150e 2010-09-25 pbug }
1232 8c01150e 2010-09-25 pbug }
1233 8c01150e 2010-09-25 pbug
1234 8c01150e 2010-09-25 pbug if (j >= RECORD_COUNT) {
1235 dd869383 2013-02-16 pjp dolog(LOG_INFO, "db can't hold any more records\n");
1236 8c01150e 2010-09-25 pbug update = 0;
1237 8c01150e 2010-09-25 pbug }
1238 8c01150e 2010-09-25 pbug
1239 f1e825ef 2010-09-28 pbug /*
1240 f1e825ef 2010-09-28 pbug * check if we're a 2nd level domain or higher and
1241 f1e825ef 2010-09-28 pbug * if we were directly querying the zone...
1242 f1e825ef 2010-09-28 pbug */
1243 f1e825ef 2010-09-28 pbug
1244 8c01150e 2010-09-25 pbug if (update) {
1245 f1e825ef 2010-09-28 pbug if (level(sr->lookrecord) > 1) {
1246 f1e825ef 2010-09-28 pbug if (!contains(sr->lookrecord, converted_name[i])) {
1247 f1e825ef 2010-09-28 pbug memcpy(ns.nsserver, converted_name[i], cn_len[i]);
1248 f1e825ef 2010-09-28 pbug ns.nslen = cn_len[i];
1249 f1e825ef 2010-09-28 pbug
1250 f1e825ef 2010-09-28 pbug fakerecurse(db, sr, &ns, DNS_TYPE_AAAA);
1251 f1e825ef 2010-09-28 pbug update = 0;
1252 f1e825ef 2010-09-28 pbug }
1253 f1e825ef 2010-09-28 pbug }
1254 f1e825ef 2010-09-28 pbug }
1255 f1e825ef 2010-09-28 pbug
1256 f1e825ef 2010-09-28 pbug if (update) {
1257 f98bb34d 2011-09-19 pbug memcpy(&sdomain.aaaa[j], p, sizeof(struct in6_addr));
1258 8c01150e 2010-09-25 pbug sdomain.aaaa_count++;
1259 8c01150e 2010-09-25 pbug sdomain.aaaa_ptr = 0;
1260 8c01150e 2010-09-25 pbug sdomain.flags |= DOMAIN_HAVE_AAAA;
1261 8c01150e 2010-09-25 pbug sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1262 8c01150e 2010-09-25 pbug sdomain.created = time(NULL);
1263 8c01150e 2010-09-25 pbug sdomain.ttl = ntohl(a->ttl);
1264 8c01150e 2010-09-25 pbug
1265 8c01150e 2010-09-25 pbug if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1266 8c01150e 2010-09-25 pbug update_db(db, &sdomain);
1267 8c01150e 2010-09-25 pbug inet_ntop(AF_INET6, p, abuf, sizeof(abuf));
1268 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "updateing zone %s with address %s ttl= %u\n", converted_name[i], abuf, sdomain.ttl);
1269 8c01150e 2010-09-25 pbug }
1270 08769151 2010-10-03 pbug }
1271 8c01150e 2010-09-25 pbug
1272 b36746d8 2010-09-25 pbug if (pointer > 2) {
1273 dd869383 2013-02-16 pjp dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1274 b36746d8 2010-09-25 pbug return (-1);
1275 b36746d8 2010-09-25 pbug }
1276 8c01150e 2010-09-25 pbug rrcount[pointer]--;
1277 8c01150e 2010-09-25 pbug if (rrcount[pointer] == 0)
1278 8c01150e 2010-09-25 pbug pointer++;
1279 b36746d8 2010-09-25 pbug
1280 1f906207 2010-09-17 pbug p += 16; /* sizeof 4 * 32 bit */
1281 1f906207 2010-09-17 pbug break;
1282 1f906207 2010-09-17 pbug case DNS_TYPE_TXT:
1283 b55adb0c 2010-09-26 pbug txtlen = (*p);
1284 f98bb34d 2011-09-19 pbug
1285 f98bb34d 2011-09-19 pbug memcpy(&sdomain.txt, (p + 1), txtlen);
1286 b55adb0c 2010-09-26 pbug sdomain.txtlen = txtlen;
1287 b55adb0c 2010-09-26 pbug
1288 b55adb0c 2010-09-26 pbug sdomain.flags |= DOMAIN_HAVE_TXT;
1289 b55adb0c 2010-09-26 pbug sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1290 b55adb0c 2010-09-26 pbug sdomain.created = time(NULL);
1291 b55adb0c 2010-09-26 pbug sdomain.ttl = ntohl(a->ttl);
1292 b55adb0c 2010-09-26 pbug
1293 b55adb0c 2010-09-26 pbug if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1294 b55adb0c 2010-09-26 pbug update_db(db, &sdomain);
1295 b55adb0c 2010-09-26 pbug }
1296 b55adb0c 2010-09-26 pbug
1297 b55adb0c 2010-09-26 pbug if (pointer > 2) {
1298 dd869383 2013-02-16 pjp dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1299 b55adb0c 2010-09-26 pbug return (-1);
1300 b55adb0c 2010-09-26 pbug }
1301 b55adb0c 2010-09-26 pbug
1302 b55adb0c 2010-09-26 pbug rrcount[pointer]--;
1303 b55adb0c 2010-09-26 pbug if (rrcount[pointer] == 0)
1304 b55adb0c 2010-09-26 pbug pointer++;
1305 b55adb0c 2010-09-26 pbug
1306 b55adb0c 2010-09-26 pbug
1307 1f906207 2010-09-17 pbug p += *p;
1308 1f906207 2010-09-17 pbug p++;
1309 1f906207 2010-09-17 pbug break;
1310 1f906207 2010-09-17 pbug case DNS_TYPE_MX:
1311 8bd942da 2010-09-26 pbug preference = (u_int16_t *)p;
1312 1f906207 2010-09-17 pbug p += sizeof(u_int16_t); /* mx_priority */
1313 1f906207 2010-09-17 pbug /* FALLTHROUGH */
1314 1f906207 2010-09-17 pbug case DNS_TYPE_NS:
1315 1f906207 2010-09-17 pbug case DNS_TYPE_PTR:
1316 1f906207 2010-09-17 pbug case DNS_TYPE_CNAME:
1317 1f906207 2010-09-17 pbug label[++i] = p;
1318 1f906207 2010-09-17 pbug while (p <= end && *p) {
1319 1f906207 2010-09-17 pbug if ((*p & 0xc0) == 0xc0) {
1320 1f906207 2010-09-17 pbug p++;
1321 1f906207 2010-09-17 pbug break;
1322 1f906207 2010-09-17 pbug }
1323 1f906207 2010-09-17 pbug p += *p;
1324 1f906207 2010-09-17 pbug p++;
1325 1f906207 2010-09-17 pbug
1326 1f906207 2010-09-17 pbug if (p > end)
1327 1f906207 2010-09-17 pbug goto end;
1328 1f906207 2010-09-17 pbug }
1329 1f906207 2010-09-17 pbug
1330 b55adb0c 2010-09-26 pbug if (ntohs(a->type) == DNS_TYPE_CNAME) {
1331 f1e825ef 2010-09-28 pbug /*
1332 f1e825ef 2010-09-28 pbug * we check this as well as the A and AAAA
1333 f1e825ef 2010-09-28 pbug * types since it may be possible to glue
1334 f1e825ef 2010-09-28 pbug * a CNAME instead of an A and thus poison
1335 f1e825ef 2010-09-28 pbug * our cache...
1336 f1e825ef 2010-09-28 pbug */
1337 f1e825ef 2010-09-28 pbug if (level(sr->lookrecord) > 1) {
1338 f1e825ef 2010-09-28 pbug if (!contains(sr->lookrecord, converted_name[i - 1])) {
1339 f1e825ef 2010-09-28 pbug
1340 f1e825ef 2010-09-28 pbug memcpy(ns.nsserver, converted_name[i - 1], cn_len[i - 1]);
1341 f1e825ef 2010-09-28 pbug ns.nslen = cn_len[i];
1342 f1e825ef 2010-09-28 pbug
1343 f1e825ef 2010-09-28 pbug fakerecurse(db, sr, &ns, DNS_TYPE_A);
1344 f1e825ef 2010-09-28 pbug rrcount[pointer]--;
1345 f1e825ef 2010-09-28 pbug if (rrcount[pointer] == 0)
1346 f1e825ef 2010-09-28 pbug pointer++;
1347 f1e825ef 2010-09-28 pbug p++;
1348 f1e825ef 2010-09-28 pbug break;
1349 f1e825ef 2010-09-28 pbug }
1350 f1e825ef 2010-09-28 pbug }
1351 3553d5f3 2010-09-26 pbug
1352 f98bb34d 2011-09-19 pbug memcpy(&sdomain.cname, converted_name[i], cn_len[i]);
1353 b55adb0c 2010-09-26 pbug sdomain.cnamelen = cn_len[i];
1354 b55adb0c 2010-09-26 pbug
1355 b55adb0c 2010-09-26 pbug sdomain.flags |= DOMAIN_HAVE_CNAME;
1356 b55adb0c 2010-09-26 pbug sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1357 b55adb0c 2010-09-26 pbug sdomain.created = time(NULL);
1358 b55adb0c 2010-09-26 pbug sdomain.ttl = ntohl(a->ttl);
1359 b55adb0c 2010-09-26 pbug
1360 b55adb0c 2010-09-26 pbug if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1361 b55adb0c 2010-09-26 pbug update_db(db, &sdomain);
1362 b55adb0c 2010-09-26 pbug #if 1
1363 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "updateing zone %s with PTR name %s ttl= %u\n", converted_name[i - 1], converted_name[i], sdomain.ttl);
1364 b55adb0c 2010-09-26 pbug #endif
1365 b55adb0c 2010-09-26 pbug }
1366 b55adb0c 2010-09-26 pbug
1367 b55adb0c 2010-09-26 pbug if (pointer > 2) {
1368 dd869383 2013-02-16 pjp dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1369 b55adb0c 2010-09-26 pbug return (-1);
1370 b55adb0c 2010-09-26 pbug }
1371 b55adb0c 2010-09-26 pbug
1372 b55adb0c 2010-09-26 pbug rrcount[pointer]--;
1373 b55adb0c 2010-09-26 pbug if (rrcount[pointer] == 0)
1374 b55adb0c 2010-09-26 pbug pointer++;
1375 b55adb0c 2010-09-26 pbug } else if (ntohs(a->type) == DNS_TYPE_PTR) {
1376 f98bb34d 2011-09-19 pbug memcpy(&sdomain.ptr, converted_name[i], cn_len[i]);
1377 3553d5f3 2010-09-26 pbug sdomain.ptrlen = cn_len[i];
1378 3553d5f3 2010-09-26 pbug
1379 3553d5f3 2010-09-26 pbug sdomain.flags |= DOMAIN_HAVE_PTR;
1380 3553d5f3 2010-09-26 pbug sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1381 3553d5f3 2010-09-26 pbug sdomain.created = time(NULL);
1382 3553d5f3 2010-09-26 pbug sdomain.ttl = ntohl(a->ttl);
1383 3553d5f3 2010-09-26 pbug
1384 3553d5f3 2010-09-26 pbug if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1385 3553d5f3 2010-09-26 pbug update_db(db, &sdomain);
1386 3553d5f3 2010-09-26 pbug #if 1
1387 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "updateing zone %s with PTR name %s ttl= %u\n", converted_name[i - 1], converted_name[i], sdomain.ttl);
1388 3553d5f3 2010-09-26 pbug #endif
1389 3553d5f3 2010-09-26 pbug }
1390 8bd942da 2010-09-26 pbug
1391 8bd942da 2010-09-26 pbug if (pointer > 2) {
1392 dd869383 2013-02-16 pjp dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1393 8bd942da 2010-09-26 pbug return (-1);
1394 8bd942da 2010-09-26 pbug }
1395 8bd942da 2010-09-26 pbug
1396 8bd942da 2010-09-26 pbug rrcount[pointer]--;
1397 8bd942da 2010-09-26 pbug if (rrcount[pointer] == 0)
1398 8bd942da 2010-09-26 pbug pointer++;
1399 3553d5f3 2010-09-26 pbug } else if (ntohs(a->type) == DNS_TYPE_NS) {
1400 1f906207 2010-09-17 pbug update = 1;
1401 1f906207 2010-09-17 pbug for (j = 0; j < sdomain.ns_count; j++) {
1402 f98bb34d 2011-09-19 pbug if (memcasecmp((u_char *)sdomain.ns[j].nsserver, (u_char *)converted_name[i], MIN(cn_len[i], sdomain.ns[j].nslen)) == 0) {
1403 22893736 2010-09-19 pbug #if 0
1404 dd869383 2013-02-16 pjp dolog(LOG_INFO, "record exists already");
1405 22893736 2010-09-19 pbug #endif
1406 1f906207 2010-09-17 pbug update = 0;
1407 1f906207 2010-09-17 pbug }
1408 1f906207 2010-09-17 pbug }
1409 1f906207 2010-09-17 pbug
1410 1f906207 2010-09-17 pbug if (j >= RECORD_COUNT) {
1411 dd869383 2013-02-16 pjp dolog(LOG_INFO, "db can't hold any more records\n");
1412 1f906207 2010-09-17 pbug update = 0;
1413 1f906207 2010-09-17 pbug }
1414 1f906207 2010-09-17 pbug
1415 1f906207 2010-09-17 pbug if (update) {
1416 f98bb34d 2011-09-19 pbug memcpy(sdomain.ns[j].nsserver, converted_name[i], cn_len[i]);
1417 f98bb34d 2011-09-19 pbug sdomain.ns[j].nslen = cn_len[i];
1418 1f906207 2010-09-17 pbug
1419 1f906207 2010-09-17 pbug sdomain.ns_count++;
1420 1f906207 2010-09-17 pbug sdomain.ns_ptr = 0;
1421 1f906207 2010-09-17 pbug sdomain.flags |= DOMAIN_HAVE_NS;
1422 1f906207 2010-09-17 pbug sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1423 1f906207 2010-09-17 pbug sdomain.created = time(NULL);
1424 1f906207 2010-09-17 pbug sdomain.ttl = ntohl(a->ttl);
1425 1f906207 2010-09-17 pbug
1426 1f906207 2010-09-17 pbug if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1427 1f906207 2010-09-17 pbug update_db(db, &sdomain);
1428 1f906207 2010-09-17 pbug #if 0
1429 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "updateing zone %s with NS name %s ttl= %u\n", converted_name[i - 1], converted_name[i], sdomain.ttl);
1430 1f906207 2010-09-17 pbug #endif
1431 1f906207 2010-09-17 pbug }
1432 1f906207 2010-09-17 pbug } /* if update */
1433 8c01150e 2010-09-25 pbug if (pointer > 2) {
1434 dd869383 2013-02-16 pjp dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1435 8c01150e 2010-09-25 pbug return (-1);
1436 8c01150e 2010-09-25 pbug }
1437 1f906207 2010-09-17 pbug
1438 b36746d8 2010-09-25 pbug rrcount[pointer]--;
1439 b36746d8 2010-09-25 pbug if (pointer == 1) /* authoritative */
1440 b36746d8 2010-09-25 pbug sr->authoritative = DNS_TYPE_NS;
1441 8bd942da 2010-09-26 pbug if (rrcount[pointer] == 0)
1442 8bd942da 2010-09-26 pbug pointer++;
1443 8bd942da 2010-09-26 pbug
1444 8bd942da 2010-09-26 pbug } else if (ntohs(a->type) == DNS_TYPE_MX) {
1445 8bd942da 2010-09-26 pbug update = 1;
1446 8bd942da 2010-09-26 pbug for (j = 0; j < sdomain.mx_count; j++) {
1447 f98bb34d 2011-09-19 pbug if (memcasecmp((u_char *)sdomain.mx[j].exchange, (u_char *)converted_name[i], MIN(cn_len[i], sdomain.mx[j].exchangelen)) == 0) {
1448 8bd942da 2010-09-26 pbug update = 0;
1449 8bd942da 2010-09-26 pbug }
1450 8bd942da 2010-09-26 pbug }
1451 8bd942da 2010-09-26 pbug
1452 8bd942da 2010-09-26 pbug if (j >= RECORD_COUNT) {
1453 dd869383 2013-02-16 pjp dolog(LOG_INFO, "db can't hold any more records\n");
1454 8bd942da 2010-09-26 pbug update = 0;
1455 8bd942da 2010-09-26 pbug }
1456 8bd942da 2010-09-26 pbug
1457 8bd942da 2010-09-26 pbug if (update) {
1458 f98bb34d 2011-09-19 pbug memcpy(&sdomain.mx[j].exchange, converted_name[i], cn_len[i]);
1459 f98bb34d 2011-09-19 pbug sdomain.mx[j].exchangelen = cn_len[i];
1460 f98bb34d 2011-09-19 pbug sdomain.mx[j].preference = ntohs(*preference);
1461 8bd942da 2010-09-26 pbug
1462 8bd942da 2010-09-26 pbug sdomain.mx_count++;
1463 8bd942da 2010-09-26 pbug sdomain.mx_ptr = 0;
1464 8bd942da 2010-09-26 pbug sdomain.flags |= DOMAIN_HAVE_MX;
1465 8bd942da 2010-09-26 pbug sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1466 8bd942da 2010-09-26 pbug sdomain.created = time(NULL);
1467 8bd942da 2010-09-26 pbug sdomain.ttl = ntohl(a->ttl);
1468 8bd942da 2010-09-26 pbug
1469 8bd942da 2010-09-26 pbug if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1470 8bd942da 2010-09-26 pbug update_db(db, &sdomain);
1471 8bd942da 2010-09-26 pbug #if 0
1472 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "updateing zone %s with MX name %s ttl= %u\n", converted_name[i - 1], converted_name[i], sdomain.ttl);
1473 8bd942da 2010-09-26 pbug #endif
1474 8bd942da 2010-09-26 pbug }
1475 8bd942da 2010-09-26 pbug } /* if update */
1476 8bd942da 2010-09-26 pbug if (pointer > 2) {
1477 dd869383 2013-02-16 pjp dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1478 8bd942da 2010-09-26 pbug return (-1);
1479 8bd942da 2010-09-26 pbug }
1480 8bd942da 2010-09-26 pbug
1481 8bd942da 2010-09-26 pbug rrcount[pointer]--;
1482 8bd942da 2010-09-26 pbug #if 0
1483 8bd942da 2010-09-26 pbug if (pointer == 1) /* authoritative */
1484 8bd942da 2010-09-26 pbug sr->authoritative = DNS_TYPE_MX;
1485 8bd942da 2010-09-26 pbug #endif
1486 b36746d8 2010-09-25 pbug if (rrcount[pointer] == 0)
1487 b36746d8 2010-09-25 pbug pointer++;
1488 b36746d8 2010-09-25 pbug
1489 1f906207 2010-09-17 pbug } /* if type ns */
1490 1f906207 2010-09-17 pbug
1491 1f906207 2010-09-17 pbug p++; /* one more */
1492 1f906207 2010-09-17 pbug break;
1493 1f906207 2010-09-17 pbug case DNS_TYPE_SOA:
1494 1f906207 2010-09-17 pbug /* nsserver */
1495 1f906207 2010-09-17 pbug label[++i] = p;
1496 1f906207 2010-09-17 pbug while (p <= end && *p) {
1497 1f906207 2010-09-17 pbug if ((*p & 0xc0) == 0xc0) {
1498 1f906207 2010-09-17 pbug p++;
1499 1f906207 2010-09-17 pbug break;
1500 1f906207 2010-09-17 pbug }
1501 1f906207 2010-09-17 pbug p += *p;
1502 1f906207 2010-09-17 pbug p++;
1503 1f906207 2010-09-17 pbug if (p > end)
1504 1f906207 2010-09-17 pbug goto end;
1505 1f906207 2010-09-17 pbug }
1506 1f906207 2010-09-17 pbug
1507 1f906207 2010-09-17 pbug p++; /* one more */
1508 1f906207 2010-09-17 pbug
1509 1f906207 2010-09-17 pbug if (p > end)
1510 1f906207 2010-09-17 pbug goto end;
1511 1f906207 2010-09-17 pbug
1512 1f906207 2010-09-17 pbug /* responsible person */
1513 1f906207 2010-09-17 pbug label[++i] = p;
1514 1f906207 2010-09-17 pbug while (p <= end && *p) {
1515 1f906207 2010-09-17 pbug if ((*p & 0xc0) == 0xc0) {
1516 1f906207 2010-09-17 pbug p++;
1517 1f906207 2010-09-17 pbug break;
1518 1f906207 2010-09-17 pbug }
1519 1f906207 2010-09-17 pbug p += *p;
1520 1f906207 2010-09-17 pbug p++;
1521 1f906207 2010-09-17 pbug }
1522 1f906207 2010-09-17 pbug
1523 1f906207 2010-09-17 pbug p++; /* one more */
1524 1f906207 2010-09-17 pbug
1525 1f906207 2010-09-17 pbug if (p > end)
1526 1f906207 2010-09-17 pbug goto end;
1527 1f906207 2010-09-17 pbug
1528 dbaa9c14 2010-09-23 pbug mysoa = (struct mysoa *)p;
1529 dbaa9c14 2010-09-23 pbug p += sizeof(struct mysoa); /* advance struct soa */
1530 1f906207 2010-09-17 pbug
1531 dbaa9c14 2010-09-23 pbug /* malloc struct soa */
1532 dbaa9c14 2010-09-23 pbug
1533 dbaa9c14 2010-09-23 pbug soa = malloc(sizeof(struct soa));
1534 dbaa9c14 2010-09-23 pbug if (soa == NULL) {
1535 dd869383 2013-02-16 pjp dolog(LOG_ERR, "malloc: %m");
1536 dbaa9c14 2010-09-23 pbug return (-1);
1537 dbaa9c14 2010-09-23 pbug }
1538 dbaa9c14 2010-09-23 pbug
1539 dbaa9c14 2010-09-23 pbug memcpy(soa->nsserver, converted_name[i - 1], cn_len[i - 1]);
1540 dbaa9c14 2010-09-23 pbug soa->nsserver_len = cn_len[i - 1];
1541 dbaa9c14 2010-09-23 pbug memcpy(soa->responsible_person, converted_name[i], cn_len[i]);
1542 dbaa9c14 2010-09-23 pbug soa->rp_len = cn_len[i];
1543 b36746d8 2010-09-25 pbug soa->serial = ntohl(mysoa->serial);
1544 b36746d8 2010-09-25 pbug soa->refresh = ntohl(mysoa->refresh);
1545 b36746d8 2010-09-25 pbug soa->retry = ntohl(mysoa->retry);
1546 b36746d8 2010-09-25 pbug soa->expire = ntohl(mysoa->expire);
1547 b36746d8 2010-09-25 pbug soa->minttl = ntohl(mysoa->minttl);
1548 dbaa9c14 2010-09-23 pbug
1549 f98bb34d 2011-09-19 pbug memcpy(&sdomain.soa, soa, sizeof(sdomain.soa));
1550 f98bb34d 2011-09-19 pbug free(soa);
1551 f98bb34d 2011-09-19 pbug
1552 dbaa9c14 2010-09-23 pbug sdomain.flags |= DOMAIN_HAVE_SOA;
1553 dbaa9c14 2010-09-23 pbug sdomain.created = time(NULL);
1554 b36746d8 2010-09-25 pbug sdomain.ttl = htonl(a->ttl);
1555 dbaa9c14 2010-09-23 pbug
1556 dbaa9c14 2010-09-23 pbug if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1557 dbaa9c14 2010-09-23 pbug update_db(db, &sdomain);
1558 8c01150e 2010-09-25 pbug }
1559 8c01150e 2010-09-25 pbug
1560 8c01150e 2010-09-25 pbug if (pointer > 2) {
1561 dd869383 2013-02-16 pjp dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1562 8c01150e 2010-09-25 pbug return (-1);
1563 dbaa9c14 2010-09-23 pbug }
1564 dbaa9c14 2010-09-23 pbug
1565 b36746d8 2010-09-25 pbug rrcount[pointer]--;
1566 b36746d8 2010-09-25 pbug if (pointer == 1) /* authoritative */
1567 b36746d8 2010-09-25 pbug sr->authoritative = DNS_TYPE_SOA;
1568 b36746d8 2010-09-25 pbug if (rrcount[pointer] == 0)
1569 b36746d8 2010-09-25 pbug pointer++;
1570 b36746d8 2010-09-25 pbug
1571 b36746d8 2010-09-25 pbug
1572 1f906207 2010-09-17 pbug break;
1573 1f906207 2010-09-17 pbug default:
1574 1f906207 2010-09-17 pbug break;
1575 1f906207 2010-09-17 pbug /* XXX */
1576 1f906207 2010-09-17 pbug } /* switch */
1577 1f906207 2010-09-17 pbug
1578 1f906207 2010-09-17 pbug if (p >= end)
1579 1f906207 2010-09-17 pbug break;
1580 1f906207 2010-09-17 pbug } /* for (i *) */
1581 1f906207 2010-09-17 pbug
1582 1f906207 2010-09-17 pbug
1583 604e0a34 2010-09-15 pbug return (0);
1584 c7eceeba 2010-09-16 pbug
1585 c7eceeba 2010-09-16 pbug end:
1586 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "mangled input packet");
1587 c7eceeba 2010-09-16 pbug return (-1);
1588 c7eceeba 2010-09-16 pbug
1589 604e0a34 2010-09-15 pbug }
1590 1c8eb9ed 2010-09-17 pbug
1591 1c8eb9ed 2010-09-17 pbug
1592 1c8eb9ed 2010-09-17 pbug /*
1593 1c8eb9ed 2010-09-17 pbug * NETLOOKUP - do a internet lookup of the requested internet record
1594 1c8eb9ed 2010-09-17 pbug *
1595 1c8eb9ed 2010-09-17 pbug */
1596 1c8eb9ed 2010-09-17 pbug
1597 1c8eb9ed 2010-09-17 pbug int
1598 1c8eb9ed 2010-09-17 pbug netlookup(DB *db, struct recurses *sr)
1599 1c8eb9ed 2010-09-17 pbug {
1600 1c8eb9ed 2010-09-17 pbug struct sockaddr_in sin;
1601 1c8eb9ed 2010-09-17 pbug struct dns_header *dh;
1602 1c8eb9ed 2010-09-17 pbug
1603 1c8eb9ed 2010-09-17 pbug char buf[2048];
1604 3553d5f3 2010-09-26 pbug int flag;
1605 1c8eb9ed 2010-09-17 pbug
1606 1c8eb9ed 2010-09-17 pbug
1607 1c8eb9ed 2010-09-17 pbug /* do the network stuff then */
1608 1c8eb9ed 2010-09-17 pbug /* XXX should be IPv6 ready */
1609 518aa971 2010-09-30 pbug
1610 518aa971 2010-09-30 pbug if (sr->af == AF_INET6)
1611 518aa971 2010-09-30 pbug return (netlookup6(db, sr));
1612 518aa971 2010-09-30 pbug
1613 3553d5f3 2010-09-26 pbug if (sr->so != -1) {
1614 3553d5f3 2010-09-26 pbug if (close(sr->so) < 0)
1615 dd869383 2013-02-16 pjp dolog(LOG_ERR, "close: %m");
1616 3553d5f3 2010-09-26 pbug }
1617 3553d5f3 2010-09-26 pbug
1618 1c8eb9ed 2010-09-17 pbug sr->so = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1619 1c8eb9ed 2010-09-17 pbug if (sr->so < 0) {
1620 dd869383 2013-02-16 pjp dolog(LOG_ERR, "socket: %m");
1621 22893736 2010-09-19 pbug sr->so = -1;
1622 1c8eb9ed 2010-09-17 pbug return (-1);
1623 1c8eb9ed 2010-09-17 pbug }
1624 1c8eb9ed 2010-09-17 pbug
1625 fedd844f 2014-09-27 pjp sr->port = arc4random() & 0xffff;
1626 1c8eb9ed 2010-09-17 pbug /*
1627 1c8eb9ed 2010-09-17 pbug * we have to avoid picking servers already
1628 1c8eb9ed 2010-09-17 pbug * running ..
1629 1c8eb9ed 2010-09-17 pbug */
1630 1c8eb9ed 2010-09-17 pbug if (sr->port < 1024)
1631 1c8eb9ed 2010-09-17 pbug sr->port += 1024;
1632 1c8eb9ed 2010-09-17 pbug
1633 fedd844f 2014-09-27 pjp sr->id = arc4random() & 0xffff;
1634 1c8eb9ed 2010-09-17 pbug
1635 1c8eb9ed 2010-09-17 pbug memset(&sin, 0, sizeof(sin));
1636 1c8eb9ed 2010-09-17 pbug sin.sin_family = AF_INET;
1637 1c8eb9ed 2010-09-17 pbug sin.sin_port = htons(sr->port);
1638 1c8eb9ed 2010-09-17 pbug sin.sin_addr.s_addr = INADDR_ANY;
1639 1c8eb9ed 2010-09-17 pbug
1640 1c8eb9ed 2010-09-17 pbug if (bind(sr->so, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
1641 dd869383 2013-02-16 pjp dolog(LOG_ERR, "bind: %m");
1642 3553d5f3 2010-09-26 pbug if (close(sr->so) < 0) {
1643 dd869383 2013-02-16 pjp dolog(LOG_ERR, "close: %m");
1644 3553d5f3 2010-09-26 pbug }
1645 22893736 2010-09-19 pbug sr->so = -1;
1646 1c8eb9ed 2010-09-17 pbug return (-1);
1647 3553d5f3 2010-09-26 pbug }
1648 3553d5f3 2010-09-26 pbug
1649 3553d5f3 2010-09-26 pbug /*
1650 3553d5f3 2010-09-26 pbug * make this socket nonblocking
1651 3553d5f3 2010-09-26 pbug */
1652 3553d5f3 2010-09-26 pbug
1653 3553d5f3 2010-09-26 pbug if ((flag = fcntl(sr->so, F_GETFL)) < 0) {
1654 dd869383 2013-02-16 pjp dolog(LOG_INFO, "fcntl 3: %m");
1655 1c8eb9ed 2010-09-17 pbug }
1656 3553d5f3 2010-09-26 pbug flag |= O_NONBLOCK;
1657 3553d5f3 2010-09-26 pbug if (fcntl(sr->so, F_SETFL, flag) < 0) {
1658 dd869383 2013-02-16 pjp dolog(LOG_INFO, "fcntl 4: %m");
1659 3553d5f3 2010-09-26 pbug }
1660 1c8eb9ed 2010-09-17 pbug
1661 1c8eb9ed 2010-09-17 pbug if (lookup_ns(db, sr) <= 0) {
1662 dd869383 2013-02-16 pjp dolog(LOG_ERR, "can't establish any servers to reach for zone \"%s\"", sr->question->converted_name);
1663 3553d5f3 2010-09-26 pbug if (close(sr->so) < 0) {
1664 dd869383 2013-02-16 pjp dolog(LOG_ERR, "close: %m");
1665 3553d5f3 2010-09-26 pbug }
1666 22893736 2010-09-19 pbug sr->so = -1;
1667 1c8eb9ed 2010-09-17 pbug return (-1);
1668 1c8eb9ed 2010-09-17 pbug }
1669 1c8eb9ed 2010-09-17 pbug
1670 1c8eb9ed 2010-09-17 pbug memset(&sin, 0, sizeof(sin));
1671 1c8eb9ed 2010-09-17 pbug sin.sin_family = AF_INET;
1672 1c8eb9ed 2010-09-17 pbug sin.sin_port = htons(53);
1673 1c8eb9ed 2010-09-17 pbug
1674 1c8eb9ed 2010-09-17 pbug sin.sin_addr.s_addr = sr->a[0];
1675 1c8eb9ed 2010-09-17 pbug
1676 1c8eb9ed 2010-09-17 pbug /* XXX we use buf here in order to preserve
1677 1c8eb9ed 2010-09-17 pbug * the state of query...
1678 1c8eb9ed 2010-09-17 pbug */
1679 1c8eb9ed 2010-09-17 pbug memcpy(buf, sr->query, sr->len);
1680 1c8eb9ed 2010-09-17 pbug dh = (struct dns_header *)&buf[0];
1681 1c8eb9ed 2010-09-17 pbug NTOHS(dh->query);
1682 1c8eb9ed 2010-09-17 pbug UNSET_DNS_RECURSION(dh);
1683 1c8eb9ed 2010-09-17 pbug HTONS(dh->query);
1684 1c8eb9ed 2010-09-17 pbug dh->id = htons(sr->id);
1685 1c8eb9ed 2010-09-17 pbug
1686 1c8eb9ed 2010-09-17 pbug #if 1
1687 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sending request with id %u\n", sr->id);
1688 1c8eb9ed 2010-09-17 pbug
1689 1c8eb9ed 2010-09-17 pbug #endif
1690 1c8eb9ed 2010-09-17 pbug
1691 1c8eb9ed 2010-09-17 pbug if (sendto(sr->so, buf, sr->len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
1692 dd869383 2013-02-16 pjp dolog(LOG_ERR, "sendto: %m");
1693 3553d5f3 2010-09-26 pbug if (close(sr->so) < 0) {
1694 dd869383 2013-02-16 pjp dolog(LOG_ERR, "close: %m");
1695 3553d5f3 2010-09-26 pbug }
1696 22893736 2010-09-19 pbug sr->so = -1;
1697 1c8eb9ed 2010-09-17 pbug return (-1);
1698 1c8eb9ed 2010-09-17 pbug }
1699 1c8eb9ed 2010-09-17 pbug
1700 1c8eb9ed 2010-09-17 pbug sr->sent_last_query = time(NULL);
1701 437140e3 2010-09-25 pbug sr->packetcount++;
1702 1c8eb9ed 2010-09-17 pbug
1703 1c8eb9ed 2010-09-17 pbug
1704 1c8eb9ed 2010-09-17 pbug return (0);
1705 1c8eb9ed 2010-09-17 pbug }
1706 c8a9dee0 2010-09-18 pbug
1707 c8a9dee0 2010-09-18 pbug /*
1708 c8a9dee0 2010-09-18 pbug * FAKERECURSE - create a fake query of type A, for a nameserver that has
1709 c8a9dee0 2010-09-18 pbug * no glued A record, attach a callback to the struct recurses
1710 c8a9dee0 2010-09-18 pbug * that did the initiation for this...
1711 c8a9dee0 2010-09-18 pbug */
1712 c8a9dee0 2010-09-18 pbug
1713 c8a9dee0 2010-09-18 pbug int
1714 f1e825ef 2010-09-28 pbug fakerecurse(DB *db, struct recurses *sr, struct ns *ns, int type)
1715 c8a9dee0 2010-09-18 pbug {
1716 c8a9dee0 2010-09-18 pbug struct recurses *fakesr;
1717 c8a9dee0 2010-09-18 pbug struct dns_header *dh;
1718 c8a9dee0 2010-09-18 pbug
1719 c8a9dee0 2010-09-18 pbug char *p;
1720 22893736 2010-09-19 pbug
1721 c8a9dee0 2010-09-18 pbug int len;
1722 22893736 2010-09-19 pbug u_int16_t *qtype, *qclass;
1723 c8a9dee0 2010-09-18 pbug
1724 5528a18e 2010-09-21 pbug /* check if we have already started a fakerecurse on the same name */
1725 5528a18e 2010-09-21 pbug
1726 c0963faf 2014-05-01 pjp SLIST_FOREACH(sr2, &recurseshead, recurses_entry) {
1727 f1e825ef 2010-09-28 pbug if (memcasecmp((u_char *)ns->nsserver, (u_char *)sr2->question->hdr->name, MIN(ns->nslen, sr2->question->hdr->namelen)) == 0) {
1728 dd869383 2013-02-16 pjp dolog(LOG_INFO, "already have a fakerecurse structure with name %s, drop\n", ns->nsserver);
1729 5528a18e 2010-09-21 pbug return (-1);
1730 5528a18e 2010-09-21 pbug }
1731 5528a18e 2010-09-21 pbug }
1732 5528a18e 2010-09-21 pbug
1733 22893736 2010-09-19 pbug
1734 c8a9dee0 2010-09-18 pbug /* place request on struct recurses linked list */
1735 c8a9dee0 2010-09-18 pbug
1736 c8a9dee0 2010-09-18 pbug fakesr = calloc(sizeof(struct recurses), 1);
1737 c8a9dee0 2010-09-18 pbug if (fakesr == NULL) {
1738 dd869383 2013-02-16 pjp dolog(LOG_ERR, "calloc: %m");
1739 c8a9dee0 2010-09-18 pbug return (-1);
1740 c8a9dee0 2010-09-18 pbug }
1741 c8a9dee0 2010-09-18 pbug
1742 c8a9dee0 2010-09-18 pbug
1743 c8a9dee0 2010-09-18 pbug fakesr->af = sr->af;
1744 c8a9dee0 2010-09-18 pbug fakesr->proto = sr->proto;
1745 c8a9dee0 2010-09-18 pbug fakesr->so = -1;
1746 c8a9dee0 2010-09-18 pbug fakesr->callback = sr;
1747 22893736 2010-09-19 pbug sr->hascallback++;
1748 22893736 2010-09-19 pbug fakesr->hascallback = 0;
1749 c8a9dee0 2010-09-18 pbug fakesr->isfake = 1;
1750 5528a18e 2010-09-21 pbug fakesr->launched = 0;
1751 c8a9dee0 2010-09-18 pbug fakesr->received = time(NULL);
1752 437140e3 2010-09-25 pbug fakesr->packetcount = 0;
1753 f1e825ef 2010-09-28 pbug fakesr->lookrecord = NULL;
1754 c8a9dee0 2010-09-18 pbug
1755 f1e825ef 2010-09-28 pbug fakesr->question = build_fake_question(ns->nsserver, ns->nslen, htons(type));
1756 c8a9dee0 2010-09-18 pbug if (fakesr->question == NULL) {
1757 dd869383 2013-02-16 pjp dolog(LOG_ERR, "malformed question in recurse.c");
1758 c8a9dee0 2010-09-18 pbug free(fakesr);
1759 c8a9dee0 2010-09-18 pbug return (-1);
1760 c8a9dee0 2010-09-18 pbug }
1761 c8a9dee0 2010-09-18 pbug
1762 c8a9dee0 2010-09-18 pbug /* construct the question packet */
1763 c8a9dee0 2010-09-18 pbug
1764 c8a9dee0 2010-09-18 pbug len = sizeof(struct dns_header);
1765 c8a9dee0 2010-09-18 pbug dh = (struct dns_header *)fakesr->query;
1766 c8a9dee0 2010-09-18 pbug dh->id = htons(1);
1767 c8a9dee0 2010-09-18 pbug SET_DNS_QUERY(dh);
1768 c8a9dee0 2010-09-18 pbug HTONS(dh->query);
1769 c8a9dee0 2010-09-18 pbug dh->question = htons(1);
1770 c8a9dee0 2010-09-18 pbug dh->answer = 0;
1771 c8a9dee0 2010-09-18 pbug dh->nsrr = 0;
1772 c8a9dee0 2010-09-18 pbug dh->additional = 0;
1773 c8a9dee0 2010-09-18 pbug
1774 c8a9dee0 2010-09-18 pbug p = (char *)&fakesr->query[len];
1775 c8a9dee0 2010-09-18 pbug memcpy(p, ns->nsserver, ns->nslen);
1776 c8a9dee0 2010-09-18 pbug len += ns->nslen;
1777 22893736 2010-09-19 pbug qtype = (u_int16_t *)&fakesr->query[len];
1778 22893736 2010-09-19 pbug *qtype = fakesr->question->hdr->qtype;
1779 c8a9dee0 2010-09-18 pbug len += sizeof(u_int16_t);
1780 22893736 2010-09-19 pbug qclass = (u_int16_t *)&fakesr->query[len];
1781 22893736 2010-09-19 pbug *qclass = fakesr->question->hdr->qclass;
1782 c8a9dee0 2010-09-18 pbug len += sizeof(u_int16_t);
1783 c8a9dee0 2010-09-18 pbug
1784 c8a9dee0 2010-09-18 pbug fakesr->len = len;
1785 c8a9dee0 2010-09-18 pbug
1786 c0963faf 2014-05-01 pjp SLIST_INSERT_HEAD(&recurseshead, fakesr, recurses_entry);
1787 c8a9dee0 2010-09-18 pbug
1788 c8a9dee0 2010-09-18 pbug return (0);
1789 c8a9dee0 2010-09-18 pbug }
1790 dbaa9c14 2010-09-23 pbug
1791 dbaa9c14 2010-09-23 pbug /*
1792 dbaa9c14 2010-09-23 pbug * REPLY_RAW -
1793 dbaa9c14 2010-09-23 pbug *
1794 dbaa9c14 2010-09-23 pbug *
1795 dbaa9c14 2010-09-23 pbug */
1796 22893736 2010-09-19 pbug
1797 22893736 2010-09-19 pbug void
1798 22893736 2010-09-19 pbug reply_raw(DB *db, struct recurses *sr, struct domain *sd, int *raw)
1799 22893736 2010-09-19 pbug {
1800 22893736 2010-09-19 pbug int so;
1801 22893736 2010-09-19 pbug struct sreply sreply;
1802 22893736 2010-09-19 pbug
1803 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "reply_raw called");
1804 22893736 2010-09-19 pbug
1805 22893736 2010-09-19 pbug switch (sr->af) {
1806 22893736 2010-09-19 pbug case AF_INET:
1807 22893736 2010-09-19 pbug so = raw[0];
1808 22893736 2010-09-19 pbug break;
1809 22893736 2010-09-19 pbug case AF_INET6:
1810 22893736 2010-09-19 pbug so = raw[1];
1811 22893736 2010-09-19 pbug break;
1812 22893736 2010-09-19 pbug default:
1813 dd869383 2013-02-16 pjp dolog(LOG_ERR, "reply_raw(): unknown address family in struct recurses");
1814 fe3d3220 2010-09-21 pbug return;
1815 fe3d3220 2010-09-21 pbug }
1816 fe3d3220 2010-09-21 pbug
1817 fe3d3220 2010-09-21 pbug switch (sr->proto) {
1818 fe3d3220 2010-09-21 pbug case IPPROTO_UDP:
1819 fe3d3220 2010-09-21 pbug break;
1820 fe3d3220 2010-09-21 pbug default:
1821 dd869383 2013-02-16 pjp dolog(LOG_ERR, "reply_raw(): can't do any protocol other than udp right now");
1822 22893736 2010-09-19 pbug return;
1823 22893736 2010-09-19 pbug }
1824 22893736 2010-09-19 pbug
1825 22893736 2010-09-19 pbug build_reply(&sreply, so, sr->query, sr->len, sr->question, NULL, 0, sd, NULL, 0xff, 0, 0, sr);
1826 22893736 2010-09-19 pbug
1827 22893736 2010-09-19 pbug switch (ntohs(sr->question->hdr->qtype)) {
1828 22893736 2010-09-19 pbug case DNS_TYPE_A:
1829 22893736 2010-09-19 pbug reply_a(&sreply, db);
1830 22893736 2010-09-19 pbug break;
1831 8c01150e 2010-09-25 pbug case DNS_TYPE_AAAA:
1832 8c01150e 2010-09-25 pbug reply_aaaa(&sreply, db);
1833 8c01150e 2010-09-25 pbug break;
1834 09fdca23 2010-09-25 pbug case DNS_TYPE_NS:
1835 09fdca23 2010-09-25 pbug reply_ns(&sreply, db);
1836 3553d5f3 2010-09-26 pbug break;
1837 3553d5f3 2010-09-26 pbug case DNS_TYPE_PTR:
1838 3553d5f3 2010-09-26 pbug reply_ptr(&sreply);
1839 09fdca23 2010-09-25 pbug break;
1840 8bd942da 2010-09-26 pbug case DNS_TYPE_MX:
1841 8bd942da 2010-09-26 pbug reply_mx(&sreply, db);
1842 8bd942da 2010-09-26 pbug break;
1843 b55adb0c 2010-09-26 pbug case DNS_TYPE_SOA:
1844 b55adb0c 2010-09-26 pbug reply_soa(&sreply);
1845 b55adb0c 2010-09-26 pbug break;
1846 b55adb0c 2010-09-26 pbug case DNS_TYPE_CNAME:
1847 b55adb0c 2010-09-26 pbug reply_cname(&sreply);
1848 b55adb0c 2010-09-26 pbug break;
1849 b55adb0c 2010-09-26 pbug case DNS_TYPE_TXT:
1850 b55adb0c 2010-09-26 pbug reply_txt(&sreply);
1851 b55adb0c 2010-09-26 pbug break;
1852 22893736 2010-09-19 pbug default:
1853 dd869383 2013-02-16 pjp dolog(LOG_ERR, "other types have not been implemented yet");
1854 22893736 2010-09-19 pbug break;
1855 22893736 2010-09-19 pbug }
1856 22893736 2010-09-19 pbug
1857 22893736 2010-09-19 pbug return;
1858 fe3d3220 2010-09-21 pbug }
1859 fe3d3220 2010-09-21 pbug
1860 b55adb0c 2010-09-26 pbug void
1861 b55adb0c 2010-09-26 pbug reply_raw_cname(DB *db, struct recurses *sr, struct domain *sd, int *raw)
1862 b55adb0c 2010-09-26 pbug {
1863 b55adb0c 2010-09-26 pbug int so;
1864 b55adb0c 2010-09-26 pbug struct sreply sreply;
1865 b55adb0c 2010-09-26 pbug
1866 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "reply_raw called");
1867 b55adb0c 2010-09-26 pbug
1868 b55adb0c 2010-09-26 pbug switch (sr->af) {
1869 b55adb0c 2010-09-26 pbug case AF_INET:
1870 b55adb0c 2010-09-26 pbug so = raw[0];
1871 b55adb0c 2010-09-26 pbug break;
1872 b55adb0c 2010-09-26 pbug case AF_INET6:
1873 b55adb0c 2010-09-26 pbug so = raw[1];
1874 b55adb0c 2010-09-26 pbug break;
1875 b55adb0c 2010-09-26 pbug default:
1876 dd869383 2013-02-16 pjp dolog(LOG_ERR, "reply_raw_cname(): unknown address family in struct recurses");
1877 b55adb0c 2010-09-26 pbug return;
1878 b55adb0c 2010-09-26 pbug }
1879 b55adb0c 2010-09-26 pbug
1880 b55adb0c 2010-09-26 pbug switch (sr->proto) {
1881 b55adb0c 2010-09-26 pbug case IPPROTO_UDP:
1882 b55adb0c 2010-09-26 pbug break;
1883 b55adb0c 2010-09-26 pbug default:
1884 dd869383 2013-02-16 pjp dolog(LOG_ERR, "reply_raw_cname(): can't do any protocol other than udp right now");
1885 b55adb0c 2010-09-26 pbug return;
1886 b55adb0c 2010-09-26 pbug }
1887 b55adb0c 2010-09-26 pbug
1888 b55adb0c 2010-09-26 pbug build_reply(&sreply, so, sr->query, sr->len, sr->question, NULL, 0, sd, NULL, 0xff, 0, 0, sr);
1889 b55adb0c 2010-09-26 pbug
1890 b55adb0c 2010-09-26 pbug reply_cname(&sreply);
1891 b55adb0c 2010-09-26 pbug
1892 b55adb0c 2010-09-26 pbug return;
1893 b55adb0c 2010-09-26 pbug }
1894 b55adb0c 2010-09-26 pbug
1895 fe3d3220 2010-09-21 pbug /*
1896 fe3d3220 2010-09-21 pbug * REMOVE_ZONE - remove a zone from the database (it probably expired)
1897 fe3d3220 2010-09-21 pbug *
1898 fe3d3220 2010-09-21 pbug *
1899 fe3d3220 2010-09-21 pbug */
1900 fe3d3220 2010-09-21 pbug
1901 fe3d3220 2010-09-21 pbug void
1902 fe3d3220 2010-09-21 pbug remove_zone(DB *db, struct domain *sd)
1903 fe3d3220 2010-09-21 pbug {
1904 fe3d3220 2010-09-21 pbug DBT key;
1905 fe3d3220 2010-09-21 pbug char *zone;
1906 fe3d3220 2010-09-21 pbug int zonelen;
1907 fe3d3220 2010-09-21 pbug
1908 fe3d3220 2010-09-21 pbug zone = sd->zone;
1909 fe3d3220 2010-09-21 pbug zonelen = sd->zonelen;
1910 fe3d3220 2010-09-21 pbug
1911 fe3d3220 2010-09-21 pbug key.data = (char *)zone;
1912 fe3d3220 2010-09-21 pbug key.size = zonelen;
1913 fe3d3220 2010-09-21 pbug
1914 ce12744a 2010-09-25 pbug if (db->del(db, NULL, &key, 0) != 0) {
1915 dd869383 2013-02-16 pjp dolog(LOG_ERR, "could not delete zone %s: %m", zone);
1916 fe3d3220 2010-09-21 pbug }
1917 fe3d3220 2010-09-21 pbug
1918 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "deleting zone %s\n", zone);
1919 fe3d3220 2010-09-21 pbug
1920 fe3d3220 2010-09-21 pbug free(zone);
1921 fe3d3220 2010-09-21 pbug
1922 fe3d3220 2010-09-21 pbug return;
1923 b36746d8 2010-09-25 pbug }
1924 b36746d8 2010-09-25 pbug
1925 b36746d8 2010-09-25 pbug void
1926 b36746d8 2010-09-25 pbug reply_raw_noerror(DB *db, struct recurses *sr, struct domain *sd, int *raw)
1927 b36746d8 2010-09-25 pbug {
1928 b36746d8 2010-09-25 pbug int so;
1929 b36746d8 2010-09-25 pbug struct sreply sreply;
1930 b36746d8 2010-09-25 pbug
1931 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "reply_raw_noerror called");
1932 b36746d8 2010-09-25 pbug
1933 b36746d8 2010-09-25 pbug switch (sr->af) {
1934 b36746d8 2010-09-25 pbug case AF_INET:
1935 b36746d8 2010-09-25 pbug so = raw[0];
1936 b36746d8 2010-09-25 pbug break;
1937 b36746d8 2010-09-25 pbug case AF_INET6:
1938 b36746d8 2010-09-25 pbug so = raw[1];
1939 b36746d8 2010-09-25 pbug break;
1940 b36746d8 2010-09-25 pbug default:
1941 dd869383 2013-02-16 pjp dolog(LOG_ERR, "reply_raw_noerror(): unknown address family in struct recurses");
1942 b36746d8 2010-09-25 pbug return;
1943 b36746d8 2010-09-25 pbug }
1944 b36746d8 2010-09-25 pbug
1945 b36746d8 2010-09-25 pbug switch (sr->proto) {
1946 b36746d8 2010-09-25 pbug case IPPROTO_UDP:
1947 b36746d8 2010-09-25 pbug break;
1948 b36746d8 2010-09-25 pbug default:
1949 dd869383 2013-02-16 pjp dolog(LOG_ERR, "reply_raw_noerror(): can't do any protocol other than udp right now");
1950 b36746d8 2010-09-25 pbug return;
1951 b36746d8 2010-09-25 pbug }
1952 b36746d8 2010-09-25 pbug
1953 b36746d8 2010-09-25 pbug build_reply(&sreply, so, sr->query, sr->len, sr->question, NULL, 0, sd, NULL, 0xff, 0, 0, sr);
1954 b36746d8 2010-09-25 pbug
1955 b36746d8 2010-09-25 pbug reply_noerror(&sreply);
1956 df7b3e7e 2010-09-25 pbug
1957 df7b3e7e 2010-09-25 pbug return;
1958 df7b3e7e 2010-09-25 pbug }
1959 df7b3e7e 2010-09-25 pbug
1960 df7b3e7e 2010-09-25 pbug void
1961 df7b3e7e 2010-09-25 pbug reply_raw_nxdomain(DB *db, struct recurses *sr, struct domain *sd, int *raw)
1962 df7b3e7e 2010-09-25 pbug {
1963 df7b3e7e 2010-09-25 pbug int so;
1964 df7b3e7e 2010-09-25 pbug struct sreply sreply;
1965 df7b3e7e 2010-09-25 pbug
1966 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "reply_raw_nxdomain called");
1967 b36746d8 2010-09-25 pbug
1968 df7b3e7e 2010-09-25 pbug switch (sr->af) {
1969 df7b3e7e 2010-09-25 pbug case AF_INET:
1970 df7b3e7e 2010-09-25 pbug so = raw[0];
1971 df7b3e7e 2010-09-25 pbug break;
1972 df7b3e7e 2010-09-25 pbug case AF_INET6:
1973 df7b3e7e 2010-09-25 pbug so = raw[1];
1974 df7b3e7e 2010-09-25 pbug break;
1975 df7b3e7e 2010-09-25 pbug default:
1976 dd869383 2013-02-16 pjp dolog(LOG_ERR, "reply_raw_nxdomain(): unknown address family in struct recurses");
1977 df7b3e7e 2010-09-25 pbug return;
1978 df7b3e7e 2010-09-25 pbug }
1979 df7b3e7e 2010-09-25 pbug
1980 df7b3e7e 2010-09-25 pbug switch (sr->proto) {
1981 df7b3e7e 2010-09-25 pbug case IPPROTO_UDP:
1982 df7b3e7e 2010-09-25 pbug break;
1983 df7b3e7e 2010-09-25 pbug default:
1984 dd869383 2013-02-16 pjp dolog(LOG_ERR, "reply_raw_nxdomain(): can't do any protocol other than udp right now");
1985 df7b3e7e 2010-09-25 pbug return;
1986 df7b3e7e 2010-09-25 pbug }
1987 df7b3e7e 2010-09-25 pbug
1988 df7b3e7e 2010-09-25 pbug build_reply(&sreply, so, sr->query, sr->len, sr->question, NULL, 0, sd, NULL, 0xff, 0, 0, sr);
1989 df7b3e7e 2010-09-25 pbug
1990 df7b3e7e 2010-09-25 pbug reply_nxdomain(&sreply);
1991 df7b3e7e 2010-09-25 pbug
1992 b36746d8 2010-09-25 pbug return;
1993 f1e825ef 2010-09-28 pbug }
1994 f1e825ef 2010-09-28 pbug
1995 f1e825ef 2010-09-28 pbug
1996 f1e825ef 2010-09-28 pbug /*
1997 f1e825ef 2010-09-28 pbug * LEVEL - traverse a domain name and count how many levels it has
1998 f1e825ef 2010-09-28 pbug * first level is a TLD, then a 2nd level domain and so on.
1999 f1e825ef 2010-09-28 pbug */
2000 f1e825ef 2010-09-28 pbug
2001 f1e825ef 2010-09-28 pbug int
2002 f1e825ef 2010-09-28 pbug level(u_char *p)
2003 f1e825ef 2010-09-28 pbug {
2004 f1e825ef 2010-09-28 pbug int level = 0;
2005 f1e825ef 2010-09-28 pbug
2006 f1e825ef 2010-09-28 pbug while (*p) {
2007 f1e825ef 2010-09-28 pbug level++;
2008 f1e825ef 2010-09-28 pbug p += ((*p) + 1);
2009 f1e825ef 2010-09-28 pbug }
2010 f1e825ef 2010-09-28 pbug
2011 f1e825ef 2010-09-28 pbug return (level);
2012 22893736 2010-09-19 pbug }
2013 f1e825ef 2010-09-28 pbug
2014 f1e825ef 2010-09-28 pbug /*
2015 f1e825ef 2010-09-28 pbug * CONTAINS - check if domain name A is contained in domain name B
2016 f1e825ef 2010-09-28 pbug *
2017 f1e825ef 2010-09-28 pbug */
2018 f1e825ef 2010-09-28 pbug
2019 f1e825ef 2010-09-28 pbug int
2020 f1e825ef 2010-09-28 pbug contains(u_char *a, u_char *b)
2021 f1e825ef 2010-09-28 pbug {
2022 f1e825ef 2010-09-28 pbug u_char *p = a;
2023 f1e825ef 2010-09-28 pbug u_char *q = b;
2024 f1e825ef 2010-09-28 pbug u_int plen = 0, qlen = 0;
2025 f1e825ef 2010-09-28 pbug
2026 f1e825ef 2010-09-28 pbug while (*p) {
2027 f1e825ef 2010-09-28 pbug plen += (*p) + 1;
2028 f1e825ef 2010-09-28 pbug p += ((*p) + 1);
2029 f1e825ef 2010-09-28 pbug }
2030 f1e825ef 2010-09-28 pbug
2031 f1e825ef 2010-09-28 pbug while (*q) {
2032 f1e825ef 2010-09-28 pbug qlen += ((*q) + 1);
2033 f1e825ef 2010-09-28 pbug q += ((*q) + 1);
2034 f1e825ef 2010-09-28 pbug }
2035 f1e825ef 2010-09-28 pbug
2036 f1e825ef 2010-09-28 pbug p = a;
2037 f1e825ef 2010-09-28 pbug q = b;
2038 f1e825ef 2010-09-28 pbug
2039 f1e825ef 2010-09-28 pbug while (*q) {
2040 3f255a8f 2011-04-19 pbug if ((plen == qlen) && memcasecmp((u_char *)p, (u_char *)q, qlen) == 0)
2041 f1e825ef 2010-09-28 pbug return (1);
2042 f1e825ef 2010-09-28 pbug
2043 f1e825ef 2010-09-28 pbug qlen -= ((*q) + 1);
2044 f1e825ef 2010-09-28 pbug q += ((*q) + 1);
2045 518aa971 2010-09-30 pbug }
2046 518aa971 2010-09-30 pbug
2047 518aa971 2010-09-30 pbug return (0);
2048 518aa971 2010-09-30 pbug }
2049 518aa971 2010-09-30 pbug
2050 518aa971 2010-09-30 pbug /*
2051 518aa971 2010-09-30 pbug * NETLOOKUP6 - do an ipv6 lookup of the requested internet record
2052 518aa971 2010-09-30 pbug *
2053 518aa971 2010-09-30 pbug */
2054 518aa971 2010-09-30 pbug
2055 518aa971 2010-09-30 pbug int
2056 518aa971 2010-09-30 pbug netlookup6(DB *db, struct recurses *sr)
2057 518aa971 2010-09-30 pbug {
2058 518aa971 2010-09-30 pbug struct sockaddr_in6 sin6;
2059 518aa971 2010-09-30 pbug struct dns_header *dh;
2060 518aa971 2010-09-30 pbug
2061 518aa971 2010-09-30 pbug char buf[2048];
2062 518aa971 2010-09-30 pbug int flag;
2063 518aa971 2010-09-30 pbug
2064 518aa971 2010-09-30 pbug if (sr->so != -1) {
2065 518aa971 2010-09-30 pbug if (close(sr->so) < 0)
2066 dd869383 2013-02-16 pjp dolog(LOG_ERR, "close: %m");
2067 518aa971 2010-09-30 pbug }
2068 518aa971 2010-09-30 pbug
2069 518aa971 2010-09-30 pbug sr->so = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
2070 518aa971 2010-09-30 pbug if (sr->so < 0) {
2071 dd869383 2013-02-16 pjp dolog(LOG_ERR, "socket6: %m");
2072 518aa971 2010-09-30 pbug sr->so = -1;
2073 518aa971 2010-09-30 pbug return (-1);
2074 518aa971 2010-09-30 pbug }
2075 518aa971 2010-09-30 pbug
2076 fedd844f 2014-09-27 pjp sr->port = arc4random() & 0xffff;
2077 518aa971 2010-09-30 pbug /*
2078 518aa971 2010-09-30 pbug * we have to avoid picking servers already
2079 518aa971 2010-09-30 pbug * running ..
2080 518aa971 2010-09-30 pbug */
2081 518aa971 2010-09-30 pbug if (sr->port < 1024)
2082 518aa971 2010-09-30 pbug sr->port += 1024;
2083 518aa971 2010-09-30 pbug
2084 fedd844f 2014-09-27 pjp sr->id = arc4random() & 0xffff;
2085 518aa971 2010-09-30 pbug
2086 518aa971 2010-09-30 pbug memset(&sin6, 0, sizeof(sin6));
2087 518aa971 2010-09-30 pbug sin6.sin6_family = AF_INET6;
2088 518aa971 2010-09-30 pbug sin6.sin6_port = htons(sr->port);
2089 df41eab0 2010-10-06 pbug #ifndef __linux__
2090 dc729c6b 2010-10-05 pbug sin6.sin6_len = sizeof(struct sockaddr_in6);
2091 df41eab0 2010-10-06 pbug #endif
2092 518aa971 2010-09-30 pbug
2093 518aa971 2010-09-30 pbug if (bind(sr->so, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
2094 dd869383 2013-02-16 pjp dolog(LOG_ERR, "bind: %m");
2095 518aa971 2010-09-30 pbug if (close(sr->so) < 0) {
2096 dd869383 2013-02-16 pjp dolog(LOG_ERR, "close: %m");
2097 518aa971 2010-09-30 pbug }
2098 518aa971 2010-09-30 pbug sr->so = -1;
2099 518aa971 2010-09-30 pbug return (-1);
2100 518aa971 2010-09-30 pbug }
2101 518aa971 2010-09-30 pbug
2102 518aa971 2010-09-30 pbug /*
2103 518aa971 2010-09-30 pbug * make this socket nonblocking
2104 518aa971 2010-09-30 pbug */
2105 518aa971 2010-09-30 pbug
2106 518aa971 2010-09-30 pbug if ((flag = fcntl(sr->so, F_GETFL)) < 0) {
2107 dd869383 2013-02-16 pjp dolog(LOG_INFO, "fcntl 3: %m");
2108 518aa971 2010-09-30 pbug }
2109 518aa971 2010-09-30 pbug flag |= O_NONBLOCK;
2110 518aa971 2010-09-30 pbug if (fcntl(sr->so, F_SETFL, flag) < 0) {
2111 dd869383 2013-02-16 pjp dolog(LOG_INFO, "fcntl 4: %m");
2112 518aa971 2010-09-30 pbug }
2113 518aa971 2010-09-30 pbug
2114 518aa971 2010-09-30 pbug if (lookup_ns(db, sr) <= 0) {
2115 dd869383 2013-02-16 pjp dolog(LOG_ERR, "can't establish any servers to reach for zone \"%s\"", sr->question->converted_name);
2116 518aa971 2010-09-30 pbug if (close(sr->so) < 0) {
2117 dd869383 2013-02-16 pjp dolog(LOG_ERR, "close: %m");
2118 518aa971 2010-09-30 pbug }
2119 518aa971 2010-09-30 pbug sr->so = -1;
2120 518aa971 2010-09-30 pbug return (-1);
2121 518aa971 2010-09-30 pbug }
2122 518aa971 2010-09-30 pbug
2123 518aa971 2010-09-30 pbug memset(&sin6, 0, sizeof(sin6));
2124 518aa971 2010-09-30 pbug sin6.sin6_family = AF_INET6;
2125 518aa971 2010-09-30 pbug sin6.sin6_port = htons(53);
2126 518aa971 2010-09-30 pbug
2127 dc729c6b 2010-10-05 pbug /* pjp */
2128 dc729c6b 2010-10-05 pbug memcpy((char *)&sin6.sin6_addr, (char *)&sr->aaaa[0], sizeof(struct in6_addr));
2129 518aa971 2010-09-30 pbug
2130 518aa971 2010-09-30 pbug /* XXX we use buf here in order to preserve
2131 518aa971 2010-09-30 pbug * the state of query...
2132 518aa971 2010-09-30 pbug */
2133 518aa971 2010-09-30 pbug memcpy(buf, sr->query, sr->len);
2134 518aa971 2010-09-30 pbug dh = (struct dns_header *)&buf[0];
2135 518aa971 2010-09-30 pbug NTOHS(dh->query);
2136 518aa971 2010-09-30 pbug UNSET_DNS_RECURSION(dh);
2137 518aa971 2010-09-30 pbug HTONS(dh->query);
2138 518aa971 2010-09-30 pbug dh->id = htons(sr->id);
2139 518aa971 2010-09-30 pbug
2140 518aa971 2010-09-30 pbug #if 1
2141 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sending request with id %u\n", sr->id);
2142 518aa971 2010-09-30 pbug
2143 518aa971 2010-09-30 pbug #endif
2144 518aa971 2010-09-30 pbug
2145 518aa971 2010-09-30 pbug if (sendto(sr->so, buf, sr->len, 0, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
2146 dd869383 2013-02-16 pjp dolog(LOG_ERR, "sendto6: %m");
2147 518aa971 2010-09-30 pbug if (close(sr->so) < 0) {
2148 dd869383 2013-02-16 pjp dolog(LOG_ERR, "close: %m");
2149 518aa971 2010-09-30 pbug }
2150 518aa971 2010-09-30 pbug sr->so = -1;
2151 518aa971 2010-09-30 pbug return (-1);
2152 f1e825ef 2010-09-28 pbug }
2153 f1e825ef 2010-09-28 pbug
2154 518aa971 2010-09-30 pbug sr->sent_last_query = time(NULL);
2155 518aa971 2010-09-30 pbug sr->packetcount++;
2156 518aa971 2010-09-30 pbug
2157 518aa971 2010-09-30 pbug
2158 f1e825ef 2010-09-28 pbug return (0);
2159 f1e825ef 2010-09-28 pbug }
2160 518aa971 2010-09-30 pbug
2161 518aa971 2010-09-30 pbug /*
2162 518aa971 2010-09-30 pbug * LOOKUP_AAAA - given a path, lookup the AAAA record in that record
2163 518aa971 2010-09-30 pbug *
2164 518aa971 2010-09-30 pbug */
2165 518aa971 2010-09-30 pbug
2166 518aa971 2010-09-30 pbug int
2167 518aa971 2010-09-30 pbug lookup_aaaa(DB *db, struct recurses *sr, struct ns *ns)
2168 518aa971 2010-09-30 pbug {
2169 518aa971 2010-09-30 pbug int ret, plen;
2170 518aa971 2010-09-30 pbug char *p;
2171 518aa971 2010-09-30 pbug
2172 518aa971 2010-09-30 pbug DBT key, data;
2173 518aa971 2010-09-30 pbug
2174 518aa971 2010-09-30 pbug struct domain *sd, sdomain;
2175 518aa971 2010-09-30 pbug int found = 0;
2176 518aa971 2010-09-30 pbug
2177 518aa971 2010-09-30 pbug p = ns->nsserver;
2178 518aa971 2010-09-30 pbug plen = ns->nslen;
2179 518aa971 2010-09-30 pbug
2180 518aa971 2010-09-30 pbug memset(&key, 0, sizeof(key));
2181 518aa971 2010-09-30 pbug memset(&data, 0, sizeof(data));
2182 518aa971 2010-09-30 pbug
2183 518aa971 2010-09-30 pbug key.data = (char *)p;
2184 518aa971 2010-09-30 pbug key.size = plen;
2185 518aa971 2010-09-30 pbug
2186 518aa971 2010-09-30 pbug data.data = NULL;
2187 518aa971 2010-09-30 pbug data.size = 0;
2188 518aa971 2010-09-30 pbug
2189 518aa971 2010-09-30 pbug found = 0;
2190 518aa971 2010-09-30 pbug
2191 518aa971 2010-09-30 pbug ret = db->get(db, NULL, &key, &data, 0);
2192 518aa971 2010-09-30 pbug if (ret == 0) {
2193 518aa971 2010-09-30 pbug if (data.size != sizeof(struct domain)) {
2194 dd869383 2013-02-16 pjp dolog(LOG_ERR, "btree db is damaged");
2195 518aa971 2010-09-30 pbug return (-1);
2196 518aa971 2010-09-30 pbug }
2197 518aa971 2010-09-30 pbug
2198 518aa971 2010-09-30 pbug memcpy((char*)&sdomain, data.data, sizeof(struct domain));
2199 518aa971 2010-09-30 pbug sd = &sdomain;
2200 518aa971 2010-09-30 pbug
2201 518aa971 2010-09-30 pbug if ((sd->flags & DOMAIN_HAVE_AAAA) == DOMAIN_HAVE_AAAA) {
2202 f98bb34d 2011-09-19 pbug memcpy((char *)&sr->aaaa[sr->aaaa_count], (char *)&sd->aaaa[0], sizeof(struct in6_addr));
2203 518aa971 2010-09-30 pbug sd->a_count++;
2204 518aa971 2010-09-30 pbug found = 1;
2205 518aa971 2010-09-30 pbug
2206 518aa971 2010-09-30 pbug }
2207 518aa971 2010-09-30 pbug }
2208 518aa971 2010-09-30 pbug
2209 518aa971 2010-09-30 pbug if (! found) {
2210 dd869383 2013-02-16 pjp dolog(LOG_DEBUG, "calling fakerecurse");
2211 518aa971 2010-09-30 pbug fakerecurse(db, sr, ns, DNS_TYPE_AAAA);
2212 518aa971 2010-09-30 pbug return (-1);
2213 518aa971 2010-09-30 pbug }
2214 518aa971 2010-09-30 pbug
2215 518aa971 2010-09-30 pbug return (0);
2216 518aa971 2010-09-30 pbug }