Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 6 additions & 0 deletions envoy/network/io_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ class IoHandle {
*/
virtual bool isOpen() const PURE;

/**
* Return true if connect() has successfully been called on the socket.
* Use isOpen() to check if the socket is still connected or not.
Comment thread
abeyad marked this conversation as resolved.
*/
virtual bool isConnected() const PURE;

/**
* Read data into given slices.
* @param max_length supplies the maximum length to read.
Expand Down
2 changes: 2 additions & 0 deletions source/common/network/io_socket_handle_base_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ IoSocketHandleBaseImpl::~IoSocketHandleBaseImpl() {

bool IoSocketHandleBaseImpl::isOpen() const { return SOCKET_VALID(fd_); }

bool IoSocketHandleBaseImpl::isConnected() const { return is_connected_; }

bool IoSocketHandleBaseImpl::supportsMmsg() const {
return Api::OsSysCallsSingleton::get().supportsMmsg();
}
Expand Down
2 changes: 2 additions & 0 deletions source/common/network/io_socket_handle_base_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class IoSocketHandleBaseImpl : public IoHandle, protected Logger::Loggable<Logge
// TODO(sbelair2) To be removed when the fd is fully abstracted from clients.
os_fd_t fdDoNotUse() const override { return fd_; }
bool isOpen() const override;
bool isConnected() const override;
bool supportsMmsg() const override;
bool supportsUdpGro() const override;
Api::SysCallIntResult setOption(int level, int optname, const void* optval,
Expand All @@ -38,6 +39,7 @@ class IoSocketHandleBaseImpl : public IoHandle, protected Logger::Loggable<Logge
os_fd_t fd_;
int socket_v6only_;
const absl::optional<int> domain_;
bool is_connected_ = false;
};

} // namespace Network
Expand Down
6 changes: 5 additions & 1 deletion source/common/network/io_socket_handle_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,11 @@ Api::SysCallIntResult IoSocketHandleImpl::connect(Address::InstanceConstSharedPt
}
#endif

return Api::OsSysCallsSingleton::get().connect(fd_, sockaddr_to_use, sockaddr_len_to_use);
auto result = Api::OsSysCallsSingleton::get().connect(fd_, sockaddr_to_use, sockaddr_len_to_use);
if (result.return_value_ != -1) {
is_connected_ = true;
}
return result;
}

IoHandlePtr IoSocketHandleImpl::duplicate() {
Expand Down
10 changes: 9 additions & 1 deletion source/common/network/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,15 @@ Api::IoCallUint64Result Utility::writeToSocket(IoHandle& handle, Buffer::RawSlic
Api::IoCallUint64Result send_result(
/*rc=*/0, /*err=*/Api::IoError::none());
do {
send_result = handle.sendmsg(slices, num_slices, 0, local_ip, peer_address);
if (handle.isConnected()) {
// The socket is already connected, so the local and peer addresses should not be specified.
// Instead, a writev/send is called.
Comment thread
abeyad marked this conversation as resolved.
Outdated
send_result = handle.writev(slices, num_slices);
} else {
// For non-connected sockets(), calling sendmsg with the peer address specified ensures the
// connection happens first.
send_result = handle.sendmsg(slices, num_slices, 0, local_ip, peer_address);
}
} while (!send_result.ok() &&
// Send again if interrupted.
send_result.err_->getErrorCode() == Api::IoError::IoErrorCode::Interrupt);
Expand Down
15 changes: 8 additions & 7 deletions source/common/quic/envoy_quic_client_connection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ EnvoyQuicClientConnection::EnvoyQuicClientConnection(
Network::Address::InstanceConstSharedPtr local_addr, Event::Dispatcher& dispatcher,
const Network::ConnectionSocket::OptionsSharedPtr& options,
quic::ConnectionIdGeneratorInterface& generator, const bool prefer_gro)
: EnvoyQuicClientConnection(
server_connection_id, helper, alarm_factory, supported_versions, dispatcher,
createConnectionSocket(initial_peer_address, local_addr, options, prefer_gro), generator,
prefer_gro) {}
: EnvoyQuicClientConnection(server_connection_id, helper, alarm_factory, supported_versions,
dispatcher,
createConnectionSocket(initial_peer_address, local_addr, options,
prefer_gro, /*connect=*/true),
generator, prefer_gro) {}

EnvoyQuicClientConnection::EnvoyQuicClientConnection(
const quic::QuicConnectionId& server_connection_id, quic::QuicConnectionHelperInterface& helper,
Expand Down Expand Up @@ -179,9 +180,9 @@ void EnvoyQuicClientConnection::probeWithNewPort(const quic::QuicSocketAddress&
}

// The probing socket will have the same host but a different port.
auto probing_socket =
createConnectionSocket(connectionSocket()->connectionInfoProvider().remoteAddress(),
Comment thread
abeyad marked this conversation as resolved.
new_local_address, connectionSocket()->options(), prefer_gro_);
auto probing_socket = createConnectionSocket(
connectionSocket()->connectionInfoProvider().remoteAddress(), new_local_address,
connectionSocket()->options(), prefer_gro_, /*connect=*/true);
setUpConnectionSocket(*probing_socket, delegate_);
auto writer = std::make_unique<EnvoyQuicPacketWriter>(
std::make_unique<Network::UdpDefaultWriter>(probing_socket->ioHandle()));
Expand Down
15 changes: 13 additions & 2 deletions source/common/quic/envoy_quic_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ Network::ConnectionSocketPtr
createConnectionSocket(const Network::Address::InstanceConstSharedPtr& peer_addr,
Network::Address::InstanceConstSharedPtr& local_addr,
const Network::ConnectionSocket::OptionsSharedPtr& options,
const bool prefer_gro) {
const bool prefer_gro, const bool connect) {
Comment thread
abeyad marked this conversation as resolved.
Outdated
if (local_addr == nullptr) {
local_addr = Network::Utility::getLocalAddress(peer_addr->ip()->version());
Comment thread
abeyad marked this conversation as resolved.
Outdated
}
Expand Down Expand Up @@ -201,7 +201,18 @@ createConnectionSocket(const Network::Address::InstanceConstSharedPtr& peer_addr
ENVOY_LOG_MISC(error, "Fail to apply pre-bind options");
return connection_socket;
}
connection_socket->bind(local_addr);

if (connect) {
if (auto result = connection_socket->connect(peer_addr); result.return_value_ != 0) {
connection_socket->close();
ENVOY_LOG_MISC(error, "Fail to connect socket: ({}) {}", result.errno_,
errorDetails(result.errno_));
return connection_socket;
}
} else {
connection_socket->bind(local_addr);
}

ASSERT(local_addr->ip());
local_addr = connection_socket->connectionInfoProvider().localAddress();
if (!Network::Socket::applyOptions(connection_socket->options(), *connection_socket,
Expand Down
7 changes: 6 additions & 1 deletion source/common/quic/envoy_quic_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,16 @@ Http::StreamResetReason quicErrorCodeToEnvoyRemoteResetReason(quic::QuicErrorCod

// Create a connection socket instance and apply given socket options to the
// socket. IP_PKTINFO and SO_RXQ_OVFL is always set if supported.
//
// If `connect` is set to true, the socket is connected (connect() is called on the socket). If
// `connect` is set to false, the socket is not connected, but instead bind() is called. The bind()
// call is not made when `connect` is set to true. Set `connect` to true when creating a client
// outbound QUIC connection.
Comment thread
abeyad marked this conversation as resolved.
Outdated
Network::ConnectionSocketPtr
createConnectionSocket(const Network::Address::InstanceConstSharedPtr& peer_addr,
Network::Address::InstanceConstSharedPtr& local_addr,
const Network::ConnectionSocket::OptionsSharedPtr& options,
bool prefer_gro = false);
bool prefer_gro = false, bool connect = false);

// Convert a cert in string form to X509 object.
// Return nullptr if the bytes passed cannot be passed.
Expand Down
1 change: 1 addition & 0 deletions source/common/quic/quic_io_handle_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class QuicIoHandleWrapper : public Network::IoHandle {
return Api::ioCallUint64ResultNoError();
}
bool isOpen() const override { return !closed_; }
bool isConnected() const override { return io_handle_.isConnected(); }
Api::IoCallUint64Result readv(uint64_t max_length, Buffer::RawSlice* slices,
uint64_t num_slice) override {
if (closed_) {
Expand Down
2 changes: 2 additions & 0 deletions source/extensions/io_socket/user_space/io_handle_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ Api::IoCallUint64Result IoHandleImpl::close() {

bool IoHandleImpl::isOpen() const { return !closed_; }

bool IoHandleImpl::isConnected() const { return false; }

Api::IoCallUint64Result IoHandleImpl::readv(uint64_t max_length, Buffer::RawSlice* slices,
uint64_t num_slice) {
if (!isOpen()) {
Expand Down
1 change: 1 addition & 0 deletions source/extensions/io_socket/user_space/io_handle_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class IoHandleImpl final : public Network::IoHandle,
}
Api::IoCallUint64Result close() override;
bool isOpen() const override;
bool isConnected() const override;
Api::IoCallUint64Result readv(uint64_t max_length, Buffer::RawSlice* slices,
uint64_t num_slice) override;
Api::IoCallUint64Result read(Buffer::Instance& buffer,
Expand Down
1 change: 1 addition & 0 deletions test/mocks/network/io_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class MockIoHandle : public IoHandle {
MOCK_METHOD(os_fd_t, fdDoNotUse, (), (const));
MOCK_METHOD(Api::IoCallUint64Result, close, ());
MOCK_METHOD(bool, isOpen, (), (const));
MOCK_METHOD(bool, isConnected, (), (const));
MOCK_METHOD(Api::IoCallUint64Result, readv,
(uint64_t max_length, Buffer::RawSlice* slices, uint64_t num_slice));
MOCK_METHOD(Api::IoCallUint64Result, read,
Expand Down