Skip to content

Commit 6becd01

Browse files
authored
mobile: Filter reserved IP address ranges in IPv6 probing (envoyproxy#40345)
IPv6 probing will now filter out: * Link-local IP addresses * Site-local IPv6 addresses * Unique Local IPv6 addresses * Teredo addresses This is the same as Chromium's logic for IPv6 connectivity probing: https://source.chromium.org/chromium/chromium/src/+/main:net/dns/host_resolver_manager.cc;l=1572-1581;drc=d0260a368e65b2be56d179d21fab90976fd494b8. Though it doesn't seem like Chromium filters out site-local addresses, local testing has shown that the IPv6 probe socket will successfully connect but the local address will be site-local on non-IPv6 networks/machines. --------- Signed-off-by: Ali Beyad <abeyad@google.com>
1 parent 92762ea commit 6becd01

File tree

1 file changed

+36
-14
lines changed

1 file changed

+36
-14
lines changed

mobile/library/common/internal_engine.cc

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ MobileProcessWide& initOnceMobileProcessWide(const OptionsImplBase& options) {
2727

2828
Network::Address::InstanceConstSharedPtr ipv6ProbeAddr() {
2929
// Use Google DNS IPv6 address for IPv6 probes.
30+
// Same as Chromium:
31+
// https://source.chromium.org/chromium/chromium/src/+/main:net/dns/host_resolver_manager.cc;l=155;drc=7b232da0f22e8cdf555d43c52b6491baeb87f729.
3032
CONSTRUCT_ON_FIRST_USE(Network::Address::InstanceConstSharedPtr,
3133
new Network::Address::Ipv6Instance("2001:4860:4860::8888", 53));
3234
}
@@ -545,9 +547,6 @@ void InternalEngine::logInterfaces(absl::string_view event,
545547

546548
Network::Address::InstanceConstSharedPtr InternalEngine::probeAndGetLocalAddr(int domain) {
547549
// This probing logic is borrowed from Chromium.
548-
// -
549-
// https://source.chromium.org/chromium/chromium/src/+/main:net/dns/host_resolver_manager.cc;l=154-157;drc=7b232da0f22e8cdf555d43c52b6491baeb87f729
550-
// -
551550
// https://source.chromium.org/chromium/chromium/src/+/main:net/dns/host_resolver_manager.cc;l=1467-1488;drc=7b232da0f22e8cdf555d43c52b6491baeb87f729
552551
ENVOY_LOG(trace, "Checking for {} connectivity.", domain == AF_INET6 ? "IPv6" : "IPv4");
553552
const Api::SysCallSocketResult socket_result =
@@ -560,18 +559,41 @@ Network::Address::InstanceConstSharedPtr InternalEngine::probeAndGetLocalAddr(in
560559
/* socket_v6only= */ domain == AF_INET6, {domain});
561560
Api::SysCallIntResult connect_result =
562561
socket_handle.connect(domain == AF_INET6 ? ipv6ProbeAddr() : ipv4ProbeAddr());
563-
if (connect_result.return_value_ == 0) {
564-
auto address_or_error = socket_handle.localAddress();
565-
if (!address_or_error.status().ok()) {
566-
ENVOY_LOG(trace, "Local address error: {}", address_or_error.status().message());
567-
return nullptr;
568-
}
569-
ENVOY_LOG(trace, "Found {} connectivity.", domain == AF_INET6 ? "IPv6" : "IPv4");
570-
return *address_or_error;
562+
if (connect_result.return_value_ != 0) {
563+
ENVOY_LOG(trace, "No {} connectivity found with errno: {}.",
564+
domain == AF_INET6 ? "IPv6" : "IPv4", connect_result.errno_);
565+
return nullptr;
566+
}
567+
568+
absl::StatusOr<Network::Address::InstanceConstSharedPtr> address = socket_handle.localAddress();
569+
if (!address.status().ok()) {
570+
ENVOY_LOG(trace, "Local address error: {}", address.status().message());
571+
return nullptr;
571572
}
572-
ENVOY_LOG(trace, "No {} connectivity found with errno: {}.", domain == AF_INET6 ? "IPv6" : "IPv4",
573-
connect_result.errno_);
574-
return nullptr;
573+
574+
if ((*address)->ip() == nullptr) {
575+
ENVOY_LOG(trace, "Local address is not an IP address: {}.", (*address)->asString());
576+
return nullptr;
577+
}
578+
if ((*address)->ip()->isLinkLocalAddress()) {
579+
ENVOY_LOG(trace, "Ignoring link-local address: {}.", (*address)->asString());
580+
return nullptr;
581+
}
582+
if ((*address)->ip()->isUniqueLocalAddress()) {
583+
ENVOY_LOG(trace, "Ignoring unique-local address: {}.", (*address)->asString());
584+
return nullptr;
585+
}
586+
if ((*address)->ip()->isSiteLocalAddress()) {
587+
ENVOY_LOG(trace, "Ignoring site-local address: {}.", (*address)->asString());
588+
return nullptr;
589+
}
590+
if ((*address)->ip()->isTeredoAddress()) {
591+
ENVOY_LOG(trace, "Ignoring teredo address: {}.", (*address)->asString());
592+
return nullptr;
593+
}
594+
595+
ENVOY_LOG(trace, "Found {} connectivity.", domain == AF_INET6 ? "IPv6" : "IPv4");
596+
return *address;
575597
}
576598

577599
} // namespace Envoy

0 commit comments

Comments
 (0)