Skip to content

Commit

Permalink
Remove scope id from ipv6 address in getLocalAddress (#25414)
Browse files Browse the repository at this point in the history
Commit Message: Remove scope id from ipv6 address in getLocalAddress
Additional Description: This fixes the issue where Envoy-mobile fails to send out any packet on ipv6.
Risk Level: Low
Testing: unit tests
Docs Changes: n/a
Release Notes: n/a
Platform Specific Features: n/a
Fixes #25326

Signed-off-by: Renjie Tang <renjietang@google.com>
  • Loading branch information
RenjieTang authored Feb 8, 2023
1 parent b7a5f87 commit 79acebd
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 0 deletions.
6 changes: 6 additions & 0 deletions envoy/network/address.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ class Ipv6 {
* if the Ipv6 address isn't Ipv4 mapped.
*/
virtual InstanceConstSharedPtr v4CompatibleAddress() const PURE;

/**
* @return Ipv6 address that has no scope/zone identifier. Return `nullptr`
* if the conversion failed.
*/
virtual InstanceConstSharedPtr addressWithoutScopeId() const PURE;
};

enum class IpVersion { v4, v6 }; // NOLINT(readability-identifier-naming)
Expand Down
7 changes: 7 additions & 0 deletions source/common/network/address_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,13 @@ InstanceConstSharedPtr Ipv6Instance::Ipv6Helper::v4CompatibleAddress() const {
return nullptr;
}

InstanceConstSharedPtr Ipv6Instance::Ipv6Helper::addressWithoutScopeId() const {
struct sockaddr_in6 ret_addr = address_;
ret_addr.sin6_scope_id = 0;
auto addr = Address::InstanceFactory::createInstancePtr<Address::Ipv6Instance>(ret_addr, v6only_);
return addr.ok() ? addr.value() : nullptr;
}

Ipv6Instance::Ipv6Instance(const sockaddr_in6& address, bool v6only,
const SocketInterface* sock_interface)
: InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
Expand Down
1 change: 1 addition & 0 deletions source/common/network/address_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ class Ipv6Instance : public InstanceBase {
uint32_t scopeId() const override;
uint32_t port() const;
InstanceConstSharedPtr v4CompatibleAddress() const override;
InstanceConstSharedPtr addressWithoutScopeId() const override;

std::string makeFriendlyAddress() const;

Expand Down
3 changes: 3 additions & 0 deletions source/common/network/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ Address::InstanceConstSharedPtr Utility::getLocalAddress(const Address::IpVersio
if (!isLoopbackAddress(*interface_address.interface_addr_) &&
interface_address.interface_addr_->ip()->version() == version) {
ret = interface_address.interface_addr_;
if (ret->ip()->version() == Address::IpVersion::v6) {
ret = ret->ip()->ipv6()->addressWithoutScopeId();
}
break;
}
}
Expand Down
18 changes: 18 additions & 0 deletions test/common/network/address_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,24 @@ TEST(Ipv6InstanceTest, AddressAndPort) {
EXPECT_TRUE(address.ip()->isUnicastAddress());
}

TEST(Ipv6InstanceTest, ScopeIdStripping) {
sockaddr_in6 addr6;
memset(&addr6, 0, sizeof(addr6));
addr6.sin6_family = AF_INET6;
EXPECT_EQ(1, inet_pton(AF_INET6, "fe80::f8f3:11ff:fef4:25a8", &addr6.sin6_addr));
addr6.sin6_port = htons(80);
addr6.sin6_scope_id = 20u;

Ipv6Instance address(addr6);
EXPECT_EQ("[fe80::f8f3:11ff:fef4:25a8%20]:80", address.asString());
EXPECT_EQ(IpVersion::v6, address.ip()->version());
EXPECT_EQ(20U, address.ip()->ipv6()->scopeId());
auto no_scope_address = address.ip()->ipv6()->addressWithoutScopeId();
EXPECT_EQ("[fe80::f8f3:11ff:fef4:25a8]:80", no_scope_address->asString());
EXPECT_EQ(IpVersion::v6, no_scope_address->ip()->version());
EXPECT_EQ(0U, no_scope_address->ip()->ipv6()->scopeId());
}

TEST(Ipv6InstanceTest, PortOnly) {
Ipv6Instance address(443);
EXPECT_EQ("[::]:443", address.asString());
Expand Down
3 changes: 3 additions & 0 deletions test/common/network/utility_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,9 @@ TEST_P(NetworkUtilityGetLocalAddress, GetLocalAddress) {
auto local_address = Utility::getLocalAddress(ip_version);
EXPECT_NE(nullptr, local_address);
EXPECT_EQ(ip_version, local_address->ip()->version());
if (ip_version == Address::IpVersion::v6) {
EXPECT_EQ(0u, local_address->ip()->ipv6()->scopeId());
}
}

TEST(NetworkUtility, GetOriginalDst) {
Expand Down

0 comments on commit 79acebd

Please sign in to comment.