diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 6e98a54280387..3e48f80ab19ea 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -138,6 +138,14 @@ class IoHandle { virtual Api::IoCallUint64Result recvmmsg(RawSliceArrays& slices, uint32_t self_port, RecvMsgOutput& output) PURE; + /** + * Read data into given buffer for connected handles + * @param buffer buffer to read the data into + * @param length buffer length + * @param flags flags to pass to the underlying recv function (see man 2 recv) + */ + virtual Api::IoCallUint64Result recv(void* buffer, size_t length, int flags) PURE; + /** * return true if the platform supports recvmmsg() and sendmmsg(). */ diff --git a/source/common/network/io_socket_handle_impl.cc b/source/common/network/io_socket_handle_impl.cc index fb0ecf4615e81..99606805117cd 100644 --- a/source/common/network/io_socket_handle_impl.cc +++ b/source/common/network/io_socket_handle_impl.cc @@ -372,6 +372,12 @@ Api::IoCallUint64Result IoSocketHandleImpl::recvmmsg(RawSliceArrays& slices, uin return sysCallResultToIoCallResult(result); } +Api::IoCallUint64Result IoSocketHandleImpl::recv(void* buffer, size_t length, int flags) { + const Api::SysCallSizeResult result = + Api::OsSysCallsSingleton::get().recv(fd_, buffer, length, flags); + return sysCallResultToIoCallResult(result); +} + bool IoSocketHandleImpl::supportsMmsg() const { return Api::OsSysCallsSingleton::get().supportsMmsg(); } diff --git a/source/common/network/io_socket_handle_impl.h b/source/common/network/io_socket_handle_impl.h index 8be4b5aa92521..55c3916ad908d 100644 --- a/source/common/network/io_socket_handle_impl.h +++ b/source/common/network/io_socket_handle_impl.h @@ -43,6 +43,7 @@ class IoSocketHandleImpl : public IoHandle, protected Logger::Loggablesocket(); - const Api::SysCallSizeResult result = - os_syscalls.recv(socket.ioHandle().fd(), buf_, Config::MAX_INSPECT_SIZE, MSG_PEEK); + auto result = cb_->socket().ioHandle().recv(buf_, Config::MAX_INSPECT_SIZE, MSG_PEEK); ENVOY_LOG(trace, "http inspector: recv: {}", result.rc_); - if (SOCKET_FAILURE(result.rc_) && result.errno_ == SOCKET_ERROR_AGAIN) { - return ParseState::Continue; - } else if (SOCKET_FAILURE(result.rc_)) { + if (!result.ok()) { + if (result.err_->getErrorCode() == Api::IoError::IoErrorCode::Again) { + return ParseState::Continue; + } config_->stats().read_error_.inc(); return ParseState::Error; } diff --git a/source/extensions/quic_listeners/quiche/quic_io_handle_wrapper.h b/source/extensions/quic_listeners/quiche/quic_io_handle_wrapper.h index d58d4a1060446..49794b579e4a8 100644 --- a/source/extensions/quic_listeners/quiche/quic_io_handle_wrapper.h +++ b/source/extensions/quic_listeners/quiche/quic_io_handle_wrapper.h @@ -62,6 +62,14 @@ class QuicIoHandleWrapper : public Network::IoHandle { } return io_handle_.recvmmsg(slices, self_port, output); } + Api::IoCallUint64Result recv(void* buffer, size_t length, int flags) override { + if (closed_) { + ASSERT(false, "recv called after close."); + return Api::IoCallUint64Result(0, Api::IoErrorPtr(new Network::IoSocketError(EBADF), + Network::IoSocketError::deleteIoError)); + } + 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 { diff --git a/test/extensions/filters/listener/http_inspector/http_inspector_test.cc b/test/extensions/filters/listener/http_inspector/http_inspector_test.cc index e685ceb98211e..0af545ade9861 100644 --- a/test/extensions/filters/listener/http_inspector/http_inspector_test.cc +++ b/test/extensions/filters/listener/http_inspector/http_inspector_test.cc @@ -41,6 +41,7 @@ class HttpInspectorTest : public testing::Test { EXPECT_CALL(socket_, detectedTransportProtocol()).WillRepeatedly(Return("raw_buffer")); EXPECT_CALL(cb_, dispatcher()).WillRepeatedly(ReturnRef(dispatcher_)); EXPECT_CALL(testing::Const(socket_), ioHandle()).WillRepeatedly(ReturnRef(*io_handle_)); + EXPECT_CALL(socket_, ioHandle()).WillRepeatedly(ReturnRef(*io_handle_)); if (include_inline_recv) { EXPECT_CALL(os_sys_calls_, recv(42, _, _, MSG_PEEK)) diff --git a/test/mocks/network/io_handle.h b/test/mocks/network/io_handle.h index 5bfdcc23ac45f..44e391b45395e 100644 --- a/test/mocks/network/io_handle.h +++ b/test/mocks/network/io_handle.h @@ -28,6 +28,7 @@ class MockIoHandle : public IoHandle { RecvMsgOutput& output)); MOCK_METHOD(Api::IoCallUint64Result, recvmmsg, (RawSliceArrays & slices, uint32_t self_port, RecvMsgOutput& output)); + MOCK_METHOD(Api::IoCallUint64Result, recv, (void* buffer, size_t length, int flags)); MOCK_METHOD(bool, supportsMmsg, (), (const)); MOCK_METHOD(bool, supportsUdpGro, (), (const)); MOCK_METHOD(Api::SysCallIntResult, bind, (Address::InstanceConstSharedPtr address));