append the interface index instead of throwing an exception when the scope id lookup...
authorEli Lindsey <elindsey@fb.com>
Wed, 19 Jul 2017 15:51:26 +0000 (08:51 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Wed, 19 Jul 2017 16:12:07 +0000 (09:12 -0700)
Summary: As written, this str() method depends on the current state of the host - if an interface disappears (as is commong with eg. mobile, ipsec, etc.) then attempting to generate a string representation of this v6 address will currently throw an exception. Instead, we're going toignore the lookup failure and append the index i; this form is interchangeable, though slightly less legible.

Reviewed By: yfeldblum

Differential Revision: D5443618

fbshipit-source-id: bbd3b4edaee8098671140af7400377d5e2b1937b

folly/IPAddressV6.cpp
folly/test/IPAddressTest.cpp

index 3490669dcbdd72db0cf2484c24e3e6708c045970..cff206f3cc1d7b0a891af2708985229a0a1401de 100644 (file)
@@ -432,17 +432,14 @@ string IPAddressV6::str() const {
   if (scopeId != 0) {
     auto len = strlen(buffer);
     buffer[len] = '%';
+
+    auto errsv = errno;
     if (!if_indextoname(scopeId, buffer + len + 1)) {
-      throw IPAddressFormatException(to<std::string>(
-          "Invalid scope for address with hex ",
-          "'",
-          detail::Bytes::toHex(bytes(), 16),
-          "%",
-          scopeId,
-          "'",
-          " with error ",
-          strerror(errno)));
+      // if we can't map the if because eg. it no longer exists,
+      // append the if index instead
+      snprintf(buffer + len + 1, IFNAMSIZ, "%u", scopeId);
     }
+    errno = errsv;
   }
 
   return string(buffer);
index f41bb8fd67e816f60645a59c3db495fabe17706c..2f93e466313874607d9b21eb39771d83806f0a2f 100644 (file)
@@ -72,6 +72,25 @@ TEST(IPAddress, Scope) {
   EXPECT_TRUE(a2 < a1);
 }
 
+TEST(IPAddress, ScopeNumeric) {
+  // it's very unlikely that the host running these
+  // tests will have 42 network interfaces
+  auto str = "fe80::62eb:69ff:fe9b:ba60%42";
+  IPAddressV6 a2(str);
+  EXPECT_EQ(str, a2.str());
+
+  sockaddr_in6 sock = a2.toSockAddr();
+  EXPECT_NE(0, sock.sin6_scope_id);
+
+  IPAddress a1(str);
+  EXPECT_EQ(str, a1.str());
+
+  a2.setScopeId(0);
+  EXPECT_NE(a1, a2);
+
+  EXPECT_TRUE(a2 < a1);
+}
+
 TEST(IPAddress, Ordering) {
   IPAddress a1("0.1.1.1");
   IPAddress a2("1.1.1.0");