From 9448901723fd649aab640d8945c99164db5aa54c Mon Sep 17 00:00:00 2001 From: Vladislav Tyulbashev Date: Thu, 13 Feb 2020 19:54:45 +0300 Subject: [PATCH 1/3] ZOOKEEPER-3726: invalid ipv6 address comparison --- .../zookeeper-client-c/src/addrvec.c | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/zookeeper-client/zookeeper-client-c/src/addrvec.c b/zookeeper-client/zookeeper-client-c/src/addrvec.c index fdfb68d34fd..b7f244e7afb 100644 --- a/zookeeper-client/zookeeper-client-c/src/addrvec.c +++ b/zookeeper-client/zookeeper-client-c/src/addrvec.c @@ -126,8 +126,26 @@ int addrvec_contains(const addrvec_t *avec, const struct sockaddr_storage *addr) for (i = 0; i < avec->count; i++) { - if(memcmp(&avec->data[i], addr, INET_ADDRSTRLEN) == 0) - return 1; + if (avec->data[i].ss_family != addr->ss_family) + continue; + switch (addr->ss_family) { + case AF_INET: + if (memcmp(&((struct sockaddr_in*)&avec->data[i])->sin_addr, + &((struct sockaddr_in*)addr)->sin_addr, + sizeof(struct in_addr)) == 0) + return 1; + break; +#ifdef AF_INET6 + case AF_INET6: + if (memcmp(&((struct sockaddr_in6*)&avec->data[i])->sin6_addr, + &((struct sockaddr_in6*)addr)->sin6_addr, + sizeof(struct in6_addr)) == 0) + return 1; + break; +#endif + default: + break; + } } return 0; From f7b59508369b0e762db939f2d7b981ce35333f70 Mon Sep 17 00:00:00 2001 From: Vladislav Tyulbashev Date: Sat, 29 Feb 2020 00:29:49 +0300 Subject: [PATCH 2/3] ZOOKEEPER-3726: added unit tests for addrvec_contains behaviour --- .../zookeeper-client-c/tests/TestReconfig.cc | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/zookeeper-client/zookeeper-client-c/tests/TestReconfig.cc b/zookeeper-client/zookeeper-client-c/tests/TestReconfig.cc index 317ffcddfed..600f9f4a192 100644 --- a/zookeeper-client/zookeeper-client-c/tests/TestReconfig.cc +++ b/zookeeper-client/zookeeper-client-c/tests/TestReconfig.cc @@ -26,6 +26,10 @@ #include #include +extern "C" { +#include +} + #include "Util.h" #include "LibCMocks.h" #include "ZKMocks.h" @@ -218,6 +222,10 @@ class Zookeeper_reconfig : public CPPUNIT_NS::TestFixture CPPUNIT_TEST(testcycleNextServer); CPPUNIT_TEST(testMigrateOrNot); CPPUNIT_TEST(testMigrationCycle); + CPPUNIT_TEST(testAddrVecContainsIPv4); +#ifdef AF_INET6 + CPPUNIT_TEST(testAddrVecContainsIPv6); +#endif // In threaded mode each 'create' is a thread -- it's not practical to create // 10,000 threads to test load balancing. The load balancing code can easily @@ -609,6 +617,87 @@ class Zookeeper_reconfig : public CPPUNIT_NS::TestFixture numServers = 9; updateAllClientsAndServers(numServers); } + + /** + * This tests that client can detect server's ipv4 address change. + * + * (1) We generate some address and put in addr, which saddr point to + * (2) Add all addresses that differ by one bit from the source + * (3) Add same address, but set ipv6 protocol + * (4) Ensure, that our address is not equal to any of generated, + * and that it equals to itself + */ + void testAddrVecContainsIPv4() { + addrvec_t vec; + addrvec_init(&vec); + + sockaddr_storage addr; + sockaddr_in* saddr = (sockaddr_in*)&addr; + saddr->sin_family = AF_INET; + saddr->sin_port = htons((u_short)1234); + saddr->sin_addr.s_addr = INADDR_ANY; + + CPPUNIT_ASSERT(sizeof(saddr->sin_addr.s_addr) == 4); + + sockaddr_storage changedAddrs[33]; + for (int i = 0; i < 32; i++) { + saddr->sin_addr.s_addr ^= (1 << i); + changedAddrs[i] = addr; + addrvec_append(&vec, &changedAddrs[i]); + saddr->sin_addr.s_addr ^= (1 << i); + } + + saddr->sin_family = AF_INET6; + changedAddrs[32] = addr; + addrvec_append(&vec, &changedAddrs[32]); + saddr->sin_family = AF_INET; + + CPPUNIT_ASSERT(!addrvec_contains(&vec, &addr)); + addrvec_append(&vec, &addr); + CPPUNIT_ASSERT(addrvec_contains(&vec, &addr)); + addrvec_free(&vec); + } + + /** + * This tests that client can detect server's ipv6 address change. + * + * Same logic as in previous testAddrVecContainsIPv4 method, + * but we keep in mind, that ipv6 is 128-bit long. + */ +#ifdef AF_INET6 + void testAddrVecContainsIPv6() { + addrvec_t vec; + addrvec_init(&vec); + + sockaddr_storage addr; + sockaddr_in6* saddr = (sockaddr_in6*)&addr; + saddr->sin6_family = AF_INET6; + saddr->sin6_port = htons((u_short)1234); + saddr->sin6_addr = in6addr_any; + + CPPUNIT_ASSERT(sizeof(saddr->sin6_addr.s6_addr) == 16); + + sockaddr_storage changedAddrs[129]; + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 8; j++) { + saddr->sin6_addr.s6_addr[i] ^= (1 << j); + changedAddrs[i * 8 + j] = addr; + addrvec_append(&vec, &changedAddrs[i * 8 + j]); + saddr->sin6_addr.s6_addr[i] ^= (1 << j); + } + } + + saddr->sin6_family = AF_INET; + changedAddrs[128] = addr; + addrvec_append(&vec, &changedAddrs[128]); + saddr->sin6_family = AF_INET6; + + CPPUNIT_ASSERT(!addrvec_contains(&vec, &addr)); + addrvec_append(&vec, &addr); + CPPUNIT_ASSERT(addrvec_contains(&vec, &addr)); + addrvec_free(&vec); + } +#endif }; CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_reconfig); From fd9f7b08bee1a16343029a99df5ffd8b43805c2f Mon Sep 17 00:00:00 2001 From: Vladislav Tyulbashev Date: Sat, 29 Feb 2020 01:26:40 +0300 Subject: [PATCH 3/3] ZOOKEEPER-3726: removed extra buffers from tests --- .../zookeeper-client-c/tests/TestReconfig.cc | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/zookeeper-client/zookeeper-client-c/tests/TestReconfig.cc b/zookeeper-client/zookeeper-client-c/tests/TestReconfig.cc index 600f9f4a192..22f87e94491 100644 --- a/zookeeper-client/zookeeper-client-c/tests/TestReconfig.cc +++ b/zookeeper-client/zookeeper-client-c/tests/TestReconfig.cc @@ -639,17 +639,14 @@ class Zookeeper_reconfig : public CPPUNIT_NS::TestFixture CPPUNIT_ASSERT(sizeof(saddr->sin_addr.s_addr) == 4); - sockaddr_storage changedAddrs[33]; for (int i = 0; i < 32; i++) { saddr->sin_addr.s_addr ^= (1 << i); - changedAddrs[i] = addr; - addrvec_append(&vec, &changedAddrs[i]); + addrvec_append(&vec, &addr); saddr->sin_addr.s_addr ^= (1 << i); } saddr->sin_family = AF_INET6; - changedAddrs[32] = addr; - addrvec_append(&vec, &changedAddrs[32]); + addrvec_append(&vec, &addr); saddr->sin_family = AF_INET; CPPUNIT_ASSERT(!addrvec_contains(&vec, &addr)); @@ -677,19 +674,16 @@ class Zookeeper_reconfig : public CPPUNIT_NS::TestFixture CPPUNIT_ASSERT(sizeof(saddr->sin6_addr.s6_addr) == 16); - sockaddr_storage changedAddrs[129]; for (int i = 0; i < 16; i++) { for (int j = 0; j < 8; j++) { saddr->sin6_addr.s6_addr[i] ^= (1 << j); - changedAddrs[i * 8 + j] = addr; - addrvec_append(&vec, &changedAddrs[i * 8 + j]); + addrvec_append(&vec, &addr); saddr->sin6_addr.s6_addr[i] ^= (1 << j); } } saddr->sin6_family = AF_INET; - changedAddrs[128] = addr; - addrvec_append(&vec, &changedAddrs[128]); + addrvec_append(&vec, &addr); saddr->sin6_family = AF_INET6; CPPUNIT_ASSERT(!addrvec_contains(&vec, &addr));