Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

network: address socket interface pointer instead of name #12550

Merged
merged 5 commits into from
Aug 12, 2020
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
8 changes: 6 additions & 2 deletions include/envoy/network/address.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

namespace Envoy {
namespace Network {

/* Forward declaration */
class SocketInterface;

namespace Address {

/**
Expand Down Expand Up @@ -178,9 +182,9 @@ class Instance {
virtual Type type() const PURE;

/**
* @return name of socket interface that should be used with this address
* @return SocketInterface to be used with the address
*/
virtual const std::string& socketInterface() const PURE;
virtual const Network::SocketInterface& socketInterface() const PURE;
};

using InstanceConstSharedPtr = std::shared_ptr<const Instance>;
Expand Down
44 changes: 24 additions & 20 deletions source/common/network/address_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ std::string friendlyNameFromAbstractPath(absl::string_view path) {
return friendly_name;
}

const SocketInterface* sockInterfaceOrDefault(const SocketInterface* sock_interface) {
return sock_interface == nullptr ? &SocketInterfaceSingleton::get() : sock_interface;
}

} // namespace

Address::InstanceConstSharedPtr addressFromSockAddr(const sockaddr_storage& ss, socklen_t ss_len,
Expand Down Expand Up @@ -91,8 +95,8 @@ Address::InstanceConstSharedPtr addressFromSockAddr(const sockaddr_storage& ss,
NOT_REACHED_GCOVR_EXCL_LINE;
}

Ipv4Instance::Ipv4Instance(const sockaddr_in* address, absl::string_view sock_interface)
: InstanceBase(Type::Ip, sock_interface) {
Ipv4Instance::Ipv4Instance(const sockaddr_in* address, const SocketInterface* sock_interface)
: InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
memset(&ip_.ipv4_.address_, 0, sizeof(ip_.ipv4_.address_));
ip_.ipv4_.address_ = *address;
ip_.friendly_address_ = sockaddrToString(*address);
Expand All @@ -106,12 +110,12 @@ Ipv4Instance::Ipv4Instance(const sockaddr_in* address, absl::string_view sock_in
validateIpv4Supported(friendly_name_);
}

Ipv4Instance::Ipv4Instance(const std::string& address, absl::string_view sock_interface)
: Ipv4Instance(address, 0, sock_interface) {}
Ipv4Instance::Ipv4Instance(const std::string& address, const SocketInterface* sock_interface)
: Ipv4Instance(address, 0, sockInterfaceOrDefault(sock_interface)) {}

Ipv4Instance::Ipv4Instance(const std::string& address, uint32_t port,
absl::string_view sock_interface)
: InstanceBase(Type::Ip, sock_interface) {
const SocketInterface* sock_interface)
: InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
memset(&ip_.ipv4_.address_, 0, sizeof(ip_.ipv4_.address_));
ip_.ipv4_.address_.sin_family = AF_INET;
ip_.ipv4_.address_.sin_port = htons(port);
Expand All @@ -125,8 +129,8 @@ Ipv4Instance::Ipv4Instance(const std::string& address, uint32_t port,
ip_.friendly_address_ = address;
}

Ipv4Instance::Ipv4Instance(uint32_t port, absl::string_view sock_interface)
: InstanceBase(Type::Ip, sock_interface) {
Ipv4Instance::Ipv4Instance(uint32_t port, const SocketInterface* sock_interface)
: InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
memset(&ip_.ipv4_.address_, 0, sizeof(ip_.ipv4_.address_));
ip_.ipv4_.address_.sin_family = AF_INET;
ip_.ipv4_.address_.sin_port = htons(port);
Expand Down Expand Up @@ -188,21 +192,21 @@ std::string Ipv6Instance::Ipv6Helper::makeFriendlyAddress() const {
}

Ipv6Instance::Ipv6Instance(const sockaddr_in6& address, bool v6only,
absl::string_view sock_interface)
: InstanceBase(Type::Ip, sock_interface) {
const SocketInterface* sock_interface)
: InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
ip_.ipv6_.address_ = address;
ip_.friendly_address_ = ip_.ipv6_.makeFriendlyAddress();
ip_.ipv6_.v6only_ = v6only;
friendly_name_ = fmt::format("[{}]:{}", ip_.friendly_address_, ip_.port());
validateIpv6Supported(friendly_name_);
}

Ipv6Instance::Ipv6Instance(const std::string& address, absl::string_view sock_interface)
: Ipv6Instance(address, 0, sock_interface) {}
Ipv6Instance::Ipv6Instance(const std::string& address, const SocketInterface* sock_interface)
: Ipv6Instance(address, 0, sockInterfaceOrDefault(sock_interface)) {}

Ipv6Instance::Ipv6Instance(const std::string& address, uint32_t port,
absl::string_view sock_interface)
: InstanceBase(Type::Ip, sock_interface) {
const SocketInterface* sock_interface)
: InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
ip_.ipv6_.address_.sin6_family = AF_INET6;
ip_.ipv6_.address_.sin6_port = htons(port);
if (!address.empty()) {
Expand All @@ -218,8 +222,8 @@ Ipv6Instance::Ipv6Instance(const std::string& address, uint32_t port,
validateIpv6Supported(friendly_name_);
}

Ipv6Instance::Ipv6Instance(uint32_t port, absl::string_view sock_interface)
: Ipv6Instance("", port, sock_interface) {}
Ipv6Instance::Ipv6Instance(uint32_t port, const SocketInterface* sock_interface)
: Ipv6Instance("", port, sockInterfaceOrDefault(sock_interface)) {}

bool Ipv6Instance::operator==(const Instance& rhs) const {
const auto* rhs_casted = dynamic_cast<const Ipv6Instance*>(&rhs);
Expand All @@ -228,8 +232,8 @@ bool Ipv6Instance::operator==(const Instance& rhs) const {
}

PipeInstance::PipeInstance(const sockaddr_un* address, socklen_t ss_len, mode_t mode,
absl::string_view sock_interface)
: InstanceBase(Type::Pipe, sock_interface) {
const SocketInterface* sock_interface)
: InstanceBase(Type::Pipe, sockInterfaceOrDefault(sock_interface)) {
if (address->sun_path[0] == '\0') {
#if !defined(__linux__)
throw EnvoyException("Abstract AF_UNIX sockets are only supported on linux.");
Expand All @@ -254,8 +258,8 @@ PipeInstance::PipeInstance(const sockaddr_un* address, socklen_t ss_len, mode_t
}

PipeInstance::PipeInstance(const std::string& pipe_path, mode_t mode,
absl::string_view sock_interface)
: InstanceBase(Type::Pipe, sock_interface) {
const SocketInterface* sock_interface)
: InstanceBase(Type::Pipe, sockInterfaceOrDefault(sock_interface)) {
if (pipe_path.size() >= sizeof(pipe_.address_.sun_path)) {
throw EnvoyException(
fmt::format("Path \"{}\" exceeds maximum UNIX domain socket path size of {}.", pipe_path,
Expand Down
36 changes: 20 additions & 16 deletions source/common/network/address_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "envoy/common/platform.h"
#include "envoy/network/address.h"
#include "envoy/network/socket.h"

namespace Envoy {
namespace Network {
Expand Down Expand Up @@ -37,16 +38,14 @@ class InstanceBase : public Instance {
const std::string& logicalName() const override { return asString(); }
Type type() const override { return type_; }

const std::string& socketInterface() const override { return socket_interface_; }
const SocketInterface& socketInterface() const override { return socket_interface_; }

protected:
InstanceBase(Type type) : type_(type) {}
InstanceBase(Type type, absl::string_view sock_interface) : type_(type) {
socket_interface_ = std::string(sock_interface);
}
InstanceBase(Type type, const SocketInterface* sock_interface)
: socket_interface_(*sock_interface), type_(type) {}

std::string friendly_name_;
std::string socket_interface_;
const SocketInterface& socket_interface_;

private:
const Type type_;
Expand All @@ -60,23 +59,26 @@ class Ipv4Instance : public InstanceBase {
/**
* Construct from an existing unix IPv4 socket address (IP v4 address and port).
*/
explicit Ipv4Instance(const sockaddr_in* address, absl::string_view sock_interface = "");
explicit Ipv4Instance(const sockaddr_in* address,
const SocketInterface* sock_interface = nullptr);

/**
* Construct from a string IPv4 address such as "1.2.3.4". Port will be unset/0.
*/
explicit Ipv4Instance(const std::string& address, absl::string_view sock_interface = "");
explicit Ipv4Instance(const std::string& address,
const SocketInterface* sock_interface = nullptr);

/**
* Construct from a string IPv4 address such as "1.2.3.4" as well as a port.
*/
Ipv4Instance(const std::string& address, uint32_t port, absl::string_view sock_interface = "");
Ipv4Instance(const std::string& address, uint32_t port,
const SocketInterface* sock_interface = nullptr);

/**
* Construct from a port. The IPv4 address will be set to "any" and is suitable for binding
* a port to any available address.
*/
explicit Ipv4Instance(uint32_t port, absl::string_view sock_interface = "");
explicit Ipv4Instance(uint32_t port, const SocketInterface* sock_interface = nullptr);

// Network::Address::Instance
bool operator==(const Instance& rhs) const override;
Expand Down Expand Up @@ -131,23 +133,25 @@ class Ipv6Instance : public InstanceBase {
* Construct from an existing unix IPv6 socket address (IP v6 address and port).
*/
Ipv6Instance(const sockaddr_in6& address, bool v6only = true,
absl::string_view sock_interface = "");
const SocketInterface* sock_interface = nullptr);

/**
* Construct from a string IPv6 address such as "12:34::5". Port will be unset/0.
*/
explicit Ipv6Instance(const std::string& address, absl::string_view sock_interface = "");
explicit Ipv6Instance(const std::string& address,
const SocketInterface* sock_interface = nullptr);

/**
* Construct from a string IPv6 address such as "12:34::5" as well as a port.
*/
Ipv6Instance(const std::string& address, uint32_t port, absl::string_view sock_interface = "");
Ipv6Instance(const std::string& address, uint32_t port,
const SocketInterface* sock_interface = nullptr);

/**
* Construct from a port. The IPv6 address will be set to "any" and is suitable for binding
* a port to any available address.
*/
explicit Ipv6Instance(uint32_t port, absl::string_view sock_interface = "");
explicit Ipv6Instance(uint32_t port, const SocketInterface* sock_interface = nullptr);

// Network::Address::Instance
bool operator==(const Instance& rhs) const override;
Expand Down Expand Up @@ -203,13 +207,13 @@ class PipeInstance : public InstanceBase {
* Construct from an existing unix address.
*/
explicit PipeInstance(const sockaddr_un* address, socklen_t ss_len, mode_t mode = 0,
absl::string_view sock_interface = "");
const SocketInterface* sock_interface = nullptr);

/**
* Construct from a string pipe path.
*/
explicit PipeInstance(const std::string& pipe_path, mode_t mode = 0,
absl::string_view sock_interface = "");
const SocketInterface* sock_interface = nullptr);

// Network::Address::Instance
bool operator==(const Instance& rhs) const override;
Expand Down
9 changes: 1 addition & 8 deletions source/common/network/socket_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,7 @@ using SocketInterfaceLoader = ScopedInjectableLoader<SocketInterface>;
*/
static inline IoHandlePtr ioHandleForAddr(Socket::Type type,
const Address::InstanceConstSharedPtr addr) {
auto sock_interface_name = addr->socketInterface();
if (!sock_interface_name.empty()) {
auto sock_interface = socketInterface(sock_interface_name);
RELEASE_ASSERT(sock_interface != nullptr,
fmt::format("missing socket interface {}", sock_interface_name));
return sock_interface->socket(type, addr);
}
return SocketInterfaceSingleton::get().socket(type, addr);
return addr->socketInterface().socket(type, addr);
}

} // namespace Network
Expand Down
5 changes: 3 additions & 2 deletions source/common/network/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,12 @@ bool Utility::isLoopbackAddress(const Address::Instance& address) {

Address::InstanceConstSharedPtr Utility::getCanonicalIpv4LoopbackAddress() {
CONSTRUCT_ON_FIRST_USE(Address::InstanceConstSharedPtr,
new Address::Ipv4Instance("127.0.0.1", 0));
new Address::Ipv4Instance("127.0.0.1", 0, nullptr));
}

Address::InstanceConstSharedPtr Utility::getIpv6LoopbackAddress() {
CONSTRUCT_ON_FIRST_USE(Address::InstanceConstSharedPtr, new Address::Ipv6Instance("::1", 0));
CONSTRUCT_ON_FIRST_USE(Address::InstanceConstSharedPtr,
new Address::Ipv6Instance("::1", 0, nullptr));
}

Address::InstanceConstSharedPtr Utility::getIpv4AnyAddress() {
Expand Down
12 changes: 6 additions & 6 deletions test/common/network/connection_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1079,11 +1079,11 @@ TEST_P(ConnectionImplTest, BindTest) {
std::string address_string = TestUtility::getIpv4Loopback();
if (GetParam() == Network::Address::IpVersion::v4) {
source_address_ = Network::Address::InstanceConstSharedPtr{
new Network::Address::Ipv4Instance(address_string, 0)};
new Network::Address::Ipv4Instance(address_string, 0, nullptr)};
} else {
address_string = "::1";
source_address_ = Network::Address::InstanceConstSharedPtr{
new Network::Address::Ipv6Instance(address_string, 0)};
new Network::Address::Ipv6Instance(address_string, 0, nullptr)};
}
setUpBasicConnection();
connect();
Expand All @@ -1097,11 +1097,11 @@ TEST_P(ConnectionImplTest, BindFromSocketTest) {
Address::InstanceConstSharedPtr new_source_address;
if (GetParam() == Network::Address::IpVersion::v4) {
new_source_address = Network::Address::InstanceConstSharedPtr{
new Network::Address::Ipv4Instance(address_string, 0)};
new Network::Address::Ipv4Instance(address_string, 0, nullptr)};
} else {
address_string = "::1";
new_source_address = Network::Address::InstanceConstSharedPtr{
new Network::Address::Ipv6Instance(address_string, 0)};
new Network::Address::Ipv6Instance(address_string, 0, nullptr)};
}
auto option = std::make_shared<NiceMock<MockSocketOption>>();
EXPECT_CALL(*option, setOption(_, Eq(envoy::config::core::v3::SocketOption::STATE_PREBIND)))
Expand All @@ -1123,11 +1123,11 @@ TEST_P(ConnectionImplTest, BindFailureTest) {
if (GetParam() == Network::Address::IpVersion::v6) {
const std::string address_string = TestUtility::getIpv4Loopback();
source_address_ = Network::Address::InstanceConstSharedPtr{
new Network::Address::Ipv4Instance(address_string, 0)};
new Network::Address::Ipv4Instance(address_string, 0, nullptr)};
} else {
const std::string address_string = "::1";
source_address_ = Network::Address::InstanceConstSharedPtr{
new Network::Address::Ipv6Instance(address_string, 0)};
new Network::Address::Ipv6Instance(address_string, 0, nullptr)};
}
dispatcher_ = api_->allocateDispatcher("test_thread");
socket_ = std::make_shared<Network::TcpListenSocket>(
Expand Down
5 changes: 3 additions & 2 deletions test/common/network/dns_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -393,12 +393,13 @@ class CustomInstance : public Address::Instance {
const sockaddr* sockAddr() const override { return instance_.sockAddr(); }
socklen_t sockAddrLen() const override { return instance_.sockAddrLen(); }
Address::Type type() const override { return instance_.type(); }
const std::string& socketInterface() const override { return socket_interface_; }
const SocketInterface& socketInterface() const override {
return SocketInterfaceSingleton::get();
}

private:
std::string antagonistic_name_;
Address::Ipv4Instance instance_;
std::string socket_interface_{""};
};

TEST_F(DnsImplConstructor, SupportCustomAddressInstances) {
Expand Down
Loading