carp: add carp_group_demote_adj()
[dragonfly.git] / contrib / ldns / net.c
1 /*
2  * net.c
3  *
4  * Network implementation
5  * All network related functions are grouped here
6  *
7  * a Net::DNS like library for C
8  *
9  * (c) NLnet Labs, 2004-2006
10  *
11  * See the file LICENSE for the license
12  */
13
14 #include <ldns/config.h>
15
16 #include <ldns/ldns.h>
17
18 #ifdef HAVE_NETINET_IN_H
19 #include <netinet/in.h>
20 #endif
21 #ifdef HAVE_SYS_SOCKET_H
22 #include <sys/socket.h>
23 #endif
24 #ifdef HAVE_NETDB_H
25 #include <netdb.h>
26 #endif
27 #ifdef HAVE_ARPA_INET_H
28 #include <arpa/inet.h>
29 #endif
30 #include <sys/time.h>
31 #include <errno.h>
32 #include <fcntl.h>
33
34 ldns_status
35 ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
36 {
37         ldns_buffer *qb;
38         ldns_status result;
39         ldns_rdf *tsig_mac = NULL;
40
41         qb = ldns_buffer_new(LDNS_MIN_BUFLEN);
42
43         if (query_pkt && ldns_pkt_tsig(query_pkt)) {
44                 tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3);
45         }
46
47
48         if (!query_pkt ||
49             ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) {
50                 result = LDNS_STATUS_ERR;
51         } else {
52                 result = ldns_send_buffer(result_packet, r, qb, tsig_mac);
53         }
54
55         ldns_buffer_free(qb);
56         
57         return result;
58 }
59
60 ldns_status
61 ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
62 {
63         uint8_t i;
64         
65         struct sockaddr_storage *ns;
66         size_t ns_len;
67         struct timeval tv_s;
68         struct timeval tv_e;
69
70         ldns_rdf **ns_array;
71         size_t *rtt;
72         ldns_pkt *reply;
73         bool all_servers_rtt_inf;
74         uint8_t retries;
75
76         uint8_t *reply_bytes = NULL;
77         size_t reply_size = 0;
78         ldns_status status, send_status;
79
80         assert(r != NULL);
81
82         status = LDNS_STATUS_OK;
83         rtt = ldns_resolver_rtt(r);
84         ns_array = ldns_resolver_nameservers(r);
85         reply = NULL; 
86         ns_len = 0;
87
88         all_servers_rtt_inf = true;
89
90         if (ldns_resolver_random(r)) {
91                 ldns_resolver_nameservers_randomize(r);
92         }
93
94         /* loop through all defined nameservers */
95         for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
96                 if (rtt[i] == LDNS_RESOLV_RTT_INF) {
97                         /* not reachable nameserver! */
98                         continue;
99                 }
100                 all_servers_rtt_inf = false;
101
102                 /* maybe verbosity setting?
103                 printf("Sending to ");
104                 ldns_rdf_print(stdout, ns_array[i]);
105                 printf("\n");
106                 */
107                 ns = ldns_rdf2native_sockaddr_storage(ns_array[i],
108                                 ldns_resolver_port(r), &ns_len);
109                 
110                 if ((ns->ss_family == AF_INET) && 
111                                 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
112                         continue;
113                 }
114
115                 if ((ns->ss_family == AF_INET6) &&
116                                  (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
117                         continue;
118                 }
119
120                 gettimeofday(&tv_s, NULL);
121
122                 send_status = LDNS_STATUS_ERR;
123
124                 /* reply_bytes implicitly handles our error */
125                 if (1 == ldns_resolver_usevc(r)) {
126                         for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
127                                 send_status = 
128                                         ldns_tcp_send(&reply_bytes, qb, ns, 
129                                         (socklen_t)ns_len, ldns_resolver_timeout(r), 
130                                         &reply_size);
131                                 if (send_status == LDNS_STATUS_OK) {
132                                         break;
133                                 }
134                         }
135                 } else {
136                         for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
137                                 /* ldns_rdf_print(stdout, ns_array[i]); */
138                                 send_status = 
139                                         ldns_udp_send(&reply_bytes, qb, ns, 
140                                                         (socklen_t)ns_len, ldns_resolver_timeout(r), 
141                                                         &reply_size);
142                                 
143                                 if (send_status == LDNS_STATUS_OK) {
144                                         break;
145                                 }
146                         }
147                 }
148
149                 if (send_status != LDNS_STATUS_OK) {
150                         ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
151                         status = send_status;
152                 }
153                 
154                 /* obey the fail directive */
155                 if (!reply_bytes) {
156                         /* the current nameserver seems to have a problem, blacklist it */
157                         if (ldns_resolver_fail(r)) {
158                                 LDNS_FREE(ns);
159                                 return LDNS_STATUS_ERR;
160                         } else {
161                                 LDNS_FREE(ns);
162                                 continue;
163                         }
164                 } 
165                 
166                 status = ldns_wire2pkt(&reply, reply_bytes, reply_size);
167                 if (status != LDNS_STATUS_OK) {
168                         LDNS_FREE(reply_bytes);
169                         LDNS_FREE(ns);
170                         return status;
171                 }
172                 
173                 LDNS_FREE(ns);
174                 gettimeofday(&tv_e, NULL);
175
176                 if (reply) {
177                         ldns_pkt_set_querytime(reply, (uint32_t)
178                                 ((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
179                                 (tv_e.tv_usec - tv_s.tv_usec) / 1000);
180                         ldns_pkt_set_answerfrom(reply, ns_array[i]);
181                         ldns_pkt_set_timestamp(reply, tv_s);
182                         ldns_pkt_set_size(reply, reply_size);
183                         break;
184                 } else {
185                         if (ldns_resolver_fail(r)) {
186                                 /* if fail is set bail out, after the first
187                                  * one */
188                                 break;
189                         }
190                 }
191
192                 /* wait retrans seconds... */
193                 sleep((unsigned int) ldns_resolver_retrans(r));
194         }
195
196         if (all_servers_rtt_inf) {
197                 LDNS_FREE(reply_bytes);
198                 return LDNS_STATUS_RES_NO_NS;
199         }
200 #ifdef HAVE_SSL
201         if (tsig_mac && reply_bytes) {
202                 if (!ldns_pkt_tsig_verify(reply,
203                                           reply_bytes,
204                                           reply_size,
205                                           ldns_resolver_tsig_keyname(r),
206                                           ldns_resolver_tsig_keydata(r), tsig_mac)) {
207                         status = LDNS_STATUS_CRYPTO_TSIG_BOGUS;
208                 }
209         }
210 #else
211         (void)tsig_mac;
212 #endif /* HAVE_SSL */
213         
214         LDNS_FREE(reply_bytes);
215         if (result) {
216                 *result = reply;
217         }
218
219         return status;
220 }
221
222 /** best effort to set nonblocking */
223 static void
224 ldns_sock_nonblock(int sockfd)
225 {
226 #ifdef HAVE_FCNTL
227         int flag;
228         if((flag = fcntl(sockfd, F_GETFL)) != -1) {
229                 flag |= O_NONBLOCK;
230                 if(fcntl(sockfd, F_SETFL, flag) == -1) {
231                         /* ignore error, continue blockingly */
232                 }
233         }
234 #elif defined(HAVE_IOCTLSOCKET)
235         unsigned long on = 1;
236         if(ioctlsocket(sockfd, FIONBIO, &on) != 0) {
237                 /* ignore error, continue blockingly */
238         }
239 #endif
240 }
241
242 /** best effort to set blocking */
243 static void
244 ldns_sock_block(int sockfd)
245 {
246 #ifdef HAVE_FCNTL
247         int flag;
248         if((flag = fcntl(sockfd, F_GETFL)) != -1) {
249                 flag &= ~O_NONBLOCK;
250                 if(fcntl(sockfd, F_SETFL, flag) == -1) {
251                         /* ignore error, continue */
252                 }
253         }
254 #elif defined(HAVE_IOCTLSOCKET)
255         unsigned long off = 0;
256         if(ioctlsocket(sockfd, FIONBIO, &off) != 0) {
257                 /* ignore error, continue */
258         }
259 #endif
260 }
261
262 /** wait for a socket to become ready */
263 static int
264 ldns_sock_wait(int sockfd, struct timeval timeout, int write)
265 {
266         fd_set fds;
267         int ret;
268         FD_ZERO(&fds);
269         FD_SET(FD_SET_T sockfd, &fds);
270         if(write)
271                 ret = select(sockfd+1, NULL, &fds, NULL, &timeout);
272         else
273                 ret = select(sockfd+1, &fds, NULL, NULL, &timeout);
274         if(ret == 0)
275                 /* timeout expired */
276                 return 0;
277         else if(ret == -1)
278                 /* error */
279                 return 0;
280         return 1;
281 }
282
283 ldns_status
284 ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, 
285                 socklen_t tolen, struct timeval timeout, size_t *answer_size)
286 {
287         int sockfd;
288         uint8_t *answer;
289
290         sockfd = ldns_udp_bgsend(qbin, to, tolen, timeout);
291
292         if (sockfd == 0) {
293                 return LDNS_STATUS_SOCKET_ERROR;
294         }
295
296         /* wait for an response*/
297         if(!ldns_sock_wait(sockfd, timeout, 0)) {
298                 close(sockfd);
299                 return LDNS_STATUS_NETWORK_ERR;
300         }
301         
302         answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
303         close(sockfd);
304
305         if (*answer_size == 0) {
306                 /* oops */
307                 return LDNS_STATUS_NETWORK_ERR;
308         }
309
310         *result = answer;
311         return LDNS_STATUS_OK;
312 }
313
314 int
315 ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, 
316                 struct timeval timeout)
317 {
318         int sockfd;
319
320         sockfd = ldns_udp_connect(to, timeout);
321
322         if (sockfd == 0) {
323                 return 0;
324         }
325
326         if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) {
327                 return 0;
328         }
329         return sockfd;
330 }
331
332 int
333 ldns_udp_connect(const struct sockaddr_storage *to, struct timeval ATTR_UNUSED(timeout))
334 {
335         int sockfd;
336         
337         if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM, 
338                                         IPPROTO_UDP)) 
339                         == -1) {
340                 return 0;
341         }
342         return sockfd;
343 }
344
345 int
346 ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, 
347                 struct timeval timeout)
348 {
349         int sockfd;
350         
351         if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM, 
352                                         IPPROTO_TCP)) == -1) {
353                 return 0;
354         }
355
356         /* perform nonblocking connect, to be able to wait with select() */
357         ldns_sock_nonblock(sockfd);
358         if (connect(sockfd, (struct sockaddr*)to, tolen) == -1) {
359 #ifndef USE_WINSOCK
360 #ifdef EINPROGRESS
361                 if(errno != EINPROGRESS) {
362 #else
363                 if(1) {
364 #endif
365                         close(sockfd);
366                         return 0;
367                 }
368 #else /* USE_WINSOCK */
369                 if(WSAGetLastError() != WSAEINPROGRESS &&
370                         WSAGetLastError() != WSAEWOULDBLOCK) {
371                         closesocket(sockfd);
372                         return 0;
373                 }
374 #endif
375                 /* error was only telling us that it would block */
376         }
377
378         /* wait(write) until connected or error */
379         while(1) {
380                 int error = 0;
381                 socklen_t len = (socklen_t)sizeof(error);
382
383                 if(!ldns_sock_wait(sockfd, timeout, 1)) {
384                         close(sockfd);
385                         return 0;
386                 }
387
388                 /* check if there is a pending error for nonblocking connect */
389                 if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&error,
390                         &len) < 0) {
391 #ifndef USE_WINSOCK
392                         error = errno; /* on solaris errno is error */
393 #else
394                         error = WSAGetLastError();
395 #endif
396                 }
397 #ifndef USE_WINSOCK
398 #if defined(EINPROGRESS) && defined(EWOULDBLOCK)
399                 if(error == EINPROGRESS || error == EWOULDBLOCK)
400                         continue; /* try again */
401 #endif
402                 else if(error != 0) {
403                         close(sockfd);
404                         /* error in errno for our user */
405                         errno = error;
406                         return 0;
407                 }
408 #else /* USE_WINSOCK */
409                 if(error == WSAEINPROGRESS)
410                         continue;
411                 else if(error == WSAEWOULDBLOCK)
412                         continue;
413                 else if(error != 0) {
414                         closesocket(sockfd);
415                         errno = error;
416                         return 0;
417                 }
418 #endif /* USE_WINSOCK */
419                 /* connected */
420                 break;
421         }
422
423         /* set the socket blocking again */
424         ldns_sock_block(sockfd);
425
426         return sockfd;
427 }
428
429 ssize_t
430 ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, 
431                     const struct sockaddr_storage *to, socklen_t tolen)
432 {
433         uint8_t *sendbuf;
434         ssize_t bytes;
435
436         /* add length of packet */
437         sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
438         ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
439         memcpy(sendbuf + 2, ldns_buffer_export(qbin), ldns_buffer_position(qbin));
440
441         bytes = sendto(sockfd, (void*)sendbuf,
442                         ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen);
443
444         LDNS_FREE(sendbuf);
445
446         if (bytes == -1 || (size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
447                 return 0;
448         }
449         return bytes;
450 }
451
452 /* don't wait for an answer */
453 ssize_t
454 ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, 
455                 socklen_t tolen)
456 {
457         ssize_t bytes;
458
459         bytes = sendto(sockfd, (void*)ldns_buffer_begin(qbin),
460                         ldns_buffer_position(qbin), 0, (struct sockaddr *)to, tolen);
461
462         if (bytes == -1 || (size_t)bytes != ldns_buffer_position(qbin)) {
463                 return 0;
464         }
465         if ((size_t) bytes != ldns_buffer_position(qbin)) {
466                 return 0;
467         }
468         return bytes;
469 }
470
471 uint8_t *
472 ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
473                 socklen_t *fromlen)
474 {
475         uint8_t *wire;
476         ssize_t wire_size;
477
478         wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
479         if (!wire) {
480                 *size = 0;
481                 return NULL;
482         }
483
484         wire_size = recvfrom(sockfd, (void*)wire, LDNS_MAX_PACKETLEN, 0, 
485                         (struct sockaddr *)from, fromlen);
486
487         /* recvfrom can also return 0 */
488         if (wire_size == -1 || wire_size == 0) {
489                 *size = 0;
490                 LDNS_FREE(wire);
491                 return NULL;
492         }
493
494         *size = (size_t)wire_size;
495         wire = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
496
497         return wire;
498 }
499
500 uint8_t *
501 ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
502 {
503         uint8_t *wire;
504         uint16_t wire_size;
505         ssize_t bytes = 0;
506
507         wire = LDNS_XMALLOC(uint8_t, 2);
508         if (!wire) {
509                 *size = 0;
510                 return NULL;
511         }
512         
513         while (bytes < 2) {
514                 if(!ldns_sock_wait(sockfd, timeout, 0)) {
515                         *size = 0;
516                         LDNS_FREE(wire);
517                         return NULL;
518                 }
519                 bytes = recv(sockfd, (void*)wire, 2, 0);
520                 if (bytes == -1 || bytes == 0) {
521                         *size = 0;
522                         LDNS_FREE(wire);
523                         return NULL;
524                 }
525         }
526
527         wire_size = ldns_read_uint16(wire);
528         
529         LDNS_FREE(wire);
530         wire = LDNS_XMALLOC(uint8_t, wire_size);
531         bytes = 0;
532
533         while (bytes < (ssize_t) wire_size) {
534                 if(!ldns_sock_wait(sockfd, timeout, 0)) {
535                         *size = 0;
536                         LDNS_FREE(wire);
537                         return NULL;
538                 }
539                 bytes += recv(sockfd, (void*) (wire + bytes), 
540                                 (size_t) (wire_size - bytes), 0);
541                 if (bytes == -1 || bytes == 0) {
542                         LDNS_FREE(wire);
543                         *size = 0;
544                         return NULL;
545                 }
546         }
547         
548         *size = (size_t) bytes;
549         return wire;
550 }
551
552 uint8_t *
553 ldns_tcp_read_wire(int sockfd, size_t *size)
554 {
555         uint8_t *wire;
556         uint16_t wire_size;
557         ssize_t bytes = 0;
558
559         wire = LDNS_XMALLOC(uint8_t, 2);
560         if (!wire) {
561                 *size = 0;
562                 return NULL;
563         }
564         
565         while (bytes < 2) {
566                 bytes = recv(sockfd, (void*)wire, 2, 0);
567                 if (bytes == -1 || bytes == 0) {
568                         *size = 0;
569                         LDNS_FREE(wire);
570                         return NULL;
571                 }
572         }
573
574         wire_size = ldns_read_uint16(wire);
575         
576         LDNS_FREE(wire);
577         wire = LDNS_XMALLOC(uint8_t, wire_size);
578         bytes = 0;
579
580         while (bytes < (ssize_t) wire_size) {
581                 bytes += recv(sockfd, (void*) (wire + bytes), 
582                                 (size_t) (wire_size - bytes), 0);
583                 if (bytes == -1 || bytes == 0) {
584                         LDNS_FREE(wire);
585                         *size = 0;
586                         return NULL;
587                 }
588         }
589         
590         *size = (size_t) bytes;
591         return wire;
592 }
593
594 /* keep in mind that in DNS tcp messages the first 2 bytes signal the
595  * amount data to expect
596  */
597 ldns_status
598 ldns_tcp_send(uint8_t **result,  ldns_buffer *qbin, const struct sockaddr_storage *to, 
599                 socklen_t tolen, struct timeval timeout, size_t *answer_size)
600 {
601         int sockfd;
602         uint8_t *answer;
603         
604         sockfd = ldns_tcp_bgsend(qbin, to, tolen, timeout);
605         
606         if (sockfd == 0) {
607                 return LDNS_STATUS_ERR;
608         }
609
610         answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout);
611         close(sockfd);
612
613         if (*answer_size == 0) {
614                 /* oops */
615                 return LDNS_STATUS_NETWORK_ERR;
616         }
617
618         /* resize accordingly */
619         answer = (uint8_t*)LDNS_XREALLOC(answer, uint8_t *, (size_t)*answer_size);
620         *result = answer;
621         return LDNS_STATUS_OK;
622 }
623
624 int
625 ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, 
626                 struct timeval timeout)
627 {
628         int sockfd;
629         
630         sockfd = ldns_tcp_connect(to, tolen, timeout);
631         
632         if (sockfd == 0) {
633                 return 0;
634         }
635         
636         if (ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) {
637                 return 0;
638         }
639         
640         return sockfd;
641 }
642
643 /* code from rdata.c */
644 struct sockaddr_storage *
645 ldns_rdf2native_sockaddr_storage(const ldns_rdf *rd, uint16_t port, size_t *size)
646 {
647         struct sockaddr_storage *data;
648         struct sockaddr_in  *data_in;
649         struct sockaddr_in6 *data_in6;
650
651         data = LDNS_MALLOC(struct sockaddr_storage);
652         if (!data) {
653                 return NULL;
654         }
655                 /* zero the structure for portability */
656                 memset(data, 0, sizeof(struct sockaddr_storage));
657         if (port == 0) {
658                 port =  LDNS_PORT;
659         }
660
661         switch(ldns_rdf_get_type(rd)) {
662                 case LDNS_RDF_TYPE_A:
663                         data->ss_family = AF_INET;
664                         data_in = (struct sockaddr_in*) data;
665                         data_in->sin_port = (in_port_t)htons(port);
666                         memcpy(&(data_in->sin_addr), ldns_rdf_data(rd), ldns_rdf_size(rd));
667                         *size = sizeof(struct sockaddr_in);
668                         return data;
669                 case LDNS_RDF_TYPE_AAAA:
670                         data->ss_family = AF_INET6;
671                         data_in6 = (struct sockaddr_in6*) data;
672                         data_in6->sin6_port = (in_port_t)htons(port);
673                         memcpy(&data_in6->sin6_addr, ldns_rdf_data(rd), ldns_rdf_size(rd));
674                         *size = sizeof(struct sockaddr_in6);
675                         return data;
676                 default:
677                         LDNS_FREE(data);
678                         return NULL;
679         }
680 }
681
682 ldns_rdf *
683 ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port)
684 {
685         ldns_rdf *addr;
686         struct sockaddr_in *data_in;
687         struct sockaddr_in6 *data_in6;
688
689         switch(sock->ss_family) {
690                 case AF_INET:
691                         data_in = (struct sockaddr_in*)sock;
692                         if (port) {
693                                 *port = ntohs((uint16_t)data_in->sin_port);
694                         }
695                         addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A,
696                                         LDNS_IP4ADDRLEN, &data_in->sin_addr);
697                         break;
698                 case AF_INET6:
699                         data_in6 = (struct sockaddr_in6*)sock;
700                         if (port) {
701                                 *port = ntohs((uint16_t)data_in6->sin6_port);
702                         }
703                         addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA,
704                                         LDNS_IP6ADDRLEN, &data_in6->sin6_addr);
705                         break;
706                 default:
707                         if (port) {
708                                 *port = 0;
709                         }
710                         return NULL;
711         }
712         return addr;
713 }
714
715 /* code from resolver.c */
716 ldns_status
717 ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) 
718 {
719         ldns_pkt *query;
720         ldns_buffer *query_wire;
721
722         struct sockaddr_storage *ns = NULL;
723         size_t ns_len = 0;
724         size_t ns_i;
725         ldns_status status;
726
727         if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) {
728                 return LDNS_STATUS_ERR;
729         }
730
731         query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0);
732
733         if (!query) {
734                 return LDNS_STATUS_ADDRESS_ERR;
735         }
736         /* For AXFR, we have to make the connection ourselves */
737         /* try all nameservers (which usually would mean v4 fallback if 
738          * @hostname is used */
739         for (ns_i = 0;
740              ns_i < ldns_resolver_nameserver_count(resolver) &&
741              resolver->_socket == 0;
742              ns_i++) {
743                 ns = ldns_rdf2native_sockaddr_storage(
744                         resolver->_nameservers[ns_i],
745                         ldns_resolver_port(resolver), &ns_len);
746         
747                 resolver->_socket = ldns_tcp_connect(ns, (socklen_t)ns_len, 
748                                 ldns_resolver_timeout(resolver));
749         }
750
751         if (resolver->_socket == 0) {
752                 ldns_pkt_free(query);
753                 LDNS_FREE(ns);
754                 return LDNS_STATUS_NETWORK_ERR;
755         }
756
757 #ifdef HAVE_SSL
758         if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) {
759                 status = ldns_pkt_tsig_sign(query,
760                                             ldns_resolver_tsig_keyname(resolver),
761                                             ldns_resolver_tsig_keydata(resolver),
762                                             300, ldns_resolver_tsig_algorithm(resolver), NULL);
763                 if (status != LDNS_STATUS_OK) {
764                         return LDNS_STATUS_CRYPTO_TSIG_ERR;
765                 }
766         }
767 #endif /* HAVE_SSL */
768
769         /* Convert the query to a buffer          * Is this necessary?
770          */
771         query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
772         status = ldns_pkt2buffer_wire(query_wire, query);
773         if (status != LDNS_STATUS_OK) {
774                 ldns_pkt_free(query);
775                 LDNS_FREE(ns);
776                 return status;
777         }
778         /* Send the query */
779         if (ldns_tcp_send_query(query_wire, resolver->_socket, ns, 
780                                 (socklen_t)ns_len) == 0) {
781                 ldns_pkt_free(query);
782                 ldns_buffer_free(query_wire);
783                 LDNS_FREE(ns);
784                 return LDNS_STATUS_NETWORK_ERR;
785         }
786
787         ldns_pkt_free(query);
788         ldns_buffer_free(query_wire);
789         LDNS_FREE(ns);
790
791         /*
792          * The AXFR is done once the second SOA record is sent
793          */
794         resolver->_axfr_soa_count = 0;
795         return LDNS_STATUS_OK;
796 }