mirror of
https://github.com/transmission/transmission
synced 2025-03-01 17:25:38 +00:00
Use large kernel buffers for the UDP socket when uTP is enabled.
Since we're using a single UDP socket to implement multiple uTP sockets, and since we're not always timely in servicing an incoming UDP packet, it's important to use a large receive buffer. The send buffer is probably less critical, we increase it nonetheless.
This commit is contained in:
parent
a348c5d421
commit
5af8e26251
3 changed files with 76 additions and 1 deletions
|
@ -1990,6 +1990,8 @@ toggle_utp( void * data )
|
|||
|
||||
session->isUTPEnabled = !session->isUTPEnabled;
|
||||
|
||||
tr_udpSetSocketBuffers( session );
|
||||
|
||||
/* But don't call tr_utpClose -- see reset_timer in tr-utp.c for an
|
||||
explanation. */
|
||||
}
|
||||
|
|
|
@ -33,6 +33,77 @@ THE SOFTWARE.
|
|||
#include "tr-utp.h"
|
||||
#include "tr-udp.h"
|
||||
|
||||
/* Since we use a single UDP socket in order to implement multiple
|
||||
uTP sockets, try to set up huge buffers. */
|
||||
|
||||
#define RECV_BUFFER_SIZE (4 * 1024 * 1024)
|
||||
#define SEND_BUFFER_SIZE (1 * 1024 * 1024)
|
||||
#define SMALL_BUFFER_SIZE (32 * 1024)
|
||||
|
||||
static void
|
||||
set_socket_buffers(int fd, int large)
|
||||
{
|
||||
int size, rbuf, sbuf, rc;
|
||||
socklen_t rbuf_len = sizeof(rbuf), sbuf_len = sizeof(sbuf);
|
||||
|
||||
size = large ? RECV_BUFFER_SIZE : SMALL_BUFFER_SIZE;
|
||||
rc = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
|
||||
if(rc < 0)
|
||||
tr_nerr("UDP", "Failed to set receive buffer: %s",
|
||||
tr_strerror(errno));
|
||||
|
||||
size = large ? SEND_BUFFER_SIZE : SMALL_BUFFER_SIZE;
|
||||
rc = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
|
||||
if(rc < 0)
|
||||
tr_nerr("UDP", "Failed to set send buffer: %s",
|
||||
tr_strerror(errno));
|
||||
|
||||
if(large) {
|
||||
rc = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rbuf, &rbuf_len);
|
||||
if(rc < 0)
|
||||
rbuf = 0;
|
||||
|
||||
rc = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sbuf, &sbuf_len);
|
||||
if(rc < 0)
|
||||
sbuf = 0;
|
||||
|
||||
if(rbuf < RECV_BUFFER_SIZE) {
|
||||
tr_nerr("UDP", "Failed to set receive buffer: requested %d, got %d",
|
||||
RECV_BUFFER_SIZE, rbuf);
|
||||
#ifdef __linux__
|
||||
tr_ninf("UDP",
|
||||
"Please add the line "
|
||||
"\"net.core.rmem_max = %d\" to /etc/sysctl.conf",
|
||||
RECV_BUFFER_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(sbuf < SEND_BUFFER_SIZE) {
|
||||
tr_nerr("UDP", "Failed to set send buffer: requested %d, got %d",
|
||||
SEND_BUFFER_SIZE, sbuf);
|
||||
#ifdef __linux__
|
||||
tr_ninf("UDP",
|
||||
"Please add the line "
|
||||
"\"net.core.wmem_max = %d\" to /etc/sysctl.conf",
|
||||
SEND_BUFFER_SIZE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tr_udpSetSocketBuffers(tr_session *session)
|
||||
{
|
||||
tr_bool utp = tr_sessionIsUTPEnabled(session);
|
||||
if(session->udp_socket >= 0)
|
||||
set_socket_buffers(session->udp_socket, utp);
|
||||
if(session->udp6_socket >= 0)
|
||||
set_socket_buffers(session->udp6_socket, utp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* BEP-32 has a rather nice explanation of why we need to bind to one
|
||||
IPv6 address, if I may say so myself. */
|
||||
|
||||
|
@ -199,6 +270,8 @@ tr_udpInit(tr_session *ss)
|
|||
tr_nerr("UDP", "Couldn't allocate IPv6 event");
|
||||
}
|
||||
|
||||
tr_udpSetSocketBuffers(ss);
|
||||
|
||||
if(ss->isDHTEnabled)
|
||||
tr_dhtInit(ss);
|
||||
|
||||
|
|
|
@ -27,4 +27,4 @@ THE SOFTWARE.
|
|||
|
||||
void tr_udpInit( tr_session * );
|
||||
void tr_udpUninit( tr_session * );
|
||||
|
||||
void tr_udpSetSocketBuffers(tr_session *);
|
||||
|
|
Loading…
Reference in a new issue