mirror of https://github.com/aria2/aria2
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 optionpull/498/head
parent
699f04d0b8
commit
e8a9a366db
|
@ -1562,6 +1562,14 @@ Advanced Options
|
||||||
:option:`--save-session` option every SEC seconds. If ``0`` is
|
:option:`--save-session` option every SEC seconds. If ``0`` is
|
||||||
given, file will be saved only when aria2 exits. Default: ``0``
|
given, file will be saved only when aria2 exits. Default: ``0``
|
||||||
|
|
||||||
|
|
||||||
|
.. option:: --socket-recv-buffer-size=<SIZE>
|
||||||
|
|
||||||
|
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. Default: ``0``
|
||||||
|
|
||||||
.. option:: --stop=<SEC>
|
.. option:: --stop=<SEC>
|
||||||
|
|
||||||
Stop application after SEC seconds has passed.
|
Stop application after SEC seconds has passed.
|
||||||
|
|
|
@ -223,6 +223,8 @@ Context::Context(bool standalone,
|
||||||
setDefaultAIFlags(0);
|
setDefaultAIFlags(0);
|
||||||
}
|
}
|
||||||
SocketCore::setIpDscp(op->getAsInt(PREF_DSCP));
|
SocketCore::setIpDscp(op->getAsInt(PREF_DSCP));
|
||||||
|
SocketCore::setSocketRecvBufferSize(op->getAsInt
|
||||||
|
(PREF_SOCKET_RECV_BUFFER_SIZE));
|
||||||
net::checkAddrconfig();
|
net::checkAddrconfig();
|
||||||
// Bind interface
|
// Bind interface
|
||||||
if(!op->get(PREF_INTERFACE).empty()) {
|
if(!op->get(PREF_INTERFACE).empty()) {
|
||||||
|
|
|
@ -811,6 +811,16 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
|
||||||
op->addTag(TAG_ADVANCED);
|
op->addTag(TAG_ADVANCED);
|
||||||
handlers.push_back(op);
|
handlers.push_back(op);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
OptionHandler* op(new UnitNumberOptionHandler
|
||||||
|
(PREF_SOCKET_RECV_BUFFER_SIZE,
|
||||||
|
TEXT_SOCKET_RECV_BUFFER_SIZE,
|
||||||
|
"0",
|
||||||
|
0,
|
||||||
|
16_m));
|
||||||
|
op->addTag(TAG_ADVANCED);
|
||||||
|
handlers.push_back(op);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
OptionHandler* op(new NumberOptionHandler
|
OptionHandler* op(new NumberOptionHandler
|
||||||
(PREF_STOP,
|
(PREF_STOP,
|
||||||
|
|
|
@ -143,6 +143,8 @@ SocketCore::bindAddrsList_;
|
||||||
std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > >::iterator
|
std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > >::iterator
|
||||||
SocketCore::bindAddrsListIt_;
|
SocketCore::bindAddrsListIt_;
|
||||||
|
|
||||||
|
int SocketCore::socketRecvBufferSize_ = 0;
|
||||||
|
|
||||||
#ifdef ENABLE_SSL
|
#ifdef ENABLE_SSL
|
||||||
std::shared_ptr<TLSContext> SocketCore::clTlsContext_;
|
std::shared_ptr<TLSContext> SocketCore::clTlsContext_;
|
||||||
std::shared_ptr<TLSContext> SocketCore::svTlsContext_;
|
std::shared_ptr<TLSContext> SocketCore::svTlsContext_;
|
||||||
|
@ -187,6 +189,23 @@ SocketCore::~SocketCore() {
|
||||||
closeConnection();
|
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)
|
void SocketCore::create(int family, int protocol)
|
||||||
{
|
{
|
||||||
int errNum;
|
int errNum;
|
||||||
|
@ -205,6 +224,9 @@ void SocketCore::create(int family, int protocol)
|
||||||
throw DL_ABORT_EX
|
throw DL_ABORT_EX
|
||||||
(fmt("Failed to create socket. Cause:%s", errorMsg(errNum).c_str()));
|
(fmt("Failed to create socket. Cause:%s", errorMsg(errNum).c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applySocketBufferSize(fd);
|
||||||
|
|
||||||
sockfd_ = fd;
|
sockfd_ = fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,6 +262,9 @@ static sock_t bindInternal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // IPV6_V6ONLY
|
#endif // IPV6_V6ONLY
|
||||||
|
|
||||||
|
applySocketBufferSize(fd);
|
||||||
|
|
||||||
if(::bind(fd, addr, addrlen) == -1) {
|
if(::bind(fd, addr, addrlen) == -1) {
|
||||||
errNum = SOCKET_ERRNO;
|
errNum = SOCKET_ERRNO;
|
||||||
error = errorMsg(errNum);
|
error = errorMsg(errNum);
|
||||||
|
@ -364,6 +389,9 @@ std::shared_ptr<SocketCore> SocketCore::acceptConnection() const
|
||||||
if(fd == (sock_t) -1) {
|
if(fd == (sock_t) -1) {
|
||||||
throw DL_ABORT_EX(fmt(EX_SOCKET_ACCEPT, errorMsg(errNum).c_str()));
|
throw DL_ABORT_EX(fmt(EX_SOCKET_ACCEPT, errorMsg(errNum).c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applySocketBufferSize(fd);
|
||||||
|
|
||||||
auto sock = std::make_shared<SocketCore>(fd, sockType_);
|
auto sock = std::make_shared<SocketCore>(fd, sockType_);
|
||||||
sock->setNonBlockingMode();
|
sock->setNonBlockingMode();
|
||||||
return sock;
|
return sock;
|
||||||
|
@ -437,6 +465,9 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port,
|
||||||
CLOSE(fd);
|
CLOSE(fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applySocketBufferSize(fd);
|
||||||
|
|
||||||
if(!bindAddrs_.empty()) {
|
if(!bindAddrs_.empty()) {
|
||||||
bool bindSuccess = false;
|
bool bindSuccess = false;
|
||||||
for(std::vector<std::pair<sockaddr_union, socklen_t> >::
|
for(std::vector<std::pair<sockaddr_union, socklen_t> >::
|
||||||
|
@ -1284,6 +1315,16 @@ void SocketCore::bindAllAddress(const std::string& ifaces)
|
||||||
bindAddrs_ = *bindAddrsListIt_;
|
bindAddrs_ = *bindAddrsListIt_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SocketCore::setSocketRecvBufferSize(int size)
|
||||||
|
{
|
||||||
|
socketRecvBufferSize_ = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SocketCore::getSocketRecvBufferSize()
|
||||||
|
{
|
||||||
|
return socketRecvBufferSize_;
|
||||||
|
}
|
||||||
|
|
||||||
void getInterfaceAddress
|
void getInterfaceAddress
|
||||||
(std::vector<std::pair<sockaddr_union, socklen_t> >& ifAddrs,
|
(std::vector<std::pair<sockaddr_union, socklen_t> >& ifAddrs,
|
||||||
const std::string& iface, int family, int aiFlags)
|
const std::string& iface, int family, int aiFlags)
|
||||||
|
|
|
@ -76,6 +76,8 @@ private:
|
||||||
static std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > > bindAddrsList_;
|
static std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > > bindAddrsList_;
|
||||||
static std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > >::iterator bindAddrsListIt_;
|
static std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > >::iterator bindAddrsListIt_;
|
||||||
|
|
||||||
|
static int socketRecvBufferSize_;
|
||||||
|
|
||||||
bool blocking_;
|
bool blocking_;
|
||||||
int secure_;
|
int secure_;
|
||||||
|
|
||||||
|
@ -359,6 +361,9 @@ public:
|
||||||
protocolFamily_ = protocolFamily;
|
protocolFamily_ = protocolFamily;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setSocketRecvBufferSize(int size);
|
||||||
|
static int getSocketRecvBufferSize();
|
||||||
|
|
||||||
// Bind socket to interface. interface may be specified as a
|
// Bind socket to interface. interface may be specified as a
|
||||||
// hostname, IP address or interface name like eth0. If the given
|
// hostname, IP address or interface name like eth0. If the given
|
||||||
// interface is not found or binding socket is failed, exception
|
// interface is not found or binding socket is failed, exception
|
||||||
|
|
|
@ -375,6 +375,8 @@ PrefPtr PREF_PAUSE_METADATA = makePref("pause-metadata");
|
||||||
PrefPtr PREF_RLIMIT_NOFILE = makePref("rlimit-nofile");
|
PrefPtr PREF_RLIMIT_NOFILE = makePref("rlimit-nofile");
|
||||||
// values: SSLv3 | TLSv1 | TLSv1.1 | TLSv1.2
|
// values: SSLv3 | TLSv1 | TLSv1.1 | TLSv1.2
|
||||||
PrefPtr PREF_MIN_TLS_VERSION = makePref("min-tls-version");
|
PrefPtr PREF_MIN_TLS_VERSION = makePref("min-tls-version");
|
||||||
|
// value: 1*digit
|
||||||
|
PrefPtr PREF_SOCKET_RECV_BUFFER_SIZE = makePref("socket-recv-buffer-size");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FTP related preferences
|
* FTP related preferences
|
||||||
|
|
|
@ -312,6 +312,8 @@ extern PrefPtr PREF_PAUSE_METADATA;
|
||||||
extern PrefPtr PREF_RLIMIT_NOFILE;
|
extern PrefPtr PREF_RLIMIT_NOFILE;
|
||||||
// values: SSLv3 | TLSv1 | TLSv1.1 | TLSv1.2
|
// values: SSLv3 | TLSv1 | TLSv1.1 | TLSv1.2
|
||||||
extern PrefPtr PREF_MIN_TLS_VERSION;
|
extern PrefPtr PREF_MIN_TLS_VERSION;
|
||||||
|
// value: 1*digit
|
||||||
|
extern PrefPtr PREF_SOCKET_RECV_BUFFER_SIZE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FTP related preferences
|
* FTP related preferences
|
||||||
|
|
|
@ -1040,3 +1040,9 @@
|
||||||
" public key when SFTP is used. If this option is\n" \
|
" public key when SFTP is used. If this option is\n" \
|
||||||
" not set, which is default, no validation takes\n" \
|
" not set, which is default, no validation takes\n" \
|
||||||
" place.")
|
" place.")
|
||||||
|
#define TEXT_SOCKET_RECV_BUFFER_SIZE \
|
||||||
|
_(" --socket-recv-buffer-size=SIZE\n" \
|
||||||
|
" Set the maximum socket receive buffer in bytes.\n" \
|
||||||
|
" Specifing 0 will disable this option. This value\n" \
|
||||||
|
" will be set to socket file descriptor using\n" \
|
||||||
|
" SO_RCVBUF socket option with setsockopt() call.")
|
||||||
|
|
Loading…
Reference in New Issue