commit 4baa578f2b7552ed44482b32fb18dc4bbb53f538
Author: githublvv <ymaillvv@yahoo.com>
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;
}