Author: breed Date: Wed Mar 10 16:32:22 2010 New Revision: 921439 URL: http://svn.apache.org/viewvc?rev=921439&view=rev Log: ZOOKEEPER-677. c client doesn't allow ipv6 numeric connect string
Modified: hadoop/zookeeper/trunk/CHANGES.txt hadoop/zookeeper/trunk/src/c/configure.ac hadoop/zookeeper/trunk/src/c/src/zookeeper.c hadoop/zookeeper/trunk/src/c/tests/TestClient.cc hadoop/zookeeper/trunk/src/c/tests/TestZookeeperInit.cc Modified: hadoop/zookeeper/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/CHANGES.txt?rev=921439&r1=921438&r2=921439&view=diff ============================================================================== --- hadoop/zookeeper/trunk/CHANGES.txt (original) +++ hadoop/zookeeper/trunk/CHANGES.txt Wed Mar 10 16:32:22 2010 @@ -258,6 +258,8 @@ BUGFIXES: ZOOKEEPER-685. Race in LENonTerminateTest (henry via breed) + ZOOKEEPER-677. c client doesn't allow ipv6 numeric connect string (breed & phunt & mahadev via breed) + IMPROVEMENTS: ZOOKEEPER-473. cleanup junit tests to eliminate false positives due to "socket reuse" and failure to close client (phunt via mahadev) Modified: hadoop/zookeeper/trunk/src/c/configure.ac URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/configure.ac?rev=921439&r1=921438&r2=921439&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/c/configure.ac (original) +++ hadoop/zookeeper/trunk/src/c/configure.ac Wed Mar 10 16:32:22 2010 @@ -52,9 +52,13 @@ AC_PROG_LN_S # AC_DISABLE_SHARED AC_PROG_LIBTOOL +#enable -D_GNU_SOURCE since the return code value of getaddrinfo +#ifdefed with __USE_GNU +#features.h header undef's __USE_GNU and defines it only if _GNU_SOURCE is defined +#hence this define for gcc AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug],[enable debug build [default=no]])], - [CFLAGS="-g -O0";CXXFLAGS="-g -O0"],[CFLAGS="-g -O2";CXXFLAGS="-g -O2"]) + [CFLAGS="-g -O0 -D_GNU_SOURCE";CXXFLAGS="-g -O0"],[CFLAGS="-g -O2 -D_GNU_SOURCE";CXXFLAGS="-g -O2"]) AC_ARG_WITH([syncapi], [AS_HELP_STRING([--with-syncapi],[build with support for SyncAPI [default=yes]])], Modified: hadoop/zookeeper/trunk/src/c/src/zookeeper.c URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/src/zookeeper.c?rev=921439&r1=921438&r2=921439&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/c/src/zookeeper.c (original) +++ hadoop/zookeeper/trunk/src/c/src/zookeeper.c Wed Mar 10 16:32:22 2010 @@ -189,6 +189,7 @@ static __attribute__((unused)) void prin static void *SYNCHRONOUS_MARKER = (void*)&SYNCHRONOUS_MARKER; static int isValidPath(const char* path, const int flags); +static int getaddrinfo_errno(int rc); const void *zoo_get_context(zhandle_t *zh) { @@ -403,6 +404,24 @@ static void setup_random() } /** + * get the errno from the return code + * of get addrinfo. Errno is not set + * with the call to getaddrinfo, so thats + * why we have to do this. + */ +static int getaddrinfo_errno(int rc) { + switch(rc) { + case EAI_NONAME: + case EAI_NODATA: + return ENOENT; + case EAI_MEMORY: + return ENOMEM; + default: + return EINVAL; + } +} + +/** * fill in the addrs array of the zookeeper servers in the zhandle. after filling * them in, we will permute them for load balancing. */ @@ -430,7 +449,7 @@ int getaddrs(zhandle_t *zh) zh->addrs = 0; host=strtok_r(hosts, ",", &strtok_last); while(host) { - char *port_spec = strchr(host, ':'); + char *port_spec = strrchr(host, ':'); char *end_port_spec; int port; if (!port_spec) { @@ -462,10 +481,23 @@ int getaddrs(zhandle_t *zh) while(isspace(*host) && host != strtok_last) host++; - if (getaddrinfo(host, port_spec, &hints, &res0) != 0) { - LOG_ERROR(("getaddrinfo: %s\n", strerror(errno))); - rc=ZSYSTEMERROR; - goto fail; + if ((rc = getaddrinfo(host, port_spec, &hints, &res0)) != 0) { + //bug in getaddrinfo implementation when it returns + //EAI_BADFLAGS or EAI_ADDRFAMILY with AF_UNSPEC and + // ai_flags as AI_ADDRCONFIG + if ((hints.ai_flags == AI_ADDRCONFIG) && + ((rc ==EAI_BADFLAGS) || (rc == EAI_ADDRFAMILY))) { + //reset ai_flags to null + hints.ai_flags = 0; + //retry getaddrinfo + rc = getaddrinfo(host, port_spec, &hints, &res0); + } + if (rc != 0) { + errno = getaddrinfo_errno(rc); + LOG_ERROR(("getaddrinfo: %s\n", strerror(errno))); + rc=ZSYSTEMERROR; + goto fail; + } } for (res = res0; res; res = res->ai_next) { Modified: hadoop/zookeeper/trunk/src/c/tests/TestClient.cc URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/tests/TestClient.cc?rev=921439&r1=921438&r2=921439&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/c/tests/TestClient.cc (original) +++ hadoop/zookeeper/trunk/src/c/tests/TestClient.cc Wed Mar 10 16:32:22 2010 @@ -180,6 +180,7 @@ class Zookeeper_simpleSystem : public CP CPPUNIT_TEST(testAsyncWatcherAutoReset); #ifdef THREADED CPPUNIT_TEST(testNullData); + CPPUNIT_TEST(testIPV6); CPPUNIT_TEST(testPath); CPPUNIT_TEST(testPathValidation); CPPUNIT_TEST(testPing); @@ -215,7 +216,11 @@ class Zookeeper_simpleSystem : public CP } zhandle_t *createClient(watchctx_t *ctx) { - zhandle_t *zk = zookeeper_init(hostPorts, watcher, 10000, 0, ctx, 0); + return createClient(hostPorts, ctx); + } + + zhandle_t *createClient(const char *hp, watchctx_t *ctx) { + zhandle_t *zk = zookeeper_init(hp, watcher, 10000, 0, ctx, 0); ctx->zh = zk; sleep(1); return zk; @@ -571,6 +576,16 @@ public: CPPUNIT_ASSERT(stat_a.numChildren == 4); } + void testIPV6() { + watchctx_t ctx; + zhandle_t *zk = createClient("::1:22181", &ctx); + CPPUNIT_ASSERT(zk); + int rc = 0; + rc = zoo_create(zk, "/ipv6", NULL, -1, + &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0); + CPPUNIT_ASSERT_EQUAL((int) ZOK, rc); + } + void testNullData() { watchctx_t ctx; zhandle_t *zk = createClient(&ctx); Modified: hadoop/zookeeper/trunk/src/c/tests/TestZookeeperInit.cc URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/tests/TestZookeeperInit.cc?rev=921439&r1=921438&r2=921439&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/c/tests/TestZookeeperInit.cc (original) +++ hadoop/zookeeper/trunk/src/c/tests/TestZookeeperInit.cc Wed Mar 10 16:32:22 2010 @@ -228,7 +228,7 @@ public: const string INVALID_HOST("host1:1111+host:123"); zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0); CPPUNIT_ASSERT(zh==0); - CPPUNIT_ASSERT_EQUAL(EINVAL,errno); + CPPUNIT_ASSERT_EQUAL(ENOENT,errno); } void testNonexistentHost() {