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