Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions source/common/network/addr_family_aware_socket_option_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,24 @@ namespace Envoy {
namespace Network {

namespace {
Address::IpVersion getVersionFromAddress(Address::InstanceConstSharedPtr addr) {
if (addr->ip() != nullptr) {
return addr->ip()->version();
}
throw EnvoyException("Unable to set socket option on non-IP sockets");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this method throw a more generic EnvoyException, followed by setOption throwing this one?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is caught in getVersionFromSocket() and converted to a nullopt return.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just felt that the exception message didn't match the function's operation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, technically it doesn't, but I don't think it's a big deal given the hyper local use here.

}

absl::optional<Address::IpVersion> getVersionFromSocket(const Socket& socket) {
try {
// We have local address when the socket is used in a listener but have to
// infer the IP from the socket FD when initiating connections.
// TODO(htuch): Figure out a way to obtain a consistent interface for IP
// version from socket.
if (socket.localAddress()) {
return absl::optional<Address::IpVersion>(socket.localAddress()->ip()->version());
return absl::optional<Address::IpVersion>(getVersionFromAddress(socket.localAddress()));
} else {
return absl::optional<Address::IpVersion>(
Address::addressFromFd(socket.ioHandle().fd())->ip()->version());
getVersionFromAddress(Address::addressFromFd(socket.ioHandle().fd())));
}
} catch (const EnvoyException&) {
// Ignore, we get here because we failed in getsockname().
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ TEST_F(AddrFamilyAwareSocketOptionImplTest, SetOptionFailure) {
EXPECT_LOG_CONTAINS("warning", "Failed to set IP socket option on non-IP socket",
EXPECT_FALSE(socket_option.setOption(
socket_, envoy::api::v2::core::SocketOption::STATE_PREBIND)));

Address::InstanceConstSharedPtr pipe_address =
std::make_shared<Network::Address::PipeInstance>("/foo");
{
EXPECT_CALL(socket_, localAddress).WillRepeatedly(testing::ReturnRef(pipe_address));
EXPECT_LOG_CONTAINS("warning", "Failed to set IP socket option on non-IP socket",
EXPECT_FALSE(socket_option.setOption(
socket_, envoy::api::v2::core::SocketOption::STATE_PREBIND)));
}
}

// If a platform supports IPv4 socket option variant for an IPv4 address, it works
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
static_resources {
listeners {
address {
pipe {
}
}
filter_chains {
}
freebind {
}
}
}