ldns  1.8.4
net.c
Go to the documentation of this file.
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
38ldns_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
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
58
59 return result;
60}
61
62/* code from rdata.c */
63static struct sockaddr_storage *
64ldns_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;
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
103struct 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
112static void
113ldns_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
132static void
133ldns_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
152static int
153ldns_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
191static int
192ldns_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
282int
283ldns_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
290int
291ldns_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
297static int
298ldns_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
315int
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
324int
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 */
335static ldns_status
336ldns_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 */
356 }
357
358 *result = answer;
359 return LDNS_STATUS_OK;
360}
361
363ldns_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
371int
372ldns_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
386int
387ldns_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
401static int
402ldns_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
427int
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
436int
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
445static int
446ldns_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
488static ldns_status
489ldns_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) {
503 }
504
505 /* wait for an response*/
506 if(!ldns_sock_wait(sockfd, timeout, 0)) {
507 close_socket(sockfd);
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 */
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);
530 }
531
532 *result = answer;
533 return LDNS_STATUS_OK;
534}
535
537ldns_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
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)
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)) {
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) &&
609 /* not reachable */
610 LDNS_FREE(ns);
611 continue;
612 }
613
614 if ((ns->ss_family == AF_INET6) &&
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,
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,
649 &reply_size);
650 if (send_status == LDNS_STATUS_OK) {
651 break;
652 }
653 }
654 }
655
656 if (send_status != LDNS_STATUS_OK) {
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) {
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);
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);
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,
732 ldns_resolver_tsig_keydata(r), tsig_mac)) {
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) {
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
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
768ssize_t
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 */
793ssize_t
794ldns_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
808uint8_t *
809ldns_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
838uint8_t *
839ldns_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 wire = LDNS_XMALLOC(uint8_t, 2);
846 if (!wire) {
847 *size = 0;
848 return NULL;
849 }
850
851 while (bytes < 2) {
852 if(!ldns_sock_wait(sockfd, timeout, 0)) {
853 *size = 0;
854 LDNS_FREE(wire);
855 return NULL;
856 }
857 rc = recv(sockfd, (void*) (wire + bytes),
858 (size_t) (2 - bytes), 0);
859 if (rc == -1 || rc == 0) {
860 *size = 0;
861 LDNS_FREE(wire);
862 return NULL;
863 }
864 bytes += rc;
865 }
866
867 wire_size = ldns_read_uint16(wire);
868
869 LDNS_FREE(wire);
870 wire = LDNS_XMALLOC(uint8_t, wire_size);
871 if (!wire) {
872 *size = 0;
873 return NULL;
874 }
875 bytes = 0;
876
877 while (bytes < (ssize_t) wire_size) {
878 if(!ldns_sock_wait(sockfd, timeout, 0)) {
879 *size = 0;
880 LDNS_FREE(wire);
881 return NULL;
882 }
883 rc = recv(sockfd, (void*) (wire + bytes),
884 (size_t) (wire_size - bytes), 0);
885 if (rc == -1 || rc == 0) {
886 LDNS_FREE(wire);
887 *size = 0;
888 return NULL;
889 }
890 bytes += rc;
891 }
892
893 *size = (size_t) bytes;
894 return wire;
895}
896
897uint8_t *
898ldns_tcp_read_wire(int sockfd, size_t *size)
899{
900 uint8_t *wire;
901 uint16_t wire_size;
902 ssize_t bytes = 0, rc = 0;
903
904 wire = LDNS_XMALLOC(uint8_t, 2);
905 if (!wire) {
906 *size = 0;
907 return NULL;
908 }
909
910 while (bytes < 2) {
911 rc = recv(sockfd, (void*) (wire + bytes),
912 (size_t) (2 - bytes), 0);
913 if (rc == -1 || rc == 0) {
914 *size = 0;
915 LDNS_FREE(wire);
916 return NULL;
917 }
918 bytes += rc;
919 }
920
921 wire_size = ldns_read_uint16(wire);
922
923 LDNS_FREE(wire);
924 wire = LDNS_XMALLOC(uint8_t, wire_size);
925 if (!wire) {
926 *size = 0;
927 return NULL;
928 }
929 bytes = 0;
930
931 while (bytes < (ssize_t) wire_size) {
932 rc = recv(sockfd, (void*) (wire + bytes),
933 (size_t) (wire_size - bytes), 0);
934 if (rc == -1 || rc == 0) {
935 LDNS_FREE(wire);
936 *size = 0;
937 return NULL;
938 }
939 bytes += rc;
940 }
941
942 *size = (size_t) bytes;
943 return wire;
944}
945
946#ifndef S_SPLINT_S
947ldns_rdf *
948ldns_sockaddr_storage2rdf(const struct sockaddr_storage *sock, uint16_t *port)
949{
950 ldns_rdf *addr;
951 struct sockaddr_in *data_in;
952 struct sockaddr_in6 *data_in6;
953
954 switch(sock->ss_family) {
955 case AF_INET:
956 data_in = (struct sockaddr_in*)sock;
957 if (port) {
958 *port = ntohs((uint16_t)data_in->sin_port);
959 }
961 LDNS_IP4ADDRLEN, &data_in->sin_addr);
962 break;
963 case AF_INET6:
964 data_in6 = (struct sockaddr_in6*)sock;
965 if (port) {
966 *port = ntohs((uint16_t)data_in6->sin6_port);
967 }
969 LDNS_IP6ADDRLEN, &data_in6->sin6_addr);
970 break;
971 default:
972 if (port) {
973 *port = 0;
974 }
975 return NULL;
976 }
977 return addr;
978}
979#endif
980
981/* code from resolver.c */
983ldns_axfr_start(ldns_resolver *resolver, const ldns_rdf *domain, ldns_rr_class class)
984{
985 ldns_pkt *query;
986 ldns_buffer *query_wire;
987
988 struct sockaddr_storage *src = NULL;
989 size_t src_len = 0;
990 struct sockaddr_storage *ns = NULL;
991 size_t ns_len = 0;
992 size_t ns_i;
993 ldns_status status;
994
995 if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) {
996 return LDNS_STATUS_ERR;
997 }
998
999 query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0);
1000
1001 if (!query) {
1003 }
1004 if(ldns_resolver_source(resolver)) {
1005 src = ldns_rdf2native_sockaddr_storage_port(
1006 ldns_resolver_source(resolver), 0, &src_len);
1007 }
1008 /* For AXFR, we have to make the connection ourselves */
1009 /* try all nameservers (which usually would mean v4 fallback if
1010 * @hostname is used */
1011 for (ns_i = 0;
1012 ns_i < ldns_resolver_nameserver_count(resolver) &&
1013 resolver->_socket == SOCK_INVALID;
1014 ns_i++) {
1015 if (ns != NULL) {
1016 LDNS_FREE(ns);
1017 }
1019 resolver->_nameservers[ns_i],
1020 ldns_resolver_port(resolver), &ns_len);
1021#ifndef S_SPLINT_S
1022 if ((ns->ss_family == AF_INET) &&
1023 (ldns_resolver_ip6(resolver) == LDNS_RESOLV_INET6)) {
1024 /* not reachable */
1025 LDNS_FREE(ns);
1026 ns = NULL;
1027 continue;
1028 }
1029
1030 if ((ns->ss_family == AF_INET6) &&
1031 (ldns_resolver_ip6(resolver) == LDNS_RESOLV_INET)) {
1032 /* not reachable */
1033 LDNS_FREE(ns);
1034 ns = NULL;
1035 continue;
1036 }
1037#endif
1038
1039 resolver->_socket = ldns_tcp_connect_from(
1040 ns, (socklen_t)ns_len,
1041 src, (socklen_t)src_len,
1042 ldns_resolver_timeout(resolver));
1043 }
1044 if (src) {
1045 LDNS_FREE(src);
1046 }
1047
1048 if (resolver->_socket == SOCK_INVALID) {
1049 ldns_pkt_free(query);
1050 LDNS_FREE(ns);
1052 }
1053
1054#ifdef HAVE_SSL
1055 if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) {
1056 status = ldns_pkt_tsig_sign(query,
1059 300, ldns_resolver_tsig_algorithm(resolver), NULL);
1060 if (status != LDNS_STATUS_OK) {
1061 /* to prevent problems on subsequent calls to
1062 * ldns_axfr_start we have to close the socket here! */
1063 close_socket(resolver->_socket);
1064 resolver->_socket = 0;
1065
1066 ldns_pkt_free(query);
1067 LDNS_FREE(ns);
1068
1070 }
1071 }
1072#endif /* HAVE_SSL */
1073
1074 /* Convert the query to a buffer
1075 * Is this necessary?
1076 */
1077 query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
1078 if(!query_wire) {
1079 ldns_pkt_free(query);
1080 LDNS_FREE(ns);
1081
1082 close_socket(resolver->_socket);
1083
1084 return LDNS_STATUS_MEM_ERR;
1085 }
1086 status = ldns_pkt2buffer_wire(query_wire, query);
1087 if (status != LDNS_STATUS_OK) {
1088 ldns_pkt_free(query);
1089 ldns_buffer_free(query_wire);
1090 LDNS_FREE(ns);
1091
1092 /* to prevent problems on subsequent calls to ldns_axfr_start
1093 * we have to close the socket here! */
1094 close_socket(resolver->_socket);
1095 resolver->_socket = 0;
1096
1097 return status;
1098 }
1099 /* Send the query */
1100 if (ldns_tcp_send_query(query_wire, resolver->_socket, ns,
1101 (socklen_t)ns_len) == 0) {
1102 ldns_pkt_free(query);
1103 ldns_buffer_free(query_wire);
1104 LDNS_FREE(ns);
1105
1106 /* to prevent problems on subsequent calls to ldns_axfr_start
1107 * we have to close the socket here! */
1108
1109
1110 close_socket(resolver->_socket);
1111
1113 }
1114
1115 ldns_pkt_free(query);
1116 ldns_buffer_free(query_wire);
1117 LDNS_FREE(ns);
1118
1119 /*
1120 * The AXFR is done once the second SOA record is sent
1121 */
1122 resolver->_axfr_soa_count = 0;
1123 return LDNS_STATUS_OK;
1124}
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
Definition buffer.c:137
struct ldns_struct_buffer ldns_buffer
Definition buffer.h:72
ldns_buffer * ldns_buffer_new(size_t capacity)
creates a new buffer with the specified capacity.
Definition buffer.c:16
#define LDNS_MIN_BUFLEN
number of initial bytes in buffer of which we cannot tell the size before hand
Definition buffer.h:33
#define ATTR_UNUSED(x)
Definition common.h:72
@ LDNS_STATUS_NETWORK_ERR
Definition error.h:46
@ LDNS_STATUS_SOCKET_ERROR
Definition error.h:96
@ LDNS_STATUS_ERR
Definition error.h:37
@ LDNS_STATUS_MEM_ERR
Definition error.h:34
@ LDNS_STATUS_QDCOUNT_MUST_BE_ONE
Definition error.h:148
@ LDNS_STATUS_CRYPTO_TSIG_BOGUS
Definition error.h:64
@ LDNS_STATUS_QUERY_DID_NOT_MATCH
Definition error.h:149
@ LDNS_STATUS_ADDRESS_ERR
Definition error.h:47
@ LDNS_STATUS_OK
Definition error.h:26
@ LDNS_STATUS_CRYPTO_TSIG_ERR
Definition error.h:65
@ LDNS_STATUS_RES_NO_NS
Definition error.h:70
@ LDNS_STATUS_ID_DID_NOT_MATCH
Definition error.h:147
enum ldns_enum_status ldns_status
Definition error.h:151
ldns_status ldns_pkt2buffer_wire(ldns_buffer *output, const ldns_pkt *pkt)
Copies the packet data to the buffer in wire format.
Definition host2wire.c:376
#define close_socket(_s)
Definition config.h:776
#define SOCK_INVALID
Definition config.h:775
#define FD_SET_T
Definition config.h:685
Including this file will include all ldns files, and define some lookup tables.
#define LDNS_IP4ADDRLEN
Definition ldns.h:132
#define LDNS_IP6ADDRLEN
Definition ldns.h:133
#define LDNS_PORT
Definition ldns.h:134
int ldns_udp_connect(const struct sockaddr_storage *to, struct timeval timeout __attribute__((unused)))
Definition net.c:372
uint8_t * ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from, socklen_t *fromlen)
Gives back a raw packet from the wire and reads the header data from the given socket.
Definition net.c:809
ldns_status ldns_axfr_start(ldns_resolver *resolver, const ldns_rdf *domain, ldns_rr_class class)
Prepares the resolver for an axfr query The query is sent and the answers can be read with ldns_axfr_...
Definition net.c:983
ldns_status ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
Sends ptk to the nameserver at the resolver object.
Definition net.c:38
uint8_t * ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
Gives back a raw packet from the wire and reads the header data from the given socket.
Definition net.c:839
uint8_t * ldns_tcp_read_wire(int sockfd, size_t *size)
This routine may block.
Definition net.c:898
struct sockaddr_storage * ldns_rdf2native_sockaddr_storage(const ldns_rdf *rd, uint16_t port, size_t *size)
returns the native sockaddr representation from the rdf.
Definition net.c:104
ssize_t ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen)
send a query via tcp to a server.
Definition net.c:769
ldns_rdf * ldns_sockaddr_storage2rdf(const struct sockaddr_storage *sock, uint16_t *port)
returns an rdf with the sockaddr info.
Definition net.c:948
int ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Create a tcp socket to the specified address This function has the flaw that it returns 0 on failure,...
Definition net.c:283
int ldns_tcp_connect2(const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Create a tcp socket to the specified address.
Definition net.c:291
ldns_status ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
Sends and ldns_buffer (presumably containing a packet to the nameserver at the resolver object.
Definition net.c:546
int ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Send an udp query and don't wait for an answer but return the socket This function has the flaw that ...
Definition net.c:428
int ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Send an tcp query and don't wait for an answer but return the socket This function has the flaw that ...
Definition net.c:316
int ldns_tcp_bgsend2(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Send an tcp query and don't wait for an answer but return the socket.
Definition net.c:325
int ldns_udp_bgsend2(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Send an udp query and don't wait for an answer but return the socket.
Definition net.c:437
ldns_status ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answer_size)
Sends a buffer to an ip using udp and return the response as a ldns_pkt.
Definition net.c:537
ldns_status ldns_tcp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answer_size)
Sends a buffer to an ip using tcp and return the response as a ldns_pkt.
Definition net.c:363
ssize_t ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen)
send a query via udp to a server.
Definition net.c:794
int ldns_udp_connect2(const struct sockaddr_storage *to, struct timeval timeout __attribute__((unused)))
Definition net.c:387
#define LDNS_MAX_PACKETLEN
Definition packet.h:24
void ldns_pkt_free(ldns_pkt *packet)
frees the packet structure and all data that it contains.
Definition packet.c:897
void ldns_pkt_set_timestamp(ldns_pkt *p, struct timeval timeval)
Set the packet's timestamp.
Definition packet.c:599
void ldns_pkt_set_size(ldns_pkt *p, size_t s)
Set the packet's size.
Definition packet.c:606
void ldns_pkt_set_answerfrom(ldns_pkt *p, ldns_rdf *r)
Set the packet's answering server.
Definition packet.c:593
ldns_rr_list * ldns_pkt_question(const ldns_pkt *p)
Return the packet's question section.
Definition packet.c:124
ldns_pkt * ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags)
creates a packet with a query in it for the given name, type and class.
Definition packet.c:1150
struct ldns_struct_pkt ldns_pkt
Definition packet.h:272
uint16_t ldns_pkt_qdcount(const ldns_pkt *p)
Return the packet's qd count.
Definition packet.c:100
ldns_rr * ldns_pkt_tsig(const ldns_pkt *p)
Return the packet's tsig pseudo rr's.
Definition packet.c:465
void ldns_pkt_set_querytime(ldns_pkt *p, uint32_t t)
Set the packet's query time.
Definition packet.c:587
uint8_t * ldns_rdf_data(const ldns_rdf *rd)
returns the data of the rdf.
Definition rdata.c:38
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition rdata.c:222
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
Definition rdata.c:31
ldns_rdf * ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
allocates a new rdf structure and fills it.
Definition rdata.c:193
@ LDNS_RDF_TYPE_AAAA
AAAA record.
Definition rdata.h:60
@ LDNS_RDF_TYPE_A
A record.
Definition rdata.h:58
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
Definition rdata.c:24
struct ldns_struct_rdf ldns_rdf
Definition rdata.h:205
size_t * ldns_resolver_rtt(const ldns_resolver *r)
Return the used round trip times for the nameservers.
Definition resolver.c:177
const char * ldns_resolver_tsig_keydata(const ldns_resolver *r)
Return the tsig keydata as used by the nameserver.
Definition resolver.c:219
signed char ldns_resolver_fail(const ldns_resolver *r)
Does the resolver only try the first nameserver.
Definition resolver.c:84
void ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
Set round trip time for a specific nameserver.
Definition resolver.c:506
#define LDNS_RESOLV_RTT_INF
Definition resolver.h:53
const char * ldns_resolver_tsig_keyname(const ldns_resolver *r)
Return the tsig keyname as used by the nameserver.
Definition resolver.c:207
size_t ldns_resolver_nameserver_count(const ldns_resolver *r)
How many nameserver are configured in the resolver.
Definition resolver.c:114
ldns_rdf ** ldns_resolver_nameservers(const ldns_resolver *r)
Return the configured nameserver ip address.
Definition resolver.c:108
uint8_t ldns_resolver_retrans(const ldns_resolver *r)
Get the retransmit interval.
Definition resolver.c:48
struct ldns_struct_resolver ldns_resolver
Definition resolver.h:147
void ldns_resolver_nameservers_randomize(ldns_resolver *r)
Randomize the nameserver list in the resolver.
Definition resolver.c:1541
struct timeval ldns_resolver_timeout(const ldns_resolver *r)
What is the timeout on socket connections.
Definition resolver.c:201
uint8_t ldns_resolver_ip6(const ldns_resolver *r)
Does the resolver use ip6 or ip4.
Definition resolver.c:60
signed char ldns_resolver_random(const ldns_resolver *r)
Does the resolver randomize the nameserver before usage.
Definition resolver.c:225
uint8_t ldns_resolver_retry(const ldns_resolver *r)
Get the number of retries.
Definition resolver.c:42
ldns_rdf * ldns_resolver_source(const ldns_resolver *r)
Get the source address the resolver should use.
Definition resolver.c:30
#define LDNS_RESOLV_INET
Definition resolver.h:50
signed char ldns_resolver_usevc(const ldns_resolver *r)
Does the resolver use tcp or udp.
Definition resolver.c:171
const char * ldns_resolver_tsig_algorithm(const ldns_resolver *r)
Return the tsig algorithm as used by the nameserver.
Definition resolver.c:213
uint16_t ldns_resolver_port(const ldns_resolver *r)
Get the port the resolver should use.
Definition resolver.c:24
#define LDNS_RESOLV_INET6
Definition resolver.h:51
@ LDNS_RR_TYPE_AXFR
Definition rr.h:218
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition rr.c:913
enum ldns_enum_rr_class ldns_rr_class
Definition rr.h:61
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
Definition rr.c:994
int ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs.
Definition rr.c:1642
int _socket
Keep some things to make AXFR possible.
Definition resolver.h:117
ldns_rdf ** _nameservers
Array of nameservers to query (IP addresses or dnames).
Definition resolver.h:65
int _axfr_soa_count
Count the number of LDNS_RR_TYPE_SOA RRs we have seen so far (the second one signifies the end of the...
Definition resolver.h:121
bool ldns_pkt_tsig_verify(ldns_pkt *pkt, const uint8_t *wire, size_t wire_size, const char *key_name, const char *key_data, const ldns_rdf *mac)
verifies the tsig rr for the given packet and key.
Definition tsig.c:288
ldns_status ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge, const char *algorithm_name, const ldns_rdf *query_mac)
creates a tsig rr for the given packet and key.
Definition tsig.c:376
#define LDNS_FREE(ptr)
Definition util.h:60
#define LDNS_MALLOC(type)
Memory management macros.
Definition util.h:49
#define LDNS_XMALLOC(type, count)
Definition util.h:51
#define LDNS_XREALLOC(ptr, type, count)
Definition util.h:57
ldns_status ldns_wire2pkt(ldns_pkt **packet, const uint8_t *data, size_t len)
converts the data on the uint8_t bytearray (in wire format) to a DNS packet.
Definition wire2host.c:403