https://bugs.exim.org/show_bug.cgi?id=2518
Bug ID: 2518
Summary: TCP fastopen breaks remote_smtp on Linux <3.6
Product: Exim
Version: 4.88
Hardware: All
OS: Linux
Status: NEW
Severity: bug
Priority: medium
Component: Transports
Assignee: unallocated@???
Reporter: bpfoley@???
CC: exim-dev@???
Created attachment 1264
-->
https://bugs.exim.org/attachment.cgi?id=1264&action=edit
Show sendto behavior on Linux with and without TCP fastopen
The TCP fastopen function functionality introduced in 4.88 works on Linux by
modifying ip_connect to:
* Create a new socket with socket()
* Set some options with setsockopt()
* Open a fastopen connect using sendto with the MSG_FASTOPEN flag on the
currently closed socket.
On versions of Linux that implement fastopen (Linux >=3.6), if this connect
fails it sets errno to EINPROGRESS.
On earlier versions of Linux, this will unconditionally fail by setting errno
to EPIPE (and sending a SIGPIPE signal to the process).
The patch that adds fastopen support to the Linux kernel can be seen below, as
can the tcp_sendmsg code before that modification.
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/net/ipv4/tcp.c?id=cf60af03ca4e
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/net/ipv4/tcp.c?h=linux-3.5.y
Unfortunately exim's daemon_go() unconditionally sets the global
tcp_fastoption_ok to TRUE if TCP_FASTOPEN is defined. Butthe presence of
TCP_FASTOPEN in the system header files doesn't imply that it's also present in
the running kernel.
This has the nasty effect of breaking all outbound remote_smtp connections from
exim 4.88 or later unless you explicitly clear the hosts_try_fastopen
configuration setting (it defaults to *)
For compatibility's sake I think the correct solution is to check if sendto()
returns either EINPROGRESS or EPIPE, and if so, fall back to legacy
connections.
I've attached a patch for this, and a trivial test case that shows the
difference between Linux <3.6 and Linux >= 3.6
On <3.6 it prints
s_addr=100007f
sendto: Broken pipe
errno=32
On >=3.6 it prints
s_addr=100007f
sendto: Operation now in progress
errno=115
--
You are receiving this mail because:
You are on the CC list for the bug.