diff options
author | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2013-11-12 13:48:16 +0000 |
---|---|---|
committer | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2013-11-12 13:48:16 +0000 |
commit | 657dd839a69993a02ca672fe4f6d1513afcb5f84 (patch) | |
tree | 6acda1edd1523b6c65baf99fdb5a210797f3ad9f | |
parent | da01992d919dba5b641678869e9b4c777cd77d26 (diff) | |
download | libapr-657dd839a69993a02ca672fe4f6d1513afcb5f84.tar.gz |
add apr_sockaddr_is_wildcard() API
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@1541061 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | include/apr_network_io.h | 10 | ||||
-rw-r--r-- | network_io/unix/sockaddr.c | 29 | ||||
-rw-r--r-- | test/testsock.c | 11 |
3 files changed, 50 insertions, 0 deletions
diff --git a/include/apr_network_io.h b/include/apr_network_io.h index d7ffaf509..8eaed2607 100644 --- a/include/apr_network_io.h +++ b/include/apr_network_io.h @@ -760,6 +760,16 @@ APR_DECLARE(int) apr_sockaddr_equal(const apr_sockaddr_t *addr1, const apr_sockaddr_t *addr2); /** + * See if the IP address in an APR socket address refers to the wildcard + * address for the protocol family (e.g., INADDR_ANY for IPv4). + * + * @param addr The APR socket address to examine. + * @remark The return value will be non-zero if the address is + * initialized and is the wildcard address. + */ +APR_DECLARE(int) apr_sockaddr_is_wildcard(const apr_sockaddr_t *addr); + +/** * Return the type of the socket. * @param sock The socket to query. * @param type The returned type (e.g., SOCK_STREAM). diff --git a/network_io/unix/sockaddr.c b/network_io/unix/sockaddr.c index 1ccc3f571..080c7a298 100644 --- a/network_io/unix/sockaddr.c +++ b/network_io/unix/sockaddr.c @@ -879,6 +879,35 @@ APR_DECLARE(int) apr_sockaddr_equal(const apr_sockaddr_t *addr1, return 0; /* not equal */ } +APR_DECLARE(int) apr_sockaddr_is_wildcard(const apr_sockaddr_t *addr) +{ + static const char inaddr_any[ +#if APR_HAVE_IPV6 + sizeof(struct in6_addr) +#else + sizeof(struct in_addr) +#endif + ] = {0}; + + if (addr->ipaddr_ptr /* IP address initialized */ + && addr->ipaddr_len <= sizeof inaddr_any) { /* else bug elsewhere? */ + if (!memcmp(inaddr_any, addr->ipaddr_ptr, addr->ipaddr_len)) { + return 1; + } +#if APR_HAVE_IPV6 + if (addr->family == AF_INET6 + && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addr->ipaddr_ptr)) { + struct in_addr *v4 = (struct in_addr *)&((apr_uint32_t *)addr->ipaddr_ptr)[3]; + + if (!memcmp(inaddr_any, v4, sizeof *v4)) { + return 1; + } + } +#endif + } + return 0; +} + static apr_status_t parse_network(apr_ipsubnet_t *ipsub, const char *network) { /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */ diff --git a/test/testsock.c b/test/testsock.c index 41b2774f7..b2ef80dd1 100644 --- a/test/testsock.c +++ b/test/testsock.c @@ -73,14 +73,21 @@ static void test_addr_info(abts_case *tc, void *data) { apr_status_t rv; apr_sockaddr_t *sa; + int rc; rv = apr_sockaddr_info_get(&sa, NULL, APR_UNSPEC, 80, 0, p); APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv); + rc = apr_sockaddr_is_wildcard(sa); + ABTS_INT_NEQUAL(tc, 0, rc); + rv = apr_sockaddr_info_get(&sa, "127.0.0.1", APR_UNSPEC, 80, 0, p); APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv); ABTS_STR_EQUAL(tc, "127.0.0.1", sa->hostname); + rc = apr_sockaddr_is_wildcard(sa); + ABTS_INT_EQUAL(tc, 0, rc); + rv = apr_sockaddr_info_get(&sa, "127.0.0.1", APR_UNSPEC, 0, 0, p); APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv); ABTS_STR_EQUAL(tc, "127.0.0.1", sa->hostname); @@ -324,6 +331,10 @@ static void test_print_addr(abts_case *tc, void *data) if (rv == APR_SUCCESS && sa) { /* sa should now be a v4-mapped IPv6 address. */ char buf[128]; + int rc; + + rc = apr_sockaddr_is_wildcard(sa); + ABTS_INT_NEQUAL(tc, 0, rc); memset(buf, 'z', sizeof buf); |