Don't hardcode listen() backlog
While investigating Ticket legacy/trac#9708 (moved), I also found a lot of kernel messages along the lines of:
- sonewconn: pcb 0xfffffe005b7af000: Listen queue overflow: 193 already in queue awaiting acceptance
This despite the fact that "kern.somaxconn", which controls the length of the listen queue, was set to 4096.
Reading through the code, I found two instances of "listen(s,SOMAXCONN)" in src/or/connection.c. I think using SOMAXCONN as backlog is wrong. I think the correct backlog parameter is -1 -- which tells the kernel to accept as many connections as it's configured to accept, rather than a hardcoded constant (which happens to be the default the kernel will accept -- if not configured diferently).
SOMAXCONN is defined to 128 in <sys/socket.h> and is the default for kern.somaxconn. I'm not sure why it's exposed to userland. Possibly hysterical raisins?
Setting the backlog to -1 will allow tor to accept more connections faster if kern.somaxconn > SOMAXCONN (ie > 128).
This is true for FreeBSD (viz solisten_proto() in sys/kern/uipc_socket.) I've not tested Linux, but looking at the code (SYSCALL_DEFINE2(listen, int, fd, int, backlog) in net/socket.c) it should behave the same if I'm reading that cast correctly. On Linux, the moral equivalent of kern.somaxconn is configured with /proc/sys/net/core/somaxconn. It's also set to 128 by default. If raised to something huge, and listen() given a backlog of -1, it will also accept more connections.
Trac:
Username: philip