Using strace I tracked it down to the listen() system call that Factorio uses on the RCON server socket:
Code: Select all
[pid 10058] setsockopt(19, SOL_SOCKET, SO_RCVBUF, [262144], 4) = 0
[pid 10058] setsockopt(19, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
[pid 10058] bind(19, {sa_family=AF_INET, sin_port=htons(9999), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
[pid 10058] listen(19, 0) = 0
Changing the second listen() parameter into a 1 fixes the problem, as I confirmed with a small LD_PRELOAD wrapper for the listen() call.
On the other hand with SYN cookies enabled there's another problem. When sending small RCON packets everything works fine, but with larger packets (>2kB) there's a significant latency (>200ms). This was noticed by the developers of Clusterio 2.0. Investigations lead to some obscure problems with TCP window scaling, which are triggered by the 0 backlog in the listen() call and Linux's subsequent use of SYN cookies as well. Again changing the listen() parameter to a positive value through LD_PRELOAD fixes the problem.
One could argue that both are potentially bugs in the Linux kernel, however changing the backlog parameter in Factorio should be a simple and safe fix for both problems.