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

Chris Darroch updated ZOOKEEPER-208:
------------------------------------

    Attachment: zookeeper-strtok_getaddrinfo-trunk.patch

I've reformatted the original submitter's normal patch as a unified diff file 
to use against 3.0.0 and SVN trunk (at the moment).

I won't grant a license for it, though, since I didn't do the original work.

Hopefully this saves the submitter a little work.  If they can just sign off on 
this file, they shouldn't need to deal with any other details.

> 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
>
>         Attachments: zookeeper-strtok_getaddrinfo-trunk.patch
>
>
> 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.

Reply via email to