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