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.