1 /* dns_query.c - Execute outgoing dns queries and write entries to cache
2
3 Copyright (C) 2000, 2001 Thomas Moestl
4 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 Paul A. Rombouts
5
6 This file is part of the pdnsd package.
7
8 pdnsd is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 pdnsd is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with pdnsd; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 */
22
23 #include <config.h>
24 #include <sys/types.h>
25 #ifdef HAVE_SYS_POLL_H
26 #include <sys/poll.h>
27 #endif
28 #include <stdlib.h>
29 #include <netdb.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <time.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <ctype.h>
36 #include "list.h"
37 #include "consts.h"
38 #include "ipvers.h"
39 #include "dns_query.h"
40 #include "cache.h"
41 #include "dns.h"
42 #include "conff.h"
43 #include "servers.h"
44 #include "helpers.h"
45 #include "netdev.h"
46 #include "error.h"
47 #include "debug.h"
48
49
50 #if defined(NO_TCP_QUERIES) && M_PRESET!=UDP_ONLY
51 # error "You may not define NO_TCP_QUERIES when M_PRESET is not set to UDP_ONLY"
52 #endif
53 #if defined(NO_UDP_QUERIES) && M_PRESET!=TCP_ONLY
54 # error "You may not define NO_UDP_QUERIES when M_PRESET is not set to TCP_ONLY"
55 #endif
56
57 /* data type to hold lists of IP addresses (both v4 and v6)
58 The allocated size should be:
59 sizeof(rejectlist_t) + na4*sizeof(addr4maskpair_t) + na6*sizeof(addr6maskpair_t)
60 */
61 typedef struct rejectlist_s {
62 struct rejectlist_s *next;
63 short policy;
64 short inherit;
65 int na4;
66 #if ALLOW_LOCAL_AAAA
67 int na6;
68 addr6maskpair_t rdata[0]; /* dummy array for alignment */
69 #else
70 addr4maskpair_t rdata[0];
71 #endif
72 } rejectlist_t;
73
74 /* --- structures and state constants for parallel query */
75 typedef struct {
76 union {
77 #ifdef ENABLE_IPV4
78 struct sockaddr_in sin4;
79 #endif
80 #ifdef ENABLE_IPV6
81 struct sockaddr_in6 sin6;
82 #endif
83 } a;
84 #ifdef ENABLE_IPV6
85 struct in_addr a4fallback;
86 #endif
87 time_t timeout;
88 unsigned short flags;
89 short nocache;
90 short state;
91 short qm;
92 char auth_serv;
93 char lean_query;
94 char edns_query;
95 char needs_testing;
96 char trusted;
97 char aa;
98 char tc;
99 char failed;
100 const unsigned char *nsdomain;
101 rejectlist_t *rejectlist;
102 /* internal state for p_exec_query */
103 int sock;
104 #if 0
105 dns_cent_t nent;
106 dns_cent_t servent;
107 #endif
108 unsigned short transl;
109 unsigned short recvl;
110 #ifndef NO_TCP_QUERIES
111 int iolen; /* number of bytes written or read up to now */
112 #endif
113 dns_msg_t *msg;
114 dns_hdr_t *recvbuf;
115 unsigned short myrid;
116 int s_errno;
117 } query_stat_t;
118 typedef DYNAMIC_ARRAY(query_stat_t) *query_stat_array;
119
120 /* Some macros for handling data in reject lists
121 Perhaps we should use inline functions instead of macros.
122 */
123 #define have_rejectlist(st) ((st)->rejectlist!=NULL)
124 #define inherit_rejectlist(st) ((st)->rejectlist && (st)->rejectlist->inherit)
125 #define reject_policy(st) ((st)->rejectlist->policy)
126 #define nreject_a4(st) ((st)->rejectlist->na4)
127 #if ALLOW_LOCAL_AAAA
128 #define nreject_a6(st) ((st)->rejectlist->na6)
129 #define rejectlist_a6(st) ((addr6maskpair_t *)(st)->rejectlist->rdata)
130 #define rejectlist_a4(st) ((addr4maskpair_t *)(rejectlist_a6(st)+nreject_a6(st)))
131 #else
132 #define rejectlist_a4(st) ((addr4maskpair_t *)(st)->rejectlist->rdata)
133 #endif
134
135 #define QS_INITIAL 0 /* This is the initial state. Set this before starting. */
136
137 #define QS_TCPINITIAL 1 /* Start a TCP query. */
138 #define QS_TCPWRITE 2 /* Waiting to write data. */
139 #define QS_TCPREAD 3 /* Waiting to read data. */
140
141 #define QS_UDPINITIAL 4 /* Start a UDP query */
142 #define QS_UDPRECEIVE 5 /* UDP query transmitted, waiting for response. */
143
144 #define QS_QUERY_CASES case QS_TCPINITIAL: case QS_TCPWRITE: case QS_TCPREAD: case QS_UDPINITIAL: case QS_UDPRECEIVE
145
146 #define QS_CANCELED 7 /* query was started, but canceled before completion */
147 #define QS_DONE 8 /* done, resources freed, result is in stat_t */
148
149
150 /* Events to be polled/selected for */
151 #define QS_WRITE_CASES case QS_TCPWRITE
152 #define QS_READ_CASES case QS_TCPREAD: case QS_UDPRECEIVE
153
154 /*
155 * This is for error handling to prevent spewing the log files.
156 * Races do not really matter here, so no locks.
157 */
158 #define MAXPOLLERRS 10
159 static volatile unsigned long poll_errs=0;
160
161 #define SOCK_ADDR(p) ((struct sockaddr *) &(p)->a)
162
163 #ifdef SIN_LEN
164 #undef SIN_LEN
165 #endif
166
167 #define SIN_LEN SEL_IPVER(sizeof(struct sockaddr_in),sizeof(struct sockaddr_in6))
168 #define PDNSD_A(p) SEL_IPVER(((pdnsd_a *) &(p)->a.sin4.sin_addr),((pdnsd_a *) &(p)->a.sin6.sin6_addr))
169
170 #ifndef EWOULDBLOCK
171 #define EWOULDBLOCK EAGAIN
172 #endif
173
174 typedef DYNAMIC_ARRAY(dns_cent_t) *dns_cent_array;
175
176
177 /*
178 * Take the data from an RR and add it to an array of cache entries.
179 * The return value will be RC_OK in case of success,
180 * RC_SERVFAIL in case there is a problem with inconsistent ttl timestamps
181 * or RC_FATALERR in case of a memory allocation failure.
182 */
rr_to_cache(dns_cent_array * centa,unsigned char * oname,int tp,time_t ttl,unsigned dlen,void * data,unsigned flags,time_t queryts)183 static int rr_to_cache(dns_cent_array *centa, unsigned char *oname, int tp, time_t ttl,
184 unsigned dlen, void *data, unsigned flags, time_t queryts)
185 {
186 int i,n;
187 dns_cent_t *cent;
188
189 n=DA_NEL(*centa);
190 for(i=0;i<n;++i) {
191 cent=&DA_INDEX(*centa,i);
192 if (rhnicmp(cent->qname,oname)) {
193 int retval=RC_OK;
194 /* We already have an entry in the array for this name. add_cent_rr is sufficient.
195 However, make sure there are no double records. This is done by add_cent_rr */
196 #ifdef RFC2181_ME_HARDER
197 rr_set_t *rrset= getrrset(cent,tp);
198 if (rrset && rrset->ttl!=ttl)
199 retval= RC_SERVFAIL;
200 #endif
201 return add_cent_rr(cent,tp,ttl,queryts,flags,dlen,data DBG1)? retval: RC_FATALERR;
202 }
203 }
204
205 /* Add a new entry to the array for this name. */
206 if (!(*centa=DA_GROW1_F(*centa,free_cent0)))
207 return RC_FATALERR;
208 cent=&DA_LAST(*centa);
209 if (!init_cent(cent,oname, 0, 0, 0 DBG1)) {
210 *centa=DA_RESIZE(*centa,n);
211 return RC_FATALERR;
212 }
213 return add_cent_rr(cent,tp,ttl,queryts,flags,dlen,data DBG1)? RC_OK: RC_FATALERR;
214 }
215
216 /*
217 * Takes a pointer (ptr) to a buffer with recnum rrs,decodes them and enters
218 * them into an array of cache entries. *ptr is modified to point after the last
219 * rr, and *lcnt is decremented by the size of the rrs.
220 *
221 * *numopt is incremented with the number of OPT pseudo RRs found (should be at most one).
222 * The structure pointed to by ep is filled with the information of the first OPT pseudo RR found,
223 * but only if *numopt was set to zero before the call.
224 *
225 * The return value will be either RC_OK (which indicates success),
226 * or one of the failure codes RC_FORMAT, RC_TRUNC, RC_SERVFAIL or RC_FATALERR
227 * (the latter indicates a memory allocation failure).
228 */
rrs2cent(unsigned char * msg,size_t msgsz,unsigned char ** ptr,size_t * lcnt,int recnum,unsigned flags,time_t queryts,dns_cent_array * centa,int * numopt,edns_info_t * ep)229 static int rrs2cent(unsigned char *msg, size_t msgsz, unsigned char **ptr, size_t *lcnt, int recnum,
230 unsigned flags, time_t queryts, dns_cent_array *centa, int *numopt, edns_info_t *ep)
231 {
232 int rc, retval=RC_OK;
233 int i;
234 uint16_t type,class; uint32_t ttl; uint16_t rdlength;
235
236 for (i=0;i<recnum;i++) {
237 unsigned char oname[DNSNAMEBUFSIZE], *ttlp;
238 unsigned int len;
239 if ((rc=decompress_name(msg, msgsz, ptr, lcnt, oname, &len))!=RC_OK) {
240 return rc;
241 }
242 if (*lcnt<sizeof_rr_hdr_t) {
243 return RC_TRUNC;
244 }
245 *lcnt -= sizeof_rr_hdr_t;
246 GETINT16(type,*ptr);
247 GETINT16(class,*ptr);
248 ttlp= *ptr; /* Remember pointer to ttl field. */
249 GETINT32(ttl,*ptr);
250 GETINT16(rdlength,*ptr);
251 if (*lcnt<rdlength) {
252 return RC_TRUNC;
253 }
254
255 if(type==T_OPT) {
256 /* Found OPT pseudo-RR */
257 if((*numopt)++ == 0) {
258 #if DEBUG>0
259 if(oname[0]!=0) {
260 DEBUG_MSG("rrs2cent: name in OPT record not empty!\n");
261 }
262 #endif
263 ep->udpsize= class;
264 ep->rcode= ((uint16_t)ttlp[0]<<4) | ((dns_hdr_t *)msg)->rcode;
265 ep->version= ttlp[1];
266 ep->do_flg= (ttlp[2]>>7)&1;
267 #if DEBUG>0
268 if(debug_p) {
269 unsigned int Zflags= ((uint16_t)ttlp[2]<<8) | ttlp[3];
270 if(Zflags & 0x7fff) {
271 DEBUG_MSG("rrs2cent: Z field contains unknown nonzero bits (%04x).\n",
272 Zflags);
273 }
274 }
275 if(rdlength) {
276 DEBUG_MSG("rrs2cent: RDATA field in OPT record not empty!\n");
277 }
278 #endif
279 }
280 else {
281 DEBUG_MSG("rrs2cent: ingnoring surplus OPT record.\n");
282 }
283 }
284 else if (!(PDNSD_NOT_CACHED_TYPE(type) || class!=C_IN)) {
285 /* Some types contain names that may be compressed, so these need to be processed.
286 * The other records are taken as they are. */
287
288 size_t blcnt=rdlength;
289 unsigned char *bptr=*ptr; /* make backup for decompression, because rdlength is the
290 authoritative record length and pointer and size will be
291 modified by decompress_name. */
292 unsigned char *nptr;
293 unsigned int slen;
294
295 switch (type) {
296 case T_A:
297 /* Validate types we use internally */
298 if(rdlength!=4) goto invalid_length;
299 goto default_case;
300
301 case T_CNAME:
302 case T_MB:
303 case T_MD:
304 case T_MF:
305 case T_MG:
306 case T_MR:
307 case T_NS:
308 case T_PTR:
309 {
310 unsigned char db[DNSNAMEBUFSIZE];
311 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, db, &len))!=RC_OK)
312 return rc==RC_TRUNC?RC_FORMAT:rc;
313 if (blcnt!=0)
314 goto trailing_junk;
315 if ((rc=rr_to_cache(centa, oname, type, ttl, len, db, flags,queryts))!=RC_OK) {
316 if(rc==RC_FATALERR)
317 return rc;
318 retval=rc;
319 }
320 }
321 break;
322
323 #if IS_CACHED_MINFO || IS_CACHED_RP
324 #if IS_CACHED_MINFO
325 case T_MINFO:
326 #endif
327 #if IS_CACHED_RP
328 case T_RP:
329 #endif
330 {
331 unsigned char db[DNSNAMEBUFSIZE+DNSNAMEBUFSIZE];
332 nptr=db;
333 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK)
334 return rc==RC_TRUNC?RC_FORMAT:rc;
335 /* PDNSD_ASSERT(len + DNSNAMEBUFSIZE <= sizeof(db), "T_MINFO/T_RP: buffer limit reached"); */
336 nptr+=len;
337 slen=len;
338 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK)
339 return rc==RC_TRUNC?RC_FORMAT:rc;
340 /*nptr+=len;*/
341 slen+=len;
342 if (blcnt!=0)
343 goto trailing_junk;
344 if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) {
345 if(rc==RC_FATALERR)
346 return rc;
347 retval=rc;
348 }
349 }
350 break;
351 #endif
352 case T_MX:
353 #if IS_CACHED_AFSDB
354 case T_AFSDB:
355 #endif
356 #if IS_CACHED_RT
357 case T_RT:
358 #endif
359 #if IS_CACHED_KX
360 case T_KX:
361 #endif
362 {
363 unsigned char db[2+DNSNAMEBUFSIZE];
364 if (blcnt<2)
365 goto record_too_short;
366 memcpy(db,bptr,2); /* copy the preference field*/
367 blcnt-=2;
368 bptr+=2;
369 nptr=db+2;
370 slen=2;
371 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK)
372 return rc==RC_TRUNC?RC_FORMAT:rc;
373 /*nptr+=len;*/
374 slen+=len;
375 if (blcnt!=0)
376 goto trailing_junk;
377 if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) {
378 if(rc==RC_FATALERR)
379 return rc;
380 retval=rc;
381 }
382 }
383 break;
384
385 case T_SOA:
386 {
387 unsigned char db[DNSNAMEBUFSIZE+DNSNAMEBUFSIZE+20];
388 nptr=db;
389 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK)
390 return rc==RC_TRUNC?RC_FORMAT:rc;
391 /* PDNSD_ASSERT(len + DNSNAMEBUFSIZE <= sizeof(db), "T_SOA: buffer limit reached"); */
392 nptr+=len;
393 slen=len;
394 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK)
395 return rc==RC_TRUNC?RC_FORMAT:rc;
396 nptr+=len;
397 slen+=len;
398 /* PDNSD_ASSERT(slen + 20 <= sizeof(db), "T_SOA: buffer limit reached"); */
399 if (blcnt<20)
400 goto record_too_short;
401 memcpy(nptr,bptr,20); /*copy the rest of the SOA record*/
402 blcnt-=20;
403 slen+=20;
404 if (blcnt!=0)
405 goto trailing_junk;
406 if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) {
407 if(rc==RC_FATALERR)
408 return rc;
409 retval=rc;
410 }
411 }
412 break;
413 #if IS_CACHED_AAAA
414 case T_AAAA:
415 /* Validate types we use internally */
416 if(rdlength!=16) goto invalid_length;
417 goto default_case;
418 #endif
419 #if IS_CACHED_PX
420 case T_PX:
421 {
422 unsigned char db[2+DNSNAMEBUFSIZE+DNSNAMEBUFSIZE];
423 if (blcnt<2)
424 goto record_too_short;
425 memcpy(db,bptr,2); /* copy the preference field*/
426 blcnt-=2;
427 bptr+=2;
428 nptr=db+2;
429 slen=2;
430 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK)
431 return rc==RC_TRUNC?RC_FORMAT:rc;
432 /* PDNSD_ASSERT(len + DNSNAMEBUFSIZE <= sizeof(db), "T_PX: buffer limit reached"); */
433 nptr+=len;
434 slen+=len;
435 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK)
436 return rc==RC_TRUNC?RC_FORMAT:rc;
437 /* nptr+=len; */
438 slen+=len;
439 if (blcnt!=0)
440 goto trailing_junk;
441 if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) {
442 if(rc==RC_FATALERR)
443 return rc;
444 retval=rc;
445 }
446 }
447 break;
448 #endif
449 #if IS_CACHED_SRV
450 case T_SRV:
451 {
452 unsigned char db[6+DNSNAMEBUFSIZE];
453 if (blcnt<6)
454 goto record_too_short;
455 memcpy(db,bptr,6);
456 blcnt-=6;
457 bptr+=6;
458 nptr=db+6;
459 slen=6;
460 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK)
461 return rc==RC_TRUNC?RC_FORMAT:rc;
462 /*nptr+=len;*/
463 slen+=len;
464 if (blcnt!=0)
465 goto trailing_junk;
466 if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) {
467 if(rc==RC_FATALERR)
468 return rc;
469 retval=rc;
470 }
471 }
472 break;
473 #endif
474 #if IS_CACHED_NXT
475 case T_NXT:
476 {
477 unsigned char db[1040];
478 nptr=db;
479 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK)
480 return rc==RC_TRUNC?RC_FORMAT:rc;
481 nptr+=len;
482 slen=len+blcnt;
483 if (slen > sizeof(db))
484 goto buffer_overflow;
485 memcpy(nptr,bptr,blcnt);
486 if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) {
487 if(rc==RC_FATALERR)
488 return rc;
489 retval=rc;
490 }
491 }
492 break;
493 #endif
494 #if IS_CACHED_NAPTR
495 case T_NAPTR:
496 {
497 int j;
498 unsigned char db[4 + 3*256 + DNSNAMEBUFSIZE];
499 nptr=db;
500 /*
501 * After the preference field, three text strings follow, the maximum length being 255
502 * characters for each (this is ensured by the type of *bptr), plus one length byte for
503 * each, so 3 * 256 = 786 in total. In addition, the name below is up to DNSNAMEBUFSIZE characters
504 * in size, and the preference field is another 4 bytes in size, so the total length
505 * that can be taken up is 1028 characters. This means that the whole record will always
506 * fit into db.
507 */
508 len=4; /* also copy the preference field*/
509 for (j=0;j<3;j++) {
510 if (len>=blcnt)
511 goto record_too_short;
512 len += ((unsigned)bptr[len])+1;
513 }
514 if(len>blcnt)
515 goto record_too_short;
516 memcpy(nptr,bptr,len);
517 blcnt-=len;
518 bptr+=len;
519 nptr+=len;
520 slen=len;
521
522 /* PDNSD_ASSERT(slen+DNSNAMEBUFSIZE <= sizeof(db), "T_NAPTR: buffer limit reached (name)"); */
523 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK)
524 return rc==RC_TRUNC?RC_FORMAT:rc;
525 /*nptr+=len;*/
526 slen+=len;
527 if (blcnt!=0)
528 goto trailing_junk;
529 if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) {
530 if(rc==RC_FATALERR)
531 return rc;
532 retval=rc;
533 }
534 }
535 break;
536 #endif
537 #if IS_CACHED_IPSECKEY
538 case T_IPSECKEY:
539 {
540 unsigned gwtp;
541 /* An IPSECKEY record can contain a domain name, so we do some sanity checks just to be sure. */
542 if(blcnt<3) goto record_too_short;
543 gwtp= bptr[1];
544 blcnt -= 3;
545 bptr += 3;
546 switch(gwtp) {
547 case 0: goto default_case;
548 case 1: /* There should be enough room for IPv4 address. */
549 if(blcnt<4) goto record_too_short;
550 goto default_case;
551 case 2: /* There should be enough room for IPv6 address. */
552 if(blcnt<16) goto record_too_short;
553 goto default_case;
554 case 3: /* Check that domain name is not compressed. */
555 if(isnormalencdomname(bptr,blcnt)) goto default_case;
556 /* It appears the name is compressed even though RFC 4025
557 says it shouldn't be. For the sake of flexibility, we
558 try to decompress it anyway. */
559 {
560 unsigned char *rbuf, nmbuf[DNSNAMEBUFSIZE];
561 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nmbuf, &len))!=RC_OK)
562 return rc==RC_TRUNC?RC_FORMAT:rc;
563 slen=3+len+blcnt;
564 rbuf=malloc(slen);
565 if(!rbuf) return RC_FATALERR;
566 nptr=mempcpy(rbuf,*ptr,3);
567 nptr=mempcpy(nptr,nmbuf,len);
568 memcpy(nptr,bptr,blcnt);
569 rc=rr_to_cache(centa, oname, type, ttl, slen, rbuf, flags,queryts);
570 free(rbuf);
571 if(rc!=RC_OK) {
572 if(rc==RC_FATALERR)
573 return rc;
574 retval=rc;
575 }
576 }
577 break;
578 default:
579 DEBUG_MSG("rrs2cent: %s record contains unsupported gateway type (%u).\n",getrrtpname(type),gwtp);
580 return RC_FORMAT;
581 }
582 }
583 break;
584 #endif
585 #if IS_CACHED_RRSIG
586 case T_RRSIG:
587 /* An RRSIG record contains a domain name, so we do some sanity checks just to be sure. */
588 if(blcnt<18) goto record_too_short;
589 blcnt -= 18;
590 bptr += 18;
591 if(isnormalencdomname(bptr,blcnt)) goto default_case;
592 /* It appears the name is compressed even though RFC 4034
593 says it shouldn't be. For the sake of flexibility, we
594 try to decompress it anyway. */
595 {
596 unsigned char *rbuf, nmbuf[DNSNAMEBUFSIZE];
597 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nmbuf, &len))!=RC_OK)
598 return rc==RC_TRUNC?RC_FORMAT:rc;
599 slen=18+len+blcnt;
600 rbuf=malloc(slen);
601 if(!rbuf) return RC_FATALERR;
602 nptr=mempcpy(rbuf,*ptr,18);
603 nptr=mempcpy(nptr,nmbuf,len);
604 memcpy(nptr,bptr,blcnt);
605 rc=rr_to_cache(centa, oname, type, ttl, slen, rbuf, flags,queryts);
606 free(rbuf);
607 if(rc!=RC_OK) {
608 if(rc==RC_FATALERR)
609 return rc;
610 retval=rc;
611 }
612 }
613 break;
614 #endif
615 #if IS_CACHED_NSEC
616 case T_NSEC:
617 /* An NSEC record contains a domain name, so we do some sanity checks just to be sure. */
618 if(isnormalencdomname(bptr,blcnt)) goto default_case;
619 /* It appears the name is compressed even though RFC 4034
620 says it shouldn't be. For the sake of flexibility, we
621 try to decompress it anyway. */
622 {
623 unsigned char *rbuf, nmbuf[DNSNAMEBUFSIZE];
624 if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nmbuf, &len))!=RC_OK)
625 return rc==RC_TRUNC?RC_FORMAT:rc;
626 slen=len+blcnt;
627 rbuf=malloc(slen);
628 if(!rbuf) return RC_FATALERR;
629 nptr=mempcpy(rbuf,nmbuf,len);
630 memcpy(nptr,bptr,blcnt);
631 rc=rr_to_cache(centa, oname, type, ttl, slen, rbuf, flags,queryts);
632 free(rbuf);
633 if(rc!=RC_OK) {
634 if(rc==RC_FATALERR)
635 return rc;
636 retval=rc;
637 }
638 }
639 break;
640 #endif
641 default:
642 default_case:
643 if ((rc=rr_to_cache(centa, oname, type, ttl, rdlength, *ptr, flags,queryts))!=RC_OK) {
644 if(rc==RC_FATALERR)
645 return rc;
646 retval=rc;
647 }
648 }
649 }
650 else {
651 /* skip otherwise */
652 DEBUG_MSG("rrs2cent: ignoring record of type %s (%d), class %s (%d).\n",
653 getrrtpname(type), type,
654 class==C_IN?"IN":"[unknown]", class);
655 }
656
657 *lcnt -= rdlength;
658 *ptr += rdlength;
659 }
660 return retval;
661
662 trailing_junk:
663 DEBUG_MSG("rrs2cent: %s record has trailing junk.\n",getrrtpname(type));
664 return RC_FORMAT;
665
666 record_too_short:
667 DEBUG_MSG("rrs2cent: %s record too short.\n",getrrtpname(type));
668 return RC_FORMAT;
669
670 buffer_overflow:
671 DEBUG_MSG("rrs2cent: buffer too small to process %s record.\n",getrrtpname(type));
672 return RC_FORMAT;
673
674 invalid_length:
675 DEBUG_MSG("rrs2cent: %s record has length %u.\n",getrrtpname(type),rdlength);
676 return RC_FORMAT;
677 }
678
679 /*
680 * Try to bind the socket to a port in the given port range. Returns 1 on success, or 0 on failure.
681 */
bind_socket(int s)682 static int bind_socket(int s)
683 {
684 int query_port_start=global.query_port_start,query_port_end=global.query_port_end;
685
686 /*
687 * -1, as a special value for query_port_start, denotes that we let the kernel select
688 * a port when we first use the socket, which used to be the default.
689 */
690 if (query_port_start >= 0) {
691 union {
692 #ifdef ENABLE_IPV4
693 struct sockaddr_in sin4;
694 #endif
695 #ifdef ENABLE_IPV6
696 struct sockaddr_in6 sin6;
697 #endif
698 } sin;
699 socklen_t sinl;
700 int prt, pstart, range = query_port_end-query_port_start+1, m=0xffff;
701 unsigned try1,try2, maxtry2;
702
703 if (range<=0 || range>0x10000) {
704 log_warn("Illegal port range in %s line %d, dropping query!\n",__FILE__,__LINE__);
705 return 0;
706 }
707 if(range<=0x8000) {
708 /* Find the smallest power of 2 >= range. */
709 for(m=1; m<range; m <<= 1);
710 /* Convert into a bit mask. */
711 --m;
712 }
713
714 for (try2=0,maxtry2=range*2;;) {
715 /* Get a random number < range, by rejecting those >= range. */
716 for(try1=0;;) {
717 prt= get_rand16()&m;
718 if(prt<range) break;
719 if(++try1>=0x10000) {
720 log_warn("Cannot get random number < range"
721 " after %d tries in %s line %d,"
722 " bad random number generator?\n",
723 try1,__FILE__,__LINE__);
724 return 0;
725 }
726 }
727 prt += query_port_start;
728
729 for(pstart=prt;;) {
730 #ifdef ENABLE_IPV4
731 if (run_ipv4) {
732 memset(&sin.sin4,0,sizeof(struct sockaddr_in));
733 sin.sin4.sin_family=AF_INET;
734 sin.sin4.sin_port=htons(prt);
735 sin.sin4.sin_addr=global.out_a.ipv4;
736 SET_SOCKA_LEN4(sin.sin4);
737 sinl=sizeof(struct sockaddr_in);
738 }
739 #endif
740 #ifdef ENABLE_IPV6
741 ELSE_IPV6 {
742 memset(&sin.sin6,0,sizeof(struct sockaddr_in6));
743 sin.sin6.sin6_family=AF_INET6;
744 sin.sin6.sin6_port=htons(prt);
745 sin.sin6.sin6_flowinfo=IPV6_FLOWINFO;
746 sin.sin6.sin6_addr=global.out_a.ipv6;
747 SET_SOCKA_LEN6(sin.sin6);
748 sinl=sizeof(struct sockaddr_in6);
749 }
750 #endif
751 if (bind(s,(struct sockaddr *)&sin,sinl)==-1) {
752 if (errno!=EADDRINUSE &&
753 errno!=EADDRNOTAVAIL) { /* EADDRNOTAVAIL should not happen here... */
754 log_warn("Could not bind to socket: %s\n", strerror(errno));
755 return 0;
756 }
757 /* If the address is in use, we continue. */
758 } else
759 goto done;
760
761 if(++try2>=maxtry2) {
762 /* It is possible we missed the free ports by chance,
763 try scanning the whole range. */
764 if (++prt>query_port_end)
765 prt=query_port_start;
766 if (prt==pstart) {
767 /* Wrapped around, scanned the whole range. Give up. */
768 log_warn("Out of ports in the range"
769 " %d-%d, dropping query!\n",
770 query_port_start,query_port_end);
771 return 0;
772 }
773 }
774 else /* Try new random number */
775 break;
776 }
777 }
778 }
779 done:
780 return 1;
781 }
782
783
realloc_or_cleanup(void * ptr,size_t size)784 inline static void *realloc_or_cleanup(void *ptr,size_t size)
785 {
786 void *retval=pdnsd_realloc(ptr,size);
787 if(!retval)
788 pdnsd_free(ptr);
789 return retval;
790 }
791
792 #if defined(NO_TCP_QUERIES)
793 # define USE_UDP(st) 1
794 #elif defined(NO_UDP_QUERIES)
795 # define USE_UDP(st) 0
796 #else /* !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) */
797 # define USE_UDP(st) ((st)->qm==UDP_ONLY || (st)->qm==UDP_TCP)
798
799 /* These functions will be used in case a TCP query might fail and we want to try again using UDP. */
800
801 # define tentative_tcp_query(st) ((st)->qm==TCP_UDP && ((st)->state==QS_TCPWRITE || ((st)->state==QS_TCPREAD && (st)->iolen==0)))
802
switch_to_udp(query_stat_t * st)803 inline static void switch_to_udp(query_stat_t *st)
804 {
805 st->qm=UDP_ONLY;
806 st->myrid=get_rand16();
807 st->msg->hdr.id=htons(st->myrid);
808 st->state=QS_UDPINITIAL;
809 /* st->failed=0; */
810 }
811
812 /* This function will be used in case a UDP reply was truncated and we want to try again using TCP. */
813
switch_to_tcp(query_stat_t * st)814 inline static void switch_to_tcp(query_stat_t *st)
815 {
816 /* PDNSD_ASSERT(st->state==QS_INITIAL || st->state==QS_DONE || st->state==QS_CANCELED,
817 "Attempt to switch to TCP while a query is in progress."); */
818 st->qm=TCP_ONLY;
819 st->state=QS_INITIAL;
820 st->failed=0;
821 }
822 #endif
823
824
825 /* ------ following is the parallel query code.
826 * It has been observed that a whole lot of name servers are just damn lame, with response time
827 * of about 1 min. If that slow one is by chance the first server we try, serializing the tries is quite
828 * sub-optimal. Also when doing serial queries, the timeout values given in the config will add up, which
829 * is not the Right Thing. Now that serial queries are in place, this is still true for CNAME recursion,
830 * and for recursion in quest for the holy AA, but not totally for querying multiple servers.
831 * The impact on network bandwith should be only marginal (given todays bandwith).
832 *
833 * The actual strategy is to do (max) PAR_QUERIES parallel queries, and, if these time out or fail, do again
834 * that number of queries, until we are successful or there are no more servers to query.
835 * Since the memory footprint of a thread is considerably large on some systems, and because we have better
836 * control, we will do the parallel queries multiplexed in one thread.
837 */
838
839 /* The query state machine that is called from p_exec_query. This is called once for initialization (state
840 * QS_TCPINITIAL or QS_UDPINITIAL is preset), and the state that it gives back may either be state QS_DONE,
841 * in which case it must return a return code other than -1 and is called no more for this server
842 * (except perhaps in UDP mode if TCP failed). If p_query_sm returns -1, then the state machine is in a read
843 * or write state, and a function higher up the calling chain can setup a poll() or select() together with st->sock.
844 * If that poll/select is succesful for that socket, p_exec_query is called again and will hand over to p_query_sm.
845 * So, you can assume that read(), write() and recvfrom() will not block at the start of a state handling when you
846 * have returned -1 (which means "call again") as last step of the last state handling. */
p_query_sm(query_stat_t * st)847 static int p_query_sm(query_stat_t *st)
848 {
849 int retval=RC_SERVFAIL,rv;
850
851 #if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES)
852 tryagain:
853 #endif
854 switch (st->state){
855 /* TCP query code */
856 #ifndef NO_TCP_QUERIES
857 case QS_TCPINITIAL:
858 if ((st->sock=socket(PDNSD_PF_INET,SOCK_STREAM,IPPROTO_TCP))==-1) {
859 DEBUG_MSG("Could not open socket: %s\n", strerror(errno));
860 break;
861 }
862 /* sin4 or sin6 is intialized, hopefully. */
863
864 /* maybe bind */
865 if (!bind_socket(st->sock)) {
866 close(st->sock);
867 break;
868 }
869
870 /* transmit query by tcp*/
871 /* make the socket non-blocking */
872 {
873 int oldflags = fcntl(st->sock, F_GETFL, 0);
874 if (oldflags == -1 || fcntl(st->sock,F_SETFL,oldflags|O_NONBLOCK)==-1) {
875 DEBUG_PDNSDA_MSG("fcntl error while trying to make socket to %s non-blocking: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(errno));
876 close(st->sock);
877 break;
878 }
879 }
880 st->iolen=0;
881 #ifdef ENABLE_IPV6
882 retry_tcp_connect:
883 #endif
884 if (connect(st->sock,SOCK_ADDR(st),SIN_LEN)==-1) {
885 if (errno==EINPROGRESS || errno==EPIPE) {
886 st->state=QS_TCPWRITE;
887 /* st->event=QEV_WRITE; */ /* wait for writability; the connect is then done */
888 return -1;
889 } else if (errno==ECONNREFUSED) {
890 st->s_errno=errno;
891 DEBUG_PDNSDA_MSG("TCP connection refused by %s\n", PDNSDA2STR(PDNSD_A(st)));
892 close(st->sock);
893 goto tcp_failed; /* We may want to try again using UDP */
894 } else {
895 /* Since immediate connect() errors do not cost any time, we do not try to switch the
896 * server status to offline */
897 #ifdef ENABLE_IPV6
898 /* if IPv6 connectivity is for some reason unavailable, perhaps the
899 IPv4 fallback address can still be reached. */
900 if(!run_ipv4 && (errno==ENETUNREACH || errno==ENETDOWN)
901 && st->a4fallback.s_addr!=INADDR_ANY)
902 {
903 #if DEBUG>0
904 char abuf[ADDRSTR_MAXLEN];
905 DEBUG_PDNSDA_MSG("Connecting to %s failed: %s, retrying with IPv4 address %s\n",
906 PDNSDA2STR(PDNSD_A(st)),strerror(errno),
907 inet_ntop(AF_INET,&st->a4fallback,abuf,sizeof(abuf)));
908 #endif
909 IPV6_MAPIPV4(&st->a4fallback,&st->a.sin6.sin6_addr);
910 st->a4fallback.s_addr=INADDR_ANY;
911 goto retry_tcp_connect;
912 }
913 #endif
914 DEBUG_PDNSDA_MSG("Error while connecting to %s: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(errno));
915 close(st->sock);
916 break;
917 }
918 }
919 st->state=QS_TCPWRITE;
920 /* st->event=QEV_WRITE; */
921 /* fall through in case of not EINPROGRESS */
922 case QS_TCPWRITE:
923 {
924 int rem= dnsmsghdroffset + st->transl - st->iolen;
925 if(rem>0) {
926 rv=write(st->sock,((unsigned char*)st->msg)+st->iolen,rem);
927 if(rv==-1) {
928 if(errno==EWOULDBLOCK)
929 return -1;
930 st->s_errno=errno;
931 close(st->sock);
932 if (st->iolen==0 &&
933 (st->s_errno==ECONNREFUSED || st->s_errno==ECONNRESET ||
934 st->s_errno==EPIPE))
935 {
936 /* This error may be delayed from connect() */
937 DEBUG_PDNSDA_MSG("TCP connection to %s failed: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(st->s_errno));
938 goto tcp_failed; /* We may want to try again using UDP */
939 }
940 DEBUG_PDNSDA_MSG("Error while sending data to %s: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(st->s_errno));
941 break;
942 }
943 st->iolen += rv;
944 if(rv<rem)
945 return -1;
946 }
947 }
948 st->state=QS_TCPREAD;
949 st->iolen=0;
950 /* st->event=QEV_READ; */
951 /* fall through */
952 case QS_TCPREAD:
953 if(st->iolen==0) {
954 uint16_t recvl_net;
955 rv=read(st->sock,&recvl_net,sizeof(recvl_net));
956 if(rv==-1 && errno==EWOULDBLOCK)
957 return -1;
958 if(rv!=sizeof(recvl_net))
959 goto error_receiv_data;
960 st->iolen=rv;
961 st->recvl=ntohs(recvl_net);
962 if(!(st->recvbuf=(dns_hdr_t *)realloc_or_cleanup(st->recvbuf,st->recvl))) {
963 close(st->sock);
964 DEBUG_MSG("Out of memory in query.\n");
965 retval=RC_FATALERR;
966 break;
967 }
968 }
969 {
970 int offset=st->iolen-sizeof(uint16_t);
971 int rem=st->recvl-offset;
972 if(rem>0) {
973 rv=read(st->sock,((unsigned char*)st->recvbuf)+offset,rem);
974 if(rv==-1) {
975 if(errno==EWOULDBLOCK)
976 return -1;
977 goto error_receiv_data;
978 }
979 if(rv==0)
980 goto error_receiv_data; /* unexpected EOF */
981 st->iolen += rv;
982 if(rv<rem)
983 return -1;
984 }
985 }
986 close(st->sock);
987 st->state=QS_DONE;
988 return RC_OK;
989 error_receiv_data:
990 if(rv==-1) st->s_errno=errno;
991 DEBUG_PDNSDA_MSG("Error while receiving data from %s: %s\n", PDNSDA2STR(PDNSD_A(st)),
992 rv==-1?strerror(errno):(rv==0 && st->iolen==0)?"no data":"incomplete data");
993 close(st->sock);
994 tcp_failed:
995 #if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES)
996 if(st->qm==TCP_UDP) {
997 switch_to_udp(st);
998 DEBUG_PDNSDA_MSG("TCP query to %s failed. Trying to use UDP.\n", PDNSDA2STR(PDNSD_A(st)));
999 goto tryagain;
1000 }
1001 #endif
1002 break;
1003 #endif
1004
1005 #ifndef NO_UDP_QUERIES
1006 /* UDP query code */
1007 case QS_UDPINITIAL:
1008 if ((st->sock=socket(PDNSD_PF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1) {
1009 DEBUG_MSG("Could not open socket: %s\n", strerror(errno));
1010 break;
1011 }
1012
1013 /* maybe bind */
1014 if (!bind_socket(st->sock)) {
1015 close(st->sock);
1016 break;
1017 }
1018
1019 /* connect */
1020 #ifdef ENABLE_IPV6
1021 retry_udp_connect:
1022 #endif
1023 if (connect(st->sock,SOCK_ADDR(st),SIN_LEN)==-1) {
1024 if (errno==ECONNREFUSED) st->s_errno=errno;
1025 #ifdef ENABLE_IPV6
1026 /* if IPv6 connectivity is for some reason unavailable, perhaps the
1027 IPv4 fallback address can still be reached. */
1028 else if(!run_ipv4 && (errno==ENETUNREACH || errno==ENETDOWN)
1029 && st->a4fallback.s_addr!=INADDR_ANY)
1030 {
1031 #if DEBUG>0
1032 char abuf[ADDRSTR_MAXLEN];
1033 DEBUG_PDNSDA_MSG("Connecting to %s failed: %s, retrying with IPv4 address %s\n",
1034 PDNSDA2STR(PDNSD_A(st)),strerror(errno),
1035 inet_ntop(AF_INET,&st->a4fallback,abuf,sizeof(abuf)));
1036 #endif
1037 IPV6_MAPIPV4(&st->a4fallback,&st->a.sin6.sin6_addr);
1038 st->a4fallback.s_addr=INADDR_ANY;
1039 goto retry_udp_connect;
1040 }
1041 #endif
1042 DEBUG_PDNSDA_MSG("Error while connecting to %s: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(errno));
1043 close(st->sock);
1044 break;
1045 }
1046
1047 /* transmit query by udp*/
1048 /* send will hopefully not block on a freshly opened socket (the buffer
1049 * must be empty) */
1050 if (send(st->sock,&st->msg->hdr,st->transl,0)==-1) {
1051 st->s_errno=errno;
1052 DEBUG_PDNSDA_MSG("Error while sending data to %s: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(errno));
1053 close(st->sock);
1054 break;
1055 }
1056 st->state=QS_UDPRECEIVE;
1057 /* st->event=QEV_READ; */
1058 return -1;
1059 case QS_UDPRECEIVE:
1060 {
1061 int udpbufsize= (st->edns_query?global.udpbufsize:UDP_BUFSIZE);
1062 if(!(st->recvbuf=(dns_hdr_t *)realloc_or_cleanup(st->recvbuf,udpbufsize))) {
1063 close(st->sock);
1064 DEBUG_MSG("Out of memory in query.\n");
1065 retval=RC_FATALERR;
1066 break;
1067 }
1068 if ((rv=recv(st->sock,st->recvbuf,udpbufsize,0))==-1) {
1069 st->s_errno=errno;
1070 DEBUG_PDNSDA_MSG("Error while receiving data from %s: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(errno));
1071 close(st->sock);
1072 break;
1073 }
1074 st->recvl=rv;
1075 if (st->recvl<sizeof(dns_hdr_t) || ntohs(st->recvbuf->id)!=st->myrid) {
1076 DEBUG_MSG("Bad answer received. Ignoring it.\n");
1077 /* no need to care about timeouts here. That is done at an upper layer. */
1078 st->state=QS_UDPRECEIVE;
1079 /* st->event=QEV_READ; */
1080 return -1;
1081 }
1082 close(st->sock);
1083 st->state=QS_DONE;
1084 return RC_OK;
1085 }
1086 #endif
1087 }
1088
1089 /* If we get here, something has gone wrong. */
1090 st->state=QS_DONE;
1091 return retval; /* should be either RC_SERVFAIL or RC_FATALERR */
1092 }
1093
lookup_cent_array(dns_cent_array ca,const unsigned char * nm)1094 static dns_cent_t *lookup_cent_array(dns_cent_array ca, const unsigned char *nm)
1095 {
1096 int i,n=DA_NEL(ca);
1097 for(i=0;i<n;++i) {
1098 dns_cent_t *ce=&DA_INDEX(ca,i);
1099 if(rhnicmp(ce->qname,nm))
1100 return ce;
1101 }
1102 return NULL;
1103 }
1104
1105 /* Extract the minimum ttl field from the SOA record stored in an rr bucket. */
soa_minimum(rr_bucket_t * rrs)1106 static time_t soa_minimum(rr_bucket_t *rrs)
1107 {
1108 uint32_t minimum;
1109 unsigned char *p=(unsigned char *)(rrs->data);
1110
1111 /* Skip owner and maintainer. Lengths are validated in cache. */
1112 p=skiprhn(skiprhn(p));
1113 /* Skip serial, refresh, retry, expire fields. */
1114 p += 4*sizeof(uint32_t);
1115 GETINT32(minimum,p);
1116 return minimum;
1117 }
1118
1119 /*
1120 * The function that will actually execute a query. It takes a state structure in st.
1121 * st->state must be set to QS_INITIAL before calling.
1122 * This may return one of the RC_* codes, where RC_OK indicates success, the other
1123 * RC codes indicate the appropriate errors. -1 is the return value that indicates that
1124 * you should call p_exec_query again with the same state for the result until you get
1125 * a return value >0. Alternatively, call p_cancel_query to cancel it.
1126 * Timeouts are already handled by this function.
1127 * Any records that the query has yielded and that are not a direct answer to the query
1128 * (i.e. are records for other domains) are added to the cache, while the direct answers
1129 * are returned in ent.
1130 * All ns records, to whomever they might belong, are additionally returned in the ns list.
1131 * Free it when done.
1132 * This function calls another query state machine function that supports TCP and UDP.
1133 *
1134 * If you want to tell me that this function has a truly ugly coding style, ah, well...
1135 * You are right, somehow, but I feel it is conceptually elegant ;-)
1136 */
p_exec_query(dns_cent_t ** entp,const unsigned char * name,int thint,query_stat_t * st,dlist * ns,unsigned char * c_soa)1137 static int p_exec_query(dns_cent_t **entp, const unsigned char *name, int thint,
1138 query_stat_t *st, dlist *ns, unsigned char *c_soa)
1139 {
1140 int rv,rcode;
1141 unsigned short rd;
1142
1143 switch (st->state){
1144 case QS_INITIAL: {
1145 size_t transl,allocsz;
1146 unsigned int rrnlen=0;
1147
1148 allocsz= sizeof(dns_msg_t);
1149 if(name) {
1150 rrnlen=rhnlen(name);
1151 allocsz += rrnlen+4;
1152 if(st->edns_query)
1153 allocsz += sizeof_opt_pseudo_rr;
1154 }
1155 st->msg=(dns_msg_t *)pdnsd_malloc(allocsz);
1156 if (!st->msg) {
1157 st->state=QS_DONE;
1158 return RC_FATALERR; /* unrecoverable error */
1159 }
1160 st->myrid=get_rand16();
1161 st->msg->hdr.id=htons(st->myrid);
1162 st->msg->hdr.qr=QR_QUERY;
1163 st->msg->hdr.opcode=OP_QUERY;
1164 st->msg->hdr.aa=0;
1165 st->msg->hdr.tc=0;
1166 st->msg->hdr.rd=(name && st->trusted);
1167 st->msg->hdr.ra=0;
1168 st->msg->hdr.z=0;
1169 st->msg->hdr.ad=0;
1170 st->msg->hdr.cd=0;
1171 st->msg->hdr.rcode=RC_OK;
1172 st->msg->hdr.qdcount=htons(name!=NULL);
1173 st->msg->hdr.ancount=0;
1174 st->msg->hdr.nscount=0;
1175 st->msg->hdr.arcount=0;
1176
1177 transl= sizeof(dns_hdr_t);
1178 if(name) {
1179 unsigned char *p = mempcpy((unsigned char *)(&st->msg->hdr+1),name,rrnlen);
1180 unsigned short qtype=(st->lean_query?thint:QT_ALL);
1181 PUTINT16(qtype,p);
1182 PUTINT16(C_IN,p);
1183 transl += rrnlen+4;
1184 if(st->edns_query)
1185 add_opt_pseudo_rr(&st->msg,&transl,&allocsz,
1186 global.udpbufsize,RC_OK,0,0);
1187 }
1188 st->transl=transl;
1189 #ifndef NO_TCP_QUERIES
1190 st->msg->len=htons(st->transl);
1191 #endif
1192 st->recvbuf=NULL;
1193 st->state=(USE_UDP(st)?QS_UDPINITIAL:QS_TCPINITIAL);
1194 /* fall through */
1195 }
1196 QS_QUERY_CASES:
1197 tryagain:
1198 rv=p_query_sm(st);
1199 if (rv==-1) {
1200 return -1;
1201 }
1202 if (rv!=RC_OK) {
1203 pdnsd_free(st->msg);
1204 pdnsd_free(st->recvbuf);
1205 st->state=QS_DONE;
1206 if(st->needs_testing) {
1207 switch(st->s_errno) {
1208 case ENETUNREACH: /* network unreachable */
1209 case EHOSTUNREACH: /* host unreachable */
1210 case ENOPROTOOPT: /* protocol unreachable */
1211 case ECONNREFUSED: /* port unreachable */
1212 case ENETDOWN: /* network down */
1213 case EHOSTDOWN: /* host down */
1214 #ifdef ENONET
1215 case ENONET: /* machine not on the network */
1216 #endif
1217 /* Mark this server as down for a period of time */
1218 sched_server_test(PDNSD_A(st),1,0);
1219 st->needs_testing=0;
1220 }
1221 }
1222 return rv;
1223 }
1224 /* rv==RC_OK */
1225 DEBUG_PDNSDA_MSG("Received reply from %s (msg len=%u).\n", PDNSDA2STR(PDNSD_A(st)), st->recvl);
1226 DEBUG_DUMP_DNS_MSG(st->recvbuf, st->recvl);
1227
1228 /* Basic sanity checks */
1229 if (st->recvl<sizeof(dns_hdr_t)) {
1230 DEBUG_MSG("Message too short!\n");
1231 goto discard_reply;
1232 }
1233 {
1234 uint16_t recvid=ntohs(st->recvbuf->id);
1235 if (recvid!=st->myrid) {
1236 DEBUG_MSG("ID mismatch: expected %04x, got %04x!\n", st->myrid, recvid);
1237 goto discard_reply;
1238 }
1239 }
1240 if (st->recvbuf->qr!=QR_RESP) {
1241 DEBUG_MSG("The QR bit indicates this is a query, not a response!\n");
1242 goto discard_reply;
1243 }
1244 if (st->recvbuf->opcode!=OP_QUERY) {
1245 DEBUG_MSG("Not a reply to a standard query (opcode=%u).\n",st->recvbuf->opcode);
1246 goto discard_reply;
1247 }
1248
1249 rcode=st->recvbuf->rcode;
1250 #if DEBUG>0
1251 {
1252 char flgsbuf[DNSFLAGSMAXSTRSIZE];
1253 DEBUG_MSG("rcode=%u (%s), flags:%s\n", rcode, get_ename(rcode), dnsflags2str(st->recvbuf, flgsbuf));
1254 }
1255 #endif
1256 if (st->recvbuf->z!=0) {
1257 DEBUG_MSG("Malformed response (nonzero Z bit).\n");
1258 goto discard_reply;
1259 }
1260
1261 if(st->needs_testing) {
1262 /* We got an answer from this server, so don't bother with up tests for a while. */
1263 sched_server_test(PDNSD_A(st),1,1);
1264 st->needs_testing=0;
1265 }
1266
1267 rv=rcode;
1268 if(rcode==RC_OK || rcode==RC_NAMEERR) {
1269 /* success or at least no requery is needed */
1270 st->state=QS_DONE;
1271 break;
1272 }
1273 else if (entp) {
1274 if(rcode==RC_SERVFAIL || rcode==RC_NOTSUPP || rcode==RC_REFUSED) {
1275 if (st->msg->hdr.rd && !st->recvbuf->ra) {
1276 /* seems as if we have got no recursion available.
1277 We will have to do it by ourselves (sigh...) */
1278 DEBUG_PDNSDA_MSG("Server %s returned error code: %s."
1279 " Maybe does not support recursive query?"
1280 " Querying non-recursively.\n",
1281 PDNSDA2STR(PDNSD_A(st)),get_ename(rcode));
1282 st->msg->hdr.rd=0;
1283 goto resetstate_tryagain;
1284 }
1285 else if(rcode!=RC_SERVFAIL && st->edns_query && st->msg->hdr.arcount)
1286 goto try_withoutedns;
1287 else if (st->recvbuf->ancount && st->auth_serv==2) {
1288 /* The name server returned a failure code,
1289 but the answer section is not empty,
1290 and the answer is from a server lower down the call chain.
1291 Use this answer tentatively (it may be the
1292 best we can get), but remember the failure. */
1293 DEBUG_PDNSDA_MSG("Server %s returned error code: %s,"
1294 " but the answer section is not empty."
1295 " Using the answer tentatively.\n",
1296 PDNSDA2STR(PDNSD_A(st)),get_ename(rcode));
1297 st->failed=3;
1298 st->state=QS_DONE;
1299 break;
1300 }
1301 }
1302 else if(rcode==RC_FORMAT && st->edns_query && st->msg->hdr.arcount)
1303 try_withoutedns: {
1304 size_t transl;
1305 /* Perhaps the remote server barfs when the query
1306 contains an OPT RR in the additional section.
1307 Try again with an empty addtional section. */
1308 DEBUG_PDNSDA_MSG("Server %s returned error code: %s."
1309 " Maybe cannot handle EDNS?"
1310 " Querying with empty additional section.\n",
1311 PDNSDA2STR(PDNSD_A(st)),get_ename(rcode));
1312 transl=remove_opt_pseudo_rr(st->msg,st->transl);
1313 if(transl!=0 && st->msg->hdr.arcount==0) {
1314 st->transl=transl;
1315 #ifndef NO_TCP_QUERIES
1316 st->msg->len=htons(st->transl);
1317 #endif
1318 st->edns_query=0;
1319 resetstate_tryagain:
1320 st->myrid=get_rand16();
1321 st->msg->hdr.id=htons(st->myrid);
1322 st->state=(USE_UDP(st)?QS_UDPINITIAL:QS_TCPINITIAL);
1323 goto tryagain;
1324 }
1325 else {
1326 DEBUG_PDNSDA_MSG("Internal error: could not remove additional section from query"
1327 " to server %s\n", PDNSDA2STR(PDNSD_A(st)));
1328 }
1329 }
1330 }
1331
1332 discard_reply:
1333 /* report failure */
1334 pdnsd_free(st->msg);
1335 pdnsd_free(st->recvbuf);
1336 /*close(st->sock);*/
1337 st->state=QS_DONE;
1338 #if DEBUG>0
1339 if(entp) {
1340 DEBUG_PDNSDA_MSG("Discarding reply from server %s\n", PDNSDA2STR(PDNSD_A(st)));
1341 }
1342 #endif
1343 if (rv!=RC_OK)
1344 return rv;
1345
1346 return RC_SERVFAIL; /* mock error code */
1347
1348 default: /* we shouldn't get here */
1349 st->state=QS_DONE;
1350 return RC_SERVFAIL; /* mock error code */
1351 }
1352
1353 /* If we reach this code, we have successfully received an answer,
1354 * because we have returned error codes on errors or -1 on AGAIN conditions.
1355 * So we *should* have a usable dns record in recvbuf by now.
1356 */
1357 rd= st->msg->hdr.rd; /* Save the 'Recursion Desired' bit of the query. */
1358 pdnsd_free(st->msg);
1359 if(entp) {
1360 time_t queryts=time(NULL);
1361 size_t lcnt= ((size_t)st->recvl) - sizeof(dns_hdr_t);
1362 unsigned char *rrp=(unsigned char *)(st->recvbuf+1);
1363 dns_cent_array secs[3]={NULL,NULL,NULL};
1364 # define ans_sec secs[0]
1365 # define auth_sec secs[1]
1366 # define add_sec secs[2]
1367 unsigned short qtype,flags,aa,neg_ans=0,reject_ans=0,num_ns=0;
1368 int numoptrr;
1369 edns_info_t ednsinfo= {0};
1370
1371 if (ntohs(st->recvbuf->qdcount)!=1) {
1372 DEBUG_PDNSDA_MSG("Bad number of query records in answer from %s\n",
1373 PDNSDA2STR(PDNSD_A(st)));
1374 rv=RC_SERVFAIL;
1375 goto free_recvbuf_return;
1376 }
1377 /* check & skip the query record. */
1378 {
1379 unsigned char nbuf[DNSNAMEBUFSIZE];
1380 if ((rv=decompress_name((unsigned char *)st->recvbuf, st->recvl, &rrp, &lcnt, nbuf, NULL))!=RC_OK) {
1381 DEBUG_PDNSDA_MSG("Cannot decompress QNAME in answer from %s\n",
1382 PDNSDA2STR(PDNSD_A(st)));
1383 rv=RC_SERVFAIL;
1384 goto free_recvbuf_return;
1385 }
1386 if(!rhnicmp(nbuf,name)) {
1387 DEBUG_PDNSDA_MSG("Answer from %s does not match query.\n",
1388 PDNSDA2STR(PDNSD_A(st)));
1389 rv=RC_SERVFAIL;
1390 goto free_recvbuf_return;
1391 }
1392 }
1393
1394 qtype=(st->lean_query?thint:QT_ALL);
1395 if (lcnt<4) {
1396 DEBUG_PDNSDA_MSG("Format error in reply from %s (message truncated in qtype or qclass).\n",
1397 PDNSDA2STR(PDNSD_A(st)));
1398 rv=RC_SERVFAIL; /* mock error code */
1399 goto free_recvbuf_return;
1400 }
1401 {
1402 unsigned short qt,qc;
1403 GETINT16(qt,rrp);
1404 GETINT16(qc,rrp);
1405 if(qt!=qtype) {
1406 DEBUG_PDNSDA_MSG("qtype in answer (%u) from %s does not match expected qtype (%u).\n",
1407 qt,PDNSDA2STR(PDNSD_A(st)),qtype);
1408 rv=RC_SERVFAIL;
1409 goto free_recvbuf_return;
1410 }
1411 }
1412 lcnt-=4;
1413
1414 st->aa= (st->recvbuf->aa && !st->failed);
1415 st->tc=st->recvbuf->tc;
1416
1417 /* Don't flag cache entries from a truncated reply as authoritative. */
1418 aa= (st->aa && !st->tc);
1419 flags=st->flags;
1420 if (aa) flags|=CF_AUTH;
1421
1422
1423 /* Initialize a dns_cent_t in the array for the answer section */
1424 if (!(ans_sec=DA_GROW1(ans_sec))) {
1425 rv=RC_FATALERR; /* unrecoverable error */
1426 goto free_recvbuf_return;
1427 }
1428 /* By marking DF_AUTH, we mean authoritative AND complete. */
1429 if (!init_cent(&DA_INDEX(ans_sec,0), name, 0, 0, (aa && qtype==QT_ALL)?DF_AUTH:0 DBG1)) {
1430 rv=RC_FATALERR; /* unrecoverable error */
1431 goto free_centarrays_recvbuf_return;
1432 }
1433
1434 /* Now read the answer, authority and additional sections,
1435 storing the results in the arrays ans_sec,auth_sec and add_sec.
1436 */
1437 numoptrr=0;
1438 rv=rrs2cent((unsigned char *)st->recvbuf, st->recvl, &rrp, &lcnt, ntohs(st->recvbuf->ancount),
1439 flags, queryts, &ans_sec, &numoptrr, &ednsinfo);
1440 #if DEBUG>0
1441 if(numoptrr!=0) {
1442 DEBUG_MSG("Answer section in reply contains %d OPT pseudo-RRs!\n", numoptrr);
1443 }
1444 #endif
1445 numoptrr=0;
1446 if(rv==RC_OK) {
1447 uint16_t nscount=ntohs(st->recvbuf->nscount);
1448 if (nscount) {
1449 rv=rrs2cent((unsigned char *)st->recvbuf, st->recvl, &rrp, &lcnt, nscount,
1450 flags|CF_ADDITIONAL, queryts, &auth_sec, &numoptrr, &ednsinfo);
1451 #if DEBUG>0
1452 if(numoptrr!=0) {
1453 DEBUG_MSG("Authority section in reply contains %d OPT pseudo-RRs!\n", numoptrr);
1454 }
1455 #endif
1456 }
1457 }
1458
1459 numoptrr=0;
1460 if(rv==RC_OK) {
1461 uint16_t arcount=ntohs(st->recvbuf->arcount);
1462 if (arcount) {
1463 rv=rrs2cent((unsigned char *)st->recvbuf, st->recvl, &rrp, &lcnt, arcount,
1464 flags|CF_ADDITIONAL, queryts, &add_sec, &numoptrr, &ednsinfo);
1465 if(numoptrr!=0) {
1466 #if DEBUG>0
1467 if(numoptrr!=1) {
1468 DEBUG_MSG("Additional section in reply contains %d OPT pseudo-RRs!\n", numoptrr);
1469 }
1470 DEBUG_PDNSDA_MSG("Reply from %s contains OPT pseudosection: EDNS version = %u, udp size = %u, flag DO=%u\n",
1471 PDNSDA2STR(PDNSD_A(st)), ednsinfo.version, ednsinfo.udpsize, ednsinfo.do_flg);
1472 #endif
1473 if(rcode!=ednsinfo.rcode) {
1474 DEBUG_PDNSDA_MSG("Reply from %s contains unexpected EDNS rcode %u (%s)!\n",
1475 PDNSDA2STR(PDNSD_A(st)), ednsinfo.rcode, get_ename(ednsinfo.rcode));
1476 rcode=ednsinfo.rcode;
1477 /* Mark as failed, but use answer tentatively. */
1478 if(!st->failed) st->failed=1;
1479 }
1480 }
1481 }
1482 }
1483
1484 if(!(rv==RC_OK || (rv==RC_TRUNC && st->recvbuf->tc))) {
1485 DEBUG_PDNSDA_MSG(rv==RC_FORMAT?"Format error in reply from %s.\n":
1486 rv==RC_TRUNC?"Format error in reply from %s (message unexpectedly truncated).\n":
1487 rv==RC_SERVFAIL?"Inconsistent timestamps in reply from %s.\n":
1488 "Out of memory while processing reply from %s.\n",
1489 PDNSDA2STR(PDNSD_A(st)));
1490 if(rv==RC_SERVFAIL) {
1491 /* Inconsistent ttl timestamps and we are
1492 enforcing strict RFC 2181 compliance.
1493 Mark as failed, but use answer tentatively. */
1494 if(!st->failed) st->failed=1;
1495 }
1496 else {
1497 if(rv!=RC_FATALERR) rv=RC_SERVFAIL;
1498 goto free_ent_centarrays_recvbuf_return;
1499 }
1500 }
1501
1502 {
1503 /* Remember references to NS and SOA records in the answer or authority section
1504 so that we can add this information to our own reply. */
1505 int i,n=DA_NEL(ans_sec);
1506 for(i=0;i<n;++i) {
1507 dns_cent_t *cent=&DA_INDEX(ans_sec,i);
1508 unsigned scnt=rhnsegcnt(cent->qname);
1509
1510 if(getrrset_NS(cent))
1511 cent->c_ns=scnt;
1512 if(getrrset_SOA(cent))
1513 cent->c_soa=scnt;
1514
1515 if((qtype>=QT_MIN && qtype<=QT_MAX) ||
1516 (/* (qtype>=T_MIN && qtype<=T_MAX) && */ getrrset(cent,qtype)) ||
1517 (n==1 && cent->num_rrs==0))
1518 {
1519 /* Match this name with names in the authority section */
1520 int j,m=DA_NEL(auth_sec);
1521 for(j=0;j<m;++j) {
1522 dns_cent_t *ce=&DA_INDEX(auth_sec,j);
1523 unsigned int ml,rem;
1524 ml=domain_match(ce->qname,cent->qname, &rem, NULL);
1525 if(rem==0 &&
1526 /* Don't accept records for the root domain from name servers
1527 that were not listed in the configuration file. */
1528 (ml || st->auth_serv!=2)) {
1529 if(getrrset_NS(ce)) {
1530 if(cent->c_ns==cundef || cent->c_ns<ml)
1531 cent->c_ns=ml;
1532 }
1533 if(getrrset_SOA(ce)) {
1534 if(cent->c_soa==cundef || cent->c_soa<ml)
1535 cent->c_soa=ml;
1536 }
1537 }
1538 }
1539 }
1540 }
1541 }
1542
1543 /* Check whether the answer contains an IP address that should be rejected. */
1544 if(have_rejectlist(st)) {
1545 int i;
1546 int na4=nreject_a4(st);
1547 addr4maskpair_t *a4arr=rejectlist_a4(st);
1548 #if ALLOW_LOCAL_AAAA
1549 int na6=nreject_a6(st);
1550 addr6maskpair_t *a6arr=rejectlist_a6(st);
1551 #endif
1552 /* Check addresses in the answer, authority and additional sections. */
1553 for(i=0;i<3;++i) {
1554 dns_cent_array sec=secs[i];
1555 int j,nce=DA_NEL(sec);
1556 for(j=0;j<nce;++j) {
1557 dns_cent_t *cent=&DA_INDEX(sec,j);
1558 rr_set_t *rrset=getrrset_A(cent);
1559 if(rrset && na4) {
1560 /* This is far from the world's most efficient matching algorithm,
1561 but it should work OK as long as the numbers involved are small.
1562 */
1563 rr_bucket_t *rr;
1564 for(rr=rrset->rrs; rr; rr=rr->next) {
1565 struct in_addr *a=(struct in_addr *)(rr->data);
1566 int k;
1567 for(k=0;k<na4;++k) {
1568 addr4maskpair_t *am = &a4arr[k];
1569 if(ADDR4MASK_EQUIV(a,&am->a,&am->mask)) {
1570 #if DEBUG>0
1571 unsigned char nmbuf[DNSNAMEBUFSIZE]; char abuf[ADDRSTR_MAXLEN];
1572 DEBUG_PDNSDA_MSG("Rejecting answer from server %s because it contains an A record"
1573 " for \"%s\" with an address in the reject list: %s\n",
1574 PDNSDA2STR(PDNSD_A(st)),
1575 rhn2str(cent->qname,nmbuf,sizeof(nmbuf)),
1576 inet_ntop(AF_INET,a,abuf,sizeof(abuf)));
1577 #endif
1578 reject_ans=1; goto rejectlist_scan_done;
1579 }
1580 }
1581 }
1582 }
1583 #if ALLOW_LOCAL_AAAA
1584 rrset=getrrset_AAAA(cent);
1585 if(rrset && na6) {
1586 rr_bucket_t *rr;
1587 for(rr=rrset->rrs; rr; rr=rr->next) {
1588 struct in6_addr *a=(struct in6_addr *)(rr->data);
1589 int k;
1590 for(k=0;k<na6;++k) {
1591 addr6maskpair_t *am = &a6arr[k];
1592 if(ADDR6MASK_EQUIV(a,&am->a,&am->mask)) {
1593 #if DEBUG>0
1594 unsigned char nmbuf[DNSNAMEBUFSIZE]; char abuf[INET6_ADDRSTRLEN];
1595 DEBUG_PDNSDA_MSG("Rejecting answer from server %s because it contains an AAAA record"
1596 " for \"%s\" with an address in the reject list: %s\n",
1597 PDNSDA2STR(PDNSD_A(st)),
1598 rhn2str(cent->qname,nmbuf,sizeof(nmbuf)),
1599 inet_ntop(AF_INET6,a,abuf,sizeof(abuf)));
1600 #endif
1601 reject_ans=1; goto rejectlist_scan_done;
1602 }
1603 }
1604 }
1605 }
1606 #endif
1607 }
1608 }
1609 rejectlist_scan_done:;
1610 }
1611
1612 /* negative caching for domains */
1613 if (rcode==RC_NAMEERR) {
1614 DEBUG_PDNSDA_MSG("Server %s returned error code: %s\n", PDNSDA2STR(PDNSD_A(st)),get_ename(rcode));
1615 name_error:
1616 neg_ans=1;
1617 {
1618 /* We did not get what we wanted. Cache according to policy */
1619 dns_cent_t *ent=&DA_INDEX(ans_sec,0);
1620 int neg_domain_pol=global.neg_domain_pol;
1621 if (neg_domain_pol==C_ON || (neg_domain_pol==C_AUTH && st->recvbuf->aa)) {
1622 time_t ttl=global.neg_ttl;
1623
1624 /* Try to find a SOA record that came with the reply.
1625 */
1626 if(ent->c_soa!=cundef) {
1627 unsigned scnt=rhnsegcnt(name);
1628 dns_cent_t *cent;
1629 if(ent->c_soa<scnt && (cent=lookup_cent_array(auth_sec,skipsegs(name,scnt-ent->c_soa)))) {
1630 rr_set_t *rrset=getrrset_SOA(cent);
1631 if (rrset && rrset->rrs) {
1632 time_t min=soa_minimum(rrset->rrs);
1633 ttl=rrset->ttl;
1634 if(ttl>min)
1635 ttl=min;
1636 }
1637 }
1638 }
1639 DEBUG_RHN_MSG("Caching domain %s negative with ttl %li\n",RHN2STR(name),(long)ttl);
1640 negate_cent(ent,ttl,queryts);
1641 if(st->nocache) ent->flags |= DF_NOCACHE;
1642 goto cleanup_return_OK;
1643 } else {
1644 if(c_soa) *c_soa=ent->c_soa;
1645 free_cent(ent DBG1);
1646 rv=RC_NAMEERR;
1647 goto add_additional;
1648 }
1649 }
1650 }
1651
1652 if(reject_ans) {
1653 if(reject_policy(st)==C_NEGATE && st->failed<=1)
1654 goto name_error;
1655 else {
1656 rv=RC_SERVFAIL;
1657 goto free_ent_centarrays_recvbuf_return;
1658 }
1659 }
1660
1661 if(global.deleg_only_zones && st->auth_serv<3) { /* st->auth_serv==3 means this server is a root-server. */
1662 int missingdelegation,authcnt;
1663 /* The deleg_only_zones data may change due to runtime reconfiguration,
1664 therefore use locks. */
1665 lock_server_data();
1666 missingdelegation=0; authcnt=0;
1667 {
1668 int i,n=DA_NEL(global.deleg_only_zones); unsigned rem,zrem;
1669 for(i=0;i<n;++i) {
1670 if(domain_match(name,DA_INDEX(global.deleg_only_zones,i),&rem,&zrem) && zrem==0)
1671 goto zone_match;
1672 }
1673 goto delegation_OK;
1674 zone_match:
1675 /* The name queried matches a delegation-only zone. */
1676 if(rem) {
1677 /* Check if we can find delegation in the answer or authority section. */
1678 /* dns_cent_array secs[2]={ans_sec,auth_sec}; */
1679 int j;
1680 for(j=0;j<2;++j) {
1681 dns_cent_array sec=secs[j];
1682 int k,m=DA_NEL(sec);
1683 for(k=0;k<m;++k) {
1684 dns_cent_t *ce=&DA_INDEX(sec,k);
1685 if(getrrset_NS(ce) || getrrset_SOA(ce)) {
1686 /* Found a NS or SOA record in the answer or authority section. */
1687 int l;
1688 ++authcnt;
1689 for(l=0;l<n;++l) {
1690 if(domain_match(ce->qname,DA_INDEX(global.deleg_only_zones,l),&rem,&zrem) && zrem==0) {
1691 if(rem) break;
1692 else goto try_next_auth;
1693 }
1694 }
1695 goto delegation_OK;
1696 }
1697 try_next_auth:;
1698 }
1699 }
1700 #if DEBUG>0
1701 {
1702 unsigned char nmbuf[DNSNAMEBUFSIZE],zbuf[DNSNAMEBUFSIZE];
1703 DEBUG_PDNSDA_MSG(authcnt?"%s is in %s zone, but no delegation found in answer returned by server %s\n"
1704 :"%s is in %s zone, but no authority information provided by server %s\n",
1705 rhn2str(name,nmbuf,sizeof(nmbuf)), rhn2str(DA_INDEX(global.deleg_only_zones,i),zbuf,sizeof(zbuf)),
1706 PDNSDA2STR(PDNSD_A(st)));
1707 }
1708 #endif
1709 missingdelegation=1;
1710 }
1711 delegation_OK:;
1712 }
1713 unlock_server_data();
1714
1715 if(missingdelegation) {
1716 if(authcnt && st->failed<=1) {
1717 /* Treat this as a nonexistant name. */
1718 goto name_error;
1719 }
1720 else if(st->auth_serv<2) {
1721 /* If this is one of the servers obtained from the list
1722 pdnsd was configured with, treat this as a failure.
1723 Hopefully one of the other servers in the list will
1724 return a non-empty authority section.
1725 */
1726 rv=RC_SERVFAIL;
1727 goto free_ent_centarrays_recvbuf_return;
1728 }
1729 }
1730 }
1731
1732 {
1733 /* Negative caching of rr sets */
1734 dns_cent_t *ent=&DA_INDEX(ans_sec,0);
1735
1736 if(!ent->num_rrs) neg_ans=1;
1737
1738 if (thint>=T_MIN && thint<=T_MAX && !getrrset(ent,thint) && !st->tc && st->failed<=1) {
1739 /* We did not get what we wanted. Cache according to policy */
1740 int neg_rrs_pol=global.neg_rrs_pol;
1741 if (neg_rrs_pol==C_ON || (neg_rrs_pol==C_AUTH && aa) ||
1742 (neg_rrs_pol==C_DEFAULT && (aa || (rd && st->recvbuf->ra))))
1743 {
1744 time_t ttl=global.neg_ttl;
1745 rr_set_t *rrset=getrrset_SOA(ent);
1746 dns_cent_t *cent;
1747 unsigned scnt;
1748 /* If we received a SOA, we should take the ttl of that record. */
1749 if ((rrset && rrset->rrs) ||
1750 /* Try to find a SOA record higher up the hierarchy that came with the reply. */
1751 ((cent=lookup_cent_array(auth_sec,
1752 (ent->c_soa!=cundef && ent->c_soa<(scnt=rhnsegcnt(name)))?
1753 skipsegs(name,scnt-ent->c_soa):
1754 name)) &&
1755 (rrset=getrrset_SOA(cent)) && rrset->rrs))
1756 {
1757 time_t min=soa_minimum(rrset->rrs);
1758 ttl=rrset->ttl;
1759 if(ttl>min)
1760 ttl=min;
1761 }
1762 DEBUG_RHN_MSG("Caching type %s for domain %s negative with ttl %li\n",getrrtpname(thint),RHN2STR(name),(long)ttl);
1763 if (!add_cent_rrset_by_type(ent, thint, ttl, queryts, CF_NEGATIVE|flags DBG1)) {
1764 rv=RC_FATALERR;
1765 goto free_ent_centarrays_recvbuf_return;
1766 }
1767 }
1768 }
1769 }
1770
1771 if (st->failed<=1) {
1772 /* The domain names of all name servers found in the answer and authority sections are placed in *ns,
1773 which is automatically grown. */
1774 /* dns_cent_array secs[2]={ans_sec,auth_sec}; */
1775 int i;
1776 for(i=0;i<2;++i) {
1777 dns_cent_array sec=secs[i];
1778 int j,n=DA_NEL(sec);
1779 for(j=0;j<n;++j) {
1780 dns_cent_t *cent=&DA_INDEX(sec,j);
1781 unsigned int rem;
1782 /* Don't accept records for the root domain from name servers
1783 that were not listed in the configuration file. */
1784 if((*(cent->qname) || st->auth_serv!=2) &&
1785 /* Don't accept possibly poisoning nameserver entries in paranoid mode */
1786 (st->trusted || !st->nsdomain || (domain_match(st->nsdomain, cent->qname, &rem,NULL),rem==0)) &&
1787 /* The following test is actually redundant and should never fail. */
1788 *(cent->qname)!=0xff)
1789 {
1790 /* Some nameservers obviously choose to send SOA records instead of NS ones.
1791 * Although I think that this is poor behaviour, we'll have to work around that. */
1792 static const unsigned short nstypes[2]={T_NS,T_SOA};
1793 int k;
1794 for(k=0;k<2;++k) {
1795 rr_set_t *rrset=getrrset(cent,nstypes[k]);
1796 if(rrset) {
1797 rr_bucket_t *rr;
1798 unsigned short first=1;
1799 for(rr=rrset->rrs; rr; rr=rr->next) {
1800 size_t sz1,sz2;
1801 unsigned char *p;
1802 /* Skip duplicate records */
1803 for(p=dlist_first(*ns); p; p=dlist_next(p)) {
1804 if(rhnicmp(*p==0xff?p+1:skiprhn(p),(unsigned char *)(rr->data)))
1805 goto next_nsr;
1806 }
1807 /* add to the nameserver list.
1808 Here we use a little compression trick: if
1809 the first byte of a name is 0xff, this means
1810 repeat the previous name.
1811 */
1812 sz1= (first?rhnlen(cent->qname):1);
1813 sz2=rhnlen((unsigned char *)(rr->data));
1814 if (!(*ns=dlist_grow(*ns,sz1+sz2))) {
1815 rv=RC_FATALERR;
1816 goto free_ent_centarrays_recvbuf_return;
1817 }
1818 p=dlist_last(*ns);
1819 if(first) {
1820 first=0;
1821 p=mempcpy(p,cent->qname,sz1);
1822 }
1823 else
1824 *p++ = 0xff; /* 0xff means 'idem' */
1825 /* This will only copy the first name, which is the NS */
1826 memcpy(p,(unsigned char *)(rr->data),sz2);
1827 ++num_ns;
1828 next_nsr:;
1829 }
1830 }
1831 }
1832 }
1833 }
1834 }
1835 }
1836 cleanup_return_OK:
1837 if(st->failed && neg_ans && num_ns==0) {
1838 DEBUG_PDNSDA_MSG("Answer from server %s does not contain usable records.\n",
1839 PDNSDA2STR(PDNSD_A(st)));
1840 rv=RC_SERVFAIL;
1841 goto free_ns_ent_centarrays_recvbuf_return;
1842 }
1843 if(!(*entp=malloc(sizeof(dns_cent_t)))) {
1844 rv=RC_FATALERR;
1845 goto free_ns_ent_centarrays_recvbuf_return;
1846 }
1847 **entp=DA_INDEX(ans_sec,0);
1848 rv=RC_OK;
1849 add_additional:
1850 if (!st->failed && !reject_ans) {
1851 /* Add the additional RRs to the cache. */
1852 /* dns_cent_array secs[3]={ans_sec,auth_sec,add_sec}; */
1853 int i;
1854 #if DEBUG>0
1855 if(debug_p && neg_ans) {
1856 int j,n=DA_NEL(ans_sec);
1857 for(j=1; j<n; ++j) {
1858 unsigned char nmbuf[DNSNAMEBUFSIZE],nmbuf2[DNSNAMEBUFSIZE];
1859 DEBUG_PDNSDA_MSG("Reply from %s is negative for %s, dropping record(s) for %s in answer section.\n",
1860 PDNSDA2STR(PDNSD_A(st)),
1861 rhn2str(name,nmbuf,sizeof(nmbuf)),
1862 rhn2str(DA_INDEX(ans_sec,j).qname,nmbuf2,sizeof(nmbuf2)));
1863 }
1864 }
1865 #endif
1866 for(i=neg_ans; i<3; ++i) {
1867 dns_cent_array sec=secs[i];
1868 int j,n=DA_NEL(sec);
1869 /* The first entry in the answer section is treated separately, so skip that one. */
1870 for(j= !i; j<n; ++j) {
1871 dns_cent_t *cent=&DA_INDEX(sec,j);
1872 if(*(cent->qname) || st->auth_serv!=2) {
1873 unsigned int rem;
1874 if(st->trusted || !st->nsdomain || (domain_match(st->nsdomain, cent->qname, &rem, NULL),rem==0))
1875 add_cache(cent);
1876 else {
1877 #if DEBUG>0
1878 unsigned char nmbuf[DNSNAMEBUFSIZE],nsbuf[DNSNAMEBUFSIZE];
1879 DEBUG_MSG("Record for %s not in nsdomain %s; dropped.\n",
1880 rhn2str(cent->qname,nmbuf,sizeof(nmbuf)),rhn2str(st->nsdomain,nsbuf,sizeof(nsbuf)));
1881 #endif
1882 }
1883 }
1884 else {
1885 #if DEBUG>0
1886 static const char *const secname[3]={"answer","authority","additional"};
1887 DEBUG_PDNSDA_MSG("Record(s) for root domain in %s section from %s dropped.\n", secname[i],PDNSDA2STR(PDNSD_A(st)));
1888 #endif
1889 }
1890 }
1891 }
1892 }
1893 goto free_centarrays_recvbuf_return;
1894
1895 free_ns_ent_centarrays_recvbuf_return:
1896 dlist_free(*ns); *ns=NULL;
1897 free_ent_centarrays_recvbuf_return:
1898 if(DA_NEL(ans_sec)>=1) free_cent(&DA_INDEX(ans_sec,0) DBG1);
1899 free_centarrays_recvbuf_return:
1900 {
1901 /* dns_cent_array secs[3]={ans_sec,auth_sec,add_sec}; */
1902 int i;
1903 for(i=0;i<3;++i) {
1904 dns_cent_array sec=secs[i];
1905 int j,n=DA_NEL(sec);
1906 /* The first entry in the answer section is treated separately, so skip that one. */
1907 for(j= !i; j<n; ++j)
1908 free_cent(&DA_INDEX(sec,j) DBG1);
1909
1910 da_free(sec);
1911 }
1912 }
1913 #undef ans_sec
1914 #undef auth_sec
1915 #undef add_sec
1916 }
1917 free_recvbuf_return:
1918 pdnsd_free(st->recvbuf);
1919 return rv;
1920 }
1921
1922 /*
1923 * Cancel a query, freeing all resources. Any query state is valid as input (this may even be called
1924 * if a call to p_exec_query already returned error or success)
1925 */
p_cancel_query(query_stat_t * st)1926 static void p_cancel_query(query_stat_t *st)
1927 {
1928 switch (st->state) {
1929 QS_WRITE_CASES:
1930 QS_READ_CASES:
1931 close(st->sock);
1932 /* fall through */
1933 case QS_TCPINITIAL:
1934 case QS_UDPINITIAL:
1935 pdnsd_free(st->recvbuf);
1936 pdnsd_free(st->msg);
1937 }
1938 if(st->state!=QS_INITIAL && st->state!=QS_DONE)
1939 st->state=QS_CANCELED;
1940 }
1941
1942 #if 0
1943 /*
1944 * Initialize a query_serv_t (server list for parallel query)
1945 * This is there for historical reasons only.
1946 */
1947 inline static void init_qserv(query_stat_array *q)
1948 {
1949 *q=NULL;
1950 }
1951 #endif
1952
1953 /*
1954 * Add a server entry to a query_serv_t
1955 * Note: only a reference to nsdomain is copied, not the name itself.
1956 * Be sure to free the q-list before freeing the name.
1957 */
add_qserv(query_stat_array * q,pdnsd_a2 * a,int port,time_t timeout,unsigned flags,int nocache,char lean_query,char edns_query,char auth_s,char needs_testing,char trusted,const unsigned char * nsdomain,rejectlist_t * rejectlist)1958 static int add_qserv(query_stat_array *q, pdnsd_a2 *a, int port, time_t timeout, unsigned flags,
1959 int nocache, char lean_query, char edns_query, char auth_s, char needs_testing, char trusted,
1960 const unsigned char *nsdomain, rejectlist_t *rejectlist)
1961 {
1962 query_stat_t *qs;
1963
1964 if ((*q=DA_GROW1(*q))==NULL) {
1965 DEBUG_MSG("Out of memory in add_qserv()\n");
1966 return 0;
1967 }
1968
1969 qs=&DA_LAST(*q);
1970 #ifdef ENABLE_IPV4
1971 if (run_ipv4) {
1972 memset(&qs->a.sin4,0,sizeof(qs->a.sin4));
1973 qs->a.sin4.sin_family=AF_INET;
1974 qs->a.sin4.sin_port=htons(port);
1975 qs->a.sin4.sin_addr=a->ipv4;
1976 SET_SOCKA_LEN4(qs->a.sin4);
1977 }
1978 #endif
1979 #ifdef ENABLE_IPV6
1980 ELSE_IPV6 {
1981 memset(&qs->a.sin6,0,sizeof(qs->a.sin6));
1982 qs->a.sin6.sin6_family=AF_INET6;
1983 qs->a.sin6.sin6_port=htons(port);
1984 qs->a.sin6.sin6_flowinfo=IPV6_FLOWINFO;
1985 qs->a.sin6.sin6_addr=a->ipv6;
1986 SET_SOCKA_LEN6(qs->a.sin6);
1987
1988 qs->a4fallback=a->ipv4;
1989 }
1990 #endif
1991 qs->timeout=timeout;
1992 qs->flags=flags;
1993 qs->nocache=nocache;
1994 qs->auth_serv=auth_s;
1995 qs->lean_query=lean_query;
1996 qs->edns_query=edns_query;
1997 qs->needs_testing=needs_testing;
1998 qs->trusted=trusted;
1999 qs->aa=0;
2000 qs->tc=0;
2001 qs->failed=0;
2002 qs->nsdomain=nsdomain; /* Note: only a reference is copied, not the name itself! */
2003 qs->rejectlist=rejectlist;
2004
2005 qs->state=QS_INITIAL;
2006 qs->qm=global.query_method;
2007 qs->s_errno=0;
2008 return 1;
2009 }
2010
2011 /* This can be used to check whether a server address was already used in a
2012 previous query_stat_t entry. */
query_stat_same_inaddr2(query_stat_t * qs,pdnsd_a2 * b)2013 inline static int query_stat_same_inaddr2(query_stat_t *qs, pdnsd_a2 *b)
2014 {
2015 return SEL_IPVER( qs->a.sin4.sin_addr.s_addr==b->ipv4.s_addr,
2016 IN6_ARE_ADDR_EQUAL(&qs->a.sin6.sin6_addr,&b->ipv6) &&
2017 qs->a4fallback.s_addr==b->ipv4.s_addr );
2018 }
2019
2020
2021 /*
2022 * Free resources used by a query_serv_t
2023 * There for historical reasons only.
2024 */
del_qserv(query_stat_array q)2025 inline static void del_qserv(query_stat_array q)
2026 {
2027 da_free(q);
2028 }
2029
2030 struct qstatnode_s {
2031 query_stat_array qa;
2032 struct qstatnode_s *next;
2033 };
2034 typedef struct qstatnode_s qstatnode_t;
2035
2036 struct qhintnode_s {
2037 const unsigned char *nm;
2038 int tp;
2039 struct qhintnode_s *next;
2040 };
2041 /* typedef struct qhintnode_s qhintnode_t; */ /* Already defined in dns_query.h */
2042
2043 static int auth_ok(query_stat_array q, const unsigned char *name, int thint, dns_cent_t *ent,
2044 int hops, qstatnode_t *qslist, qhintnode_t *qhlist,
2045 query_stat_t *qse, dlist ns, query_stat_array *serv);
2046 static int p_dns_cached_resolve(query_stat_array q, const unsigned char *name, int thint, dns_cent_t **cachedp,
2047 int hops, qstatnode_t *qslist, qhintnode_t *qhlist, time_t queryts,
2048 unsigned char *c_soa);
2049 static int simple_dns_cached_resolve(atup_array atup_a, int port, char edns_query, time_t timeout,
2050 const unsigned char *name, int thint, dns_cent_t **cachedp);
2051
2052
2053 /*
2054 * Performs a semi-parallel query on the servers in q. PAR_QUERIES are executed parallel at a time.
2055 * name is the query name in dns protocol format (number.string etc),
2056 * ent is the dns_cent_t that will be filled.
2057 * hops is the number of recursions left.
2058 * qslist should refer to a list of server arrays used higher up in the calling chain. This way we can
2059 * avoid name servers that have already been tried for this name.
2060 * qhlist should refer to a list of names that we are trying to resolve higher up in the calling chain.
2061 * These names should be avoided further down the chain, or we risk getting caught in a wasteful cycle.
2062 * thint is a hint on the requested query type used to decide whether an aa record must be fetched
2063 * or a non-authoritative answer will be enough.
2064 *
2065 * nocache is needed because we add AA records to the cache. If the nocache flag is set, we do not
2066 * take the original values for the record, but flags=0 and ttl=0 (but only if we do not already have
2067 * a cached record for that set). These settings cause the record be purged on the next cache addition.
2068 * It will also not be used again.
2069 */
p_recursive_query(query_stat_array q,const unsigned char * name,int thint,dns_cent_t ** entp,int * nocache,int hops,qstatnode_t * qslist,qhintnode_t * qhlist,unsigned char * c_soa)2070 static int p_recursive_query(query_stat_array q, const unsigned char *name, int thint, dns_cent_t **entp,
2071 int *nocache, int hops, qstatnode_t *qslist, qhintnode_t *qhlist,
2072 unsigned char *c_soa)
2073 {
2074 dns_cent_t *ent,*entsave=NULL;
2075 int i,j,k;
2076 int rv=RC_SERVFAIL;
2077 int qualval=0;
2078 query_stat_t *qse=NULL; /* Initialized to inhibit compiler warning */
2079 dlist ns=NULL,nssave=NULL;
2080 query_stat_array serv=NULL,servsave=NULL;
2081
2082 # define W_AUTHOK 8
2083 # define W_NOTFAILED 2
2084 # define W_NOTTRUNC 1
2085 # define NOTFAILMASK 6
2086 # define GOODQUAL (W_AUTHOK+3*W_NOTFAILED)
2087 # define save_query_result(ent,qs,ns,serv,authok) \
2088 { \
2089 int qval = authok*W_AUTHOK + (3-qs->failed)*W_NOTFAILED + (!qs->tc)*W_NOTTRUNC; \
2090 if(entsave && qval>qualval) { \
2091 /* Free the old copy, because the new result is better. */ \
2092 free_cent(entsave DBG1); \
2093 pdnsd_free(entsave); \
2094 entsave=NULL; \
2095 del_qserv(servsave); \
2096 dlist_free(nssave); \
2097 } \
2098 if(!entsave) { \
2099 entsave=ent; \
2100 servsave=serv; \
2101 /* The serv array contains references to data within the ns list, \
2102 so we need to save a copy of the ns list as well! */ \
2103 if(DA_NEL(serv)>0) nssave=ns; else {nssave=NULL;dlist_free(ns);} \
2104 qualval=qval; \
2105 qse=qs; \
2106 } \
2107 else { \
2108 /* We already have a copy, free the present one. */ \
2109 free_cent(ent DBG1); \
2110 pdnsd_free(ent); \
2111 del_qserv(serv); \
2112 dlist_free(ns); \
2113 } \
2114 serv=NULL; \
2115 ns=NULL; \
2116 }
2117
2118 {
2119 time_t ts0=time(NULL),global_timeout=global.timeout;
2120 int dc=0,mc=0,nq=DA_NEL(q),parqueries=global.par_queries;
2121
2122 for (j=0; j<nq; j += parqueries) {
2123 mc=j+parqueries;
2124 if (mc>nq) mc=nq;
2125
2126 /* First, call p_exec_query once for each parallel set to initialize.
2127 * Then, as long as not all have the state QS_DONE or we have a timeout,
2128 * build a poll/select set for all active queries and call them accordingly. */
2129 for (i=dc;i<mc;i++) {
2130 query_stat_t *qs=&DA_INDEX(q,i);
2131 if(i>=j) {
2132 /* The below should not happen any more, but may once again
2133 * (immediate success) */
2134 DEBUG_PDNSDA_MSG("Sending query to %s\n", PDNSDA2STR(PDNSD_A(qs)));
2135 retryquery:
2136 rv=p_exec_query(&ent, name, thint, qs,&ns,c_soa);
2137 if (rv==RC_OK) {
2138 int authok;
2139 DEBUG_PDNSDA_MSG("Query to %s succeeded.\n", PDNSDA2STR(PDNSD_A(qs)));
2140 if((authok=auth_ok(q, name, thint, ent, hops, qslist, qhlist, qs, ns, &serv))) {
2141 if(authok>=0) {
2142 if(!qs->failed
2143 #if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES)
2144 && !(qs->qm==UDP_TCP && qs->tc)
2145 #endif
2146 )
2147 {
2148 qse=qs;
2149 mc=i; /* No need to cancel queries beyond i */
2150 goto done;
2151 }
2152 }
2153 else {
2154 mc=i; /* No need to cancel queries beyond i */
2155 goto free_ent_return_failed;
2156 }
2157 }
2158 /* We do not have a satisfactory answer.
2159 However, we will save a copy in case none of the other
2160 servers in the q list give a satisfactory answer either.
2161 */
2162 save_query_result(ent,qs,ns,serv,authok);
2163 #if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES)
2164 if(qs->qm==UDP_TCP && qs->tc) {
2165 switch_to_tcp(qs);
2166 DEBUG_PDNSDA_MSG("Reply from %s was truncated. Trying again using TCP.\n",
2167 PDNSDA2STR(PDNSD_A(qs)));
2168 goto retryquery;
2169 }
2170 #endif
2171 }
2172 else if (rv==RC_NAMEERR || rv==RC_FATALERR) {
2173 mc=i; /* No need to cancel queries beyond i */
2174 goto done;
2175 }
2176 }
2177 if (qs->state==QS_DONE && i==dc)
2178 dc++;
2179 }
2180 if (dc<mc) {
2181 time_t ts,maxto,now;
2182 int pc,nevents;
2183 #ifdef NO_POLL
2184 int maxfd;
2185 fd_set reads;
2186 fd_set writes;
2187 struct timeval tv;
2188 #else
2189 int ic;
2190 struct pollfd polls[mc-dc]; /* Variable length array, may cause portability problems */
2191 #endif
2192 /* we do time keeping by hand, because poll/select might be interrupted and
2193 * the returned times are not always to be trusted upon */
2194 ts=time(NULL);
2195 do {
2196 /* build poll/select sets, maintain time.
2197 * If you do parallel queries, the highest timeout will be honored
2198 * also for the other servers when their timeout is exceeded and
2199 * the highest is not.
2200 * Changed by Paul Rombouts: queries are not canceled until we receive
2201 * a useful reply or everything has failed or timed out (also taking into
2202 * account the global timeout option).
2203 * Thus in the worst case all the queries in the q list will be active
2204 * simultaneously. The downside is that we may be wasting more resources
2205 * this way. The advantage is that we have a greater chance of catching a
2206 * reply. After all, if we wait longer anyway, why not for more servers. */
2207 maxto=0;
2208 pc=0;
2209 rv=RC_SERVFAIL;
2210
2211 #ifdef NO_POLL
2212 FD_ZERO(&reads);
2213 FD_ZERO(&writes);
2214 maxfd=0;
2215 #endif
2216 for (i=dc;i<mc;i++) {
2217 query_stat_t *qs=&DA_INDEX(q,i);
2218 if (qs->state!=QS_DONE) {
2219 if (i>=j && qs->timeout>maxto)
2220 maxto=qs->timeout;
2221 #ifdef NO_POLL
2222 if (qs->sock>maxfd) {
2223 maxfd=qs->sock;
2224 PDNSD_ASSERT(maxfd<FD_SETSIZE,"socket file descriptor exceeds FD_SETSIZE.");
2225 }
2226
2227 switch (qs->state) {
2228 QS_READ_CASES:
2229 FD_SET(qs->sock,&reads);
2230 break;
2231 QS_WRITE_CASES:
2232 FD_SET(qs->sock,&writes);
2233 break;
2234 }
2235 #else
2236 polls[pc].fd=qs->sock;
2237 switch (qs->state) {
2238 QS_READ_CASES:
2239 polls[pc].events=POLLIN;
2240 break;
2241 QS_WRITE_CASES:
2242 polls[pc].events=POLLOUT;
2243 break;
2244 default:
2245 polls[pc].events=0;
2246 }
2247 #endif
2248 pc++;
2249 }
2250 }
2251 if (pc==0) {
2252 /* In this case, ALL are done and we do not need to cancel any
2253 * query. */
2254 dc=mc;
2255 break;
2256 }
2257 now=time(NULL);
2258 maxto -= now-ts;
2259 if (mc==nq) {
2260 #if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES)
2261 /* Don't use the global timeout if there are TCP queries
2262 we might want to retry using UDP. */
2263 for (i=j;i<mc;i++) {
2264 query_stat_t *qs=&DA_INDEX(q,i);
2265 if(tentative_tcp_query(qs))
2266 goto skip_globto;
2267 }
2268 #endif
2269 {
2270 time_t globto=global_timeout-(now-ts0);
2271 if(globto>maxto) maxto=globto;
2272 }
2273 #if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES)
2274 skip_globto:;
2275 #endif
2276 }
2277 #ifdef NO_POLL
2278 tv.tv_sec=(maxto>0)?maxto:0;
2279 tv.tv_usec=0;
2280 nevents=select(maxfd+1,&reads,&writes,NULL,&tv);
2281 #else
2282 nevents=poll(polls,pc,(maxto>0)?(maxto*1000):0);
2283 #endif
2284 if (nevents<0) {
2285 /* if(errno==EINTR)
2286 continue; */
2287 log_warn("poll/select failed: %s",strerror(errno));
2288 goto done;
2289 }
2290 if (nevents==0) {
2291 /* We have timed out. Mark the unresponsive servers so that we can consider
2292 them for retesting later on. We will continue to listen for replies from
2293 these servers as long as we have additional servers to try. */
2294 for (i=j;i<mc;i++) {
2295 query_stat_t *qs=&DA_INDEX(q,i);
2296 if (qs->state!=QS_DONE && qs->needs_testing)
2297 qs->needs_testing=2;
2298 #if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES)
2299 if (tentative_tcp_query(qs)) {
2300 /* We timed out while waiting for a TCP connection.
2301 Try again using UDP.
2302 */
2303 close(qs->sock);
2304 switch_to_udp(qs);
2305 DEBUG_PDNSDA_MSG("TCP connection to %s timed out. Trying to use UDP.\n",
2306 PDNSDA2STR(PDNSD_A(qs)));
2307
2308 rv=p_exec_query(&ent, name, thint, qs,&ns,c_soa);
2309 /* In the unlikely case of immediate success */
2310 if (rv==RC_OK) {
2311 int authok;
2312 DEBUG_PDNSDA_MSG("Query to %s succeeded.\n", PDNSDA2STR(PDNSD_A(qs)));
2313 if((authok=auth_ok(q, name, thint, ent, hops, qslist, qhlist, qs, ns, &serv))) {
2314 if(authok>=0) {
2315 if(!qs->failed) {
2316 qse=qs;
2317 goto done;
2318 }
2319 }
2320 else
2321 goto free_ent_return_failed;
2322 }
2323 save_query_result(ent,qs,ns,serv,authok);
2324 }
2325 else if (rv==RC_NAMEERR || rv==RC_FATALERR) {
2326 goto done;
2327 }
2328 ++nevents;
2329 }
2330 #endif
2331 }
2332 #if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES)
2333 if (mc==nq) {
2334 /* We will not try additional servers, but we might want to try again
2335 using UDP instead of TCP
2336 */
2337 if(nevents && (time(NULL)-ts0)<global_timeout)
2338 continue;
2339 }
2340 #endif
2341 break;
2342 }
2343 #ifndef NO_POLL
2344 ic=0;
2345 #endif
2346 for (i=dc;i<mc;i++) {
2347 query_stat_t *qs=&DA_INDEX(q,i);
2348 /* Check if we got a poll/select event */
2349 if (qs->state!=QS_DONE) {
2350 int srv_event=0;
2351 /* This detection may seem suboptimal, but normally, we have at most 2-3 parallel
2352 * queries, and anything else would be higher overhead, */
2353 #ifdef NO_POLL
2354 switch (qs->state) {
2355 QS_READ_CASES:
2356 srv_event=FD_ISSET(qs->sock,&reads);
2357 break;
2358 QS_WRITE_CASES:
2359 srv_event=FD_ISSET(qs->sock,&writes);
2360 break;
2361 }
2362 #else
2363 do {
2364 PDNSD_ASSERT(ic<pc, "file descriptor not found in poll() array");
2365 k=ic++;
2366 } while(polls[k].fd!=qs->sock);
2367 /*
2368 * In case of an error, reenter the state machine
2369 * to catch it.
2370 */
2371 switch (qs->state) {
2372 QS_READ_CASES:
2373 srv_event=polls[k].revents&(POLLIN|POLLERR|POLLHUP|POLLNVAL);
2374 break;
2375 QS_WRITE_CASES:
2376 srv_event=polls[k].revents&(POLLOUT|POLLERR|POLLHUP|POLLNVAL);
2377 break;
2378 }
2379 #endif
2380 if (srv_event) {
2381 --nevents;
2382 retryquery2:
2383 rv=p_exec_query(&ent, name, thint, qs,&ns,c_soa);
2384 if (rv==RC_OK) {
2385 int authok;
2386 DEBUG_PDNSDA_MSG("Query to %s succeeded.\n", PDNSDA2STR(PDNSD_A(qs)));
2387 if((authok=auth_ok(q, name, thint, ent, hops, qslist, qhlist, qs, ns, &serv))) {
2388 if(authok>=0) {
2389 if(!qs->failed
2390 #if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES)
2391 && !(qs->qm==UDP_TCP && qs->tc)
2392 #endif
2393 )
2394 {
2395 qse=qs;
2396 goto done;
2397 }
2398 }
2399 else
2400 goto free_ent_return_failed;
2401 }
2402 save_query_result(ent,qs,ns,serv,authok);
2403 #if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES)
2404 if(qs->qm==UDP_TCP && qs->tc) {
2405 switch_to_tcp(qs);
2406 DEBUG_PDNSDA_MSG("Reply from %s was truncated. Trying again using TCP.\n",
2407 PDNSDA2STR(PDNSD_A(qs)));
2408 goto retryquery2;
2409 }
2410 #endif
2411 }
2412 else if (rv==RC_NAMEERR || rv==RC_FATALERR) {
2413 goto done;
2414 }
2415 }
2416 }
2417 /* recheck, this might have changed after the last p_exec_query */
2418 if (qs->state==QS_DONE && i==dc)
2419 dc++;
2420 }
2421 if(nevents>0) {
2422 /* We have not managed to handle all the events reported by poll/select.
2423 Better call it quits, or we risk getting caught in a wasteful cycle.
2424 */
2425 if(++poll_errs<=MAXPOLLERRS)
2426 log_error("%d unhandled poll/select event(s) in p_recursive_query() at %s, line %d.",nevents,__FILE__,__LINE__);
2427 rv=RC_SERVFAIL;
2428 goto done;
2429 }
2430 } while (dc<mc);
2431 }
2432 }
2433 goto cancel_queries;
2434 free_ent_return_failed:
2435 free_cent(ent DBG1);
2436 pdnsd_free(ent);
2437 rv=RC_FATALERR;
2438 done:
2439 if (entsave) {
2440 /* We have or will get an authoritative answer, or we have encountered an error.
2441 Free the non-authoritative answer. */
2442 free_cent(entsave DBG1);
2443 pdnsd_free(entsave);
2444 entsave=NULL;
2445 del_qserv(servsave);
2446 dlist_free(nssave);
2447 }
2448 cancel_queries:
2449 /* Cancel any remaining queries. */
2450 for (i=dc;i<mc;i++)
2451 p_cancel_query(&DA_INDEX(q,i));
2452
2453 {
2454 /* See if any servers need to be retested for availability.
2455 We build up a list of addresses rather than call
2456 sched_server_test() separately for each address to
2457 reduce the overhead caused by locking and signaling */
2458 int n=0;
2459 for (i=0;i<mc;i++)
2460 if (DA_INDEX(q,i).needs_testing > 1)
2461 ++n;
2462 if(n>0) {
2463 pdnsd_a addrs[n]; /* variable length array */
2464 k=0;
2465 for (i=0;i<mc;i++) {
2466 query_stat_t *qs=&DA_INDEX(q,i);
2467 if (qs->needs_testing > 1)
2468 addrs[k++]= *PDNSD_A(qs);
2469 }
2470 sched_server_test(addrs,n,-1);
2471 }
2472 }
2473 }
2474
2475 if(entsave) {
2476 /*
2477 * If we didn't get rrs from any of the authoritative servers, or the answers were
2478 * unsatisfactory for another reason, take the one we had.
2479 * However, raise the CF_NOCACHE flag, so that it won't be used again (outside the
2480 * cache latency period).
2481 */
2482 DEBUG_PDNSDA_MSG("Using %s reply from %s.\n",
2483 !(qualval&NOTFAILMASK)? "reportedly failed":
2484 !(qualval&W_NOTFAILED)? "inconsistent":
2485 !(qualval&W_NOTTRUNC)? "truncated":
2486 !(qualval&W_AUTHOK)? "non-authoritative": "good",
2487 PDNSDA2STR(PDNSD_A(qse)));
2488 ent=entsave;
2489 serv=servsave;
2490 ns=nssave;
2491 if(qualval<GOODQUAL) {
2492 if(!(ent->flags&DF_NEGATIVE)) {
2493 int jlim= RRARR_LEN(ent);
2494 for (j=0; j<jlim; ++j) {
2495 rr_set_t *rrs= RRARR_INDEX(ent,j);
2496 if (rrs)
2497 rrs->flags |= CF_NOCACHE;
2498 }
2499 }
2500 else /* Very unlikely, but not impossible. */
2501 ent->flags |= DF_NOCACHE;
2502 }
2503 rv=RC_OK;
2504 }
2505 else if (rv!=RC_OK) {
2506 if(rv==RC_FATALERR) {
2507 DEBUG_MSG("Unrecoverable error encountered while processing query.\n");
2508 rv=RC_SERVFAIL;
2509 }
2510 DEBUG_MSG("No query succeeded. Returning error code \"%s\"\n",get_ename(rv));
2511 goto clean_up_return;
2512 }
2513
2514 if(nocache) *nocache=qse->nocache;
2515
2516 if (DA_NEL(serv)>0) {
2517 /* Authority records present. Ask them, because the answer was non-authoritative. */
2518 qstatnode_t qsn={q,qslist};
2519 unsigned char save_ns=ent->c_ns,save_soa=ent->c_soa;
2520 free_cent(ent DBG1);
2521 pdnsd_free(ent);
2522 rv=p_dns_cached_resolve(serv, name, thint,&ent,hops-1,&qsn,qhlist,time(NULL),c_soa);
2523 if(rv==RC_OK) {
2524 if(save_ns!=cundef && (ent->c_ns==cundef || ent->c_ns<save_ns))
2525 ent->c_ns=save_ns;
2526 if(save_soa!=cundef && (ent->c_soa==cundef || ent->c_soa<save_soa))
2527 ent->c_soa=save_soa;
2528 }
2529 else if(rv==RC_NAMEERR && c_soa) {
2530 if(save_soa!=cundef && (*c_soa==cundef || *c_soa<save_soa))
2531 *c_soa=save_soa;
2532 }
2533 /* return the answer in any case. */
2534 }
2535
2536 clean_up_return:
2537 /* Always free the serv array before freeing the ns list,
2538 because the serv array contains references to data within the ns list! */
2539 del_qserv(serv);
2540 dlist_free(ns);
2541
2542 if(rv==RC_OK) *entp=ent;
2543 return rv;
2544 # undef save_query_result
2545 }
2546
2547 /* auth_ok returns 1 if we don't need an authoritative answer or
2548 if we can find servers to ask for an authoritative answer.
2549 In the latter case these servers will be added to the *serv list.
2550 A return value of 0 means the answer is not satisfactory in the
2551 previous sense.
2552 A return value of -1 indicates an error.
2553 */
auth_ok(query_stat_array q,const unsigned char * name,int thint,dns_cent_t * ent,int hops,qstatnode_t * qslist,qhintnode_t * qhlist,query_stat_t * qse,dlist ns,query_stat_array * serv)2554 static int auth_ok(query_stat_array q, const unsigned char *name, int thint, dns_cent_t *ent,
2555 int hops, qstatnode_t *qslist, qhintnode_t *qhlist,
2556 query_stat_t *qse, dlist ns, query_stat_array *serv)
2557 {
2558 int retval=0;
2559
2560 /* If the answer was obtained from a name server which returned a failure code,
2561 the answer is never satisfactory. */
2562 if(qse->failed > 1) return 0;
2563
2564 /*
2565 Look into the query type hint. If it is a wildcard (QT_*), we need an authoritative answer.
2566 Same if there is no record that answers the query.
2567 This test will also succeed if we have a negative cached record. This is done purposely.
2568 */
2569 #define aa_needed ((thint>=QT_MIN && thint<=QT_MAX) || \
2570 ((thint>=T_MIN && thint<=T_MAX) && \
2571 (!have_rr(ent,thint) && !have_rr_CNAME(ent))))
2572
2573 /* We will want to query authoritative servers if all of the following conditions apply:
2574
2575 1) The server from which we got the answer was not configured as "proxy only".
2576 2) The answer is not a negatively cached domain (i.e. the server did not reply with NXDOMAIN).
2577 3) The query type is a wild card (QT_*), or no record answers the query.
2578 4) The answer that we have is non-authoritative.
2579 */
2580 if(!(qse->auth_serv && !(ent->flags&DF_NEGATIVE) && aa_needed))
2581 return 1;
2582
2583 if(qse->aa) {
2584 /* The reply we have claims to be authoritative.
2585 However, I have seen cases where name servers raise the authority flag incorrectly (groan...),
2586 so as a work-around, we will check whether the domains for which the servers in the ns
2587 list are responsible, match the queried name better than the domain for which the
2588 last server was responsible. */
2589 unsigned char *nsdomain;
2590
2591 if(!qse->nsdomain)
2592 return 1;
2593
2594 nsdomain=dlist_first(ns);
2595 if(!nsdomain)
2596 return 1;
2597 for(;;) {
2598 unsigned int rem,crem;
2599 domain_match(nsdomain,qse->nsdomain,&rem,&crem);
2600 if(!(rem>0 && crem==0))
2601 return 1;
2602 domain_match(nsdomain,name,&rem,NULL);
2603 if(rem!=0)
2604 return 1;
2605 do {
2606 nsdomain=dlist_next(nsdomain);
2607 if(!nsdomain)
2608 goto done_checkauth;
2609 } while(*nsdomain==0xff); /* Skip repeats. */
2610 }
2611 done_checkauth:;
2612
2613 /* The name servers in the ns list are a better match for the queried name than
2614 the server from which we got the last reply, so ignore the aa flag.
2615 */
2616 #if DEBUG>0
2617 if(debug_p) {
2618 unsigned char dbuf[DNSNAMEBUFSIZE],sdbuf[DNSNAMEBUFSIZE];
2619 nsdomain=dlist_first(ns);
2620 DEBUG_PDNSDA_MSG("The name server %s which is responsible for the %s domain, raised the aa flag, but appears to delegate to the sub-domain %s\n",
2621 PDNSDA2STR(PDNSD_A(qse)),
2622 rhn2str(qse->nsdomain,dbuf,sizeof(dbuf)),
2623 rhn2str(nsdomain,sdbuf,sizeof(sdbuf)));
2624 }
2625 #endif
2626 }
2627
2628 /* The answer was non-authoritative. Try to build a list of addresses of authoritative servers. */
2629 if (hops>0) {
2630 unsigned char *nsdomp, *nsdomain=NULL;
2631 rr_set_t *localrrset=NULL;
2632 rr_bucket_t *localrr=NULL;
2633 for (nsdomp=dlist_first(ns);;) {
2634 unsigned char *nsname=NULL; /* Initialize to inhibit compiler warning. */
2635 pdnsd_a2 serva;
2636
2637 /* Get next name server. */
2638 if(localrr) {
2639 /* Use next locally defined NS record. */
2640 nsname=(unsigned char *)(localrr->data);
2641 localrr= localrr->next;
2642 }
2643 else {
2644 if(localrrset) {
2645 /* clean up rrset */
2646 del_rrset(localrrset DBG1);
2647 localrrset=NULL;
2648 }
2649 if(!nsdomp)
2650 break;
2651 else if(*nsdomp!=0xff) {
2652 /* New domain. */
2653 nsdomain=nsdomp;
2654 if (global.paranoid) {
2655 unsigned int rem;
2656 /* paranoia mode: don't query name servers that are not responsible */
2657 domain_match(nsdomain,name,&rem,NULL);
2658 if (rem!=0) {
2659 #if DEBUG>0
2660 unsigned char nmbuf[DNSNAMEBUFSIZE],dbuf[DNSNAMEBUFSIZE],nsbuf[DNSNAMEBUFSIZE];
2661 DEBUG_MSG("The name server %s is responsible for the %s domain, which does not match %s\n",
2662 rhn2str(nsname,nsbuf,sizeof(nsbuf)),
2663 rhn2str(nsdomain,dbuf,sizeof(dbuf)),
2664 rhn2str(name,nmbuf,sizeof(nmbuf)));
2665 #endif
2666 /* Skip records in ns list for the same domain. */
2667 do {
2668 nsdomp=dlist_next(nsdomp);
2669 } while (nsdomp && *nsdomp==0xff);
2670 continue;
2671 }
2672 }
2673 /* Check if we have locally defined NS records, because
2674 they will override the ones provided by remote servers.
2675 */
2676 localrrset=lookup_cache_local_rrset(nsdomain,T_NS);
2677 if(localrrset) {
2678 /* Skip records in ns list for the same domain. */
2679 do {
2680 nsdomp=dlist_next(nsdomp);
2681 } while (nsdomp && *nsdomp==0xff);
2682 localrr=localrrset->rrs;
2683 if(!localrr) continue;
2684 nsname=(unsigned char *)(localrr->data);
2685 localrr= localrr->next;
2686 }
2687 else {
2688 nsname=skiprhn(nsdomp);
2689 nsdomp=dlist_next(nsdomp);
2690 }
2691 }
2692 else {
2693 /* domain repeated. */
2694 nsname= nsdomp+1;
2695 nsdomp=dlist_next(nsdomp);
2696 }
2697 }
2698 /* look it up in the cache or resolve it if needed.
2699 The records received should be in the cache now, so it's ok.
2700 */
2701 #ifdef ENABLE_IPV6
2702 if(!run_ipv4)
2703 serva.ipv6=in6addr_any;
2704 #endif
2705 serva.ipv4.s_addr=INADDR_ANY;
2706 {
2707 const unsigned char *nm=name;
2708 int tp=thint;
2709 qhintnode_t *ql=qhlist;
2710
2711 for(;;) {
2712 if(rhnicmp(nm,nsname) && tp==T_A) {
2713 DEBUG_RHN_MSG("Not looking up address for name server \"%s\": "
2714 "risk of infinite recursion.\n",RHN2STR(nsname));
2715 goto skip_server;
2716 }
2717 if(!ql) break;
2718 nm=ql->nm;
2719 tp=ql->tp;
2720 ql=ql->next;
2721 }
2722 {
2723 qhintnode_t qhn={name,thint,qhlist};
2724 dns_cent_t *servent;
2725 if (r_dns_cached_resolve(nsname,T_A, &servent, hops-1, &qhn,time(NULL),NULL)==RC_OK) {
2726 #ifdef ENABLE_IPV4
2727 if (run_ipv4) {
2728 rr_set_t *rrset=getrrset_A(servent);
2729 if (rrset && rrset->rrs)
2730 serva.ipv4 = *((struct in_addr *)rrset->rrs->data);
2731 }
2732 #endif
2733 #ifdef ENABLE_IPV6
2734 ELSE_IPV6 {
2735 rr_set_t *rrset;
2736 if ((rrset=getrrset_AAAA(servent)) && rrset->rrs) {
2737 serva.ipv6 = *((struct in6_addr *)rrset->rrs->data);
2738 if ((rrset=getrrset_A(servent)) && rrset->rrs) {
2739 /* Store IPv4 address as fallback. */
2740 serva.ipv4 = *((struct in_addr *)rrset->rrs->data);
2741 }
2742 }
2743 else if ((rrset=getrrset_A(servent)) && rrset->rrs) {
2744 struct in_addr *ina = (struct in_addr *)rrset->rrs->data;
2745 IPV6_MAPIPV4(ina,&serva.ipv6);
2746 }
2747 }
2748 #endif
2749 free_cent(servent DBG1);
2750 pdnsd_free(servent);
2751 }
2752 }
2753 }
2754
2755 if(is_inaddr2_any(&serva))
2756 continue; /* address resolution failed. */
2757
2758 if(is_local_addr(PDNSD_A2_TO_A(&serva)))
2759 continue; /* Do not use local address (as defined in netdev.c). */
2760
2761 { /* Skip duplicate addresses. */
2762 int i,n=DA_NEL(*serv);
2763 for (i=0; i<n; ++i) {
2764 query_stat_t *qs=&DA_INDEX(*serv,i);
2765 if (query_stat_same_inaddr2(qs,&serva))
2766 goto skip_server;
2767 }
2768 }
2769
2770 { /* We've got an address. Add it to the list if it wasn't one of the servers we queried. */
2771 query_stat_array qa=q;
2772 qstatnode_t *ql=qslist;
2773 for(;;) {
2774 int i,n=DA_NEL(qa);
2775 for (i=0; i<n; ++i) {
2776 /* If qa[i].state == QS_DONE, then p_exec_query() has been called,
2777 and we should not query this server again */
2778 query_stat_t *qs=&DA_INDEX(qa,i);
2779 if (qs->state==QS_DONE && equiv_inaddr2(PDNSD_A(qs),&serva)) {
2780 DEBUG_PDNSDA_MSG("Not trying name server %s, already queried.\n", PDNSDA2STR(PDNSD_A2_TO_A(&serva)));
2781 goto skip_server;
2782 }
2783 }
2784 if(!ql) break;
2785 qa=ql->qa;
2786 ql=ql->next;
2787 }
2788 }
2789
2790 /* lean query mode is inherited. CF_AUTH and CF_ADDITIONAL are not (as specified
2791 * in CFF_NOINHERIT). */
2792 if (!add_qserv(serv, &serva, 53, qse->timeout, qse->flags&~CFF_NOINHERIT, 0,
2793 qse->lean_query,qse->edns_query,2,0,!global.paranoid,nsdomain,
2794 inherit_rejectlist(qse)?qse->rejectlist:NULL))
2795 {
2796 return -1;
2797 }
2798 retval=1;
2799 skip_server:;
2800 }
2801 #if DEBUG>0
2802 if(!retval) {
2803 DEBUG_PDNSDA_MSG("No remaining authoritative name servers to try in authority section from %s.\n", PDNSDA2STR(PDNSD_A(qse)));
2804 }
2805 #endif
2806 }
2807 else {
2808 DEBUG_MSG("Maximum hops count reached; not trying any more name servers.\n");
2809 }
2810
2811 return retval;
2812
2813 #undef aa_needed
2814 }
2815
2816 /*
2817 * This checks the given name to resolve against the access list given for the server using the
2818 * include=, exclude= and policy= parameters.
2819 */
use_server(servparm_t * s,const unsigned char * name)2820 static int use_server(servparm_t *s, const unsigned char *name)
2821 {
2822 int i,n=DA_NEL(s->alist);
2823
2824 for (i=0;i<n;i++) {
2825 slist_t *sl=&DA_INDEX(s->alist,i);
2826 unsigned int nrem,lrem;
2827 domain_match(name,sl->domain,&nrem,&lrem);
2828 if(!lrem && (!sl->exact || !nrem))
2829 return sl->rule==C_INCLUDED;
2830 }
2831
2832 if (s->policy==C_SIMPLE_ONLY || s->policy==C_FQDN_ONLY) {
2833 if(rhnsegcnt(name)<=1)
2834 return s->policy==C_SIMPLE_ONLY;
2835 else
2836 return s->policy==C_FQDN_ONLY;
2837 }
2838
2839 return s->policy==C_INCLUDED;
2840 }
2841
2842 #if ALLOW_LOCAL_AAAA
2843 #define serv_has_rejectlist(s) ((s)->reject_a4!=NULL || (s)->reject_a6!=NULL)
2844 #else
2845 #define serv_has_rejectlist(s) ((s)->reject_a4!=NULL)
2846 #endif
2847
2848 /* Take the lists of IP addresses from a server section sp and
2849 convert them into a form that can be used by p_exec_query().
2850 If successful, add_rejectlist returns a new list which is added to the old list rl,
2851 otherwise the return value is NULL.
2852 */
add_rejectlist(rejectlist_t * rl,servparm_t * sp)2853 static rejectlist_t *add_rejectlist(rejectlist_t *rl, servparm_t *sp)
2854 {
2855 int i,na4=DA_NEL(sp->reject_a4);
2856 addr4maskpair_t *a4p;
2857 #if ALLOW_LOCAL_AAAA
2858 int na6=DA_NEL(sp->reject_a6);
2859 addr6maskpair_t *a6p;
2860 #endif
2861 rejectlist_t *rlist = malloc(sizeof(rejectlist_t) + na4*sizeof(addr4maskpair_t)
2862 #if ALLOW_LOCAL_AAAA
2863 + na6*sizeof(addr6maskpair_t)
2864 #endif
2865 );
2866
2867 if(rlist) {
2868 #if ALLOW_LOCAL_AAAA
2869 /* Store the larger IPv6 addresses first to avoid possible alignment problems. */
2870 rlist->na6 = na6;
2871 a6p = (addr6maskpair_t *)rlist->rdata;
2872 for(i=0;i<na6;++i)
2873 *a6p++ = DA_INDEX(sp->reject_a6,i);
2874 #endif
2875 rlist->na4 = na4;
2876 #if ALLOW_LOCAL_AAAA
2877 a4p = (addr4maskpair_t *)a6p;
2878 #else
2879 a4p = (addr4maskpair_t *)rlist->rdata;
2880 #endif
2881 for(i=0;i<na4;++i)
2882 *a4p++ = DA_INDEX(sp->reject_a4,i);
2883
2884 rlist->policy = sp->rejectpolicy;
2885 rlist->inherit = sp->rejectrecursively;
2886 rlist->next = rl;
2887 }
2888
2889 return rlist;
2890 }
2891
free_rejectlist(rejectlist_t * rl)2892 inline static void free_rejectlist(rejectlist_t *rl)
2893 {
2894 while(rl) {
2895 rejectlist_t *next = rl->next;
2896 free(rl);
2897 rl=next;
2898 }
2899 }
2900
2901 /* Lookup addresses of nameservers provided by root servers for a given domain in the cache.
2902 Returns NULL if unsuccessful (or the cache entries have timed out).
2903 */
lookup_ns(const unsigned char * domain)2904 static addr2_array lookup_ns(const unsigned char *domain)
2905 {
2906 addr2_array res=NULL;
2907
2908 dns_cent_t *cent=lookup_cache(domain,NULL);
2909 if(cent) {
2910 rr_set_t *rrset=getrrset_NS(cent);
2911 if(rrset && (rrset->flags&CF_ROOTSERV) && !timedout(rrset)) {
2912 rr_bucket_t *rr;
2913 for(rr=rrset->rrs; rr; rr=rr->next) {
2914 pdnsd_a2 *serva;
2915 dns_cent_t *servent;
2916 if(!(res=DA_GROW1(res))) {
2917 DEBUG_MSG("Out of memory in lookup_ns()\n");
2918 break;
2919 }
2920 serva=&DA_LAST(res);
2921 #ifdef ENABLE_IPV6
2922 if(!run_ipv4)
2923 serva->ipv6=in6addr_any;
2924 #endif
2925 serva->ipv4.s_addr=INADDR_ANY;
2926
2927 servent=lookup_cache((unsigned char*)(rr->data),NULL);
2928 if(servent) {
2929 #ifdef ENABLE_IPV4
2930 if (run_ipv4) {
2931 rr_set_t *rrset=getrrset_A(servent);
2932 if (rrset && !timedout(rrset) && rrset->rrs)
2933 serva->ipv4 = *((struct in_addr *)rrset->rrs->data);
2934 }
2935 #endif
2936 #ifdef ENABLE_IPV6
2937 ELSE_IPV6 {
2938 rr_set_t *rrset;
2939 if ((rrset=getrrset_AAAA(servent)) && !(rrset->flags&CF_NEGATIVE)) {
2940 if(!timedout(rrset) && rrset->rrs) {
2941 serva->ipv6 = *((struct in6_addr *)rrset->rrs->data);
2942 if ((rrset=getrrset_A(servent)) && !(rrset->flags&CF_NEGATIVE)) {
2943 if(!timedout(rrset) && rrset->rrs)
2944 serva->ipv4 = *((struct in_addr *)rrset->rrs->data);
2945 else /* Treat this as a failure. */
2946 serva->ipv6=in6addr_any;
2947 }
2948 }
2949 }
2950 else if ((rrset=getrrset_A(servent)) && !timedout(rrset) && rrset->rrs) {
2951 struct in_addr *ina = (struct in_addr *)rrset->rrs->data;
2952 IPV6_MAPIPV4(ina,&serva->ipv6);
2953 }
2954 }
2955 #endif
2956 free_cent(servent DBG1);
2957 pdnsd_free(servent);
2958 }
2959 if(is_inaddr2_any(serva)) {
2960 /* Address lookup failed. */
2961 da_free(res); res=NULL;
2962 break;
2963 }
2964 }
2965 }
2966 free_cent(cent DBG1);
2967 pdnsd_free(cent);
2968 }
2969
2970 return res;
2971 }
2972
2973
2974 /* Find addresses of root servers by looking them up in the cache or querying (non-recursively)
2975 the name servers in the list provided.
2976 Returns NULL if unsuccessful (or the cache entries have timed out).
2977 */
dns_rootserver_resolv(atup_array atup_a,int port,char edns_query,time_t timeout)2978 addr2_array dns_rootserver_resolv(atup_array atup_a, int port, char edns_query, time_t timeout)
2979 {
2980 addr2_array res=NULL;
2981 dns_cent_t *cent;
2982 static const unsigned char rdomain[1]={0}; /* root-domain name. */
2983 int rc;
2984
2985 rc=simple_dns_cached_resolve(atup_a,port,edns_query,timeout,rdomain,T_NS,¢);
2986 if(rc==RC_OK) {
2987 rr_set_t *rrset=getrrset_NS(cent);
2988 if(rrset) {
2989 rr_bucket_t *rr;
2990 unsigned nfail=0;
2991 for(rr=rrset->rrs; rr; rr=rr->next) {
2992 pdnsd_a2 serva;
2993 dns_cent_t *servent;
2994 #ifdef ENABLE_IPV6
2995 if(!run_ipv4)
2996 serva.ipv6=in6addr_any;
2997 #endif
2998 serva.ipv4.s_addr=INADDR_ANY;
2999
3000 rc=simple_dns_cached_resolve(atup_a,port,edns_query,timeout,
3001 (const unsigned char *)(rr->data),T_A,&servent);
3002 if(rc==RC_OK) {
3003 #ifdef ENABLE_IPV4
3004 if (run_ipv4) {
3005 rr_set_t *rrset=getrrset_A(servent);
3006 if (rrset && rrset->rrs)
3007 serva.ipv4 = *((struct in_addr *)rrset->rrs->data);
3008 }
3009 #endif
3010 #ifdef ENABLE_IPV6
3011 ELSE_IPV6 {
3012 rr_set_t *rrset;
3013 if ((rrset=getrrset_AAAA(servent)) && rrset->rrs) {
3014 serva.ipv6 = *((struct in6_addr *)rrset->rrs->data);
3015 if ((rrset=getrrset_A(servent)) && rrset->rrs) {
3016 /* Store IPv4 address as fallback. */
3017 serva.ipv4 = *((struct in_addr *)rrset->rrs->data);
3018 }
3019 }
3020 else if ((rrset=getrrset_A(servent)) && rrset->rrs) {
3021 struct in_addr *ina = (struct in_addr *)rrset->rrs->data;
3022 IPV6_MAPIPV4(ina,&serva.ipv6);
3023 }
3024 }
3025 #endif
3026 free_cent(servent DBG1);
3027 pdnsd_free(servent);
3028 }
3029 else {
3030 DEBUG_RHN_MSG("Simple query for %s type A failed (rc: %s)\n",
3031 RHN2STR((const unsigned char *)(rr->data)),get_ename(rc));
3032 }
3033
3034 if(is_inaddr2_any(&serva)) {
3035 /* Address lookup failed. */
3036 DEBUG_RHN_MSG("Failed to obtain address of root server %s in dns_rootserver_resolv()\n",
3037 RHN2STR((const unsigned char *)(rr->data)));
3038 ++nfail;
3039 continue;
3040 }
3041 if(!(res=DA_GROW1(res))) {
3042 DEBUG_MSG("Out of memory in dns_rootserver_resolv()\n");
3043 goto free_cent_return;
3044 }
3045 DA_LAST(res)= serva;
3046 }
3047 /* At least half of the names should resolve, otherwise we reject the result. */
3048 if(nfail>DA_NEL(res)) {
3049 DEBUG_MSG("Too many root-server resolve failures (%u succeeded, %u failed),"
3050 " rejecting the result.\n", DA_NEL(res),nfail);
3051 da_free(res); res=NULL;
3052 }
3053 }
3054 free_cent_return:
3055 free_cent(cent DBG1);
3056 pdnsd_free(cent);
3057 }
3058 else {
3059 DEBUG_MSG("Simple query for root domain type NS failed (rc: %s)\n",get_ename(rc));
3060 }
3061
3062 return res;
3063 }
3064
3065
p_dns_resolve(const unsigned char * name,int thint,dns_cent_t ** cachedp,int hops,qhintnode_t * qhlist,unsigned char * c_soa)3066 static int p_dns_resolve(const unsigned char *name, int thint, dns_cent_t **cachedp, int hops, qhintnode_t *qhlist,
3067 unsigned char *c_soa)
3068 {
3069 int i,n,rc;
3070 int one_up=0,seenrootserv=0;
3071 query_stat_array serv=NULL;
3072 rejectlist_t *rejectlist=NULL;
3073
3074 /* try the servers in the order of their definition */
3075 lock_server_data();
3076 n=DA_NEL(servers);
3077 for (i=0;i<n;++i) {
3078 servparm_t *sp=&DA_INDEX(servers,i);
3079 if(sp->rootserver<=1 && use_server(sp,name)) {
3080 int m=DA_NEL(sp->atup_a);
3081 if(m>0) {
3082 rejectlist_t *rjl=NULL;
3083 int j=0, jstart=0;
3084 if(sp->rand_servers) j=jstart=random()%m;
3085 do {
3086 atup_t *at=&DA_INDEX(sp->atup_a,j);
3087 if (at->is_up) {
3088 if(sp->rootserver) {
3089 if(!seenrootserv) {
3090 int nseg,mseg=1,l=0;
3091 const unsigned char *topdomain=NULL;
3092 addr2_array adrs=NULL;
3093 seenrootserv=1;
3094 nseg=rhnsegcnt(name);
3095 if(nseg>=2) {
3096 static const unsigned char rhn_arpa[6]= {4,'a','r','p','a',0};
3097 unsigned int rem;
3098 /* Check if the queried name ends in "arpa" */
3099 domain_match(rhn_arpa, name, &rem,NULL);
3100 if(rem==0) mseg=3;
3101 }
3102 if(nseg<=mseg) {
3103 if(nseg>0) mseg=nseg-1; else mseg=0;
3104 }
3105 for(;mseg>=1; --mseg) {
3106 topdomain=skipsegs(name,nseg-mseg);
3107 adrs=lookup_ns(topdomain);
3108 l=DA_NEL(adrs);
3109 if(l>0) break;
3110 if(adrs) da_free(adrs);
3111 }
3112 if(l>0) {
3113 /* The name servers for this top level domain have been found in the cache.
3114 Instead of asking the root server, we will use this cached information.
3115 */
3116 int k=0, kstart=0;
3117 if(sp->rand_servers) k=kstart=random()%l;
3118 if(serv_has_rejectlist(sp) && sp->rejectrecursively && !rjl) {
3119 rjl=add_rejectlist(rejectlist,sp);
3120 if(!rjl) {one_up=0; da_free(adrs); goto done;}
3121 rejectlist=rjl;
3122 }
3123 do {
3124 one_up=add_qserv(&serv, &DA_INDEX(adrs,k), 53, sp->timeout,
3125 mk_flag_val(sp)&~CFF_NOINHERIT, sp->nocache,
3126 sp->lean_query,sp->edns_query,2,0,
3127 !global.paranoid,topdomain, rjl);
3128 if(!one_up) {
3129 da_free(adrs);
3130 goto done;
3131 }
3132 if(++k==l) k=0;
3133 } while(k!=kstart);
3134 da_free(adrs);
3135 DEBUG_PDNSDA_MSG("Not querying root-server %s, using cached information instead.\n",
3136 PDNSDA2STR(PDNSD_A2_TO_A(&at->a)));
3137 seenrootserv=2;
3138 break;
3139 }
3140 }
3141 else if(seenrootserv==2)
3142 break;
3143 }
3144 if(serv_has_rejectlist(sp) && !rjl) {
3145 rjl=add_rejectlist(rejectlist,sp);
3146 if(!rjl) {one_up=0; goto done;}
3147 rejectlist=rjl;
3148 }
3149 {
3150 one_up=add_qserv(&serv, &at->a, sp->port, sp->timeout,
3151 mk_flag_val(sp), sp->nocache, sp->lean_query,sp->edns_query,
3152 sp->rootserver?3:(!sp->is_proxy),
3153 needs_testing(sp), 1, NULL, rjl);
3154 }
3155 if(!one_up)
3156 goto done;
3157 }
3158 if(++j==m) j=0;
3159 } while(j!=jstart);
3160 }
3161 }
3162 }
3163 done:
3164 unlock_server_data();
3165 if (one_up) {
3166 dns_cent_t *cached;
3167 int nocache;
3168 rc=p_recursive_query(serv, name, thint, &cached, &nocache, hops, NULL, qhlist, c_soa);
3169 if (rc==RC_OK) {
3170 if (!nocache) {
3171 dns_cent_t *tc;
3172 add_cache(cached);
3173 if ((tc=lookup_cache(name,NULL))) {
3174 /* The cache may hold more information than the recent query yielded.
3175 * try to get the merged record. If that fails, revert to the new one. */
3176 free_cent(cached DBG1);
3177 pdnsd_free(cached);
3178 cached=tc;
3179 } else
3180 DEBUG_MSG("p_dns_resolve: merging answer with cache failed, using local cent copy.\n");
3181 } else
3182 DEBUG_MSG("p_dns_resolve: nocache.\n");
3183
3184 *cachedp=cached;
3185 }
3186 }
3187 else {
3188 DEBUG_MSG("No server is marked up and allowed for this domain.\n");
3189 rc=RC_SERVFAIL; /* No server up */
3190 }
3191 del_qserv(serv);
3192 free_rejectlist(rejectlist);
3193 return rc;
3194 }
3195
set_flags_ttl(unsigned short * flags,time_t * ttl,dns_cent_t * cached,int tp)3196 static int set_flags_ttl(unsigned short *flags, time_t *ttl, dns_cent_t *cached, int tp)
3197 {
3198 rr_set_t *rrset=getrrset(cached,tp);
3199 if (rrset) {
3200 time_t t;
3201 *flags|=rrset->flags;
3202 t=rrset->ts+CLAT_ADJ(rrset->ttl);
3203 if (!*ttl || *ttl>t)
3204 *ttl=t;
3205 return 1;
3206 }
3207 return 0;
3208 }
3209
set_all_flags_ttl(unsigned short * flags,time_t * ttl,dns_cent_t * cached)3210 static void set_all_flags_ttl(unsigned short *flags, time_t *ttl, dns_cent_t *cached)
3211 {
3212 int i, ilim= RRARR_LEN(cached);
3213
3214 for(i=0; i<ilim; ++i) {
3215 rr_set_t *rrset= RRARR_INDEX(cached,i);
3216 if (rrset) {
3217 time_t t;
3218 *flags|=rrset->flags;
3219 t=rrset->ts+CLAT_ADJ(rrset->ttl);
3220 if (!*ttl || *ttl>t)
3221 *ttl=t;
3222 }
3223 }
3224 }
3225
3226 /*
3227 Lookup name in the cache, and if records of type thint are found, check whether a requery is needed.
3228 Possible returns values are:
3229 RC_OK: the name is locally defined.
3230 RC_NAMEERR: the name is locally negatively cached.
3231 RC_CACHED: name was found in the cache, requery not needed.
3232 RC_STALE: name was found in the cache, but requery is needed.
3233 RC_NOTCACHED: name was not found in the cache.
3234 */
lookup_cache_status(const unsigned char * name,int thint,dns_cent_t ** cachedp,unsigned short * flagsp,time_t queryts,unsigned char * c_soa)3235 static int lookup_cache_status(const unsigned char *name, int thint, dns_cent_t **cachedp, unsigned short *flagsp,
3236 time_t queryts, unsigned char *c_soa)
3237 {
3238 dns_cent_t *cached;
3239 int rc=RC_NOTCACHED;
3240 int wild=0;
3241 unsigned short flags=0;
3242
3243 if ((cached=lookup_cache(name,&wild))) {
3244 short int neg=0,timed=0,need_req=0;
3245 time_t ttl=0;
3246
3247 if (cached->flags&DF_LOCAL) {
3248 #if DEBUG>0
3249 {
3250 char dflagstr[DFLAGSTRLEN];
3251 DEBUG_RHN_MSG("Entry found in cache for '%s' with dflags=%s.\n",
3252 RHN2STR(cached->qname),dflags2str(cached->flags,dflagstr));
3253 }
3254 #endif
3255 if((cached->flags&DF_NEGATIVE) || wild==w_locnerr) {
3256 if(c_soa) {
3257 if(cached->c_soa!=cundef)
3258 *c_soa=cached->c_soa;
3259 else if(have_rr_SOA(cached))
3260 *c_soa=rhnsegcnt(cached->qname);
3261 else {
3262 unsigned char *owner=getlocalowner(cached->qname,T_SOA);
3263 if(owner)
3264 *c_soa=rhnsegcnt(owner);
3265 }
3266 }
3267 free_cent(cached DBG1);
3268 pdnsd_free(cached);
3269 rc= RC_NAMEERR;
3270 goto return_rc;
3271 }
3272 else {
3273 rc= RC_OK;
3274 goto return_rc_cent;
3275 }
3276 }
3277 DEBUG_RHN_MSG("Record found in cache for %s\n",RHN2STR(cached->qname));
3278 if (cached->flags&DF_NEGATIVE) {
3279 if ((ttl=cached->neg.ts+CLAT_ADJ(cached->neg.ttl))>=queryts)
3280 neg=1;
3281 else
3282 timed=1;
3283 } else {
3284 if (thint==QT_ALL) {
3285 set_all_flags_ttl(&flags, &ttl, cached);
3286 }
3287 else if (!set_flags_ttl(&flags, &ttl, cached, T_CNAME) || (getrrset_CNAME(cached)->flags&CF_NEGATIVE)) {
3288 flags=0; ttl=0;
3289 if (thint>=T_MIN && thint<=T_MAX) {
3290 if (set_flags_ttl(&flags, &ttl, cached, thint))
3291 neg=getrrset(cached,thint)->flags&CF_NEGATIVE && ttl>=queryts;
3292 }
3293 else if (thint==QT_MAILB) {
3294 set_flags_ttl(&flags, &ttl, cached, T_MB);
3295 set_flags_ttl(&flags, &ttl, cached, T_MG);
3296 set_flags_ttl(&flags, &ttl, cached, T_MR);
3297 }
3298 else if (thint==QT_MAILA) {
3299 set_flags_ttl(&flags, &ttl, cached, T_MD);
3300 set_flags_ttl(&flags, &ttl, cached, T_MF);
3301 }
3302 }
3303 if(!(flags&CF_LOCAL)) {
3304 if (thint==QT_ALL) {
3305 if(!(cached->flags&DF_AUTH))
3306 need_req=1;
3307 }
3308 else if (thint>=QT_MIN && thint<=QT_MAX) {
3309 if(!(flags&CF_AUTH && !(flags&CF_ADDITIONAL)))
3310 need_req=1;
3311 }
3312 if (ttl<queryts)
3313 timed=1;
3314 }
3315 }
3316 #if DEBUG>0
3317 {
3318 char dflagstr[DFLAGSTRLEN],cflagstr[CFLAGSTRLEN];
3319 DEBUG_MSG("Requery decision: dflags=%s, cflags=%s, req=%i, neg=%i, timed=%i, %s=%li\n",
3320 dflags2str(cached->flags,dflagstr),cflags2str(flags,cflagstr),need_req,neg,timed,
3321 ttl?"ttl":"timestamp",(long)(ttl?(ttl-queryts):ttl));
3322 }
3323 #endif
3324 rc = (!neg && (need_req || timed))? RC_STALE: RC_CACHED;
3325 return_rc_cent:
3326 *cachedp=cached;
3327 }
3328
3329 return_rc:
3330 if(flagsp) *flagsp=flags;
3331 return rc;
3332 }
3333
3334
3335 /*
3336 * Resolve records for name into dns_cent_t, type thint
3337 * q is the set of servers to query from. Set q to NULL if you want to ask the servers registered with pdnsd.
3338 * qslist should refer to a list of server arrays already used higher up the calling chain (may be NULL).
3339 */
p_dns_cached_resolve(query_stat_array q,const unsigned char * name,int thint,dns_cent_t ** cachedp,int hops,qstatnode_t * qslist,qhintnode_t * qhlist,time_t queryts,unsigned char * c_soa)3340 static int p_dns_cached_resolve(query_stat_array q, const unsigned char *name, int thint, dns_cent_t **cachedp,
3341 int hops, qstatnode_t *qslist, qhintnode_t *qhlist, time_t queryts,
3342 unsigned char *c_soa)
3343 {
3344 dns_cent_t *cached=NULL;
3345 int rc;
3346 unsigned short flags=0;
3347
3348 DEBUG_RHN_MSG("Starting cached resolve for: %s, query %s\n",RHN2STR(name),get_tname(thint));
3349 rc= lookup_cache_status(name, thint, &cached, &flags,queryts,c_soa);
3350 if(rc==RC_OK) {
3351 /* Locally defined record. */
3352 *cachedp=cached;
3353 return RC_OK;
3354 }
3355 else if(rc==RC_NAMEERR) /* Locally negated name. */
3356 return RC_NAMEERR;
3357
3358 /* update server records set onquery */
3359 if(global.onquery) test_onquery();
3360 if (global.lndown_kluge && !(flags&CF_LOCAL)) {
3361 int i,n,linkdown=1;
3362 lock_server_data();
3363 n=DA_NEL(servers);
3364 for(i=0;i<n;++i) {
3365 servparm_t *sp=&DA_INDEX(servers,i);
3366 if(sp->rootserver<=1) {
3367 int j,m=DA_NEL(sp->atup_a);
3368 for(j=0;j<m;++j) {
3369 if (DA_INDEX(sp->atup_a,j).is_up) {
3370 linkdown=0;
3371 goto done;
3372 }
3373 }
3374 }
3375 }
3376 done:
3377 unlock_server_data();
3378 if (linkdown) {
3379 DEBUG_MSG("Link is down.\n");
3380 rc=RC_SERVFAIL;
3381 goto cleanup_return;
3382 }
3383 }
3384 if (rc!=RC_CACHED) {
3385 dns_cent_t *ent;
3386 DEBUG_MSG("Trying name servers.\n");
3387 if (q)
3388 rc=p_recursive_query(q,name,thint, &ent,NULL,hops,qslist,qhlist,c_soa);
3389 else
3390 rc=p_dns_resolve(name,thint, &ent,hops,qhlist,c_soa);
3391 if (rc!=RC_OK) {
3392 if (rc==RC_SERVFAIL && cached && (flags&CF_NOPURGE)) {
3393 /* We could not get a new record, but we have a timed-out cached one
3394 with the nopurge flag set. This means that we shall use it even
3395 if timed out when no new one is available*/
3396 DEBUG_MSG("Falling back to cached record.\n");
3397 } else {
3398 goto cleanup_return;
3399 }
3400 } else {
3401 if (cached) {
3402 free_cent(cached DBG1);
3403 pdnsd_free(cached);
3404 }
3405 cached=ent;
3406 }
3407 } else {
3408 DEBUG_MSG("Using cached record.\n");
3409 }
3410 *cachedp=cached;
3411 return RC_OK;
3412
3413 cleanup_return:
3414 if(cached) {
3415 free_cent(cached DBG1);
3416 pdnsd_free(cached);
3417 }
3418 return rc;
3419 }
3420
3421
3422 /* r_dns_cached_resolve() is like p_dns_cached_resolve(), except that r_dns_cached_resolve()
3423 will not return negatively cached entries, but return RC_NAMEERR instead.
3424 */
r_dns_cached_resolve(unsigned char * name,int thint,dns_cent_t ** cachedp,int hops,qhintnode_t * qhlist,time_t queryts,unsigned char * c_soa)3425 int r_dns_cached_resolve(unsigned char *name, int thint, dns_cent_t **cachedp,
3426 int hops, qhintnode_t *qhlist, time_t queryts,
3427 unsigned char *c_soa)
3428 {
3429 dns_cent_t *cached;
3430 int rc=p_dns_cached_resolve(NULL,name,thint,&cached,hops,NULL,qhlist,queryts,c_soa);
3431 if(rc==RC_OK) {
3432 if(cached->flags&DF_NEGATIVE) {
3433 if(c_soa)
3434 *c_soa=cached->c_soa;
3435 free_cent(cached DBG1);
3436 pdnsd_free(cached);
3437 rc=RC_NAMEERR;
3438 }
3439 else
3440 *cachedp=cached;
3441 }
3442 return rc;
3443 }
3444
3445
simple_dns_cached_resolve(atup_array atup_a,int port,char edns_query,time_t timeout,const unsigned char * name,int thint,dns_cent_t ** cachedp)3446 static int simple_dns_cached_resolve(atup_array atup_a, int port, char edns_query, time_t timeout,
3447 const unsigned char *name, int thint, dns_cent_t **cachedp)
3448 {
3449 dns_cent_t *cached=NULL;
3450 int rc;
3451
3452 DEBUG_RHN_MSG("Starting simple cached resolve for: %s, query %s\n",RHN2STR(name),get_tname(thint));
3453 rc= lookup_cache_status(name, thint, &cached, NULL, time(NULL), NULL);
3454 if(rc==RC_OK) {
3455 /* Locally defined record. */
3456 *cachedp=cached;
3457 return RC_OK;
3458 }
3459 else if(rc==RC_NAMEERR) /* Locally negated name. */
3460 return RC_NAMEERR;
3461
3462 if (rc!=RC_CACHED) {
3463 query_stat_array qserv;
3464 int j,m;
3465 if (cached) {
3466 free_cent(cached DBG1);
3467 pdnsd_free(cached);
3468 cached=NULL;
3469 }
3470 DEBUG_MSG("Trying name servers.\n");
3471 qserv=NULL;
3472 m=DA_NEL(atup_a);
3473 for(j=0; j<m; ++j) {
3474 if(!add_qserv(&qserv, &DA_INDEX(atup_a,j).a, port, timeout, 0, 0, 1, edns_query, 0, 0, 1, NULL, NULL)) {
3475 /* Note: qserv array already cleaned up by add_qserv() */
3476 return RC_SERVFAIL;
3477 }
3478 }
3479 rc=p_recursive_query(qserv,name,thint, &cached,NULL,0,NULL,NULL,NULL);
3480 del_qserv(qserv);
3481 if (rc==RC_OK) {
3482 dns_cent_t *tc;
3483 add_cache(cached);
3484 if ((tc=lookup_cache(name,NULL))) {
3485 /* The cache may hold more information than the recent query yielded.
3486 * try to get the merged record. If that fails, revert to the new one. */
3487 free_cent(cached DBG1);
3488 pdnsd_free(cached);
3489 cached=tc;
3490 } else
3491 DEBUG_MSG("simple_dns_cached_resolve: merging answer with cache failed, using local cent copy.\n");
3492 }
3493 else
3494 return rc;
3495 } else {
3496 DEBUG_MSG("Using cached record.\n");
3497 }
3498
3499 if(cached->flags&DF_NEGATIVE) {
3500 free_cent(cached DBG1);
3501 pdnsd_free(cached);
3502 return RC_NAMEERR;
3503 }
3504
3505 *cachedp=cached;
3506 return RC_OK;
3507 }
3508
3509
3510 /* Check whether a server is responsive by sending it an (empty) query.
3511 rep is the number of times this is tried in case of no reply.
3512 */
query_uptest(pdnsd_a * addr,int port,const unsigned char * name,time_t timeout,int rep)3513 int query_uptest(pdnsd_a *addr, int port, const unsigned char *name, time_t timeout, int rep)
3514 {
3515 query_stat_t qs;
3516 int iter=0,rv;
3517
3518 #ifdef ENABLE_IPV4
3519 if (run_ipv4) {
3520 memset(&qs.a.sin4,0,sizeof(qs.a.sin4));
3521 qs.a.sin4.sin_family=AF_INET;
3522 qs.a.sin4.sin_port=htons(port);
3523 qs.a.sin4.sin_addr=addr->ipv4;
3524 SET_SOCKA_LEN4(qs.a.sin4);
3525 }
3526 #endif
3527 #ifdef ENABLE_IPV6
3528 ELSE_IPV6 {
3529 memset(&qs.a.sin6,0,sizeof(qs.a.sin6));
3530 qs.a.sin6.sin6_family=AF_INET6;
3531 qs.a.sin6.sin6_port=htons(port);
3532 qs.a.sin6.sin6_flowinfo=IPV6_FLOWINFO;
3533 qs.a.sin6.sin6_addr=addr->ipv6;
3534 SET_SOCKA_LEN6(qs.a.sin6);
3535
3536 qs.a4fallback.s_addr=INADDR_ANY;
3537 }
3538 #endif
3539 qs.timeout=timeout;
3540 qs.flags=0;
3541 qs.nocache=0;
3542 qs.auth_serv=0;
3543 qs.lean_query=1;
3544 qs.edns_query=0;
3545 qs.needs_testing=0;
3546 qs.trusted=1;
3547 qs.aa=0;
3548 qs.tc=0;
3549 qs.nsdomain=NULL;
3550 qs.rejectlist=NULL;
3551
3552 try_again:
3553 qs.state=QS_INITIAL;
3554 qs.qm=global.query_method;
3555 qs.s_errno=0;
3556 rv=p_exec_query(NULL, name, T_A, &qs, NULL, NULL);
3557 if(rv==-1) {
3558 time_t ts, tpassed;
3559 for(ts=time(NULL), tpassed=0;; tpassed=time(NULL)-ts) {
3560 int event;
3561 #ifdef NO_POLL
3562 fd_set reads;
3563 fd_set writes;
3564 struct timeval tv;
3565 FD_ZERO(&reads);
3566 FD_ZERO(&writes);
3567 PDNSD_ASSERT(qs.sock<FD_SETSIZE,"socket file descriptor exceeds FD_SETSIZE.");
3568 switch (qs.state) {
3569 QS_READ_CASES:
3570 FD_SET(qs.sock,&reads);
3571 break;
3572 QS_WRITE_CASES:
3573 FD_SET(qs.sock,&writes);
3574 break;
3575 }
3576 tv.tv_sec=timeout>tpassed?timeout-tpassed:0;
3577 tv.tv_usec=0;
3578 /* There is a possible race condition with the arrival of a signal here,
3579 but it is so unlikely to be a problem in practice that doing
3580 this properly is not worth the trouble.
3581 */
3582 if(is_interrupted_servstat_thread()) {
3583 DEBUG_MSG("server status thread interrupted.\n");
3584 p_cancel_query(&qs);
3585 return 0;
3586 }
3587 event=select(qs.sock+1,&reads,&writes,NULL,&tv);
3588 #else
3589 struct pollfd pfd;
3590 pfd.fd=qs.sock;
3591 switch (qs.state) {
3592 QS_READ_CASES:
3593 pfd.events=POLLIN;
3594 break;
3595 QS_WRITE_CASES:
3596 pfd.events=POLLOUT;
3597 break;
3598 default:
3599 pfd.events=0;
3600 }
3601 /* There is a possible race condition with the arrival of a signal here,
3602 but it is so unlikely to be a problem in practice that doing
3603 this properly is not worth the trouble.
3604 */
3605 if(is_interrupted_servstat_thread()) {
3606 DEBUG_MSG("server status thread interrupted.\n");
3607 p_cancel_query(&qs);
3608 return 0;
3609 }
3610 event=poll(&pfd,1,timeout>tpassed?(timeout-tpassed)*1000:0);
3611 #endif
3612 if (event<0) {
3613 if(errno==EINTR && is_interrupted_servstat_thread()) {
3614 DEBUG_MSG("poll/select interrupted in server status thread.\n");
3615 }
3616 else
3617 log_warn("poll/select failed: %s",strerror(errno));
3618 p_cancel_query(&qs);
3619 return 0;
3620 }
3621 if(event==0) {
3622 /* timed out */
3623 p_cancel_query(&qs);
3624 if(++iter<rep) goto try_again;
3625 return 0;
3626 }
3627 event=0;
3628 #ifdef NO_POLL
3629 switch (qs.state) {
3630 QS_READ_CASES:
3631 event=FD_ISSET(qs.sock,&reads);
3632 break;
3633 QS_WRITE_CASES:
3634 event=FD_ISSET(qs.sock,&writes);
3635 break;
3636 }
3637 #else
3638 switch (qs.state) {
3639 QS_READ_CASES:
3640 event=pfd.revents&(POLLIN|POLLERR|POLLHUP|POLLNVAL);
3641 break;
3642 QS_WRITE_CASES:
3643 event=pfd.revents&(POLLOUT|POLLERR|POLLHUP|POLLNVAL);
3644 break;
3645 }
3646 #endif
3647 if(event) {
3648 rv=p_exec_query(NULL, name, T_A, &qs, NULL, NULL);
3649 if(rv!=-1) break;
3650 }
3651 else {
3652 if(++poll_errs<=MAXPOLLERRS)
3653 log_error("Unhandled poll/select event in query_uptest() at %s, line %d.",__FILE__,__LINE__);
3654 p_cancel_query(&qs);
3655 return 0;
3656 }
3657 }
3658 }
3659 return (rv!=RC_SERVFAIL && rv!=RC_FATALERR);
3660 }
3661