libtorrent
libtorrent copied to clipboard
Listen queue overflow / incorrect accept() use
Hi!
I am running 0.15.1 on FreeBSD 14/stable and got messages in logs:
Mar 29 00:45:52 firewall kernel: [9615729] sonewconn: pcb 0xfffff801ca667a80 ([::]:8443 (proto 6)): Listen queue overflow: 193 already in queue awaiting acceptance (1 occurrences), euid 80, rgid 80, jail 0
Mar 29 00:45:52 firewall kernel: [9615729] sonewconn: pcb 0xfffff801ca667a80 ([::]:8443 (proto 6)): Listen queue overflow: 193 already in queue awaiting acceptance (1 occurrences), euid 80, rgid 80, jail 0
Mar 29 00:46:53 firewall kernel: [9615790] sonewconn: pcb 0xfffff801ca667a80 ([::]:8443 (proto 6)): Listen queue overflow: 193 already in queue awaiting acceptance (17 occurrences), euid 80, rgid 80, jail 0
Mar 29 00:46:53 firewall kernel: [9615790] sonewconn: pcb 0xfffff801ca667a80 ([::]:8443 (proto 6)): Listen queue overflow: 193 already in queue awaiting acceptance (17 occurrences), euid 80, rgid 80, jail 0
Mar 29 00:48:00 firewall kernel: [9615857] sonewconn: pcb 0xfffff801ca667a80 ([::]:8443 (proto 6)): Listen queue overflow: 193 already in queue awaiting acceptance (72 occurrences), euid 80, rgid 80, jail 0
Mar 29 00:48:00 firewall kernel: [9615857] sonewconn: pcb 0xfffff801ca667a80 ([::]:8443 (proto 6)): Listen queue overflow: 193 already in queue awaiting acceptance (72 occurrences), euid 80, rgid 80, jail 0
8443 used by rtorrent, it run under www user. I have no idea why only IPv6 connections have queue overflow.
I past I see errors like that, this happen due to wrong app arch:
void some_listen_socket_accept_cb(...) {
int fd_new = accept(fd_listen);
if (-1 != fd_new) {
// do something
} else {
// log error
}
}
Problem here it that listen socket may have more than 1 incoming connection in queue and event trigger system set to triggen only on new connections. In that case queue will grow until max_backlog reached.
void some_listen_socket_accept_cb(...) {
for (;;) {
int fd_new = accept(fd_listen);
if (-1 != fd_new) {
// do something
} else {
if (errno == EWOULDBLOCK || errno == EAGAIN)
break; /* all connections accepted. */
// log error
}
}
}
This simple modification allow to be sure that all connections from listen queue will be accepted before return to next event wait.