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
ldns_send(ldns_pkt ** result_packet,ldns_resolver * r,const ldns_pkt * query_pkt)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 *
ldns_rdf2native_sockaddr_storage_port(const ldns_rdf * rd,uint16_t port,size_t * size)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 *
ldns_rdf2native_sockaddr_storage(const ldns_rdf * rd,uint16_t port,size_t * size)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
ldns_sock_nonblock(int sockfd)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
ldns_sock_block(int sockfd)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
ldns_sock_wait(int sockfd,struct timeval timeout,int write)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
ldns_tcp_connect_from(const struct sockaddr_storage * to,socklen_t tolen,const struct sockaddr_storage * from,socklen_t fromlen,struct timeval timeout)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) == SOCK_INVALID){
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) == SOCK_INVALID) {
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 static ldns_status
445 ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
446 const struct sockaddr_storage *to , socklen_t tolen,
447 const struct sockaddr_storage *from, socklen_t fromlen,
448 struct timeval timeout, size_t *answer_size)
449 {
450 int sockfd;
451 uint8_t *answer;
452
453 sockfd = ldns_udp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
454
455 if (sockfd == -1) {
456 return LDNS_STATUS_SOCKET_ERROR;
457 }
458
459 /* wait for an response*/
460 if(!ldns_sock_wait(sockfd, timeout, 0)) {
461 close_socket(sockfd);
462 return LDNS_STATUS_NETWORK_ERR;
463 }
464
465 /* set to nonblocking, so if the checksum is bad, it becomes
466 * an EAGAIN error and the ldns_udp_send function does not block,
467 * but returns a 'NETWORK_ERROR' much like a timeout. */
468 ldns_sock_nonblock(sockfd);
469
470 answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
471 close_socket(sockfd);
472
473 if (!answer) {
474 /* oops */
475 return LDNS_STATUS_NETWORK_ERR;
476 }
477
478 *result = answer;
479 return LDNS_STATUS_OK;
480 }
481
482 ldns_status
483 ldns_udp_send(uint8_t **result, ldns_buffer *qbin,
484 const struct sockaddr_storage *to , socklen_t tolen,
485 struct timeval timeout, size_t *answer_size)
486 {
487 return ldns_udp_send_from(result, qbin, to, tolen, NULL, 0,
488 timeout, answer_size);
489 }
490
491 ldns_status
492 ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
493 {
494 uint8_t i;
495
496 struct sockaddr_storage *src = NULL;
497 size_t src_len = 0;
498 struct sockaddr_storage *ns;
499 size_t ns_len;
500 struct timeval tv_s;
501 struct timeval tv_e;
502
503 ldns_rdf **ns_array;
504 size_t *rtt;
505 ldns_pkt *reply;
506 bool all_servers_rtt_inf;
507 uint8_t retries;
508
509 uint8_t *reply_bytes = NULL;
510 size_t reply_size = 0;
511 ldns_status status, send_status;
512
513 assert(r != NULL);
514
515 status = LDNS_STATUS_OK;
516 rtt = ldns_resolver_rtt(r);
517 ns_array = ldns_resolver_nameservers(r);
518 reply = NULL;
519 ns_len = 0;
520
521 all_servers_rtt_inf = true;
522
523 if (ldns_resolver_random(r)) {
524 ldns_resolver_nameservers_randomize(r);
525 }
526
527 if(ldns_resolver_source(r)) {
528 src = ldns_rdf2native_sockaddr_storage_port(
529 ldns_resolver_source(r), 0, &src_len);
530 }
531
532 /* loop through all defined nameservers */
533 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
534 if (rtt[i] == LDNS_RESOLV_RTT_INF) {
535 /* not reachable nameserver! */
536 continue;
537 }
538
539 /* maybe verbosity setting?
540 printf("Sending to ");
541 ldns_rdf_print(stdout, ns_array[i]);
542 printf("\n");
543 */
544 ns = ldns_rdf2native_sockaddr_storage(ns_array[i],
545 ldns_resolver_port(r), &ns_len);
546
547
548 #ifndef S_SPLINT_S
549 if ((ns->ss_family == AF_INET) &&
550 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
551 /* not reachable */
552 LDNS_FREE(ns);
553 continue;
554 }
555
556 if ((ns->ss_family == AF_INET6) &&
557 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
558 /* not reachable */
559 LDNS_FREE(ns);
560 continue;
561 }
562 #endif
563
564 all_servers_rtt_inf = false;
565
566 gettimeofday(&tv_s, NULL);
567
568 send_status = LDNS_STATUS_ERR;
569
570 /* reply_bytes implicitly handles our error */
571 if (ldns_resolver_usevc(r)) {
572 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
573 send_status =
574 ldns_tcp_send_from(&reply_bytes, qb,
575 ns, (socklen_t)ns_len,
576 src, (socklen_t)src_len,
577 ldns_resolver_timeout(r),
578 &reply_size);
579 if (send_status == LDNS_STATUS_OK) {
580 break;
581 }
582 }
583 } else {
584 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
585 /* ldns_rdf_print(stdout, ns_array[i]); */
586 send_status =
587 ldns_udp_send_from(&reply_bytes, qb,
588 ns, (socklen_t)ns_len,
589 src, (socklen_t)src_len,
590 ldns_resolver_timeout(r),
591 &reply_size);
592 if (send_status == LDNS_STATUS_OK) {
593 break;
594 }
595 }
596 }
597
598 if (send_status != LDNS_STATUS_OK) {
599 ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
600 status = send_status;
601 }
602
603 /* obey the fail directive */
604 if (!reply_bytes) {
605 /* the current nameserver seems to have a problem, blacklist it */
606 if (ldns_resolver_fail(r)) {
607 if(src) {
608 LDNS_FREE(src);
609 }
610 LDNS_FREE(ns);
611 return LDNS_STATUS_ERR;
612 } else {
613 LDNS_FREE(ns);
614 continue;
615 }
616 }
617
618 status = ldns_wire2pkt(&reply, reply_bytes, reply_size);
619 if (status != LDNS_STATUS_OK) {
620 if(src) LDNS_FREE(src);
621 LDNS_FREE(reply_bytes);
622 LDNS_FREE(ns);
623 return status;
624 }
625 assert(reply);
626
627 LDNS_FREE(ns);
628 gettimeofday(&tv_e, NULL);
629
630 if (reply) {
631 ldns_pkt_set_querytime(reply, (uint32_t)
632 ((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
633 (tv_e.tv_usec - tv_s.tv_usec) / 1000);
634 ldns_pkt_set_answerfrom(reply,
635 ldns_rdf_clone(ns_array[i]));
636 ldns_pkt_set_timestamp(reply, tv_s);
637 ldns_pkt_set_size(reply, reply_size);
638 break;
639 } else {
640 if (ldns_resolver_fail(r)) {
641 /* if fail is set bail out, after the first
642 * one */
643 break;
644 }
645 }
646
647 /* wait retrans seconds... */
648 sleep((unsigned int) ldns_resolver_retrans(r));
649 }
650
651 if(src) {
652 LDNS_FREE(src);
653 }
654 if (all_servers_rtt_inf) {
655 LDNS_FREE(reply_bytes);
656 return LDNS_STATUS_RES_NO_NS;
657 }
658 #ifdef HAVE_SSL
659 if (tsig_mac && reply && reply_bytes) {
660 if (!ldns_pkt_tsig_verify(reply,
661 reply_bytes,
662 reply_size,
663 ldns_resolver_tsig_keyname(r),
664 ldns_resolver_tsig_keydata(r), tsig_mac)) {
665 status = LDNS_STATUS_CRYPTO_TSIG_BOGUS;
666 }
667 }
668 #else
669 (void)tsig_mac;
670 #endif /* HAVE_SSL */
671
672 LDNS_FREE(reply_bytes);
673 if (result) {
674 *result = reply;
675 }
676
677 return status;
678 }
679
680 ssize_t
681 ldns_tcp_send_query(ldns_buffer *qbin, int sockfd,
682 const struct sockaddr_storage *to, socklen_t tolen)
683 {
684 uint8_t *sendbuf;
685 ssize_t bytes;
686
687 /* add length of packet */
688 sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
689 if(!sendbuf) return 0;
690 ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
691 memcpy(sendbuf + 2, ldns_buffer_begin(qbin), ldns_buffer_position(qbin));
692
693 bytes = sendto(sockfd, (void*)sendbuf,
694 ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen);
695
696 LDNS_FREE(sendbuf);
697
698 if (bytes == -1 || (size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
699 return 0;
700 }
701 return bytes;
702 }
703
704 /* don't wait for an answer */
705 ssize_t
706 ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to,
707 socklen_t tolen)
708 {
709 ssize_t bytes;
710
711 bytes = sendto(sockfd, (void*)ldns_buffer_begin(qbin),
712 ldns_buffer_position(qbin), 0, (struct sockaddr *)to, tolen);
713
714 if (bytes == -1 || (size_t)bytes != ldns_buffer_position(qbin)) {
715 return 0;
716 }
717 return bytes;
718 }
719
720 uint8_t *
721 ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
722 socklen_t *fromlen)
723 {
724 uint8_t *wire, *wireout;
725 ssize_t wire_size;
726
727 wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
728 if (!wire) {
729 *size = 0;
730 return NULL;
731 }
732
733 wire_size = recvfrom(sockfd, (void*)wire, LDNS_MAX_PACKETLEN, 0,
734 (struct sockaddr *)from, fromlen);
735
736 /* recvfrom can also return 0 */
737 if (wire_size == -1 || wire_size == 0) {
738 *size = 0;
739 LDNS_FREE(wire);
740 return NULL;
741 }
742
743 *size = (size_t)wire_size;
744 wireout = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
745 if(!wireout) LDNS_FREE(wire);
746
747 return wireout;
748 }
749
750 uint8_t *
751 ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
752 {
753 uint8_t *wire;
754 uint16_t wire_size;
755 ssize_t bytes = 0, rc = 0;
756
757 wire = LDNS_XMALLOC(uint8_t, 2);
758 if (!wire) {
759 *size = 0;
760 return NULL;
761 }
762
763 while (bytes < 2) {
764 if(!ldns_sock_wait(sockfd, timeout, 0)) {
765 *size = 0;
766 LDNS_FREE(wire);
767 return NULL;
768 }
769 rc = recv(sockfd, (void*) (wire + bytes),
770 (size_t) (2 - bytes), 0);
771 if (rc == -1 || rc == 0) {
772 *size = 0;
773 LDNS_FREE(wire);
774 return NULL;
775 }
776 bytes += rc;
777 }
778
779 wire_size = ldns_read_uint16(wire);
780
781 LDNS_FREE(wire);
782 wire = LDNS_XMALLOC(uint8_t, wire_size);
783 if (!wire) {
784 *size = 0;
785 return NULL;
786 }
787 bytes = 0;
788
789 while (bytes < (ssize_t) wire_size) {
790 if(!ldns_sock_wait(sockfd, timeout, 0)) {
791 *size = 0;
792 LDNS_FREE(wire);
793 return NULL;
794 }
795 rc = recv(sockfd, (void*) (wire + bytes),
796 (size_t) (wire_size - bytes), 0);
797 if (rc == -1 || rc == 0) {
798 LDNS_FREE(wire);
799 *size = 0;
800 return NULL;
801 }
802 bytes += rc;
803 }
804
805 *size = (size_t) bytes;
806 return wire;
807 }
808
809 uint8_t *
810 ldns_tcp_read_wire(int sockfd, size_t *size)
811 {
812 uint8_t *wire;
813 uint16_t wire_size;
814 ssize_t bytes = 0, rc = 0;
815
816 wire = LDNS_XMALLOC(uint8_t, 2);
817 if (!wire) {
818 *size = 0;
819 return NULL;
820 }
821
822 while (bytes < 2) {
823 rc = recv(sockfd, (void*) (wire + bytes),
824 (size_t) (2 - bytes), 0);
825 if (rc == -1 || rc == 0) {
826 *size = 0;
827 LDNS_FREE(wire);
828 return NULL;
829 }
830 bytes += rc;
831 }
832
833 wire_size = ldns_read_uint16(wire);
834
835 LDNS_FREE(wire);
836 wire = LDNS_XMALLOC(uint8_t, wire_size);
837 if (!wire) {
838 *size = 0;
839 return NULL;
840 }
841 bytes = 0;
842
843 while (bytes < (ssize_t) wire_size) {
844 rc = recv(sockfd, (void*) (wire + bytes),
845 (size_t) (wire_size - bytes), 0);
846 if (rc == -1 || rc == 0) {
847 LDNS_FREE(wire);
848 *size = 0;
849 return NULL;
850 }
851 bytes += rc;
852 }
853
854 *size = (size_t) bytes;
855 return wire;
856 }
857
858 #ifndef S_SPLINT_S
859 ldns_rdf *
860 ldns_sockaddr_storage2rdf(const struct sockaddr_storage *sock, uint16_t *port)
861 {
862 ldns_rdf *addr;
863 struct sockaddr_in *data_in;
864 struct sockaddr_in6 *data_in6;
865
866 switch(sock->ss_family) {
867 case AF_INET:
868 data_in = (struct sockaddr_in*)sock;
869 if (port) {
870 *port = ntohs((uint16_t)data_in->sin_port);
871 }
872 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A,
873 LDNS_IP4ADDRLEN, &data_in->sin_addr);
874 break;
875 case AF_INET6:
876 data_in6 = (struct sockaddr_in6*)sock;
877 if (port) {
878 *port = ntohs((uint16_t)data_in6->sin6_port);
879 }
880 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA,
881 LDNS_IP6ADDRLEN, &data_in6->sin6_addr);
882 break;
883 default:
884 if (port) {
885 *port = 0;
886 }
887 return NULL;
888 }
889 return addr;
890 }
891 #endif
892
893 /* code from resolver.c */
894 ldns_status
895 ldns_axfr_start(ldns_resolver *resolver, const ldns_rdf *domain, ldns_rr_class class)
896 {
897 ldns_pkt *query;
898 ldns_buffer *query_wire;
899
900 struct sockaddr_storage *src = NULL;
901 size_t src_len = 0;
902 struct sockaddr_storage *ns = NULL;
903 size_t ns_len = 0;
904 size_t ns_i;
905 ldns_status status;
906
907 if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) {
908 return LDNS_STATUS_ERR;
909 }
910
911 query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0);
912
913 if (!query) {
914 return LDNS_STATUS_ADDRESS_ERR;
915 }
916 if(ldns_resolver_source(resolver)) {
917 src = ldns_rdf2native_sockaddr_storage_port(
918 ldns_resolver_source(resolver), 0, &src_len);
919 }
920 /* For AXFR, we have to make the connection ourselves */
921 /* try all nameservers (which usually would mean v4 fallback if
922 * @hostname is used */
923 for (ns_i = 0;
924 ns_i < ldns_resolver_nameserver_count(resolver) &&
925 resolver->_socket == SOCK_INVALID;
926 ns_i++) {
927 if (ns != NULL) {
928 LDNS_FREE(ns);
929 }
930 ns = ldns_rdf2native_sockaddr_storage(
931 resolver->_nameservers[ns_i],
932 ldns_resolver_port(resolver), &ns_len);
933 #ifndef S_SPLINT_S
934 if ((ns->ss_family == AF_INET) &&
935 (ldns_resolver_ip6(resolver) == LDNS_RESOLV_INET6)) {
936 /* not reachable */
937 LDNS_FREE(ns);
938 ns = NULL;
939 continue;
940 }
941
942 if ((ns->ss_family == AF_INET6) &&
943 (ldns_resolver_ip6(resolver) == LDNS_RESOLV_INET)) {
944 /* not reachable */
945 LDNS_FREE(ns);
946 ns = NULL;
947 continue;
948 }
949 #endif
950
951 resolver->_socket = ldns_tcp_connect_from(
952 ns, (socklen_t)ns_len,
953 src, (socklen_t)src_len,
954 ldns_resolver_timeout(resolver));
955 }
956 if (src) {
957 LDNS_FREE(src);
958 }
959
960 if (resolver->_socket == SOCK_INVALID) {
961 ldns_pkt_free(query);
962 LDNS_FREE(ns);
963 return LDNS_STATUS_NETWORK_ERR;
964 }
965
966 #ifdef HAVE_SSL
967 if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) {
968 status = ldns_pkt_tsig_sign(query,
969 ldns_resolver_tsig_keyname(resolver),
970 ldns_resolver_tsig_keydata(resolver),
971 300, ldns_resolver_tsig_algorithm(resolver), NULL);
972 if (status != LDNS_STATUS_OK) {
973 /* to prevent problems on subsequent calls to
974 * ldns_axfr_start we have to close the socket here! */
975 close_socket(resolver->_socket);
976 resolver->_socket = 0;
977
978 ldns_pkt_free(query);
979 LDNS_FREE(ns);
980
981 return LDNS_STATUS_CRYPTO_TSIG_ERR;
982 }
983 }
984 #endif /* HAVE_SSL */
985
986 /* Convert the query to a buffer
987 * Is this necessary?
988 */
989 query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
990 if(!query_wire) {
991 ldns_pkt_free(query);
992 LDNS_FREE(ns);
993
994 close_socket(resolver->_socket);
995
996 return LDNS_STATUS_MEM_ERR;
997 }
998 status = ldns_pkt2buffer_wire(query_wire, query);
999 if (status != LDNS_STATUS_OK) {
1000 ldns_pkt_free(query);
1001 ldns_buffer_free(query_wire);
1002 LDNS_FREE(ns);
1003
1004 /* to prevent problems on subsequent calls to ldns_axfr_start
1005 * we have to close the socket here! */
1006 close_socket(resolver->_socket);
1007 resolver->_socket = 0;
1008
1009 return status;
1010 }
1011 /* Send the query */
1012 if (ldns_tcp_send_query(query_wire, resolver->_socket, ns,
1013 (socklen_t)ns_len) == 0) {
1014 ldns_pkt_free(query);
1015 ldns_buffer_free(query_wire);
1016 LDNS_FREE(ns);
1017
1018 /* to prevent problems on subsequent calls to ldns_axfr_start
1019 * we have to close the socket here! */
1020
1021
1022 close_socket(resolver->_socket);
1023
1024 return LDNS_STATUS_NETWORK_ERR;
1025 }
1026
1027 ldns_pkt_free(query);
1028 ldns_buffer_free(query_wire);
1029 LDNS_FREE(ns);
1030
1031 /*
1032 * The AXFR is done once the second SOA record is sent
1033 */
1034 resolver->_axfr_soa_count = 0;
1035 return LDNS_STATUS_OK;
1036 }
1037