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,&cent);
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