diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2015-11-28 14:01:24 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2015-11-28 14:12:23 +0900 |
| commit | e8a9a366db7bf834a3e93c6ec05336e5aca882c4 (patch) | |
| tree | 01a422d15502dac3a117a80df17781b482773015 /src/SocketCore.cc | |
| parent | 699f04d0b8a93dd92a85f68cd8c307b5f3fb4741 (diff) | |
Add --socket-recv-buffer-size option
Set the maximum socket receive buffer in bytes. Specifing 0 will
disable this option. This value will be set to socket file descriptor
using SO_RCVBUF socket option with setsockopt() call.
See GH-487 about the usecase of this option
Diffstat (limited to 'src/SocketCore.cc')
| -rw-r--r-- | src/SocketCore.cc | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/SocketCore.cc b/src/SocketCore.cc index 3b8cb4a5..96727837 100644 --- a/src/SocketCore.cc +++ b/src/SocketCore.cc @@ -143,6 +143,8 @@ SocketCore::bindAddrsList_; std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > >::iterator SocketCore::bindAddrsListIt_; +int SocketCore::socketRecvBufferSize_ = 0; + #ifdef ENABLE_SSL std::shared_ptr<TLSContext> SocketCore::clTlsContext_; std::shared_ptr<TLSContext> SocketCore::svTlsContext_; @@ -187,6 +189,23 @@ SocketCore::~SocketCore() { closeConnection(); } +namespace { +void applySocketBufferSize(sock_t fd) +{ + auto recvBufSize = SocketCore::getSocketRecvBufferSize(); + if (recvBufSize == 0) { + return; + } + + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (a2_sockopt_t)&recvBufSize, + sizeof(recvBufSize)) < 0) { + auto errNum = SOCKET_ERRNO; + A2_LOG_WARN(fmt("Failed to set socket buffer size. Cause: %s", + errorMsg(errNum).c_str())); + } +} +} // namespace + void SocketCore::create(int family, int protocol) { int errNum; @@ -205,6 +224,9 @@ void SocketCore::create(int family, int protocol) throw DL_ABORT_EX (fmt("Failed to create socket. Cause:%s", errorMsg(errNum).c_str())); } + + applySocketBufferSize(fd); + sockfd_ = fd; } @@ -240,6 +262,9 @@ static sock_t bindInternal } } #endif // IPV6_V6ONLY + + applySocketBufferSize(fd); + if(::bind(fd, addr, addrlen) == -1) { errNum = SOCKET_ERRNO; error = errorMsg(errNum); @@ -364,6 +389,9 @@ std::shared_ptr<SocketCore> SocketCore::acceptConnection() const if(fd == (sock_t) -1) { throw DL_ABORT_EX(fmt(EX_SOCKET_ACCEPT, errorMsg(errNum).c_str())); } + + applySocketBufferSize(fd); + auto sock = std::make_shared<SocketCore>(fd, sockType_); sock->setNonBlockingMode(); return sock; @@ -437,6 +465,9 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port, CLOSE(fd); continue; } + + applySocketBufferSize(fd); + if(!bindAddrs_.empty()) { bool bindSuccess = false; for(std::vector<std::pair<sockaddr_union, socklen_t> >:: @@ -1284,6 +1315,16 @@ void SocketCore::bindAllAddress(const std::string& ifaces) bindAddrs_ = *bindAddrsListIt_; } +void SocketCore::setSocketRecvBufferSize(int size) +{ + socketRecvBufferSize_ = size; +} + +int SocketCore::getSocketRecvBufferSize() +{ + return socketRecvBufferSize_; +} + void getInterfaceAddress (std::vector<std::pair<sockaddr_union, socklen_t> >& ifAddrs, const std::string& iface, int family, int aiFlags) |
