ldns documentation

- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

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
34 ldns_status
35 ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
36 {
37 ldns_buffer *qb;
38 ldns_status result;
39 ldns_rdf *tsig_mac = NULL;
40
41 qb = ldns_buffer_new(LDNS_MIN_BUFLEN);
42
43 if (query_pkt && ldns_pkt_tsig(query_pkt)) {
44 tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3);
45 }
46
47 if (!query_pkt ||
48 ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) {
49 result = LDNS_STATUS_ERR;
50 } else {
51 result = ldns_send_buffer(result_packet, r, qb, tsig_mac);
52 }
53
54 ldns_buffer_free(qb);
55
56 return result;
57 }
58
59 /* code from rdata.c */
60 static struct sockaddr_storage *
61 ldns_rdf2native_sockaddr_storage_port(
62 const ldns_rdf *rd, uint16_t port, size_t *size)
63 {
64 struct sockaddr_storage *data;
65 struct sockaddr_in *data_in;
66 struct sockaddr_in6 *data_in6;
67
68 data = LDNS_MALLOC(struct sockaddr_storage);
69 if (!data) {
70 return NULL;
71 }
72 /* zero the structure for portability */
73 memset(data, 0, sizeof(struct sockaddr_storage));
74
75 switch(ldns_rdf_get_type(rd)) {
76 case LDNS_RDF_TYPE_A:
77 #ifndef S_SPLINT_S
78 data->ss_family = AF_INET;
79 #endif
80 data_in = (struct sockaddr_in*) data;
81 data_in->sin_port = (in_port_t)htons(port);
82 memcpy(&(data_in->sin_addr), ldns_rdf_data(rd), ldns_rdf_size(rd));
83 *size = sizeof(struct sockaddr_in);
84 return data;
85 case LDNS_RDF_TYPE_AAAA:
86 #ifndef S_SPLINT_S
87 data->ss_family = AF_INET6;
88 #endif
89 data_in6 = (struct sockaddr_in6*) data;
90 data_in6->sin6_port = (in_port_t)htons(port);
91 memcpy(&data_in6->sin6_addr, ldns_rdf_data(rd), ldns_rdf_size(rd));
92 *size = sizeof(struct sockaddr_in6);
93 return data;
94 default:
95 LDNS_FREE(data);
96 return NULL;
97 }
98 }
99
100 struct sockaddr_storage *
101 ldns_rdf2native_sockaddr_storage(
102 const ldns_rdf *rd, uint16_t port, size_t *size)
103 {
104 return ldns_rdf2native_sockaddr_storage_port(
105 rd, (port == 0 ? (uint16_t)LDNS_PORT : port), size);
106 }
107
109 static void
110 ldns_sock_nonblock(int sockfd)
111 {
112 #ifdef HAVE_FCNTL
113 int flag;
114 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
115 flag |= O_NONBLOCK;
116 if(fcntl(sockfd, F_SETFL, flag) == -1) {
117 /* ignore error, continue blockingly */
118 }
119 }
120 #elif defined(HAVE_IOCTLSOCKET)
121 unsigned long on = 1;
122 if(ioctlsocket(sockfd, FIONBIO, &on) != 0) {
123 /* ignore error, continue blockingly */
124 }
125 #endif
126 }
127
129 static void
130 ldns_sock_block(int sockfd)
131 {
132 #ifdef HAVE_FCNTL
133 int flag;
134 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
135 flag &= ~O_NONBLOCK;
136 if(fcntl(sockfd, F_SETFL, flag) == -1) {
137 /* ignore error, continue */
138 }
139 }
140 #elif defined(HAVE_IOCTLSOCKET)
141 unsigned long off = 0;
142 if(ioctlsocket(sockfd, FIONBIO, &off) != 0) {
143 /* ignore error, continue */
144 }
145 #endif
146 }
147
149 static int
150 ldns_sock_wait(int sockfd, struct timeval timeout, int write)
151 {
152 int ret;
153 #ifndef S_SPLINT_S
154 fd_set fds;
155 FD_ZERO(&fds);
156 FD_SET(FD_SET_T sockfd, &fds);
157 if(write)
158 ret = select(sockfd+1, NULL, &fds, NULL, &timeout);
159 else
160 ret = select(sockfd+1, &fds, NULL, NULL, &timeout);
161 #endif
162 if(ret == 0)
163 /* timeout expired */
164 return 0;
165 else if(ret == -1)
166 /* error */
167 return 0;
168 return 1;
169 }
170
171
172 static int
173 ldns_tcp_connect_from(const struct sockaddr_storage *to, socklen_t tolen,
174 const struct sockaddr_storage *from, socklen_t fromlen,
175 struct timeval timeout)
176 {
177 int sockfd;
178
179 #ifndef S_SPLINT_S
180 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM,
181 IPPROTO_TCP)) == -1) {
182 return 0;
183 }
184 #endif
185 if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == -1){
186 return 0;
187 }
188
189 /* perform nonblocking connect, to be able to wait with select() */
190 ldns_sock_nonblock(sockfd);
191 if (connect(sockfd, (struct sockaddr*)to, tolen) == -1) {
192 #ifndef USE_WINSOCK
193 #ifdef EINPROGRESS
194 if(errno != EINPROGRESS) {
195 #else
196 if(1) {
197 #endif
198 close(sockfd);
199 return 0;
200 }
201 #else /* USE_WINSOCK */
202 if(WSAGetLastError() != WSAEINPROGRESS &&
203 WSAGetLastError() != WSAEWOULDBLOCK) {
204 closesocket(sockfd);
205 return 0;
206 }
207 #endif
208 /* error was only telling us that it would block */
209 }
210
211 /* wait(write) until connected or error */
212 while(1) {
213 int error = 0;
214 socklen_t len = (socklen_t)sizeof(error);
215
216 if(!ldns_sock_wait(sockfd, timeout, 1)) {
217 #ifndef USE_WINSOCK
218 close(sockfd);
219 #else
220 closesocket(sockfd);
221 #endif
222 return 0;
223 }
224
225 /* check if there is a pending error for nonblocking connect */
226 if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&error,
227 &len) < 0) {
228 #ifndef USE_WINSOCK
229 error = errno; /* on solaris errno is error */
230 #else
231 error = WSAGetLastError();
232 #endif
233 }
234 #ifndef USE_WINSOCK
235 #if defined(EINPROGRESS) && defined(EWOULDBLOCK)
236 if(error == EINPROGRESS || error == EWOULDBLOCK)
237 continue; /* try again */
238 #endif
239 else if(error != 0) {
240 close(sockfd);
241 /* error in errno for our user */
242 errno = error;
243 return 0;
244 }
245 #else /* USE_WINSOCK */
246 if(error == WSAEINPROGRESS)
247 continue;
248 else if(error == WSAEWOULDBLOCK)
249 continue;
250 else if(error != 0) {
251 closesocket(sockfd);
252 errno = error;
253 return 0;
254 }
255 #endif /* USE_WINSOCK */
256 /* connected */
257 break;
258 }
259
260 /* set the socket blocking again */
261 ldns_sock_block(sockfd);
262
263 return sockfd;
264 }
265
266 int
267 ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen,
268 struct timeval timeout)
269 {
270 return ldns_tcp_connect_from(to, tolen, NULL, 0, timeout);
271 }
272
273 static int
274 ldns_tcp_bgsend_from(ldns_buffer *qbin,
275 const struct sockaddr_storage *to, socklen_t tolen,
276 const struct sockaddr_storage *from, socklen_t fromlen,
277 struct timeval timeout)
278 {
279 int sockfd;
280
281 sockfd = ldns_tcp_connect_from(to, tolen, from, fromlen, timeout);
282
283 if (sockfd == 0) {
284 return 0;
285 }
286
287 if (ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) {
288 #ifndef USE_WINSOCK
289 close(sockfd);
290 #else
291 closesocket(sockfd);
292 #endif
293 return 0;
294 }
295
296 return sockfd;
297 }
298
299 int
300 ldns_tcp_bgsend(ldns_buffer *qbin,
301 const struct sockaddr_storage *to, socklen_t tolen,
302 struct timeval timeout)
303 {
304 return ldns_tcp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
305 }
306
307
308 /* keep in mind that in DNS tcp messages the first 2 bytes signal the
309 * amount data to expect
310 */
311 static ldns_status
312 ldns_tcp_send_from(uint8_t **result, ldns_buffer *qbin,
313 const struct sockaddr_storage *to, socklen_t tolen,
314 const struct sockaddr_storage *from, socklen_t fromlen,
315 struct timeval timeout, size_t *answer_size)
316 {
317 int sockfd;
318 uint8_t *answer;
319
320 sockfd = ldns_tcp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
321
322 if (sockfd == 0) {
323 return LDNS_STATUS_ERR;
324 }
325
326 answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout);
327 #ifndef USE_WINSOCK
328 close(sockfd);
329 #else
330 closesocket(sockfd);
331 #endif
332
333 if (*answer_size == 0) {
334 /* oops */
335 return LDNS_STATUS_NETWORK_ERR;
336 }
337
338 /* resize accordingly */
339 *result = LDNS_XREALLOC(answer, uint8_t, (size_t)*answer_size);
340 if(!*result) {
341 LDNS_FREE(answer);
342 return LDNS_STATUS_MEM_ERR;
343 }
344 return LDNS_STATUS_OK;
345 }
346
347 ldns_status
348 ldns_tcp_send(uint8_t **result, ldns_buffer *qbin,
349 const struct sockaddr_storage *to, socklen_t tolen,
350 struct timeval timeout, size_t *answer_size)
351 {
352 return ldns_tcp_send_from(result, qbin,
353 to, tolen, NULL, 0, timeout, answer_size);
354 }
355
356 int
357 ldns_udp_connect(const struct sockaddr_storage *to, struct timeval ATTR_UNUSED(timeout))
358 {
359 int sockfd;
360
361 #ifndef S_SPLINT_S
362 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM,
363 IPPROTO_UDP))
364 == -1) {
365 return 0;
366 }
367 #endif
368 return sockfd;
369 }
370
371 static int
372 ldns_udp_bgsend_from(ldns_buffer *qbin,
373 const struct sockaddr_storage *to , socklen_t tolen,
374 const struct sockaddr_storage *from, socklen_t fromlen,
375 struct timeval timeout)
376 {
377 int sockfd;
378
379 sockfd = ldns_udp_connect(to, timeout);
380
381 if (sockfd == 0) {
382 return 0;
383 }
384
385 if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == -1){
386 return 0;
387 }
388
389 if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) {
390 #ifndef USE_WINSOCK
391 close(sockfd);
392 #else
393 closesocket(sockfd);
394 #endif
395 return 0;
396 }
397 return sockfd;
398 }
399
400 int
401 ldns_udp_bgsend(ldns_buffer *qbin,
402 const struct sockaddr_storage *to , socklen_t tolen,
403 struct timeval timeout)
404 {
405 return ldns_udp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
406 }
407
408 static ldns_status
409 ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
410 const struct sockaddr_storage *to , socklen_t tolen,
411 const struct sockaddr_storage *from, socklen_t fromlen,
412 struct timeval timeout, size_t *answer_size)
413 {
414 int sockfd;
415 uint8_t *answer;
416
417 sockfd = ldns_udp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
418
419 if (sockfd == 0) {
420 return LDNS_STATUS_SOCKET_ERROR;
421 }
422
423 /* wait for an response*/
424 if(!ldns_sock_wait(sockfd, timeout, 0)) {
425 #ifndef USE_WINSOCK
426 close(sockfd);
427 #else
428 closesocket(sockfd);
429 #endif
430 return LDNS_STATUS_NETWORK_ERR;
431 }
432
433 /* set to nonblocking, so if the checksum is bad, it becomes
434 * an EGAIN error and the ldns_udp_send function does not block,
435 * but returns a 'NETWORK_ERROR' much like a timeout. */
436 ldns_sock_nonblock(sockfd);
437
438 answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
439 #ifndef USE_WINSOCK
440 close(sockfd);
441 #else
442 closesocket(sockfd);
443 #endif
444
445 if (*answer_size == 0) {
446 /* oops */
447 return LDNS_STATUS_NETWORK_ERR;
448 }
449
450 *result = answer;
451 return LDNS_STATUS_OK;
452 }
453
454 ldns_status
455 ldns_udp_send(uint8_t **result, ldns_buffer *qbin,
456 const struct sockaddr_storage *to , socklen_t tolen,
457 struct timeval timeout, size_t *answer_size)
458 {
459 return ldns_udp_send_from(result, qbin, to, tolen, NULL, 0,
460 timeout, answer_size);
461 }
462
463 ldns_status
464 ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
465 {
466 uint8_t i;
467
468 struct sockaddr_storage *src = NULL;
469 size_t src_len;
470 struct sockaddr_storage *ns;
471 size_t ns_len;
472 struct timeval tv_s;
473 struct timeval tv_e;
474
475 ldns_rdf **ns_array;
476 size_t *rtt;
477 ldns_pkt *reply;
478 bool all_servers_rtt_inf;
479 uint8_t retries;
480
481 uint8_t *reply_bytes = NULL;
482 size_t reply_size = 0;
483 ldns_status status, send_status;
484
485 assert(r != NULL);
486
487 status = LDNS_STATUS_OK;
488 rtt = ldns_resolver_rtt(r);
489 ns_array = ldns_resolver_nameservers(r);
490 reply = NULL;
491 ns_len = 0;
492
493 all_servers_rtt_inf = true;
494
495 if (ldns_resolver_random(r)) {
496 ldns_resolver_nameservers_randomize(r);
497 }
498
499 if(ldns_resolver_source(r)) {
500 src = ldns_rdf2native_sockaddr_storage_port(
501 ldns_resolver_source(r), 0, &src_len);
502 }
503
504 /* loop through all defined nameservers */
505 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
506 if (rtt[i] == LDNS_RESOLV_RTT_INF) {
507 /* not reachable nameserver! */
508 continue;
509 }
510
511 /* maybe verbosity setting?
512 printf("Sending to ");
513 ldns_rdf_print(stdout, ns_array[i]);
514 printf("\n");
515 */
516 ns = ldns_rdf2native_sockaddr_storage(ns_array[i],
517 ldns_resolver_port(r), &ns_len);
518
519
520 #ifndef S_SPLINT_S
521 if ((ns->ss_family == AF_INET) &&
522 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
523 /* not reachable */
524 LDNS_FREE(ns);
525 continue;
526 }
527
528 if ((ns->ss_family == AF_INET6) &&
529 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
530 /* not reachable */
531 LDNS_FREE(ns);
532 continue;
533 }
534 #endif
535
536 all_servers_rtt_inf = false;
537
538 gettimeofday(&tv_s, NULL);
539
540 send_status = LDNS_STATUS_ERR;
541
542 /* reply_bytes implicitly handles our error */
543 if (ldns_resolver_usevc(r)) {
544 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
545 send_status =
546 ldns_tcp_send_from(&reply_bytes, qb,
547 ns, (socklen_t)ns_len,
548 src, (socklen_t)src_len,
549 ldns_resolver_timeout(r),
550 &reply_size);
551 if (send_status == LDNS_STATUS_OK) {
552 break;
553 }
554 }
555 } else {
556 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
557 /* ldns_rdf_print(stdout, ns_array[i]); */
558 send_status =
559 ldns_udp_send_from(&reply_bytes, qb,
560 ns, (socklen_t)ns_len,
561 src, (socklen_t)src_len,
562 ldns_resolver_timeout(r),
563 &reply_size);
564 if (send_status == LDNS_STATUS_OK) {
565 break;
566 }
567 }
568 }
569
570 if (send_status != LDNS_STATUS_OK) {
571 ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
572 status = send_status;
573 }
574
575 /* obey the fail directive */
576 if (!reply_bytes) {
577 /* the current nameserver seems to have a problem, blacklist it */
578 if (ldns_resolver_fail(r)) {
579 LDNS_FREE(ns);
580 return LDNS_STATUS_ERR;
581 } else {
582 LDNS_FREE(ns);
583 continue;
584 }
585 }
586
587 status = ldns_wire2pkt(&reply, reply_bytes, reply_size);
588 if (status != LDNS_STATUS_OK) {
589 LDNS_FREE(reply_bytes);
590 LDNS_FREE(ns);
591 return status;
592 }
593
594 LDNS_FREE(ns);
595 gettimeofday(&tv_e, NULL);
596
597 if (reply) {
598 ldns_pkt_set_querytime(reply, (uint32_t)
599 ((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
600 (tv_e.tv_usec - tv_s.tv_usec) / 1000);
601 ldns_pkt_set_answerfrom(reply,
602 ldns_rdf_clone(ns_array[i]));
603 ldns_pkt_set_timestamp(reply, tv_s);
604 ldns_pkt_set_size(reply, reply_size);
605 break;
606 } else {
607 if (ldns_resolver_fail(r)) {
608 /* if fail is set bail out, after the first
609 * one */
610 break;
611 }
612 }
613
614 /* wait retrans seconds... */
615 sleep((unsigned int) ldns_resolver_retrans(r));
616 }
617
618 if(src) {
619 LDNS_FREE(src);
620 }
621 if (all_servers_rtt_inf) {
622 LDNS_FREE(reply_bytes);
623 return LDNS_STATUS_RES_NO_NS;
624 }
625 #ifdef HAVE_SSL
626 if (tsig_mac && reply && reply_bytes) {
627 if (!ldns_pkt_tsig_verify(reply,
628 reply_bytes,
629 reply_size,
630 ldns_resolver_tsig_keyname(r),
631 ldns_resolver_tsig_keydata(r), tsig_mac)) {
632 status = LDNS_STATUS_CRYPTO_TSIG_BOGUS;
633 }
634 }
635 #else
636 (void)tsig_mac;
637 #endif /* HAVE_SSL */
638
639 LDNS_FREE(reply_bytes);
640 if (result) {
641 *result = reply;
642 }
643
644 return status;
645 }
646
647 ssize_t
648 ldns_tcp_send_query(ldns_buffer *qbin, int sockfd,
649 const struct sockaddr_storage *to, socklen_t tolen)
650 {
651 uint8_t *sendbuf;
652 ssize_t bytes;
653
654 /* add length of packet */
655 sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
656 if(!sendbuf) return 0;
657 ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
658 memcpy(sendbuf + 2, ldns_buffer_begin(qbin), ldns_buffer_position(qbin));
659
660 bytes = sendto(sockfd, (void*)sendbuf,
661 ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen);
662
663 LDNS_FREE(sendbuf);
664
665 if (bytes == -1 || (size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
666 return 0;
667 }
668 return bytes;
669 }
670
671 /* don't wait for an answer */
672 ssize_t
673 ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to,
674 socklen_t tolen)
675 {
676 ssize_t bytes;
677
678 bytes = sendto(sockfd, (void*)ldns_buffer_begin(qbin),
679 ldns_buffer_position(qbin), 0, (struct sockaddr *)to, tolen);
680
681 if (bytes == -1 || (size_t)bytes != ldns_buffer_position(qbin)) {
682 return 0;
683 }
684 if ((size_t) bytes != ldns_buffer_position(qbin)) {
685 return 0;
686 }
687 return bytes;
688 }
689
690 uint8_t *
691 ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
692 socklen_t *fromlen)
693 {
694 uint8_t *wire, *wireout;
695 ssize_t wire_size;
696
697 wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
698 if (!wire) {
699 *size = 0;
700 return NULL;
701 }
702
703 wire_size = recvfrom(sockfd, (void*)wire, LDNS_MAX_PACKETLEN, 0,
704 (struct sockaddr *)from, fromlen);
705
706 /* recvfrom can also return 0 */
707 if (wire_size == -1 || wire_size == 0) {
708 *size = 0;
709 LDNS_FREE(wire);
710 return NULL;
711 }
712
713 *size = (size_t)wire_size;
714 wireout = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
715 if(!wireout) LDNS_FREE(wire);
716
717 return wireout;
718 }
719
720 uint8_t *
721 ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
722 {
723 uint8_t *wire;
724 uint16_t wire_size;
725 ssize_t bytes = 0, rc = 0;
726
727 wire = LDNS_XMALLOC(uint8_t, 2);
728 if (!wire) {
729 *size = 0;
730 return NULL;
731 }
732
733 while (bytes < 2) {
734 if(!ldns_sock_wait(sockfd, timeout, 0)) {
735 *size = 0;
736 LDNS_FREE(wire);
737 return NULL;
738 }
739 rc = recv(sockfd, (void*) (wire + bytes),
740 (size_t) (2 - bytes), 0);
741 if (rc == -1 || rc == 0) {
742 *size = 0;
743 LDNS_FREE(wire);
744 return NULL;
745 }
746 bytes += rc;
747 }
748
749 wire_size = ldns_read_uint16(wire);
750
751 LDNS_FREE(wire);
752 wire = LDNS_XMALLOC(uint8_t, wire_size);
753 if (!wire) {
754 *size = 0;
755 return NULL;
756 }
757 bytes = 0;
758
759 while (bytes < (ssize_t) wire_size) {
760 if(!ldns_sock_wait(sockfd, timeout, 0)) {
761 *size = 0;
762 LDNS_FREE(wire);
763 return NULL;
764 }
765 rc = recv(sockfd, (void*) (wire + bytes),
766 (size_t) (wire_size - bytes), 0);
767 if (rc == -1 || rc == 0) {
768 LDNS_FREE(wire);
769 *size = 0;
770 return NULL;
771 }
772 bytes += rc;
773 }
774
775 *size = (size_t) bytes;
776 return wire;
777 }
778
779 uint8_t *
780 ldns_tcp_read_wire(int sockfd, size_t *size)
781 {
782 uint8_t *wire;
783 uint16_t wire_size;
784 ssize_t bytes = 0, rc = 0;
785
786 wire = LDNS_XMALLOC(uint8_t, 2);
787 if (!wire) {
788 *size = 0;
789 return NULL;
790 }
791
792 while (bytes < 2) {
793 rc = recv(sockfd, (void*) (wire + bytes),
794 (size_t) (2 - bytes), 0);
795 if (rc == -1 || rc == 0) {
796 *size = 0;
797 LDNS_FREE(wire);
798 return NULL;
799 }
800 bytes += rc;
801 }
802
803 wire_size = ldns_read_uint16(wire);
804
805 LDNS_FREE(wire);
806 wire = LDNS_XMALLOC(uint8_t, wire_size);
807 if (!wire) {
808 *size = 0;
809 return NULL;
810 }
811 bytes = 0;
812
813 while (bytes < (ssize_t) wire_size) {
814 rc = recv(sockfd, (void*) (wire + bytes),
815 (size_t) (wire_size - bytes), 0);
816 if (rc == -1 || rc == 0) {
817 LDNS_FREE(wire);
818 *size = 0;
819 return NULL;
820 }
821 bytes += rc;
822 }
823
824 *size = (size_t) bytes;
825 return wire;
826 }
827
828 #ifndef S_SPLINT_S
829 ldns_rdf *
830 ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port)
831 {
832 ldns_rdf *addr;
833 struct sockaddr_in *data_in;
834 struct sockaddr_in6 *data_in6;
835
836 switch(sock->ss_family) {
837 case AF_INET:
838 data_in = (struct sockaddr_in*)sock;
839 if (port) {
840 *port = ntohs((uint16_t)data_in->sin_port);
841 }
842 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A,
843 LDNS_IP4ADDRLEN, &data_in->sin_addr);
844 break;
845 case AF_INET6:
846 data_in6 = (struct sockaddr_in6*)sock;
847 if (port) {
848 *port = ntohs((uint16_t)data_in6->sin6_port);
849 }
850 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA,
851 LDNS_IP6ADDRLEN, &data_in6->sin6_addr);
852 break;
853 default:
854 if (port) {
855 *port = 0;
856 }
857 return NULL;
858 }
859 return addr;
860 }
861 #endif
862
863 /* code from resolver.c */
864 ldns_status
865 ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class)
866 {
867 ldns_pkt *query;
868 ldns_buffer *query_wire;
869
870 struct sockaddr_storage *src = NULL;
871 size_t src_len = 0;
872 struct sockaddr_storage *ns = NULL;
873 size_t ns_len = 0;
874 size_t ns_i;
875 ldns_status status;
876
877 if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) {
878 return LDNS_STATUS_ERR;
879 }
880
881 query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0);
882
883 if (!query) {
884 return LDNS_STATUS_ADDRESS_ERR;
885 }
886 if(ldns_resolver_source(resolver)) {
887 src = ldns_rdf2native_sockaddr_storage_port(
888 ldns_resolver_source(resolver), 0, &src_len);
889 }
890 /* For AXFR, we have to make the connection ourselves */
891 /* try all nameservers (which usually would mean v4 fallback if
892 * @hostname is used */
893 for (ns_i = 0;
894 ns_i < ldns_resolver_nameserver_count(resolver) &&
895 resolver->_socket == 0;
896 ns_i++) {
897 if (ns != NULL) {
898 LDNS_FREE(ns);
899 }
900 ns = ldns_rdf2native_sockaddr_storage(
901 resolver->_nameservers[ns_i],
902 ldns_resolver_port(resolver), &ns_len);
903
904 resolver->_socket = ldns_tcp_connect_from(
905 ns, (socklen_t)ns_len,
906 src, (socklen_t)src_len,
907 ldns_resolver_timeout(resolver));
908 }
909
910 if (resolver->_socket == 0) {
911 ldns_pkt_free(query);
912 LDNS_FREE(ns);
913 return LDNS_STATUS_NETWORK_ERR;
914 }
915
916 #ifdef HAVE_SSL
917 if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) {
918 status = ldns_pkt_tsig_sign(query,
919 ldns_resolver_tsig_keyname(resolver),
920 ldns_resolver_tsig_keydata(resolver),
921 300, ldns_resolver_tsig_algorithm(resolver), NULL);
922 if (status != LDNS_STATUS_OK) {
923 /* to prevent problems on subsequent calls to
924 * ldns_axfr_start we have to close the socket here! */
925 #ifndef USE_WINSOCK
926 close(resolver->_socket);
927 #else
928 closesocket(resolver->_socket);
929 #endif
930 resolver->_socket = 0;
931
932 ldns_pkt_free(query);
933 LDNS_FREE(ns);
934
935 return LDNS_STATUS_CRYPTO_TSIG_ERR;
936 }
937 }
938 #endif /* HAVE_SSL */
939
940 /* Convert the query to a buffer
941 * Is this necessary?
942 */
943 query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
944 if(!query_wire) {
945 ldns_pkt_free(query);
946 LDNS_FREE(ns);
947 #ifndef USE_WINSOCK
948 close(resolver->_socket);
949 #else
950 closesocket(resolver->_socket);
951 #endif
952 resolver->_socket = 0;
953
954 return LDNS_STATUS_MEM_ERR;
955 }
956 status = ldns_pkt2buffer_wire(query_wire, query);
957 if (status != LDNS_STATUS_OK) {
958 ldns_pkt_free(query);
959 ldns_buffer_free(query_wire);
960 LDNS_FREE(ns);
961
962 /* to prevent problems on subsequent calls to ldns_axfr_start
963 * we have to close the socket here! */
964 #ifndef USE_WINSOCK
965 close(resolver->_socket);
966 #else
967 closesocket(resolver->_socket);
968 #endif
969 resolver->_socket = 0;
970
971 return status;
972 }
973 /* Send the query */
974 if (ldns_tcp_send_query(query_wire, resolver->_socket, ns,
975 (socklen_t)ns_len) == 0) {
976 ldns_pkt_free(query);
977 ldns_buffer_free(query_wire);
978 LDNS_FREE(ns);
979
980 /* to prevent problems on subsequent calls to ldns_axfr_start
981 * we have to close the socket here! */
982
983 #ifndef USE_WINSOCK
984 close(resolver->_socket);
985 #else
986 closesocket(resolver->_socket);
987 #endif
988 resolver->_socket = 0;
989
990 return LDNS_STATUS_NETWORK_ERR;
991 }
992
993 ldns_pkt_free(query);
994 ldns_buffer_free(query_wire);
995 LDNS_FREE(ns);
996
997 /*
998 * The AXFR is done once the second SOA record is sent
999 */
1000 resolver->_axfr_soa_count = 0;
1001 return LDNS_STATUS_OK;
1002 }
ldns_rr_rdf
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition: rr.c:873
ldns_resolver_ip6
uint8_t ldns_resolver_ip6(const ldns_resolver *r)
Does the resolver use ip6 or ip4.
Definition: resolver.c:60
ldns_struct_buffer
implementation of buffers to ease operations
Definition: buffer.h:50
ldns_resolver_tsig_algorithm
char * ldns_resolver_tsig_algorithm(const ldns_resolver *r)
Return the tsig algorithm as used by the nameserver.
Definition: resolver.c:213
ldns_resolver_retry
uint8_t ldns_resolver_retry(const ldns_resolver *r)
Get the number of retries.
Definition: resolver.c:42
ldns_struct_resolver
DNS stub resolver structure.
Definition: resolver.h:59
LDNS_STATUS_ADDRESS_ERR
Definition: error.h:47
ldns_rr_class
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:64
LDNS_STATUS_CRYPTO_TSIG_BOGUS
Definition: error.h:64
LDNS_STATUS_OK
Definition: error.h:26
ldns_resolver_set_nameserver_rtt
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
LDNS_RESOLV_INET6
#define LDNS_RESOLV_INET6
Definition: resolver.h:51
LDNS_XMALLOC
#define LDNS_XMALLOC(type, count)
Definition: util.h:51
LDNS_MIN_BUFLEN
#define LDNS_MIN_BUFLEN
number of initial bytes in buffer of which we cannot tell the size before hand
Definition: buffer.h:33
LDNS_STATUS_SOCKET_ERROR
Definition: error.h:96
ldns_rdf_size
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
Definition: rdata.c:24
ldns_buffer_free
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
Definition: buffer.c:137
ldns_rdf_clone
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition: rdata.c:222
ldns_tcp_bgsend
int ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Send an tcp query and don&#39;t wait for an answer but return the socket.
Definition: net.c:300
ldns_pkt_tsig_verify
bool ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const char *key_name, const char *key_data, ldns_rdf *orig_mac_rdf)
verifies the tsig rr for the given packet and key.
Definition: tsig.c:276
LDNS_MAX_PACKETLEN
#define LDNS_MAX_PACKETLEN
Definition: packet.h:24
ldns_resolver_port
uint16_t ldns_resolver_port(const ldns_resolver *r)
Get the port the resolver should use.
Definition: resolver.c:24
ldns_udp_send_query
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:673
ldns_pkt_query_new
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:1034
LDNS_XREALLOC
#define LDNS_XREALLOC(ptr, type, count)
Definition: util.h:57
FD_SET_T
#define FD_SET_T
Definition: config.h:499
ldns_pkt_set_size
void ldns_pkt_set_size(ldns_pkt *packet, size_t s)
Set the packet&#39;s size.
Definition: packet.c:585
ldns_send
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:35
ldns.h
Including this file will include all ldns files, and define some lookup tables.
ldns_udp_connect
int ldns_udp_connect(const struct sockaddr_storage *to, struct timeval timeout __attribute__((unused)))
Definition: net.c:357
ldns_rdf_data
uint8_t * ldns_rdf_data(const ldns_rdf *rd)
returns the data of the rdf.
Definition: rdata.c:38
LDNS_IP4ADDRLEN
#define LDNS_IP4ADDRLEN
Definition: ldns.h:131
ldns_pkt2buffer_wire
ldns_status ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
Copies the packet data to the buffer in wire format.
Definition: host2wire.c:267
ldns_wire2pkt
ldns_status ldns_wire2pkt(ldns_pkt **packet_p, const uint8_t *wire, size_t max)
converts the data on the uint8_t bytearray (in wire format) to a DNS packet.
Definition: wire2host.c:401
ldns_resolver_nameservers_randomize
void ldns_resolver_nameservers_randomize(ldns_resolver *r)
Randomize the nameserver list in the resolver.
Definition: resolver.c:1405
ATTR_UNUSED
#define ATTR_UNUSED(x)
Definition: common.h:67
ldns_resolver_usevc
bool ldns_resolver_usevc(const ldns_resolver *r)
Does the resolver use tcp or udp.
Definition: resolver.c:171
ldns_resolver_nameserver_count
size_t ldns_resolver_nameserver_count(const ldns_resolver *r)
How many nameserver are configured in the resolver.
Definition: resolver.c:114
ldns_send_buffer
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:464
ldns_sockaddr_storage2rdf
ldns_rdf * ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port)
returns an rdf with the sockaddr info.
Definition: net.c:830
ldns_struct_resolver::_axfr_soa_count
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
LDNS_RDF_TYPE_A
A record.
Definition: rdata.h:58
LDNS_STATUS_NETWORK_ERR
Definition: error.h:46
LDNS_IP6ADDRLEN
#define LDNS_IP6ADDRLEN
Definition: ldns.h:132
LDNS_RDF_TYPE_AAAA
AAAA record.
Definition: rdata.h:60
ldns_struct_resolver::_nameservers
ldns_rdf ** _nameservers
Array of nameservers to query (IP addresses or dnames)
Definition: resolver.h:65
ldns_tcp_read_wire_timeout
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:721
LDNS_STATUS_RES_NO_NS
Definition: error.h:70
ldns_pkt_set_answerfrom
void ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom)
Set the packet&#39;s answering server.
Definition: packet.c:572
LDNS_PORT
#define LDNS_PORT
Definition: ldns.h:133
ldns_rdf_get_type
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
Definition: rdata.c:31
ldns_struct_pkt
DNS packet.
Definition: packet.h:233
ldns_udp_bgsend
int ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Send an udp query and don&#39;t wait for an answer but return the socket.
Definition: net.c:401
ldns_resolver_tsig_keydata
char * ldns_resolver_tsig_keydata(const ldns_resolver *r)
Return the tsig keydata as used by the nameserver.
Definition: resolver.c:219
ldns_tcp_read_wire
uint8_t * ldns_tcp_read_wire(int sockfd, size_t *size)
This routine may block.
Definition: net.c:780
ldns_resolver_random
bool ldns_resolver_random(const ldns_resolver *r)
Does the resolver randomize the nameserver before usage.
Definition: resolver.c:225
LDNS_STATUS_MEM_ERR
Definition: error.h:34
ldns_tcp_send_query
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:648
ldns_status
enum ldns_enum_status ldns_status
Definition: error.h:131
ldns_rdf_new_frm_data
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_MALLOC
#define LDNS_MALLOC(type)
Memory management macros.
Definition: util.h:49
ldns_pkt_set_querytime
void ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time)
Set the packet&#39;s query time.
Definition: packet.c:566
ldns_buffer_new
ldns_buffer * ldns_buffer_new(size_t capacity)
creates a new buffer with the specified capacity.
Definition: buffer.c:16
ldns_resolver_retrans
uint8_t ldns_resolver_retrans(const ldns_resolver *r)
Get the retransmit interval.
Definition: resolver.c:48
ldns_pkt_tsig_sign
ldns_status ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac)
creates a tsig rr for the given packet and key.
Definition: tsig.c:352
ldns_tcp_connect
int ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Create a tcp socket to the specified address.
Definition: net.c:267
ldns_resolver_rtt
size_t * ldns_resolver_rtt(const ldns_resolver *r)
Return the used round trip times for the nameservers.
Definition: resolver.c:177
ldns_resolver_fail
bool ldns_resolver_fail(const ldns_resolver *r)
Does the resolver only try the first nameserver.
Definition: resolver.c:84
ldns_resolver_source
ldns_rdf * ldns_resolver_source(const ldns_resolver *r)
Get the source address the resolver should use.
Definition: resolver.c:30
LDNS_STATUS_CRYPTO_TSIG_ERR
Definition: error.h:65
ldns_resolver_nameservers
ldns_rdf ** ldns_resolver_nameservers(const ldns_resolver *r)
Return the configured nameserver ip address.
Definition: resolver.c:108
ldns_resolver_tsig_keyname
char * ldns_resolver_tsig_keyname(const ldns_resolver *r)
Return the tsig keyname as used by the nameserver.
Definition: resolver.c:207
ldns_struct_rdf
Resource record data field.
Definition: rdata.h:166
ldns_rdf2native_sockaddr_storage
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:101
ldns_tcp_send
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 respons as a ldns_pkt.
Definition: net.c:348
ldns_pkt_tsig
ldns_rr * ldns_pkt_tsig(const ldns_pkt *pkt)
Return the packet&#39;s tsig pseudo rr&#39;s.
Definition: packet.c:444
ldns_axfr_start
ldns_status ldns_axfr_start(ldns_resolver *resolver, 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:865
LDNS_FREE
#define LDNS_FREE(ptr)
Definition: util.h:60
LDNS_RESOLV_RTT_INF
#define LDNS_RESOLV_RTT_INF
Definition: resolver.h:53
LDNS_RR_TYPE_AXFR
Definition: rr.h:213
ldns_struct_resolver::_socket
int _socket
Keep some things to make AXFR possible.
Definition: resolver.h:117
ldns_udp_send
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 respons as a ldns_pkt.
Definition: net.c:455
ldns_pkt_free
void ldns_pkt_free(ldns_pkt *packet)
frees the packet structure and all data that it contains.
Definition: packet.c:784
LDNS_STATUS_ERR
Definition: error.h:37
config.h
LDNS_RESOLV_INET
#define LDNS_RESOLV_INET
Definition: resolver.h:50
ldns_udp_read_wire
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:691
ldns_resolver_timeout
struct timeval ldns_resolver_timeout(const ldns_resolver *r)
What is the timeout on socket connections.
Definition: resolver.c:201
ldns_pkt_set_timestamp
void ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval)
Set the packet&#39;s timestamp.
Definition: packet.c:578