summaryrefslogtreecommitdiff
path: root/test/testsock.c
diff options
context:
space:
mode:
authorjorton <jorton@13f79535-47bb-0310-9956-ffa450edef68>2017-11-28 08:53:13 +0000
committerjorton <jorton@13f79535-47bb-0310-9956-ffa450edef68>2017-11-28 08:53:13 +0000
commit78d8a9229c72e1f31cb16900e11c4baccae5d38f (patch)
tree46a20c09edf04f7198f163262c487e6fefe5f738 /test/testsock.c
parent66a2a6844b1abf8acad0e5e4f735ddbbd01953a3 (diff)
downloadlibapr-78d8a9229c72e1f31cb16900e11c4baccae5d38f.tar.gz
Support IPv6 link-local address scope/zone mapping.
* network_io/unix/sockaddr.c (apr_sockaddr_zone_set, apr_sockaddr_zone_get): New functions. (apr_sockaddr_ip_getbuf): Append %scope for link-local address. (apr_sockaddr_equal): Compare link-local address with different scopes as not equal. * include/apr_network_io.h: Add function declarations. * configure.in: Test for if_indextoname and if_nametoindex. * test/testsock.c (test_zone): New test case. * include/arch/win32/apr_private.h: Assume Windows supports if_nametoindex and if_indextoname. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@1816527 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test/testsock.c')
-rw-r--r--test/testsock.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/test/testsock.c b/test/testsock.c
index 70f8235ee..933aa1da8 100644
--- a/test/testsock.c
+++ b/test/testsock.c
@@ -640,6 +640,98 @@ static void test_freebind(abts_case *tc, void *data)
#endif
}
+#define TEST_ZONE_ADDR "fe80::1"
+
+#ifdef __linux__
+/* Reasonable bet that "lo" will exist. */
+#define TEST_ZONE_NAME "lo"
+/* ... fill in other platforms here */
+#endif
+
+#ifdef TEST_ZONE_NAME
+#define TEST_ZONE_FULLADDR TEST_ZONE_ADDR "%" TEST_ZONE_NAME
+#endif
+
+static void test_zone(abts_case *tc, void *data)
+{
+#if APR_HAVE_IPV6
+ apr_sockaddr_t *sa;
+ apr_status_t rv;
+ const char *name = NULL;
+ apr_uint32_t id = 0;
+
+ /* RFC 5737 address */
+ rv = apr_sockaddr_info_get(&sa, "127.0.0.1", APR_INET, 8080, 0, p);
+ APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
+
+ /* Fail for an IPv4 address! */
+ ABTS_INT_EQUAL(tc, APR_EBADIP,
+ apr_sockaddr_zone_set(sa, "1"));
+ ABTS_INT_EQUAL(tc, APR_EBADIP,
+ apr_sockaddr_zone_get(sa, &name, &id, p));
+
+ rv = apr_sockaddr_info_get(&sa, TEST_ZONE_ADDR, APR_INET6, 8080, 0, p);
+ APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
+
+ rv = apr_sockaddr_info_get(&sa, TEST_ZONE_ADDR, APR_INET6, 8080, 0, p);
+ APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
+
+ ABTS_INT_EQUAL(tc, APR_EBADIP, apr_sockaddr_zone_get(sa, &name, &id, p));
+
+#ifdef TEST_ZONE_NAME
+ {
+ apr_sockaddr_t *sa2;
+ char buf[50];
+
+ APR_ASSERT_SUCCESS(tc, "Set zone to " TEST_ZONE_NAME,
+ apr_sockaddr_zone_set(sa, TEST_ZONE_NAME));
+
+ APR_ASSERT_SUCCESS(tc, "Get zone",
+ apr_sockaddr_zone_get(sa, NULL, NULL, p));
+
+ APR_ASSERT_SUCCESS(tc, "Get zone",
+ apr_sockaddr_zone_get(sa, &name, &id, p));
+ ABTS_STR_EQUAL(tc, TEST_ZONE_NAME, name);
+ ABTS_INT_NEQUAL(tc, 0, id); /* Only guarantee is that it should be non-zero */
+
+ /* Check string translation. */
+ APR_ASSERT_SUCCESS(tc, "get IP address",
+ apr_sockaddr_ip_getbuf(buf, 50, sa));
+ ABTS_STR_EQUAL(tc, TEST_ZONE_FULLADDR, buf);
+
+ memset(buf, 'A', sizeof buf);
+ ABTS_INT_EQUAL(tc, APR_ENOSPC, apr_sockaddr_ip_getbuf(buf, strlen(TEST_ZONE_ADDR), sa));
+ ABTS_INT_EQUAL(tc, APR_ENOSPC, apr_sockaddr_ip_getbuf(buf, strlen(TEST_ZONE_FULLADDR), sa));
+
+ APR_ASSERT_SUCCESS(tc, "get IP address",
+ apr_sockaddr_ip_getbuf(buf, strlen(TEST_ZONE_FULLADDR) + 1, sa));
+ /* Check for overflow. */
+ ABTS_INT_EQUAL(tc, 'A', buf[strlen(buf) + 1]);
+
+ rv = apr_sockaddr_info_copy(&sa2, sa, p);
+ APR_ASSERT_SUCCESS(tc, "Problem copying sockaddr", rv);
+
+ /* Copy copied zone matches */
+ APR_ASSERT_SUCCESS(tc, "Get zone",
+ apr_sockaddr_zone_get(sa2, &name, &id, p));
+ ABTS_STR_EQUAL(tc, TEST_ZONE_NAME, name);
+ ABTS_INT_NEQUAL(tc, 0, id); /* Only guarantee is that it should be non-zero */
+
+ /* Should match self and copy */
+ ABTS_INT_NEQUAL(tc, 0, apr_sockaddr_equal(sa, sa));
+ ABTS_INT_NEQUAL(tc, 0, apr_sockaddr_equal(sa2, sa2));
+ ABTS_INT_NEQUAL(tc, 0, apr_sockaddr_equal(sa2, sa));
+
+ /* Should not match against copy without zone set. */
+ rv = apr_sockaddr_info_get(&sa2, TEST_ZONE_ADDR, APR_INET6, 8080, 0, p);
+ APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
+
+ ABTS_INT_EQUAL(tc, 0, apr_sockaddr_equal(sa2, sa));
+ }
+#endif /* TEST_ZONE_NAME */
+#endif /* APR_HAVE_IPV6 */
+}
+
abts_suite *testsock(abts_suite *suite)
{
suite = ADD_SUITE(suite)
@@ -657,6 +749,7 @@ abts_suite *testsock(abts_suite *suite)
abts_run_test(suite, test_wait, NULL);
abts_run_test(suite, test_nonblock_inheritance, NULL);
abts_run_test(suite, test_freebind, NULL);
+ abts_run_test(suite, test_zone, NULL);
#if APR_HAVE_SOCKADDR_UN
socket_name = UNIX_SOCKET_NAME;
socket_type = APR_UNIX;