]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
BSD needs: addrlen set when calling recvfrom.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 7 Feb 2007 10:08:55 +0000 (10:08 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 7 Feb 2007 10:08:55 +0000 (10:08 +0000)
And it has length/padding for sockaddr structures.

git-svn-id: file:///svn/unbound/trunk@72 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
services/listen_dnsport.c
services/outside_network.c
util/netevent.c

index 226952be287acb8d5ce44a453f0d423c17b7fecc..33a892ce4c4cae5fe5a2932a8944b45b37a5e470 100644 (file)
@@ -3,6 +3,8 @@
        - created udp forwarder test. I've done some effort to make it perform
          quickly. After servers are created, no big sleep statements but
          it checks the logfiles to see if servers have come up. Takes 0.14s.
+       - set addrlen value when calling recvfrom.
+       - comparison of addrs more portable.
 
 6 February 2007: Wouter
        - reviewed code and improved in places.
index f28490400cc14b65e0333c6c350a2f447773a4a1..c72dc6e35a09a0a12142c4a95d002895dcefcc37 100644 (file)
@@ -65,8 +65,11 @@ verbose_print_addr(struct addrinfo *addr)
 {
        if(verbosity >= VERB_ALGO) {
                char buf[100];
-               if(inet_ntop(addr->ai_family, 
-                       &((struct sockaddr_in*)addr->ai_addr)->sin_addr, buf, 
+               void* sinaddr = &((struct sockaddr_in*)addr->ai_addr)->sin_addr;
+               if(addr->ai_family == AF_INET6)
+                       sinaddr = &((struct sockaddr_in6*)addr->ai_addr)->
+                               sin6_addr;
+               if(inet_ntop(addr->ai_family, sinaddr, buf,
                        (socklen_t)sizeof(buf)) == 0) {
                        strncpy(buf, "(null)", sizeof(buf));
                }
index a93456c1ae7f31c0497e0ff54f76e620a083e01e..dd349a4896c94f53ecb740c7641205112ee8058d 100644 (file)
 /** number of times to retry making a random ID that is unique. */
 #define MAX_ID_RETRY 1000
 
+/** send addr to logfile */
+static void
+log_addr(struct sockaddr_storage* addr, socklen_t addrlen)
+{
+       uint16_t port;
+       const char* family = "unknown";
+       char dest[100];
+       int af = ((struct sockaddr_in*)addr)->sin_family;
+       void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
+       switch(af) {
+               case AF_INET: family="ip4"; break;
+               case AF_INET6: family="ip6"; 
+                       sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
+                       break;
+               case AF_UNIX: family="unix"; break;
+               default: break;
+       }
+       if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
+               strncpy(dest, "(inet_ntop error)", sizeof(dest));
+       }
+       port = ntohs(((struct sockaddr_in*)addr)->sin_port);
+       log_info("addr fam=%s port=%d dest=%s len=%d",
+               family, (int)port, dest, (int)addrlen);
+}
+
 /** compare function of pending rbtree */
 static int 
 pending_cmp(const void* key1, const void* key2)
 {
        struct pending *p1 = (struct pending*)key1;
        struct pending *p2 = (struct pending*)key2;
+       struct sockaddr_in* p1_in = (struct sockaddr_in*)&p1->addr;
+       struct sockaddr_in* p2_in = (struct sockaddr_in*)&p2->addr;
+       struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)&p1->addr;
+       struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)&p2->addr;
+/** byte size of ip4 address */
+#define INET_SIZE 4
+/** byte size of ip6 address */
+#define INET6_SIZE 16 
        if(p1->id < p2->id)
                return -1;
        if(p1->id > p2->id)
@@ -71,7 +104,33 @@ pending_cmp(const void* key1, const void* key2)
        if(p1->addrlen > p2->addrlen)
                return 1;
        log_assert(p1->addrlen == p2->addrlen);
-       return memcmp(&p1->addr, &p2->addr, p1->addrlen);
+       if( p1_in->sin_family < p2_in->sin_family)
+               return -1;
+       if( p1_in->sin_family > p2_in->sin_family)
+               return 1;
+       log_assert( p1_in->sin_family == p2_in->sin_family );
+       /* compare ip4 */
+       if( p1_in->sin_family == AF_INET ) {
+               /* just order it, ntohs not required */
+               if(p1_in->sin_port < p2_in->sin_port)
+                       return -1;
+               if(p1_in->sin_port > p2_in->sin_port)
+                       return 1;
+               log_assert(p1_in->sin_port == p2_in->sin_port);
+               return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE);
+       } else if (p1_in6->sin6_family == AF_INET6) {
+               /* just order it, ntohs not required */
+               if(p1_in6->sin6_port < p2_in6->sin6_port)
+                       return -1;
+               if(p1_in6->sin6_port > p2_in6->sin6_port)
+                       return 1;
+               log_assert(p1_in6->sin6_port == p2_in6->sin6_port);
+               return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, 
+                       INET6_SIZE);
+       } else {
+               /* eek unknown type, perform this comparison for sanity. */
+               return memcmp(&p1->addr, &p2->addr, p1->addrlen);
+       }
 }
 
 /** callback for incoming udp answers from the network. */
@@ -94,8 +153,11 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
        key.id = LDNS_ID_WIRE(ldns_buffer_begin(c->buffer));
        memcpy(&key.addr, &reply_info->addr, reply_info->addrlen);
        key.addrlen = reply_info->addrlen;
+       log_info("Incoming reply id=%4.4x addr=", key.id);
+       log_addr(&key.addr, key.addrlen);
 
        /* find it, see if this thing is a valid query response */
+       log_info("lookup size is %d entries", (int)outnet->pending->count);
        p = (struct pending*)rbtree_search(outnet->pending, &key);
        if(!p) {
                verbose(VERB_DETAIL, "received unsolicited udp reply. dropped.");
@@ -391,6 +453,8 @@ new_pending(struct outside_network* outnet, ldns_buffer* packet,
                        return NULL;
                }
        }
+       log_info("inserted new pending reply id=%4.4x addr=", pend->id);
+       log_addr(&pend->addr, pend->addrlen);
        return pend;
 }
 
index 0b6eb6c245ea1c36d5cd6f5a51c079f6bb026988..69bf44d6e70ed855c26df6443e970406ffb56a48 100644 (file)
@@ -224,6 +224,7 @@ comm_point_udp_callback(int fd, short event, void* arg)
                return;
        log_assert(rep.c && rep.c->buffer && rep.c->fd == fd);
        ldns_buffer_clear(rep.c->buffer);
+       rep.addrlen = (socklen_t)sizeof(rep.addr);
        recv = recvfrom(fd, ldns_buffer_begin(rep.c->buffer), 
                ldns_buffer_remaining(rep.c->buffer), 0, 
                (struct sockaddr*)&rep.addr, &rep.addrlen);