commit 4baa578f2b7552ed44482b32fb18dc4bbb53f538 Author: githublvv Date: Fri Jan 9 18:15:36 2015 -0500 Fix for 310: memcached unable to bind to an ipv6 address URL: https://code.google.com/p/memcached/issues/detail?id=310 diff --git a/memcached.c b/memcached.c index 154b15a..1181966 100644 --- a/memcached.c +++ b/memcached.c @@ -4614,15 +4614,40 @@ static int server_sockets(int port, enum network_transport transport, p != NULL; p = strtok_r(NULL, ";,", &b)) { int the_port = port; + + char *h = NULL; + if (*p == '[') { + // expecting it to be an IPv6 address enclosed in [] + // i.e. RFC3986 style recommended by RFC5952 + char *e = strchr(p, ']'); + if (e == NULL) { + fprintf(stderr, "Invalid IPV6 address: \"%s\"", p); + return 1; + } + h = ++p; // skip the opening '[' + *e = '\0'; + p = ++e; // skip the closing ']' + } + char *s = strchr(p, ':'); if (s != NULL) { - *s = '\0'; - ++s; - if (!safe_strtol(s, &the_port)) { - fprintf(stderr, "Invalid port number: \"%s\"", s); - return 1; + // If no more semicolons - attempt to treat as port number. + // Otherwise the only valid option is an unenclosed IPv6 without port, until + // of course there was an RFC3986 IPv6 address previously specified - + // in such a case there is no good option, will just send it to fail as port number. + if (strchr(s + 1, ':') == NULL || h != NULL) { + *s = '\0'; + ++s; + if (!safe_strtol(s, &the_port)) { + fprintf(stderr, "Invalid port number: \"%s\"", s); + return 1; + } } } + + if (h != NULL) + p = h; + if (strcmp(p, "*") == 0) { p = NULL; }