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
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);
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");