Lines
92.4 %
Functions
91.4 %
#pragma once
#include <chrono>
#include <iosfwd>
#include "envoy/network/io_handle.h"
#include "source/common/common/assert.h"
#include "source/common/network/io_socket_error_impl.h"
namespace Envoy {
namespace Quic {
// A wrapper class around IoHandle object which doesn't close() upon destruction. It is used to
// create ConnectionSocket as the actual IoHandle instance should out live connection socket.
class QuicIoHandleWrapper : public Network::IoHandle {
public:
QuicIoHandleWrapper(Network::IoHandle& io_handle) : io_handle_(io_handle) {}
// Network::IoHandle
os_fd_t fdDoNotUse() const override { return io_handle_.fdDoNotUse(); }
Api::IoCallUint64Result close() override {
closed_ = true;
return Api::ioCallUint64ResultNoError();
}
bool isOpen() const override { return !closed_; }
bool wasConnected() const override { return io_handle_.wasConnected(); }
Api::IoCallUint64Result readv(uint64_t max_length, Buffer::RawSlice* slices,
uint64_t num_slice) override {
if (closed_) {
return {0, Network::IoSocketError::getIoSocketEbadfError()};
return io_handle_.readv(max_length, slices, num_slice);
Api::IoCallUint64Result read(Buffer::Instance& buffer,
absl::optional<uint64_t> max_length) override {
return io_handle_.read(buffer, max_length);
Api::IoCallUint64Result writev(const Buffer::RawSlice* slices, uint64_t num_slice) override {
return io_handle_.writev(slices, num_slice);
Api::IoCallUint64Result write(Buffer::Instance& buffer) override {
return io_handle_.write(buffer);
Api::IoCallUint64Result sendmsg(const Buffer::RawSlice* slices, uint64_t num_slice, int flags,
const Envoy::Network::Address::Ip* self_ip,
const Network::Address::Instance& peer_address) override {
return io_handle_.sendmsg(slices, num_slice, flags, self_ip, peer_address);
Api::IoCallUint64Result recvmsg(Buffer::RawSlice* slices, const uint64_t num_slice,
uint32_t self_port, const UdpSaveCmsgConfig& udp_save_cmsg_config,
RecvMsgOutput& output) override {
ASSERT(false, "recvmmsg is called after close.");
return io_handle_.recvmsg(slices, num_slice, self_port, udp_save_cmsg_config, output);
Api::IoCallUint64Result recvmmsg(RawSliceArrays& slices, uint32_t self_port,
const UdpSaveCmsgConfig& udp_save_cmsg_config,
return io_handle_.recvmmsg(slices, self_port, udp_save_cmsg_config, output);
Api::IoCallUint64Result recv(void* buffer, size_t length, int flags) override {
ASSERT(false, "recv called after close.");
return io_handle_.recv(buffer, length, flags);
bool supportsMmsg() const override { return io_handle_.supportsMmsg(); }
bool supportsUdpGro() const override { return io_handle_.supportsUdpGro(); }
Api::SysCallIntResult bind(Network::Address::InstanceConstSharedPtr address) override {
return io_handle_.bind(address);
Api::SysCallIntResult listen(int backlog) override { return io_handle_.listen(backlog); }
Network::IoHandlePtr accept(struct sockaddr* addr, socklen_t* addrlen) override {
return io_handle_.accept(addr, addrlen);
Api::SysCallIntResult connect(Network::Address::InstanceConstSharedPtr address) override {
return io_handle_.connect(address);
Api::SysCallIntResult setOption(int level, int optname, const void* optval,
socklen_t optlen) override {
return io_handle_.setOption(level, optname, optval, optlen);
Api::SysCallIntResult getOption(int level, int optname, void* optval,
socklen_t* optlen) override {
return io_handle_.getOption(level, optname, optval, optlen);
Api::SysCallIntResult ioctl(unsigned long control_code, void* in_buffer,
unsigned long in_buffer_len, void* out_buffer,
unsigned long out_buffer_len,
unsigned long* bytes_returned) override {
return io_handle_.ioctl(control_code, in_buffer, in_buffer_len, out_buffer, out_buffer_len,
bytes_returned);
Api::SysCallIntResult setBlocking(bool blocking) override {
return io_handle_.setBlocking(blocking);
absl::optional<int> domain() override { return io_handle_.domain(); }
absl::StatusOr<Network::Address::InstanceConstSharedPtr> localAddress() override {
return io_handle_.localAddress();
absl::StatusOr<Network::Address::InstanceConstSharedPtr> peerAddress() override {
return io_handle_.peerAddress();
void initializeFileEvent(Event::Dispatcher& dispatcher, Event::FileReadyCb cb,
Event::FileTriggerType trigger, uint32_t events) override {
io_handle_.initializeFileEvent(dispatcher, cb, trigger, events);
Network::IoHandlePtr duplicate() override { return io_handle_.duplicate(); }
void activateFileEvents(uint32_t events) override { io_handle_.activateFileEvents(events); }
void enableFileEvents(uint32_t events) override { io_handle_.enableFileEvents(events); }
void resetFileEvents() override { return io_handle_.resetFileEvents(); };
absl::optional<std::string> interfaceName() override { return io_handle_.interfaceName(); }
Api::SysCallIntResult shutdown(int how) override { return io_handle_.shutdown(how); }
absl::optional<std::chrono::milliseconds> lastRoundTripTime() override { return {}; }
absl::optional<uint64_t> congestionWindowInBytes() const override {
// QUIC should get congestion window from QuicFilterManagerConnectionImpl, which implements the
// Envoy::Network::Connection::congestionWindowInBytes interface.
IS_ENVOY_BUG("QuicIoHandleWrapper does not implement congestionWindowInBytes.");
return {};
private:
Network::IoHandle& io_handle_;
bool closed_{false};
};
} // namespace Quic
} // namespace Envoy