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
14 changes: 14 additions & 0 deletions api/envoy/config/core/v3/address.proto
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ message Pipe {
uint32 mode = 2 [(validate.rules).uint32 = {lte: 511}];
}

// [#not-implemented-hide:] The address represents an envoy internal listener.
// TODO(lambdai): Make this address available for listener and endpoint.
message EnvoyInternalAddress {
oneof address_name_specifier {
option (validate.required) = true;

// [#not-implemented-hide:] The :ref:`listener name <envoy_api_field_config.listener.v3.Listener.name>` of the destination internal listener.
string server_listener_name = 1;
}
}

// [#next-free-field: 7]
message SocketAddress {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.SocketAddress";
Expand Down Expand Up @@ -129,6 +140,9 @@ message Address {
SocketAddress socket_address = 1;

Pipe pipe = 2;

// [#not-implemented-hide:]
EnvoyInternalAddress envoy_internal_address = 3;
}
}

Expand Down
17 changes: 17 additions & 0 deletions api/envoy/config/core/v4alpha/address.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions generated_api_shadow/envoy/config/core/v3/address.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions generated_api_shadow/envoy/config/core/v4alpha/address.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 28 additions & 7 deletions include/envoy/network/address.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,23 +102,37 @@ class Ip {
};

/**
* Interface for a generic Pipe address
* Interface for a generic Pipe address.
*/
class Pipe {
public:
virtual ~Pipe() = default;
/**
* @return abstract namespace flag
* @return abstract namespace flag.
*/
virtual bool abstractNamespace() const PURE;

/**
* @return pipe mode
* @return pipe mode.
*/
virtual mode_t mode() const PURE;
};

enum class Type { Ip, Pipe };
/**
* Interface for a generic internal address.
*/
class EnvoyInternalAddress {
public:
virtual ~EnvoyInternalAddress() = default;

/**
* @return The unique id of the internal address. If the address represents the destination
* internal listener, the address id is that listener name.
*/
virtual const std::string& addressId() const PURE;
};

enum class Type { Ip, Pipe, EnvoyInternal };

/**
* Interface for all network addresses.
Expand Down Expand Up @@ -167,12 +181,19 @@ class Instance {
virtual const Pipe* pipe() const PURE;

/**
* @return the underlying structure wherein the address is stored
* @return the envoy internal address information IFF type() ==
* Type::EnvoyInternal, otherwise nullptr.
*/
virtual const EnvoyInternalAddress* envoyInternalAddress() const PURE;

/**
* @return the underlying structure wherein the address is stored. Return nullptr if the address
* type is internal address.
*/
virtual const sockaddr* sockAddr() const PURE;

/**
* @return length of the address container
* @return length of the address container.
*/
virtual socklen_t sockAddrLen() const PURE;

Expand All @@ -182,7 +203,7 @@ class Instance {
virtual Type type() const PURE;

/**
* @return SocketInterface to be used with the address
* @return SocketInterface to be used with the address.
*/
virtual const Network::SocketInterface& socketInterface() const PURE;
};
Expand Down
2 changes: 1 addition & 1 deletion include/envoy/network/socket_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class SocketInterface {
using SocketInterfacePtr = std::unique_ptr<SocketInterface>;

/**
* Create IoHandle for given address
* Create IoHandle for given address.
* @param type type of socket to be requested
* @param addr address that is gleaned for address type, version and socket interface name
* @return @ref Network::IoHandlePtr that wraps the underlying socket file descriptor
Expand Down
1 change: 0 additions & 1 deletion source/common/event/file_event_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,5 @@ class FileEventImpl : public FileEvent, ImplBase {
// polling and activating new fd events.
const bool activate_fd_events_next_event_loop_;
};

} // namespace Event
} // namespace Envoy
1 change: 1 addition & 0 deletions source/common/network/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ envoy_cc_library(
"//include/envoy/event:dispatcher_interface",
"//include/envoy/network:io_handle_interface",
"//source/common/api:os_sys_calls_lib",
"//source/common/event:dispatcher_includes",
"@envoy_api//envoy/extensions/network/socket_interface/v3:pkg_cc_proto",
],
)
Expand Down
11 changes: 11 additions & 0 deletions source/common/network/address_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,17 @@ PipeInstance::PipeInstance(const std::string& pipe_path, mode_t mode,

bool PipeInstance::operator==(const Instance& rhs) const { return asString() == rhs.asString(); }

EnvoyInternalInstance::EnvoyInternalInstance(const std::string& address_id,
const SocketInterface* sock_interface)
: InstanceBase(Type::EnvoyInternal, sockInterfaceOrDefault(sock_interface)),
internal_address_(address_id) {
friendly_name_ = absl::StrCat("envoy://", address_id);
}

bool EnvoyInternalInstance::operator==(const Instance& rhs) const {
return rhs.type() == Type::EnvoyInternal && asString() == rhs.asString();
}

} // namespace Address
} // namespace Network
} // namespace Envoy
32 changes: 32 additions & 0 deletions source/common/network/address_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "envoy/network/address.h"
#include "envoy/network/socket.h"

#include "common/common/assert.h"

namespace Envoy {
namespace Network {
namespace Address {
Expand Down Expand Up @@ -84,6 +86,7 @@ class Ipv4Instance : public InstanceBase {
bool operator==(const Instance& rhs) const override;
const Ip* ip() const override { return &ip_; }
const Pipe* pipe() const override { return nullptr; }
const EnvoyInternalAddress* envoyInternalAddress() const override { return nullptr; }
const sockaddr* sockAddr() const override {
return reinterpret_cast<const sockaddr*>(&ip_.ipv4_.address_);
}
Expand Down Expand Up @@ -157,6 +160,7 @@ class Ipv6Instance : public InstanceBase {
bool operator==(const Instance& rhs) const override;
const Ip* ip() const override { return &ip_; }
const Pipe* pipe() const override { return nullptr; }
const EnvoyInternalAddress* envoyInternalAddress() const override { return nullptr; }
const sockaddr* sockAddr() const override {
return reinterpret_cast<const sockaddr*>(&ip_.ipv6_.address_);
}
Expand Down Expand Up @@ -219,6 +223,7 @@ class PipeInstance : public InstanceBase {
bool operator==(const Instance& rhs) const override;
const Ip* ip() const override { return nullptr; }
const Pipe* pipe() const override { return &pipe_; }
const EnvoyInternalAddress* envoyInternalAddress() const override { return nullptr; }
const sockaddr* sockAddr() const override {
return reinterpret_cast<const sockaddr*>(&pipe_.address_);
}
Expand All @@ -245,6 +250,33 @@ class PipeInstance : public InstanceBase {
PipeHelper pipe_;
};

class EnvoyInternalInstance : public InstanceBase {
public:
/**
* Construct from a string name.
*/
explicit EnvoyInternalInstance(const std::string& envoy_listener_name,
const SocketInterface* sock_interface = nullptr);

// Network::Address::Instance
bool operator==(const Instance& rhs) const override;
const Ip* ip() const override { return nullptr; }
const Pipe* pipe() const override { return nullptr; }
const EnvoyInternalAddress* envoyInternalAddress() const override { return &internal_address_; }
// TODO(lambdai): Verify all callers accepts nullptr.
const sockaddr* sockAddr() const override { return nullptr; }
socklen_t sockAddrLen() const override { return 0; }

private:
struct EnvoyInternalAddressImpl : public EnvoyInternalAddress {
explicit EnvoyInternalAddressImpl(const std::string& address_id) : address_id_(address_id) {}
~EnvoyInternalAddressImpl() override = default;
const std::string& addressId() const override { return address_id_; }
const std::string address_id_;
};
EnvoyInternalAddressImpl internal_address_;
};

} // namespace Address
} // namespace Network
} // namespace Envoy
10 changes: 10 additions & 0 deletions source/common/network/io_socket_error_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,15 @@ void IoSocketError::deleteIoError(Api::IoError* err) {
}
}

inline IoSocketError* getIoSocketInvalidAddressInstance() {
static auto* instance = new IoSocketError(SOCKET_ERROR_NOT_SUP);
return instance;
}

Api::IoCallUint64Result IoSocketError::ioResultSocketInvalidAddress() {
return Api::IoCallUint64Result(
0, Api::IoErrorPtr(getIoSocketInvalidAddressInstance(), [](IoError*) {}));
}

} // namespace Network
} // namespace Envoy
5 changes: 5 additions & 0 deletions source/common/network/io_socket_error_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ class IoSocketError : public Api::IoError {
// deleter deleteIoError() below to avoid deallocating memory for this error.
static IoSocketError* getIoSocketEagainInstance();

// This error is introduced when Envoy create socket for unsupported address. It is either a bug,
// or this Envoy instance received config which is not yet supported. This should not be fatal
// error.
static Api::IoCallUint64Result ioResultSocketInvalidAddress();

// Deallocate memory only if the error is not Again.
static void deleteIoError(Api::IoError* err);

Expand Down
7 changes: 5 additions & 2 deletions source/common/network/io_socket_handle_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "common/api/os_sys_calls_impl.h"
#include "common/common/utility.h"
#include "common/event/file_event_impl.h"
#include "common/network/address_impl.h"

#include "absl/container/fixed_array.h"
Expand Down Expand Up @@ -71,7 +72,10 @@ Api::IoCallUint64Result IoSocketHandleImpl::sendmsg(const Buffer::RawSlice* slic
const Address::Instance& peer_address) {
const auto* address_base = dynamic_cast<const Address::InstanceBase*>(&peer_address);
sockaddr* sock_addr = const_cast<sockaddr*>(address_base->sockAddr());

if (sock_addr == nullptr) {
// Unlikely to happen unless the wrong peer address is passed.
return IoSocketError::ioResultSocketInvalidAddress();
}
absl::FixedArray<iovec> iov(num_slice);
uint64_t num_slices_to_write = 0;
for (uint64_t i = 0; i < num_slice; i++) {
Expand Down Expand Up @@ -488,6 +492,5 @@ Event::FileEventPtr IoSocketHandleImpl::createFileEvent(Event::Dispatcher& dispa
Api::SysCallIntResult IoSocketHandleImpl::shutdown(int how) {
return Api::OsSysCallsSingleton::get().shutdown(fd_, how);
}

} // namespace Network
} // namespace Envoy
3 changes: 1 addition & 2 deletions source/common/network/io_socket_handle_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Envoy {
namespace Network {

/**
* IoHandle derivative for sockets
* IoHandle derivative for sockets.
*/
class IoSocketHandleImpl : public IoHandle, protected Logger::Loggable<Logger::Id::io> {
public:
Expand Down Expand Up @@ -92,6 +92,5 @@ class IoSocketHandleImpl : public IoHandle, protected Logger::Loggable<Logger::I
const size_t cmsg_space_{CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct in_pktinfo)) +
CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(uint16_t))};
};

} // namespace Network
} // namespace Envoy
18 changes: 15 additions & 3 deletions source/common/network/resolver_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,22 @@ InstanceConstSharedPtr resolveProtoAddress(const envoy::config::core::v3::Addres
case envoy::config::core::v3::Address::AddressCase::kSocketAddress:
return resolveProtoSocketAddress(address.socket_address());
case envoy::config::core::v3::Address::AddressCase::kPipe:
return InstanceConstSharedPtr{new PipeInstance(address.pipe().path())};
default:
throw EnvoyException("Address must be a socket or pipe: " + address.DebugString());
return std::make_shared<PipeInstance>(address.pipe().path());
case envoy::config::core::v3::Address::AddressCase::kEnvoyInternalAddress:
switch (address.envoy_internal_address().address_name_specifier_case()) {
case envoy::config::core::v3::EnvoyInternalAddress::AddressNameSpecifierCase::
kServerListenerName:
return std::make_shared<EnvoyInternalInstance>(
address.envoy_internal_address().server_listener_name());
case envoy::config::core::v3::EnvoyInternalAddress::AddressNameSpecifierCase::
ADDRESS_NAME_SPECIFIER_NOT_SET:
break;
}
break;
case envoy::config::core::v3::Address::AddressCase::ADDRESS_NOT_SET:
break;
}
NOT_REACHED_GCOVR_EXCL_LINE;
}

InstanceConstSharedPtr
Expand Down
Loading