You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by ma...@apache.org on 2009/10/21 23:00:38 UTC

svn commit: r828216 - in /hadoop/zookeeper/trunk: CHANGES.txt src/c/src/zk_adaptor.h src/c/src/zookeeper.c

Author: mahadev
Date: Wed Oct 21 21:00:37 2009
New Revision: 828216

URL: http://svn.apache.org/viewvc?rev=828216&view=rev
Log:
ZOOKEEPER-530. Memory corruption: Zookeeper c client IPv6 implementation does not honor struct sockaddr_in6 size (isabel drost via mahadev)

Modified:
    hadoop/zookeeper/trunk/CHANGES.txt
    hadoop/zookeeper/trunk/src/c/src/zk_adaptor.h
    hadoop/zookeeper/trunk/src/c/src/zookeeper.c

Modified: hadoop/zookeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/CHANGES.txt?rev=828216&r1=828215&r2=828216&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/CHANGES.txt (original)
+++ hadoop/zookeeper/trunk/CHANGES.txt Wed Oct 21 21:00:37 2009
@@ -104,6 +104,9 @@
 
   ZOOKEEPER-529. Use Ivy to pull dependencies and also generate pom (phunt
   via mahadev)
+  
+  ZOOKEEPER-530. Memory corruption: Zookeeper c client IPv6 implementation
+  does not honor struct sockaddr_in6 size (isabel drost via mahadev)
 
 NEW FEATURES:
   ZOOKEEPER-539. generate eclipse project via ant target. (phunt via mahadev)

Modified: hadoop/zookeeper/trunk/src/c/src/zk_adaptor.h
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/src/zk_adaptor.h?rev=828216&r1=828215&r2=828216&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/src/c/src/zk_adaptor.h (original)
+++ hadoop/zookeeper/trunk/src/c/src/zk_adaptor.h Wed Oct 21 21:00:37 2009
@@ -170,7 +170,7 @@
 struct _zhandle {
     int fd; /* the descriptor used to talk to zookeeper */
     char *hostname; /* the hostname of zookeeper */
-    struct sockaddr *addrs; /* the addresses that correspond to the hostname */
+    struct sockaddr_storage *addrs; /* the addresses that correspond to the hostname */
     int addrs_count; /* The number of addresses in the addrs array */
     watcher_fn watcher; /* the registered watcher */
     struct timeval last_recv; /* The time that the last message was received */

Modified: hadoop/zookeeper/trunk/src/c/src/zookeeper.c
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/src/zookeeper.c?rev=828216&r1=828215&r2=828216&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/src/c/src/zookeeper.c (original)
+++ hadoop/zookeeper/trunk/src/c/src/zookeeper.c Wed Oct 21 21:00:37 2009
@@ -165,7 +165,7 @@
 
 const char*err2string(int err);
 static int queue_session_event(zhandle_t *zh, int state);
-static const char* format_endpoint_info(const struct sockaddr* ep);
+static const char* format_endpoint_info(const struct sockaddr_storage* ep);
 static const char* format_current_endpoint_info(zhandle_t* zh);
 
 /* completion routine forward declarations */
@@ -406,7 +406,7 @@
 int getaddrs(zhandle_t *zh)
 {
     struct addrinfo hints, *res, *res0;
-    struct sockaddr *addr;
+    struct sockaddr_storage *addr;
     char *hosts = strdup(zh->hostname);
     char *host;
     char *strtok_last;
@@ -500,10 +500,10 @@
         setup_random();
         /* Permute */
         for(i = 0; i < zh->addrs_count; i++) {
-            struct sockaddr *s1 = zh->addrs + random()%zh->addrs_count;
-            struct sockaddr *s2 = zh->addrs + random()%zh->addrs_count;
+            struct sockaddr_storage *s1 = zh->addrs + random()%zh->addrs_count;
+            struct sockaddr_storage *s2 = zh->addrs + random()%zh->addrs_count;
             if (s1 != s2) {
-                struct sockaddr t = *s1;
+                struct sockaddr_storage t = *s1;
                 *s1 = *s2;
                 *s2 = t;
             }
@@ -1347,11 +1347,18 @@
             int rc;
             int on = 1;
             
-            zh->fd = socket(PF_INET, SOCK_STREAM, 0);
+            zh->fd = socket(zh->addrs[zh->connect_index].ss_family, SOCK_STREAM, 0);
+            if (zh->fd < 0) {
+                return api_epilog(zh,handle_socket_error_msg(zh,__LINE__,
+                                                             ZSYSTEMERROR, "socket() call failed"));
+            }
             setsockopt(zh->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(int));
             fcntl(zh->fd, F_SETFL, O_NONBLOCK|fcntl(zh->fd, F_GETFL, 0));
-            rc = connect(zh->fd, &zh->addrs[zh->connect_index],
-                    sizeof(struct sockaddr));
+            if (zh->addrs[zh->connect_index].ss_family == AF_INET6) {
+                rc = connect(zh->fd, (struct sockaddr*) &zh->addrs[zh->connect_index], sizeof(struct sockaddr_in6));
+            } else {
+                rc = connect(zh->fd, (struct sockaddr*) &zh->addrs[zh->connect_index], sizeof(struct sockaddr_in));
+            }
             if (rc == -1) {
                 /* we are handling the non-blocking connect according to
                  * the description in section 16.3 "Non-blocking connect"
@@ -2695,7 +2702,7 @@
     return ZOK;
 }
 
-static const char* format_endpoint_info(const struct sockaddr* ep)
+static const char* format_endpoint_info(const struct sockaddr_storage* ep)
 {
     static char buf[128];
     char addrstr[128];
@@ -2704,16 +2711,18 @@
     if(ep==0)
         return "null";
 
-    inaddr=&((struct sockaddr_in*)ep)->sin_addr;
-    port=((struct sockaddr_in*)ep)->sin_port;
 #if defined(AF_INET6)
-    if(ep->sa_family==AF_INET6){
+    if(ep->ss_family==AF_INET6){
         inaddr=&((struct sockaddr_in6*)ep)->sin6_addr;
         port=((struct sockaddr_in6*)ep)->sin6_port;
+    } else {
+#endif
+        inaddr=&((struct sockaddr_in*)ep)->sin_addr;
+        port=((struct sockaddr_in*)ep)->sin_port;
+#if defined(AF_INET6)
     }
 #endif
-    
-    inet_ntop(ep->sa_family,inaddr,addrstr,sizeof(addrstr)-1);
+    inet_ntop(ep->ss_family,inaddr,addrstr,sizeof(addrstr)-1);
     sprintf(buf,"%s:%d",addrstr,ntohs(port));
     return buf;
 }