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