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 
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 *
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
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 */
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 
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
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) {
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
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 */
448  }
449 
450  *result = answer;
451  return LDNS_STATUS_OK;
452 }
453 
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 
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)) {
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) &&
523  /* not reachable */
524  LDNS_FREE(ns);
525  continue;
526  }
527 
528  if ((ns->ss_family == AF_INET6) &&
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,
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,
563  &reply_size);
564  if (send_status == LDNS_STATUS_OK) {
565  break;
566  }
567  }
568  }
569 
570  if (send_status != LDNS_STATUS_OK) {
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);
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,
631  ldns_resolver_tsig_keydata(r), tsig_mac)) {
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  }
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  }
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 */
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) {
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  }
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);
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 
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 
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_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition: rr.c:873
uint8_t ldns_resolver_ip6(const ldns_resolver *r)
Does the resolver use ip6 or ip4.
Definition: resolver.c:60
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:213
uint8_t ldns_resolver_retry(const ldns_resolver *r)
Get the number of retries.
Definition: resolver.c:42
DNS stub resolver structure.
Definition: resolver.h:59
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:64
void ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
Set round trip time for a specific nameserver.
Definition: resolver.c:506
#define LDNS_RESOLV_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't wait for an answer but return the socket.
Definition: net.c:300
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
#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:673
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
#define LDNS_XREALLOC(ptr, type, count)
Definition: util.h:57
#define FD_SET_T
Definition: config.h:499
void ldns_pkt_set_size(ldns_pkt *packet, size_t s)
Set the packet'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.
int ldns_udp_connect(const struct sockaddr_storage *to, struct timeval timeout __attribute__((unused)))
Definition: net.c:357
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:131
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_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
void ldns_resolver_nameservers_randomize(ldns_resolver *r)
Randomize the nameserver list in the resolver.
Definition: resolver.c:1405
#define ATTR_UNUSED(x)
Definition: common.h:67
bool ldns_resolver_usevc(const ldns_resolver *r)
Does the resolver use tcp or udp.
Definition: resolver.c:171
size_t ldns_resolver_nameserver_count(const ldns_resolver *r)
How many nameserver are configured in the resolver.
Definition: resolver.c:114
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_rdf * ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port)
returns an rdf with the sockaddr info.
Definition: net.c:830
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:58
#define LDNS_IP6ADDRLEN
Definition: ldns.h:132
AAAA record.
Definition: rdata.h:60
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:721
void ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom)
Set the packet's answering server.
Definition: packet.c:572
#define LDNS_PORT
Definition: ldns.h:133
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't wait for an answer but return the socket.
Definition: net.c:401
char * ldns_resolver_tsig_keydata(const ldns_resolver *r)
Return the tsig keydata as used by the nameserver.
Definition: resolver.c:219
uint8_t * ldns_tcp_read_wire(int sockfd, size_t *size)
This routine may block.
Definition: net.c:780
bool ldns_resolver_random(const ldns_resolver *r)
Does the resolver randomize the nameserver before usage.
Definition: resolver.c:225
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
enum ldns_enum_status ldns_status
Definition: error.h:131
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'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:48
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
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
size_t * ldns_resolver_rtt(const ldns_resolver *r)
Return the used round trip times for the nameservers.
Definition: resolver.c:177
bool ldns_resolver_fail(const ldns_resolver *r)
Does the resolver only try the first nameserver.
Definition: resolver.c:84
ldns_rdf * ldns_resolver_source(const ldns_resolver *r)
Get the source address the resolver should use.
Definition: resolver.c:30
ldns_rdf ** ldns_resolver_nameservers(const ldns_resolver *r)
Return the configured nameserver ip address.
Definition: resolver.c:108
char * ldns_resolver_tsig_keyname(const ldns_resolver *r)
Return the tsig keyname as used by the nameserver.
Definition: resolver.c:207
Resource record data field.
Definition: rdata.h:166
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_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_rr * ldns_pkt_tsig(const ldns_pkt *pkt)
Return the packet's tsig pseudo rr'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:865
#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:455
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:691
struct timeval ldns_resolver_timeout(const ldns_resolver *r)
What is the timeout on socket connections.
Definition: resolver.c:201
void ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval)
Set the packet's timestamp.
Definition: packet.c:578