summaryrefslogtreecommitdiff
path: root/src/SocketCore.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2015-11-28 14:01:24 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2015-11-28 14:12:23 +0900
commite8a9a366db7bf834a3e93c6ec05336e5aca882c4 (patch)
tree01a422d15502dac3a117a80df17781b482773015 /src/SocketCore.cc
parent699f04d0b8a93dd92a85f68cd8c307b5f3fb4741 (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.cc41
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)