You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@zookeeper.apache.org by "Patrick Hunt (JIRA)" <ji...@apache.org> on 2008/10/27 07:48:44 UTC

[jira] Assigned: (ZOOKEEPER-208) Zookeeper C client uses API that are not thread safe, causing crashes when multiple instances are active

     [ https://issues.apache.org/jira/browse/ZOOKEEPER-208?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Patrick Hunt reassigned ZOOKEEPER-208:
--------------------------------------

    Assignee: Austin Shoemaker

> Zookeeper C client uses API that are not thread safe, causing crashes when multiple instances are active
> --------------------------------------------------------------------------------------------------------
>
>                 Key: ZOOKEEPER-208
>                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-208
>             Project: Zookeeper
>          Issue Type: Bug
>          Components: c client
>    Affects Versions: 3.0.0
>         Environment: Linux
>            Reporter: Austin Shoemaker
>            Assignee: Austin Shoemaker
>            Priority: Critical
>             Fix For: 3.1.0
>
>
> The Zookeeper C client library uses gethostbyname and strtok, both of which are not safe to use from multiple threads. Below is the original patch we made which fixes the problem.
> The problem is resolved by using getaddrinfo and strtok_r in place of the older API.
> Patch for zookeeper-c-client-2.2.1/src/zookeeper.c (2008-06-09 on SF.net)
> 241c241
> <     struct hostent *he;
> ---
> > 	struct addrinfo hints, *res, *res0;
> 243,245d242
> <     struct sockaddr_in *addr4;
> <     struct sockaddr_in6 *addr6;
> <     char **ptr;
> 247a245
> > 	char *strtok_last;
> 263c261
> <     host=strtok(hosts, ",");
> ---
> >     host=strtok_r(hosts, ",", &strtok_last);
> 283,294c281,297
> <         he = gethostbyname(host);
> <         if (!he) {
> <             LOG_ERROR(("could not resolve %s", host));
> <             errno=EINVAL;
> <             rc=ZBADARGUMENTS;
> <             goto fail;
> <         }
> <
> <         /* Setup the address array */
> <         for(ptr = he->h_addr_list;*ptr != 0; ptr++) {
> <             if (zh->addrs_count == alen) {
> <                 void *tmpaddr;
> ---
> > 		
> > 		memset(&hints, 0, sizeof(hints));
> > 		hints.ai_flags = AI_ADDRCONFIG;
> > 		hints.ai_family = AF_UNSPEC;
> > 		hints.ai_socktype = SOCK_STREAM;
> > 		hints.ai_protocol = IPPROTO_TCP;
> >
> > 		if (getaddrinfo(host, port_spec, &hints, &res0) != 0) {
> > 			LOG_ERROR(("getaddrinfo: %s\n", strerror(errno)));
> > 			rc=ZSYSTEMERROR;
> > 			goto fail;
> > 		}
> > 		
> > 		for (res = res0; res; res = res->ai_next) {
> > 			// Expand address list if needed
> > 			if (zh->addrs_count == alen) {
> > 				void *tmpaddr;
> 304,313c307,312
> <             }
> <             addr = &zh->addrs[zh->addrs_count];
> <             addr4 = (struct sockaddr_in*)addr;
> <             addr6 = (struct sockaddr_in6*)addr;
> <             addr->sa_family = he->h_addrtype;
> <             if (addr->sa_family == AF_INET) {
> <                 addr4->sin_port = htons(port);
> <                 memset(&addr4->sin_zero, 0, sizeof(addr4->sin_zero));
> <                 memcpy(&addr4->sin_addr, *ptr, he->h_length);
> <                 zh->addrs_count++;
> ---
> > 			}
> > 			
> > 			// Copy addrinfo into address list
> > 			addr = &zh->addrs[zh->addrs_count];
> > 			switch (res->ai_family) {
> > 			case AF_INET:
> 315,320c314
> <             } else if (addr->sa_family == AF_INET6) {
> <                 addr6->sin6_port = htons(port);
> <                 addr6->sin6_scope_id = 0;
> <                 addr6->sin6_flowinfo = 0;
> <                 memcpy(&addr6->sin6_addr, *ptr, he->h_length);
> <                 zh->addrs_count++;
> ---
> > 			case AF_INET6:
> 322,327c316,328
> <             } else {
> <                 LOG_WARN(("skipping unknown address family %x for %s",
> <                         addr->sa_family, zh->hostname));
> <             }
> <         }
> <         host = strtok(0, ",");
> ---
> > 				memcpy(addr, res->ai_addr, res->ai_addrlen);
> > 				++zh->addrs_count;
> > 				break;
> > 			default:
> > 				LOG_WARN(("skipping unknown address family %x for %s",
> > 					res->ai_family, zh->hostname));
> > 				break;
> > 			}
> > 		}
> > 		
> > 		freeaddrinfo(res0);
> >
> > 		host = strtok_r(0, ",", &strtok_last);
> 329a331
> >

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.