From: Wouter Wijngaards Date: Wed, 13 Oct 2010 07:59:55 +0000 (+0000) Subject: addr_is_any X-Git-Tag: release-1.4.7rc1~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bc54fa3e58deb4e4e8fa6a560540d739814eb9e7;p=thirdparty%2Funbound.git addr_is_any git-svn-id: file:///svn/unbound/trunk@2279 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/services/outside_network.c b/services/outside_network.c index 91614024d..18ce9f348 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -156,6 +156,10 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len) log_addr(0, "failed address", &w->addr, w->addrlen); return 0; } + /* pick random outgoing-interface of that family, and bind it. + * port set to 0 so OS picks a port number for us. + * if it is the ANY address, do not bind. */ + fd_set_nonblock(s); if(connect(s, (struct sockaddr*)&w->addr, w->addrlen) == -1) { #ifndef USE_WINSOCK diff --git a/testcode/unitmain.c b/testcode/unitmain.c index e9e28c53c..3adff443b 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -304,6 +304,34 @@ net_test(void) unit_assert(ipstrtoaddr("2::ffff:192.168.0.2", 53, &a, &l)); unit_assert(!addr_is_ip4mapped(&a, l)); } + /* test addr_is_any */ + unit_show_func("util/net_help.c", "addr_is_any"); + if(1) { + struct sockaddr_storage a; + socklen_t l = (socklen_t)sizeof(a); + unit_assert(ipstrtoaddr("0.0.0.0", 53, &a, &l)); + unit_assert(addr_is_any(&a, l)); + unit_assert(ipstrtoaddr("0.0.0.0", 10053, &a, &l)); + unit_assert(addr_is_any(&a, l)); + unit_assert(ipstrtoaddr("0.0.0.0", 0, &a, &l)); + unit_assert(addr_is_any(&a, l)); + unit_assert(ipstrtoaddr("::0", 0, &a, &l)); + unit_assert(addr_is_any(&a, l)); + unit_assert(ipstrtoaddr("::0", 53, &a, &l)); + unit_assert(addr_is_any(&a, l)); + unit_assert(ipstrtoaddr("::1", 53, &a, &l)); + unit_assert(!addr_is_any(&a, l)); + unit_assert(ipstrtoaddr("2001:1667::1", 0, &a, &l)); + unit_assert(!addr_is_any(&a, l)); + unit_assert(ipstrtoaddr("2001::0", 0, &a, &l)); + unit_assert(!addr_is_any(&a, l)); + unit_assert(ipstrtoaddr("10.0.0.0", 0, &a, &l)); + unit_assert(!addr_is_any(&a, l)); + unit_assert(ipstrtoaddr("0.0.0.10", 0, &a, &l)); + unit_assert(!addr_is_any(&a, l)); + unit_assert(ipstrtoaddr("192.0.2.1", 0, &a, &l)); + unit_assert(!addr_is_any(&a, l)); + } } #include "util/config_file.h" diff --git a/util/net_help.c b/util/net_help.c index 537577658..504a415ef 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -478,6 +478,21 @@ int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen) && memcmp(sinaddr, "\377\377\377\377", 4) == 0; } +int addr_is_any(struct sockaddr_storage* addr, socklen_t addrlen) +{ + int af = (int)((struct sockaddr_in*)addr)->sin_family; + void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; + void* sin6addr = &((struct sockaddr_in6*)addr)->sin6_addr; + if(af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in) + && memcmp(sinaddr, "\000\000\000\000", 4) == 0) + return 1; + else if(af==AF_INET6 && addrlen>=(socklen_t)sizeof(struct sockaddr_in6) + && memcmp(sin6addr, "\000\000\000\000\000\000\000\000" + "\000\000\000\000\000\000\000\000", 16) == 0) + return 1; + return 0; +} + void sock_list_insert(struct sock_list** list, struct sockaddr_storage* addr, socklen_t len, struct regional* region) { diff --git a/util/net_help.h b/util/net_help.h index 142c909d6..d09904747 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -277,6 +277,14 @@ int addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen); */ int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen); +/** + * See if sockaddr is 0.0.0.0 or ::0. + * @param addr: address + * @param addrlen: length of address + * @return true if so + */ +int addr_is_any(struct sockaddr_storage* addr, socklen_t addrlen); + /** * Insert new socket list item. If fails logs error. * @param list: pointer to pointer to first item.