util: don't resolve valid IP addresses when doing FaceUri canonization
refs #4095
Change-Id: Ide7835438268aa3219540d8b2ea4143355f6f8a0
diff --git a/src/util/face-uri.cpp b/src/util/face-uri.cpp
index 83ad2eb..d1a26df 100644
--- a/src/util/face-uri.cpp
+++ b/src/util/face-uri.cpp
@@ -282,24 +282,37 @@
return;
}
- dns::AddressSelector addressSelector;
- if (faceUri.getScheme() == m_v4Scheme) {
- addressSelector = dns::Ipv4Only();
- }
- else if (faceUri.getScheme() == m_v6Scheme) {
- addressSelector = dns::Ipv6Only();
- }
- else {
- BOOST_ASSERT(faceUri.getScheme() == m_baseScheme);
- addressSelector = dns::AnyAddress();
- }
-
// make a copy because caller may modify faceUri
auto uri = make_shared<FaceUri>(faceUri);
- dns::asyncResolve(faceUri.getHost(),
- bind(&IpHostCanonizeProvider<Protocol>::onDnsSuccess, this, uri, onSuccess, onFailure, _1),
- bind(&IpHostCanonizeProvider<Protocol>::onDnsFailure, this, uri, onFailure, _1),
- io, addressSelector, timeout);
+ boost::system::error_code ec;
+ auto ipAddress = boost::asio::ip::address::from_string(faceUri.getHost(), ec);
+ if (!ec) {
+ // No need to resolve IP address if host is already an IP
+ if ((faceUri.getScheme() == m_v4Scheme && !ipAddress.is_v4()) ||
+ (faceUri.getScheme() == m_v6Scheme && !ipAddress.is_v6())) {
+ return onFailure("IPv4/v6 mismatch");
+ }
+
+ onDnsSuccess(uri, onSuccess, onFailure, ipAddress);
+ }
+ else {
+ dns::AddressSelector addressSelector;
+ if (faceUri.getScheme() == m_v4Scheme) {
+ addressSelector = dns::Ipv4Only();
+ }
+ else if (faceUri.getScheme() == m_v6Scheme) {
+ addressSelector = dns::Ipv6Only();
+ }
+ else {
+ BOOST_ASSERT(faceUri.getScheme() == m_baseScheme);
+ addressSelector = dns::AnyAddress();
+ }
+
+ dns::asyncResolve(faceUri.getHost(),
+ bind(&IpHostCanonizeProvider<Protocol>::onDnsSuccess, this, uri, onSuccess, onFailure, _1),
+ bind(&IpHostCanonizeProvider<Protocol>::onDnsFailure, this, uri, onFailure, _1),
+ io, addressSelector, timeout);
+ }
}
protected:
diff --git a/tests/unit-tests/util/face-uri.t.cpp b/tests/unit-tests/util/face-uri.t.cpp
index 0b9a61a..559a5b0 100644
--- a/tests/unit-tests/util/face-uri.t.cpp
+++ b/tests/unit-tests/util/face-uri.t.cpp
@@ -181,10 +181,13 @@
BOOST_CHECK_EQUAL(FaceUri("udp4://192.0.2.1:6363/").isCanonical(), false);
BOOST_CHECK_EQUAL(FaceUri("udp6://[2001:db8::1]:6363").isCanonical(), true);
BOOST_CHECK_EQUAL(FaceUri("udp6://[2001:db8::01]:6363").isCanonical(), false);
+ BOOST_CHECK_EQUAL(FaceUri("udp://[2001:db8::1]:6363").isCanonical(), false);
BOOST_CHECK_EQUAL(FaceUri("udp://example.net:6363").isCanonical(), false);
BOOST_CHECK_EQUAL(FaceUri("udp4://example.net:6363").isCanonical(), false);
BOOST_CHECK_EQUAL(FaceUri("udp6://example.net:6363").isCanonical(), false);
BOOST_CHECK_EQUAL(FaceUri("udp4://224.0.23.170:56363").isCanonical(), true);
+ BOOST_CHECK_EQUAL(FaceUri("udp4://[2001:db8::1]:6363").isCanonical(), false);
+ BOOST_CHECK_EQUAL(FaceUri("udp6://192.0.2.1:6363").isCanonical(), false);
}
BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(CanonizeUdpV4, 1)
@@ -209,6 +212,9 @@
addTest("udp4://224.0.23.170", true, "udp4://224.0.23.170:56363");
addTest("udp4://all-routers.mcast.net:56363", true, "udp4://224.0.0.2:56363");
+ // IPv6 used with udp4 protocol - not canonical
+ addTest("udp4://[2001:db8::1]:6363", false, "");
+
runTests();
}
@@ -233,6 +239,9 @@
addTest("udp6://[ff02::2]:56363", true, "udp6://[ff02::2]:56363");
addTest("udp6://[ff02::2]", true, "udp6://[ff02::2]:56363");
+ // IPv4 used with udp6 protocol - not canonical
+ addTest("udp6://192.0.2.1:6363", false, "");
+
runTests();
}
@@ -275,10 +284,13 @@
BOOST_CHECK_EQUAL(FaceUri("tcp4://192.0.2.1:6363/").isCanonical(), false);
BOOST_CHECK_EQUAL(FaceUri("tcp6://[2001:db8::1]:6363").isCanonical(), true);
BOOST_CHECK_EQUAL(FaceUri("tcp6://[2001:db8::01]:6363").isCanonical(), false);
+ BOOST_CHECK_EQUAL(FaceUri("tcp://[2001:db8::1]:6363").isCanonical(), false);
BOOST_CHECK_EQUAL(FaceUri("tcp://example.net:6363").isCanonical(), false);
BOOST_CHECK_EQUAL(FaceUri("tcp4://example.net:6363").isCanonical(), false);
BOOST_CHECK_EQUAL(FaceUri("tcp6://example.net:6363").isCanonical(), false);
BOOST_CHECK_EQUAL(FaceUri("tcp4://224.0.23.170:56363").isCanonical(), false);
+ BOOST_CHECK_EQUAL(FaceUri("tcp4://[2001:db8::1]:6363").isCanonical(), false);
+ BOOST_CHECK_EQUAL(FaceUri("tcp6://192.0.2.1:6363").isCanonical(), false);
}
BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(CanonizeTcpV4, 1)
@@ -303,6 +315,9 @@
addTest("tcp4://224.0.23.170", false, "");
addTest("tcp4://all-routers.mcast.net:56363", false, "");
+ // IPv6 used with tcp4 protocol - not canonical
+ addTest("tcp4://[2001:db8::1]:6363", false, "");
+
runTests();
}
@@ -327,6 +342,9 @@
addTest("tcp6://[ff02::2]:56363", false, "");
addTest("tcp6://[ff02::2]", false, "");
+ // IPv4 used with tcp6 protocol - not canonical
+ addTest("tcp6://192.0.2.1:6363", false, "");
+
runTests();
}