xref: /freebsd/contrib/ldns/net.c (revision 980ba4177b69655726485daa5ff3e931f19aa738)
1 /*
2  * net.c
3  *
4  * Network implementation
5  * All network related functions are grouped here
6  *
7  * a Net::DNS like library for C
8  *
9  * (c) NLnet Labs, 2004-2006
10  *
11  * See the file LICENSE for the license
12  */
13 
14 #include <ldns/config.h>
15 
16 #include <ldns/ldns.h>
17 
18 #ifdef HAVE_NETINET_IN_H
19 #include <netinet/in.h>
20 #endif
21 #ifdef HAVE_SYS_SOCKET_H
22 #include <sys/socket.h>
23 #endif
24 #ifdef HAVE_NETDB_H
25 #include <netdb.h>
26 #endif
27 #ifdef HAVE_ARPA_INET_H
28 #include <arpa/inet.h>
29 #endif
30 #include <sys/time.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #ifdef HAVE_POLL
34 #include <poll.h>
35 #endif
36 
37 ldns_status
38 ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
39 {
40 	ldns_buffer *qb;
41 	ldns_status result;
42 	ldns_rdf *tsig_mac = NULL;
43 
44 	qb = ldns_buffer_new(LDNS_MIN_BUFLEN);
45 
46 	if (query_pkt && ldns_pkt_tsig(query_pkt)) {
47 		tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3);
48 	}
49 
50 	if (!query_pkt ||
51 	    ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) {
52 		result = LDNS_STATUS_ERR;
53 	} else {
54         	result = ldns_send_buffer(result_packet, r, qb, tsig_mac);
55 	}
56 
57 	ldns_buffer_free(qb);
58 
59 	return result;
60 }
61 
62 /* code from rdata.c */
63 static struct sockaddr_storage *
64 ldns_rdf2native_sockaddr_storage_port(
65 		const ldns_rdf *rd, uint16_t port, size_t *size)
66 {
67         struct sockaddr_storage *data;
68         struct sockaddr_in  *data_in;
69         struct sockaddr_in6 *data_in6;
70 
71         data = LDNS_MALLOC(struct sockaddr_storage);
72         if (!data) {
73                 return NULL;
74         }
75 	/* zero the structure for portability */
76 	memset(data, 0, sizeof(struct sockaddr_storage));
77 
78         switch(ldns_rdf_get_type(rd)) {
79                 case LDNS_RDF_TYPE_A:
80 #ifndef S_SPLINT_S
81                         data->ss_family = AF_INET;
82 #endif
83                         data_in = (struct sockaddr_in*) data;
84                         data_in->sin_port = (in_port_t)htons(port);
85                         memcpy(&(data_in->sin_addr), ldns_rdf_data(rd), ldns_rdf_size(rd));
86                         *size = sizeof(struct sockaddr_in);
87                         return data;
88                 case LDNS_RDF_TYPE_AAAA:
89 #ifndef S_SPLINT_S
90                         data->ss_family = AF_INET6;
91 #endif
92                         data_in6 = (struct sockaddr_in6*) data;
93                         data_in6->sin6_port = (in_port_t)htons(port);
94                         memcpy(&data_in6->sin6_addr, ldns_rdf_data(rd), ldns_rdf_size(rd));
95                         *size = sizeof(struct sockaddr_in6);
96                         return data;
97                 default:
98                         LDNS_FREE(data);
99                         return NULL;
100         }
101 }
102 
103 struct sockaddr_storage *
104 ldns_rdf2native_sockaddr_storage(
105 		const ldns_rdf *rd, uint16_t port, size_t *size)
106 {
107 	return ldns_rdf2native_sockaddr_storage_port(
108 			rd, (port == 0 ? (uint16_t)LDNS_PORT : port), size);
109 }
110 
111 /** best effort to set nonblocking */
112 static void
113 ldns_sock_nonblock(int sockfd)
114 {
115 #ifdef HAVE_FCNTL
116 	int flag;
117 	if((flag = fcntl(sockfd, F_GETFL)) != -1) {
118 		flag |= O_NONBLOCK;
119 		if(fcntl(sockfd, F_SETFL, flag) == -1) {
120 			/* ignore error, continue blockingly */
121 		}
122 	}
123 #elif defined(HAVE_IOCTLSOCKET)
124 	unsigned long on = 1;
125 	if(ioctlsocket(sockfd, FIONBIO, &on) != 0) {
126 		/* ignore error, continue blockingly */
127 	}
128 #endif
129 }
130 
131 /** best effort to set blocking */
132 static void
133 ldns_sock_block(int sockfd)
134 {
135 #ifdef HAVE_FCNTL
136 	int flag;
137 	if((flag = fcntl(sockfd, F_GETFL)) != -1) {
138 		flag &= ~O_NONBLOCK;
139 		if(fcntl(sockfd, F_SETFL, flag) == -1) {
140 			/* ignore error, continue */
141 		}
142 	}
143 #elif defined(HAVE_IOCTLSOCKET)
144 	unsigned long off = 0;
145 	if(ioctlsocket(sockfd, FIONBIO, &off) != 0) {
146 		/* ignore error, continue */
147 	}
148 #endif
149 }
150 
151 /** wait for a socket to become ready */
152 static int
153 ldns_sock_wait(int sockfd, struct timeval timeout, int write)
154 {
155 	int ret;
156 #ifndef HAVE_POLL
157 #ifndef S_SPLINT_S
158 	fd_set fds;
159 	FD_ZERO(&fds);
160 	FD_SET(FD_SET_T sockfd, &fds);
161 	if(write)
162 		ret = select(sockfd+1, NULL, &fds, NULL, &timeout);
163 	else
164 		ret = select(sockfd+1, &fds, NULL, NULL, &timeout);
165 #endif
166 #else
167 	struct pollfd pfds[2];
168 
169 	memset(&pfds[0], 0, sizeof(pfds[0]) * 2);
170 
171 	pfds[0].fd = sockfd;
172 	pfds[0].events = POLLIN|POLLERR;
173 
174 	if (write) {
175 		pfds[0].events |= POLLOUT;
176 	}
177 
178 	ret = poll(pfds, 1, (int)(timeout.tv_sec * 1000
179 				+ timeout.tv_usec / 1000));
180 #endif
181 	if(ret == 0)
182 		/* timeout expired */
183 		return 0;
184 	else if(ret == -1)
185 		/* error */
186 		return 0;
187 	return 1;
188 }
189 
190 
191 static int
192 ldns_tcp_connect_from(const struct sockaddr_storage *to, socklen_t tolen,
193 	       	const struct sockaddr_storage *from, socklen_t fromlen,
194 		struct timeval timeout)
195 {
196 	int sockfd;
197 
198 #ifndef S_SPLINT_S
199 	if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM,
200 					IPPROTO_TCP)) == SOCK_INVALID) {
201 		return -1;
202 	}
203 #endif
204 	if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == -1){
205 		close_socket(sockfd);
206 		return -1;
207 	}
208 
209 	/* perform nonblocking connect, to be able to wait with select() */
210 	ldns_sock_nonblock(sockfd);
211 	if (connect(sockfd, (struct sockaddr*)to, tolen) == -1) {
212 #ifndef USE_WINSOCK
213 #ifdef EINPROGRESS
214 		if(errno != EINPROGRESS) {
215 #else
216 		if(1) {
217 #endif
218 			close_socket(sockfd);
219 			return -1;
220 		}
221 #else /* USE_WINSOCK */
222 		if(WSAGetLastError() != WSAEINPROGRESS &&
223 			WSAGetLastError() != WSAEWOULDBLOCK) {
224 			close_socket(sockfd);
225 			return -1;
226 		}
227 #endif
228 		/* error was only telling us that it would block */
229 	}
230 
231 	/* wait(write) until connected or error */
232 	while(1) {
233 		int error = 0;
234 		socklen_t len = (socklen_t)sizeof(error);
235 
236 		if(!ldns_sock_wait(sockfd, timeout, 1)) {
237 			close_socket(sockfd);
238 			return -1;
239 		}
240 
241 		/* check if there is a pending error for nonblocking connect */
242 		if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&error,
243 			&len) < 0) {
244 #ifndef USE_WINSOCK
245 			error = errno; /* on solaris errno is error */
246 #else
247 			error = WSAGetLastError();
248 #endif
249 		}
250 #ifndef USE_WINSOCK
251 #if defined(EINPROGRESS) && defined(EWOULDBLOCK)
252 		if(error == EINPROGRESS || error == EWOULDBLOCK)
253 			continue; /* try again */
254 #endif
255 		else if(error != 0) {
256 			close_socket(sockfd);
257 			/* error in errno for our user */
258 			errno = error;
259 			return -1;
260 		}
261 #else /* USE_WINSOCK */
262 		if(error == WSAEINPROGRESS)
263 			continue;
264 		else if(error == WSAEWOULDBLOCK)
265 			continue;
266 		else if(error != 0) {
267 			close_socket(sockfd);
268 			errno = error;
269 			return -1;
270 		}
271 #endif /* USE_WINSOCK */
272 		/* connected */
273 		break;
274 	}
275 
276 	/* set the socket blocking again */
277 	ldns_sock_block(sockfd);
278 
279 	return sockfd;
280 }
281 
282 int
283 ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen,
284 		struct timeval timeout)
285 {
286 	int s = ldns_tcp_connect_from(to, tolen, NULL, 0, timeout);
287 	return s > 0 ? s : 0;
288 }
289 
290 int
291 ldns_tcp_connect2(const struct sockaddr_storage *to, socklen_t tolen,
292 		struct timeval timeout)
293 {
294 	return ldns_tcp_connect_from(to, tolen, NULL, 0, timeout);
295 }
296 
297 static int
298 ldns_tcp_bgsend_from(ldns_buffer *qbin,
299 		const struct sockaddr_storage *to, socklen_t tolen,
300 	       	const struct sockaddr_storage *from, socklen_t fromlen,
301 		struct timeval timeout)
302 {
303 	int sockfd;
304 
305 	sockfd = ldns_tcp_connect_from(to, tolen, from, fromlen, timeout);
306 
307 	if (sockfd >= 0 && ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) {
308 		close_socket(sockfd);
309 		return -1;
310 	}
311 
312 	return sockfd;
313 }
314 
315 int
316 ldns_tcp_bgsend(ldns_buffer *qbin,
317 		const struct sockaddr_storage *to, socklen_t tolen,
318 		struct timeval timeout)
319 {
320 	int s = ldns_tcp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
321 	return s > 0 ? s : 0;
322 }
323 
324 int
325 ldns_tcp_bgsend2(ldns_buffer *qbin,
326 		const struct sockaddr_storage *to, socklen_t tolen,
327 		struct timeval timeout)
328 {
329 	return ldns_tcp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
330 }
331 
332 /* keep in mind that in DNS tcp messages the first 2 bytes signal the
333  * amount data to expect
334  */
335 static ldns_status
336 ldns_tcp_send_from(uint8_t **result,  ldns_buffer *qbin,
337 	       	const struct sockaddr_storage *to, socklen_t tolen,
338 	       	const struct sockaddr_storage *from, socklen_t fromlen,
339 		struct timeval timeout, size_t *answer_size)
340 {
341 	int sockfd;
342 	uint8_t *answer;
343 
344 	sockfd = ldns_tcp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
345 
346 	if (sockfd == -1) {
347 		return LDNS_STATUS_ERR;
348 	}
349 
350 	answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout);
351 	close_socket(sockfd);
352 
353 	if (!answer) {
354 		/* oops */
355 		return LDNS_STATUS_NETWORK_ERR;
356 	}
357 
358 	*result = answer;
359 	return LDNS_STATUS_OK;
360 }
361 
362 ldns_status
363 ldns_tcp_send(uint8_t **result,  ldns_buffer *qbin,
364 		const struct sockaddr_storage *to, socklen_t tolen,
365 		struct timeval timeout, size_t *answer_size)
366 {
367 	return ldns_tcp_send_from(result, qbin,
368 			to, tolen, NULL, 0, timeout, answer_size);
369 }
370 
371 int
372 ldns_udp_connect(const struct sockaddr_storage *to, struct timeval ATTR_UNUSED(timeout))
373 {
374 	int sockfd;
375 
376 #ifndef S_SPLINT_S
377 	if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM,
378 					IPPROTO_UDP))
379 			== SOCK_INVALID) {
380                 return 0;
381         }
382 #endif
383 	return sockfd;
384 }
385 
386 int
387 ldns_udp_connect2(const struct sockaddr_storage *to, struct timeval ATTR_UNUSED(timeout))
388 {
389 	int sockfd;
390 
391 #ifndef S_SPLINT_S
392 	if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM,
393 					IPPROTO_UDP))
394 			== SOCK_INVALID) {
395                 return -1;
396         }
397 #endif
398 	return sockfd;
399 }
400 
401 static int
402 ldns_udp_bgsend_from(ldns_buffer *qbin,
403 		const struct sockaddr_storage *to  , socklen_t tolen,
404 		const struct sockaddr_storage *from, socklen_t fromlen,
405 		struct timeval timeout)
406 {
407 	int sockfd;
408 
409 	sockfd = ldns_udp_connect2(to, timeout);
410 
411 	if (sockfd == -1) {
412 		return -1;
413 	}
414 
415 	if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == -1){
416 		close_socket(sockfd);
417 		return -1;
418 	}
419 
420 	if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) {
421 		close_socket(sockfd);
422 		return -1;
423 	}
424 	return sockfd;
425 }
426 
427 int
428 ldns_udp_bgsend(ldns_buffer *qbin,
429 		const struct sockaddr_storage *to  , socklen_t tolen,
430 		struct timeval timeout)
431 {
432 	int s = ldns_udp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
433 	return s > 0 ? s : 0;
434 }
435 
436 int
437 ldns_udp_bgsend2(ldns_buffer *qbin,
438 		const struct sockaddr_storage *to  , socklen_t tolen,
439 		struct timeval timeout)
440 {
441 	return ldns_udp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
442 }
443 
444 /** helper sockaddr compare function. returns -1, 0 or 1. */
445 static int
446 ldns_sockaddr_cmp(const struct sockaddr_storage* addr1, socklen_t len1,
447 	const struct sockaddr_storage* addr2, socklen_t len2)
448 {
449 	struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1;
450 	struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2;
451 	struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1;
452 	struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2;
453 	if(len1 < len2)
454 		return -1;
455 	if(len1 > len2)
456 		return 1;
457 	assert(len1 == len2);
458 	if( p1_in->sin_family < p2_in->sin_family)
459 		return -1;
460 	if( p1_in->sin_family > p2_in->sin_family)
461 		return 1;
462 	assert( p1_in->sin_family == p2_in->sin_family );
463 	/* compare ip4 */
464 	if( p1_in->sin_family == AF_INET ) {
465 		/* just order it, ntohs not required */
466 		if(p1_in->sin_port < p2_in->sin_port)
467 			return -1;
468 		if(p1_in->sin_port > p2_in->sin_port)
469 			return 1;
470 		assert(p1_in->sin_port == p2_in->sin_port);
471 		return memcmp(&p1_in->sin_addr, &p2_in->sin_addr,
472 			sizeof(p1_in->sin_addr));
473 	} else if (p1_in6->sin6_family == AF_INET6) {
474 		/* just order it, ntohs not required */
475 		if(p1_in6->sin6_port < p2_in6->sin6_port)
476 			return -1;
477 		if(p1_in6->sin6_port > p2_in6->sin6_port)
478 			return 1;
479 		assert(p1_in6->sin6_port == p2_in6->sin6_port);
480 		return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr,
481 			sizeof(p1_in6->sin6_addr));
482 	} else {
483 		/* eek unknown type, perform this comparison for sanity. */
484 		return memcmp(addr1, addr2, len1);
485 	}
486 }
487 
488 static ldns_status
489 ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
490 		const struct sockaddr_storage *to  , socklen_t tolen,
491 		const struct sockaddr_storage *from, socklen_t fromlen,
492 		struct timeval timeout, size_t *answer_size)
493 {
494 	int sockfd;
495 	uint8_t *answer;
496 	struct sockaddr_storage reply_addr;
497 	socklen_t reply_addr_len;
498 
499 	sockfd = ldns_udp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
500 
501 	if (sockfd == -1) {
502 		return LDNS_STATUS_SOCKET_ERROR;
503 	}
504 
505 	/* wait for an response*/
506 	if(!ldns_sock_wait(sockfd, timeout, 0)) {
507 		close_socket(sockfd);
508 		return LDNS_STATUS_NETWORK_ERR;
509 	}
510 
511         /* set to nonblocking, so if the checksum is bad, it becomes
512          * an EAGAIN error and the ldns_udp_send function does not block,
513          * but returns a 'NETWORK_ERROR' much like a timeout. */
514         ldns_sock_nonblock(sockfd);
515 
516 	reply_addr_len = sizeof(reply_addr);
517 	memset(&reply_addr, 0, reply_addr_len);
518 	answer = ldns_udp_read_wire(sockfd, answer_size, &reply_addr,
519 		&reply_addr_len);
520 	close_socket(sockfd);
521 
522 	if (!answer) {
523 		/* oops */
524 		return LDNS_STATUS_NETWORK_ERR;
525 	}
526 	/* Check that the reply came from the to addr. */
527 	if(ldns_sockaddr_cmp(to, tolen, &reply_addr, reply_addr_len) != 0) {
528 		free(answer);
529 		return LDNS_STATUS_NETWORK_ERR;
530 	}
531 
532 	*result = answer;
533 	return LDNS_STATUS_OK;
534 }
535 
536 ldns_status
537 ldns_udp_send(uint8_t **result, ldns_buffer *qbin,
538 		const struct sockaddr_storage *to  , socklen_t tolen,
539 		struct timeval timeout, size_t *answer_size)
540 {
541 	return ldns_udp_send_from(result, qbin, to, tolen, NULL, 0,
542 			timeout, answer_size);
543 }
544 
545 ldns_status
546 ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
547 {
548 	uint8_t i;
549 
550 	struct sockaddr_storage *src = NULL;
551 	size_t src_len = 0;
552 	struct sockaddr_storage *ns;
553 	size_t ns_len;
554 	struct timeval tv_s;
555 	struct timeval tv_e;
556 
557 	ldns_rdf **ns_array;
558 	size_t *rtt;
559 	ldns_pkt *reply;
560 	bool all_servers_rtt_inf;
561 	uint8_t retries;
562 
563 	uint8_t *reply_bytes = NULL;
564 	size_t reply_size = 0;
565 	ldns_status status, send_status;
566 
567 	assert(r != NULL);
568 
569 	/* The query should at least have one question */
570 	if(ldns_buffer_limit(qb) < 6 || ldns_buffer_read_u16_at(qb, 4) != 1)
571 		return LDNS_STATUS_QDCOUNT_MUST_BE_ONE;
572 
573 	status = LDNS_STATUS_OK;
574 	rtt = ldns_resolver_rtt(r);
575 	ns_array = ldns_resolver_nameservers(r);
576 	reply = NULL;
577 	ns_len = 0;
578 
579 	all_servers_rtt_inf = true;
580 
581 	if (ldns_resolver_random(r)) {
582 		ldns_resolver_nameservers_randomize(r);
583 	}
584 
585 	if(ldns_resolver_source(r)) {
586 		src = ldns_rdf2native_sockaddr_storage_port(
587 				ldns_resolver_source(r), 0, &src_len);
588 	}
589 
590 	/* loop through all defined nameservers */
591 	for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
592 		if (rtt[i] == LDNS_RESOLV_RTT_INF) {
593 			/* not reachable nameserver! */
594 			continue;
595 		}
596 
597 		/* maybe verbosity setting?
598 		printf("Sending to ");
599 		ldns_rdf_print(stdout, ns_array[i]);
600 		printf("\n");
601 		*/
602 		ns = ldns_rdf2native_sockaddr_storage(ns_array[i],
603 				ldns_resolver_port(r), &ns_len);
604 
605 
606 #ifndef S_SPLINT_S
607 		if ((ns->ss_family == AF_INET) &&
608 				(ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
609 			/* not reachable */
610 			LDNS_FREE(ns);
611 			continue;
612 		}
613 
614 		if ((ns->ss_family == AF_INET6) &&
615 				 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
616 			/* not reachable */
617 			LDNS_FREE(ns);
618 			continue;
619 		}
620 #endif
621 
622 		all_servers_rtt_inf = false;
623 
624 		gettimeofday(&tv_s, NULL);
625 
626 		send_status = LDNS_STATUS_ERR;
627 
628 		/* reply_bytes implicitly handles our error */
629 		if (ldns_resolver_usevc(r)) {
630 			for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
631 				send_status =
632 					ldns_tcp_send_from(&reply_bytes, qb,
633 						ns, (socklen_t)ns_len,
634 						src, (socklen_t)src_len,
635 						ldns_resolver_timeout(r),
636 						&reply_size);
637 				if (send_status == LDNS_STATUS_OK) {
638 					break;
639 				}
640 			}
641 		} else {
642 			for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
643 				/* ldns_rdf_print(stdout, ns_array[i]); */
644 				send_status =
645 					ldns_udp_send_from(&reply_bytes, qb,
646 						ns,  (socklen_t)ns_len,
647 						src, (socklen_t)src_len,
648 						ldns_resolver_timeout(r),
649 						&reply_size);
650 				if (send_status == LDNS_STATUS_OK) {
651 					break;
652 				}
653 			}
654 		}
655 
656 		if (send_status != LDNS_STATUS_OK) {
657 			ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
658 			status = send_status;
659 		}
660 		if(reply_bytes && ldns_buffer_limit(qb) >= 2) {
661 			uint16_t txid = ldns_buffer_read_u16_at(qb, 0);
662 			if(reply_size < 2 ||
663 				ldns_read_uint16(reply_bytes) != txid) {
664 				status = LDNS_STATUS_ID_DID_NOT_MATCH;
665 				LDNS_FREE(reply_bytes);
666 				reply_bytes = NULL;
667 				reply_size = 0;
668 			}
669 		}
670 
671 		/* obey the fail directive */
672 		if (!reply_bytes) {
673 			/* the current nameserver seems to have a problem, blacklist it */
674 			if (ldns_resolver_fail(r)) {
675 				if(src) {
676 					LDNS_FREE(src);
677 				}
678 				LDNS_FREE(ns);
679 				return status ? status : LDNS_STATUS_ERR;
680 			} else {
681 				LDNS_FREE(ns);
682 				continue;
683 			}
684 		}
685 
686 		status = ldns_wire2pkt(&reply, reply_bytes, reply_size);
687 		if (status != LDNS_STATUS_OK) {
688 			if(src) LDNS_FREE(src);
689 			LDNS_FREE(reply_bytes);
690 			LDNS_FREE(ns);
691 			return status;
692 		}
693 		assert(reply);
694 
695 		LDNS_FREE(ns);
696 		gettimeofday(&tv_e, NULL);
697 
698 		if (reply) {
699 			ldns_pkt_set_querytime(reply, (uint32_t)
700 				((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
701 				(tv_e.tv_usec - tv_s.tv_usec) / 1000);
702 			ldns_pkt_set_answerfrom(reply,
703 					ldns_rdf_clone(ns_array[i]));
704 			ldns_pkt_set_timestamp(reply, tv_s);
705 			ldns_pkt_set_size(reply, reply_size);
706 			break;
707 		} else {
708 			if (ldns_resolver_fail(r)) {
709 				/* if fail is set bail out, after the first
710 				 * one */
711 				break;
712 			}
713 		}
714 
715 		/* wait retrans seconds... */
716 		sleep((unsigned int) ldns_resolver_retrans(r));
717 	}
718 
719 	if(src) {
720 		LDNS_FREE(src);
721 	}
722 	if (all_servers_rtt_inf) {
723 		LDNS_FREE(reply_bytes);
724 		return LDNS_STATUS_RES_NO_NS;
725 	}
726 #ifdef HAVE_SSL
727 	if (tsig_mac && reply && reply_bytes) {
728 		if (!ldns_pkt_tsig_verify(reply,
729 		                          reply_bytes,
730 					  reply_size,
731 		                          ldns_resolver_tsig_keyname(r),
732 		                          ldns_resolver_tsig_keydata(r), tsig_mac)) {
733 			status = LDNS_STATUS_CRYPTO_TSIG_BOGUS;
734 		}
735 	}
736 #else
737 	(void)tsig_mac;
738 #endif /* HAVE_SSL */
739 
740 	LDNS_FREE(reply_bytes);
741 	if (reply) {
742 		ldns_pkt *query = NULL;
743 
744 		if(ldns_pkt_qdcount(reply) != 1) {
745 			status = LDNS_STATUS_QDCOUNT_MUST_BE_ONE;
746 			ldns_pkt_free(reply);
747 			reply = NULL;
748 
749 		} else if(ldns_wire2pkt(&query
750 		                , ldns_buffer_begin(qb)
751 		                , ldns_buffer_position(qb)) != LDNS_STATUS_OK
752 		|| ldns_pkt_qdcount(query) != 1
753 		|| ldns_rr_compare(ldns_rr_list_rr(ldns_pkt_question(query),0)
754 		                  ,ldns_rr_list_rr(ldns_pkt_question(reply),0))){
755 			status = LDNS_STATUS_QUERY_DID_NOT_MATCH;
756 			ldns_pkt_free(reply);
757 			reply = NULL;
758 		}
759 		ldns_pkt_free(query);
760 	}
761 	if (result) {
762 		*result = reply;
763 	}
764 
765 	return status;
766 }
767 
768 ssize_t
769 ldns_tcp_send_query(ldns_buffer *qbin, int sockfd,
770                     const struct sockaddr_storage *to, socklen_t tolen)
771 {
772 	uint8_t *sendbuf;
773 	ssize_t bytes;
774 
775 	/* add length of packet */
776 	sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
777 	if(!sendbuf) return 0;
778 	ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
779 	memcpy(sendbuf + 2, ldns_buffer_begin(qbin), ldns_buffer_position(qbin));
780 
781 	bytes = sendto(sockfd, (void*)sendbuf,
782 			ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen);
783 
784         LDNS_FREE(sendbuf);
785 
786 	if (bytes == -1 || (size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
787 		return 0;
788 	}
789 	return bytes;
790 }
791 
792 /* don't wait for an answer */
793 ssize_t
794 ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to,
795 		socklen_t tolen)
796 {
797 	ssize_t bytes;
798 
799 	bytes = sendto(sockfd, (void*)ldns_buffer_begin(qbin),
800 			ldns_buffer_position(qbin), 0, (struct sockaddr *)to, tolen);
801 
802 	if (bytes == -1 || (size_t)bytes != ldns_buffer_position(qbin)) {
803 		return 0;
804 	}
805 	return bytes;
806 }
807 
808 uint8_t *
809 ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
810 		socklen_t *fromlen)
811 {
812 	uint8_t *wire, *wireout;
813 	ssize_t wire_size;
814 
815 	wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
816 	if (!wire) {
817 		*size = 0;
818 		return NULL;
819 	}
820 
821 	wire_size = recvfrom(sockfd, (void*)wire, LDNS_MAX_PACKETLEN, 0,
822 			(struct sockaddr *)from, fromlen);
823 
824 	/* recvfrom can also return 0 */
825 	if (wire_size == -1 || wire_size == 0) {
826 		*size = 0;
827 		LDNS_FREE(wire);
828 		return NULL;
829 	}
830 
831 	*size = (size_t)wire_size;
832 	wireout = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
833 	if(!wireout) LDNS_FREE(wire);
834 
835 	return wireout;
836 }
837 
838 uint8_t *
839 ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
840 {
841 	uint8_t *wire;
842 	uint16_t wire_size;
843 	ssize_t bytes = 0, rc = 0;
844 
845 	if(sockfd < 0)
846 		return NULL;
847 	wire = LDNS_XMALLOC(uint8_t, 2);
848 	if (!wire) {
849 		*size = 0;
850 		return NULL;
851 	}
852 
853 	while (bytes < 2) {
854 		if(!ldns_sock_wait(sockfd, timeout, 0)) {
855 			*size = 0;
856 			LDNS_FREE(wire);
857 			return NULL;
858 		}
859 		rc = recv(sockfd, (void*) (wire + bytes),
860 				(size_t) (2 - bytes), 0);
861 		if (rc == -1 || rc == 0) {
862 			*size = 0;
863 			LDNS_FREE(wire);
864 			return NULL;
865 		}
866                 bytes += rc;
867 	}
868 
869 	wire_size = ldns_read_uint16(wire);
870 
871 	LDNS_FREE(wire);
872 	wire = LDNS_XMALLOC(uint8_t, wire_size);
873 	if (!wire) {
874 		*size = 0;
875 		return NULL;
876 	}
877 	bytes = 0;
878 
879 	while (bytes < (ssize_t) wire_size) {
880 		if(!ldns_sock_wait(sockfd, timeout, 0)) {
881 			*size = 0;
882 			LDNS_FREE(wire);
883 			return NULL;
884 		}
885 		rc = recv(sockfd, (void*) (wire + bytes),
886 				(size_t) (wire_size - bytes), 0);
887 		if (rc == -1 || rc == 0) {
888 			LDNS_FREE(wire);
889 			*size = 0;
890 			return NULL;
891 		}
892                 bytes += rc;
893 	}
894 
895 	*size = (size_t) bytes;
896 	return wire;
897 }
898 
899 uint8_t *
900 ldns_tcp_read_wire(int sockfd, size_t *size)
901 {
902 	uint8_t *wire;
903 	uint16_t wire_size;
904 	ssize_t bytes = 0, rc = 0;
905 
906 	wire = LDNS_XMALLOC(uint8_t, 2);
907 	if (!wire) {
908 		*size = 0;
909 		return NULL;
910 	}
911 
912 	while (bytes < 2) {
913 		rc = recv(sockfd, (void*) (wire + bytes),
914 				(size_t) (2 - bytes), 0);
915 		if (rc == -1 || rc == 0) {
916 			*size = 0;
917 			LDNS_FREE(wire);
918 			return NULL;
919 		}
920                 bytes += rc;
921 	}
922 
923 	wire_size = ldns_read_uint16(wire);
924 
925 	LDNS_FREE(wire);
926 	wire = LDNS_XMALLOC(uint8_t, wire_size);
927 	if (!wire) {
928 		*size = 0;
929 		return NULL;
930 	}
931 	bytes = 0;
932 
933 	while (bytes < (ssize_t) wire_size) {
934 		rc = recv(sockfd, (void*) (wire + bytes),
935 				(size_t) (wire_size - bytes), 0);
936 		if (rc == -1 || rc == 0) {
937 			LDNS_FREE(wire);
938 			*size = 0;
939 			return NULL;
940 		}
941                 bytes += rc;
942 	}
943 
944 	*size = (size_t) bytes;
945 	return wire;
946 }
947 
948 #ifndef S_SPLINT_S
949 ldns_rdf *
950 ldns_sockaddr_storage2rdf(const struct sockaddr_storage *sock, uint16_t *port)
951 {
952         ldns_rdf *addr;
953         struct sockaddr_in *data_in;
954         struct sockaddr_in6 *data_in6;
955 
956         switch(sock->ss_family) {
957                 case AF_INET:
958                         data_in = (struct sockaddr_in*)sock;
959                         if (port) {
960                                 *port = ntohs((uint16_t)data_in->sin_port);
961                         }
962                         addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A,
963                                         LDNS_IP4ADDRLEN, &data_in->sin_addr);
964                         break;
965                 case AF_INET6:
966                         data_in6 = (struct sockaddr_in6*)sock;
967                         if (port) {
968                                 *port = ntohs((uint16_t)data_in6->sin6_port);
969                         }
970                         addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA,
971                                         LDNS_IP6ADDRLEN, &data_in6->sin6_addr);
972                         break;
973                 default:
974                         if (port) {
975                                 *port = 0;
976                         }
977                         return NULL;
978         }
979         return addr;
980 }
981 #endif
982 
983 /* code from resolver.c */
984 ldns_status
985 ldns_axfr_start(ldns_resolver *resolver, const ldns_rdf *domain, ldns_rr_class class)
986 {
987         ldns_pkt *query;
988         ldns_buffer *query_wire;
989 
990         struct sockaddr_storage *src = NULL;
991         size_t src_len = 0;
992         struct sockaddr_storage *ns = NULL;
993         size_t ns_len = 0;
994         size_t ns_i;
995         ldns_status status;
996 
997         if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) {
998                 return LDNS_STATUS_ERR;
999         }
1000 
1001         query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0);
1002 
1003         if (!query) {
1004                 return LDNS_STATUS_ADDRESS_ERR;
1005         }
1006 	if(ldns_resolver_source(resolver)) {
1007 		src = ldns_rdf2native_sockaddr_storage_port(
1008 				ldns_resolver_source(resolver), 0, &src_len);
1009 	}
1010         /* For AXFR, we have to make the connection ourselves */
1011         /* try all nameservers (which usually would mean v4 fallback if
1012          * @hostname is used */
1013         for (ns_i = 0;
1014              ns_i < ldns_resolver_nameserver_count(resolver) &&
1015              resolver->_socket == SOCK_INVALID;
1016              ns_i++) {
1017 		if (ns != NULL) {
1018 			LDNS_FREE(ns);
1019 		}
1020 	        ns = ldns_rdf2native_sockaddr_storage(
1021 	        	resolver->_nameservers[ns_i],
1022 			ldns_resolver_port(resolver), &ns_len);
1023 #ifndef S_SPLINT_S
1024 		if ((ns->ss_family == AF_INET) &&
1025 			(ldns_resolver_ip6(resolver) == LDNS_RESOLV_INET6)) {
1026 			/* not reachable */
1027 			LDNS_FREE(ns);
1028 			ns = NULL;
1029 			continue;
1030 		}
1031 
1032 		if ((ns->ss_family == AF_INET6) &&
1033 			 (ldns_resolver_ip6(resolver) == LDNS_RESOLV_INET)) {
1034 			/* not reachable */
1035 			LDNS_FREE(ns);
1036 			ns = NULL;
1037 			continue;
1038 		}
1039 #endif
1040 
1041 		resolver->_socket = ldns_tcp_connect_from(
1042 				ns, (socklen_t)ns_len,
1043 				src, (socklen_t)src_len,
1044 				ldns_resolver_timeout(resolver));
1045 	}
1046 	if (src) {
1047 		LDNS_FREE(src);
1048 	}
1049 
1050 	if (resolver->_socket == SOCK_INVALID) {
1051 		ldns_pkt_free(query);
1052 		LDNS_FREE(ns);
1053 		return LDNS_STATUS_NETWORK_ERR;
1054 	}
1055 
1056 #ifdef HAVE_SSL
1057 	if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) {
1058 		status = ldns_pkt_tsig_sign(query,
1059 		                            ldns_resolver_tsig_keyname(resolver),
1060 		                            ldns_resolver_tsig_keydata(resolver),
1061 		                            300, ldns_resolver_tsig_algorithm(resolver), NULL);
1062 		if (status != LDNS_STATUS_OK) {
1063 			/* to prevent problems on subsequent calls to
1064 			 * ldns_axfr_start we have to close the socket here! */
1065 			close_socket(resolver->_socket);
1066 			resolver->_socket = 0;
1067 
1068 			ldns_pkt_free(query);
1069 			LDNS_FREE(ns);
1070 
1071 			return LDNS_STATUS_CRYPTO_TSIG_ERR;
1072 		}
1073 	}
1074 #endif /* HAVE_SSL */
1075 
1076         /* Convert the query to a buffer
1077          * Is this necessary?
1078          */
1079         query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
1080         if(!query_wire) {
1081                 ldns_pkt_free(query);
1082                 LDNS_FREE(ns);
1083 
1084 		close_socket(resolver->_socket);
1085 
1086                 return LDNS_STATUS_MEM_ERR;
1087         }
1088         status = ldns_pkt2buffer_wire(query_wire, query);
1089         if (status != LDNS_STATUS_OK) {
1090                 ldns_pkt_free(query);
1091 		ldns_buffer_free(query_wire);
1092                 LDNS_FREE(ns);
1093 
1094 		/* to prevent problems on subsequent calls to ldns_axfr_start
1095 		 * we have to close the socket here! */
1096 		close_socket(resolver->_socket);
1097 		resolver->_socket = 0;
1098 
1099                 return status;
1100         }
1101         /* Send the query */
1102         if (ldns_tcp_send_query(query_wire, resolver->_socket, ns,
1103 				(socklen_t)ns_len) == 0) {
1104                 ldns_pkt_free(query);
1105                 ldns_buffer_free(query_wire);
1106                 LDNS_FREE(ns);
1107 
1108 		/* to prevent problems on subsequent calls to ldns_axfr_start
1109 		 * we have to close the socket here! */
1110 
1111 
1112 		close_socket(resolver->_socket);
1113 
1114                 return LDNS_STATUS_NETWORK_ERR;
1115         }
1116 
1117         ldns_pkt_free(query);
1118         ldns_buffer_free(query_wire);
1119         LDNS_FREE(ns);
1120 
1121         /*
1122          * The AXFR is done once the second SOA record is sent
1123          */
1124         resolver->_axfr_soa_count = 0;
1125         return LDNS_STATUS_OK;
1126 }
1127