]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
msgr: parse ipv6 addresses without []'s
authorSage Weil <sage.weil@dreamhost.com>
Sat, 17 Sep 2011 04:59:46 +0000 (21:59 -0700)
committerSage Weil <sage.weil@dreamhost.com>
Sat, 17 Sep 2011 04:59:46 +0000 (21:59 -0700)
inet_pton() is annoying.  Be less lazy and work around it.

Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
src/include/addr_parsing.c
src/msg/msg_types.cc

index ce7fef10b656ee7d2a59ddefaac3f7b27094b1fc..738fd1c709b9a9ba023381f522587ca80767b929 100644 (file)
@@ -71,7 +71,7 @@ char *resolve_addrs(const char *orig_str)
       *firstcolon = 0;
       port_str = firstcolon + 1;
     } else if (bracecolon) {
-      /* {ipv6addr}:port */
+      /* [ipv6addr]:port */
       port_str = bracecolon + 1;
       *port_str = 0;
       port_str++;
index 14865d2fc793dffa59e8cc33adb9b3878a370d1f..7e361d5afc259eca9be12407574c623fd7db85bc 100644 (file)
@@ -9,42 +9,53 @@ bool entity_addr_t::parse(const char *s, const char **end)
 {
   memset(this, 0, sizeof(*this));
 
-  const char *p = s;
+  const char *start = s;
   bool brackets = false;
   bool ipv6 = false;
-  if (*p == '[') {
-    p++;
+  if (*start == '[') {
+    start++;
     brackets = true;
     ipv6 = true;
   }
   
-  char buf[39];
-  char *o = buf;
-
-  while (o < buf + sizeof(buf) &&
+  // inet_pton() requires a null terminated input, so let's fill two
+  // buffers, one with ipv4 allowed characters, and one with ipv6, and
+  // then see which parses.
+  char buf4[39];
+  char *o = buf4;
+  const char *p = start;
+  while (o < buf4 + sizeof(buf4) &&
         *p && ((*p == '.') ||
-               (ipv6 && *p == ':') ||
+               (*p >= '0' && *p <= '9'))) {
+    *o++ = *p++;
+  }
+  *o = 0;
+
+  char buf6[39];
+  o = buf6;
+  p = start;
+  while (o < buf6 + sizeof(buf6) &&
+        *p && ((*p == ':') ||
                (*p >= '0' && *p <= '9') ||
                (*p >= 'a' && *p <= 'f') ||
                (*p >= 'A' && *p <= 'F'))) {
-    if (*p == ':')
-      ipv6 = true;
     *o++ = *p++;
   }
   *o = 0;
-  //cout << "buf is '" << buf << "'" << std::endl;
+  //cout << "buf4 is '" << buf4 << "', buf6 is '" << buf6 << "'" << std::endl;
 
   // ipv4?
   struct in_addr a4;
   struct in6_addr a6;
-  if (inet_pton(AF_INET, buf, &a4)) {
+  if (inet_pton(AF_INET, buf4, &a4)) {
     addr4.sin_addr.s_addr = a4.s_addr;
     addr.ss_family = AF_INET;
-  } else if (inet_pton(AF_INET6, buf, &a6)) {
+    p = start + strlen(buf4);
+  } else if (inet_pton(AF_INET6, buf6, &a6)) {
     addr.ss_family = AF_INET6;
     memcpy(&addr6.sin6_addr, &a6, sizeof(a6));
+    p = start + strlen(buf6);
   } else {
-    //cout << "couldn't parse '" << buf << "'" << std::endl;
     return false;
   }
 
@@ -75,5 +86,7 @@ bool entity_addr_t::parse(const char *s, const char **end)
 
   if (end)
     *end = p;
+
+  //cout << *this << std::endl;
   return true;
 }