diff --git a/vsock-bridge/include/config.h b/vsock-bridge/include/config.h index a8cd0e3..3858735 100644 --- a/vsock-bridge/include/config.h +++ b/vsock-bridge/include/config.h @@ -32,6 +32,10 @@ namespace vsockproxy ServiceType _type = ServiceType::UNKNOWN; EndpointConfig _listenEndpoint; EndpointConfig _connectEndpoint; + int _acceptRcvBuf = -1; + int _acceptSndBuf = -1; + int _peerRcvBuf = -1; + int _peerSndBuf = -1; }; std::vector loadConfig(const std::string& filepath); diff --git a/vsock-bridge/include/listener.h b/vsock-bridge/include/listener.h index 52383df..f3ee79a 100644 --- a/vsock-bridge/include/listener.h +++ b/vsock-bridge/include/listener.h @@ -70,8 +70,12 @@ namespace vsockio const int MAX_POLLER_EVENTS = 256; const int SO_BACKLOG = 64; - Listener(std::unique_ptr&& listenEndpoint, std::unique_ptr&& connectEndpoint, Dispatcher& dispatcher) + Listener(std::unique_ptr&& listenEndpoint, std::unique_ptr&& connectEndpoint, Dispatcher& dispatcher, int acceptRcvBuf, int acceptSndBuf, int peerRcvBuf, int peerSndBuf) : _fd(-1) + , _acceptRcvBuf(acceptRcvBuf) + , _acceptSndBuf(acceptSndBuf) + , _peerRcvBuf(peerRcvBuf) + , _peerSndBuf(peerSndBuf) , _listenEp(std::move(listenEndpoint)) , _connectEp(std::move(connectEndpoint)) , _events(new VsbEvent[MAX_POLLER_EVENTS]) @@ -174,6 +178,35 @@ namespace vsockio return; } + if (_acceptRcvBuf != -1) { + if (setsockopt(clientFd, SOL_SOCKET, SO_RCVBUF, &_acceptRcvBuf, sizeof(int)) < 0) + { + close(clientFd); + throw std::runtime_error("error setting _acceptRcvBuf to SO_RCVBUF"); + } + } + + if (_acceptSndBuf != -1) { + if (setsockopt(clientFd, SOL_SOCKET, SO_SNDBUF, &_acceptSndBuf, sizeof(int)) < 0) + { + close(clientFd); + throw std::runtime_error("error setting _acceptSndBuf to SO_SNDBUF"); + } + } + + int debugAcceptRcvbuf; + int debugAcceptSndbuf; + socklen_t debugAcceptRcvbufLen = sizeof(debugAcceptRcvbuf); + socklen_t debugAcceptSndbufLen = sizeof(debugAcceptSndbuf); + + if (getsockopt(clientFd, SOL_SOCKET, SO_RCVBUF, &debugAcceptRcvbuf, &debugAcceptRcvbufLen) == 0) { + Logger::instance->Log(Logger::INFO, "Accept client Receive buffer size: ", debugAcceptRcvbuf, "bytes"); + } + + if (getsockopt(clientFd, SOL_SOCKET, SO_SNDBUF, &debugAcceptSndbuf, &debugAcceptSndbufLen) == 0) { + Logger::instance->Log(Logger::INFO, "Accept client Send buffer size: ", debugAcceptSndbuf, "bytes"); + } + auto outPeer = connectToPeer(); if (!outPeer) { @@ -209,6 +242,35 @@ namespace vsockio return nullptr; } + if (_peerRcvBuf != -1) { + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &_peerRcvBuf, sizeof(int)) < 0) + { + close(fd); + throw std::runtime_error("error setting _peerRcvBuf to SO_RCVBUF"); + } + } + + if (_peerSndBuf != -1) { + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &_peerSndBuf, sizeof(int)) < 0) + { + close(fd); + throw std::runtime_error("error setting _peerSndBuf to SO_SNDBUF"); + } + } + + int debugPeerRcvbuf; + int debugPeerSndbuf; + socklen_t debugPeerRcvbufLen = sizeof(debugPeerRcvbuf); + socklen_t debugPeerSndbufLen = sizeof(debugPeerSndbuf); + + if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &debugPeerRcvbuf, &debugPeerRcvbufLen) == 0) { + Logger::instance->Log(Logger::INFO, "Peer client Receive buffer size: ", debugPeerRcvbuf, "bytes"); + } + + if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &debugPeerSndbuf, &debugPeerSndbufLen) == 0) { + Logger::instance->Log(Logger::INFO, "Peer client Send buffer size: ", debugPeerSndbuf, "bytes"); + } + auto addrAndLen = _connectEp->getAddress(); int status = connect(fd, addrAndLen.first, addrAndLen.second); if (status == 0) @@ -232,6 +294,10 @@ namespace vsockio inline bool listening() const { return _fd >= 0; } int _fd; + int _acceptRcvBuf; + int _acceptSndBuf; + int _peerRcvBuf; + int _peerSndBuf; std::unique_ptr _listenEp; std::unique_ptr _listenEpClone; std::unique_ptr _connectEp; diff --git a/vsock-bridge/src/config.cpp b/vsock-bridge/src/config.cpp index eaa4693..791e57d 100644 --- a/vsock-bridge/src/config.cpp +++ b/vsock-bridge/src/config.cpp @@ -251,6 +251,22 @@ namespace vsockproxy } cs._connectEndpoint = *endpoint; } + else if (line._key == "acceptRcvBuf") + { + cs._acceptRcvBuf = std::stoi(line._value); + } + else if (line._key == "acceptSndBuf") + { + cs._acceptSndBuf = std::stoi(line._value); + } + else if (line._key == "peerRcvBuf") + { + cs._peerRcvBuf = std::stoi(line._value); + } + else if (line._key == "peerSndBuf") + { + cs._peerSndBuf = std::stoi(line._value); + } } } } diff --git a/vsock-bridge/src/vsock-bridge.cpp b/vsock-bridge/src/vsock-bridge.cpp index ed7cd6d..88fd384 100644 --- a/vsock-bridge/src/vsock-bridge.cpp +++ b/vsock-bridge/src/vsock-bridge.cpp @@ -27,7 +27,7 @@ static std::unique_ptr createEndpoint(EndpointScheme scheme, const std } } -static std::unique_ptr createListener(Dispatcher& dispatcher, EndpointScheme inScheme, const std::string& inAddress, uint16_t inPort, EndpointScheme outScheme, const std::string& outAddress, uint16_t outPort) +static std::unique_ptr createListener(Dispatcher& dispatcher, EndpointScheme inScheme, const std::string& inAddress, uint16_t inPort, EndpointScheme outScheme, const std::string& outAddress, uint16_t outPort, int acceptRcvBuf, int acceptSndBuf, int peerRcvBuf, int peerSndBuf) { auto listenEp { createEndpoint(inScheme, inAddress, inPort) }; auto connectEp{ createEndpoint(outScheme, outAddress, outPort) }; @@ -44,7 +44,7 @@ static std::unique_ptr createListener(Dispatcher& dispatcher, Endpoint } else { - return std::make_unique(std::move(listenEp), std::move(connectEp), dispatcher); + return std::make_unique(std::move(listenEp), std::move(connectEp), dispatcher, acceptRcvBuf, acceptSndBuf, peerRcvBuf, peerSndBuf); } } @@ -68,7 +68,11 @@ static void startServices(const std::vector& services, int n /*inPort:*/ sd._listenEndpoint._port, /*outScheme:*/ sd._connectEndpoint._scheme, /*outAddress:*/ sd._connectEndpoint._address, - /*outPort:*/ sd._connectEndpoint._port + /*outPort:*/ sd._connectEndpoint._port, + sd._acceptRcvBuf, + sd._acceptSndBuf, + sd._peerRcvBuf, + sd._peerSndBuf ); if (!listener)