[exim-dev] [Bug 2518] New: TCP fastopen breaks remote_smtp o…

Top Page
Delete this message
Reply to this message
Author: admin
Date:  
To: exim-dev
Subject: [exim-dev] [Bug 2518] New: TCP fastopen breaks remote_smtp on Linux <3.6
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.