mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
BSD needs: addrlen set when calling recvfrom.
And it has length/padding for sockaddr structures. git-svn-id: file:///svn/unbound/trunk@72 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
fc30ae4b9e
commit
5532a0ea67
4 changed files with 73 additions and 3 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,12 +55,45 @@
|
|||
/** 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue