]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
Better timeout handling.
authorWouter Wijngaards <wouter@NLnetLabs.nl>
Mon, 5 Oct 2009 09:19:41 +0000 (09:19 +0000)
committerWouter Wijngaards <wouter@NLnetLabs.nl>
Mon, 5 Oct 2009 09:19:41 +0000 (09:19 +0000)
Changelog
ldns/net.h.in
ldns_symbols.def
net.c

index 8fc5ea81711536a1ca728a815ade45df98eb6a66..3138429d4b876627f66a8eac90002b6a8e31b782 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -9,6 +9,7 @@
        * bug273: fix so EDNS rdata is included in pkt to wire conversion.
        * bug274: fix use of c++ keyword 'class' for RR class in the code.
        * bug275: fix memory leak of packet edns rdata.
+       * Fix timeout procedure for TCP and AXFR on Solaris.
 
 1.6.1   2009-09-14
        * --enable-gost : use the GOST algorithm (experimental).
index 9eb100fe31ae96ef5d0d79819e34b4854294dcf0..109a3f4dd8974aa614b9ee0cf0c55e4a9ec14736 100644 (file)
@@ -134,7 +134,20 @@ ssize_t ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr
  * \return number of bytes sent
  */
 ssize_t ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen);
+
+/**
+ * Gives back a raw packet from the wire and reads the header data from the given
+ * socket. Allocates the data (of size size) itself, so don't forget to free
+ *
+ * \param[in] sockfd the socket to read from
+ * \param[out] size the number of bytes that are read
+ * \param[in] timeout the time allowed between packets.
+ * \return the data read
+ */
+uint8_t *ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout);
+
 /**
+ * *DEPRECATED* please use ldns_tcp_read_wire_timeout, that checks for timeouts.
  * Gives back a raw packet from the wire and reads the header data from the given
  * socket. Allocates the data (of size size) itself, so don't forget to free
  *
index 8e925f0f3e8693216ed5b15428371869879d5dcd..3b1a064130d8c9a38a5dc1905166bc719385054d 100644 (file)
@@ -649,6 +649,7 @@ ldns_str2rdf_wks
 ldns_tcp_bgsend
 ldns_tcp_connect
 ldns_tcp_read_wire
+ldns_tcp_read_wire_timeout
 ldns_tcp_send
 ldns_tcp_send_query
 ldns_traverse_postorder
diff --git a/net.c b/net.c
index 1ec4104dcd3041654cafcca96bb807b5df9364bb..89f83e85cd7a9a766056985ac7c1eecc36fead91 100644 (file)
--- a/net.c
+++ b/net.c
@@ -497,6 +497,58 @@ ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
        return wire;
 }
 
+uint8_t *
+ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
+{
+       uint8_t *wire;
+       uint16_t wire_size;
+       ssize_t bytes = 0;
+
+       wire = LDNS_XMALLOC(uint8_t, 2);
+       if (!wire) {
+               *size = 0;
+               return NULL;
+       }
+       
+       while (bytes < 2) {
+               if(!ldns_sock_wait(sockfd, timeout, 0)) {
+                       *size = 0;
+                       LDNS_FREE(wire);
+                       return NULL;
+               }
+               bytes = recv(sockfd, (void*)wire, 2, 0);
+               if (bytes == -1 || bytes == 0) {
+                       *size = 0;
+                       LDNS_FREE(wire);
+                       return NULL;
+               }
+       }
+
+       wire_size = ldns_read_uint16(wire);
+       
+       LDNS_FREE(wire);
+       wire = LDNS_XMALLOC(uint8_t, wire_size);
+       bytes = 0;
+
+       while (bytes < (ssize_t) wire_size) {
+               if(!ldns_sock_wait(sockfd, timeout, 0)) {
+                       *size = 0;
+                       LDNS_FREE(wire);
+                       return NULL;
+               }
+               bytes += recv(sockfd, (void*) (wire + bytes), 
+                               (size_t) (wire_size - bytes), 0);
+               if (bytes == -1 || bytes == 0) {
+                       LDNS_FREE(wire);
+                       *size = 0;
+                       return NULL;
+               }
+       }
+       
+       *size = (size_t) bytes;
+       return wire;
+}
+
 uint8_t *
 ldns_tcp_read_wire(int sockfd, size_t *size)
 {
@@ -555,12 +607,7 @@ ldns_tcp_send(uint8_t **result,  ldns_buffer *qbin, const struct sockaddr_storag
                return LDNS_STATUS_ERR;
        }
 
-       if(!ldns_sock_wait(sockfd, timeout, 0)) {
-               close(sockfd);
-               return LDNS_STATUS_NETWORK_ERR;
-       }
-       
-       answer = ldns_tcp_read_wire(sockfd, answer_size);
+       answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout);
        close(sockfd);
 
        if (*answer_size == 0) {