diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2017-09-19 15:10:21 +0100 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2017-09-19 15:10:21 +0100 |
commit | ac0dcd3f05a8821d7ce042646472be1995a08042 (patch) | |
tree | 56532171a253e1b6c4eab094b8e9f401f72dee58 /src | |
parent | 4043ef1cec143692ca271bf868abf01d62b0d0d1 (diff) |
TFO: better detection of client fast-open connections
Diffstat (limited to 'src')
-rw-r--r-- | src/OS/os.h-Linux | 1 | ||||
-rw-r--r-- | src/src/ip.c | 40 | ||||
-rw-r--r-- | src/src/smtp_out.c | 27 |
3 files changed, 25 insertions, 43 deletions
diff --git a/src/OS/os.h-Linux b/src/OS/os.h-Linux index f6d35772b..cc1f3cab2 100644 --- a/src/OS/os.h-Linux +++ b/src/OS/os.h-Linux @@ -79,7 +79,6 @@ then change the 0 to 1 in the next block. */ #if defined(TCP_FASTOPEN) && !defined(MSG_FASTOPEN) # define MSG_FASTOPEN 0x20000000 #endif -#define EXIM_HAVE_TCPI_UNACKED /* End */ diff --git a/src/src/ip.c b/src/src/ip.c index 872745144..258ab5c23 100644 --- a/src/src/ip.c +++ b/src/src/ip.c @@ -229,27 +229,37 @@ if (timeout > 0) alarm(timeout); /* TCP Fast Open, if the system has a cookie from a previous call to this peer, can send data in the SYN packet. The peer can send data before it gets our ACK of its SYN,ACK - the latter is useful for -the SMTP banner. Is there any usage where the former might be? -We might extend the ip_connect() args for data if so. For now, -connect in FASTOPEN mode but with zero data. -*/ +the SMTP banner. Other (than SMTP) cases of TCP connections can +possibly use the data-on-syn, so support that too. */ if (fastopen) { if ((rc = sendto(sock, fastopen->data, fastopen->len, - MSG_FASTOPEN | MSG_DONTWAIT, s_ptr, s_len)) < 0) - if (errno == EINPROGRESS) /* expected for nonready peer */ - { /* queue the data */ - if ( (rc = send(sock, fastopen->data, fastopen->len, 0)) < 0 - && errno == EINPROGRESS) /* expected for nonready peer */ - rc = 0; - } - else if(errno == EOPNOTSUPP) + MSG_FASTOPEN | MSG_DONTWAIT, s_ptr, s_len)) >= 0) + { + DEBUG(D_transport|D_v) + debug_printf("TCP_FASTOPEN mode connection, with data\n"); + tcp_out_fastopen = TRUE; + } + else if (errno == EINPROGRESS) /* expected for nonready peer */ + { + if (!fastopen->data) { - DEBUG(D_transport) - debug_printf("Tried TCP Fast Open but apparently not enabled by sysctl\n"); - goto legacy_connect; + DEBUG(D_transport|D_v) + debug_printf("TCP_FASTOPEN mode connection, no data\n"); + tcp_out_fastopen = TRUE; + rc = 0; } + else if ( (rc = send(sock, fastopen->data, fastopen->len, 0)) < 0 + && errno == EINPROGRESS) /* expected for nonready peer */ + rc = 0; + } + else if(errno == EOPNOTSUPP) + { + DEBUG(D_transport) + debug_printf("Tried TCP Fast Open but apparently not enabled by sysctl\n"); + goto legacy_connect; + } } else #endif diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index 9221aa868..db33ac66e 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -140,30 +140,6 @@ return TRUE; -#ifdef TCP_FASTOPEN -static void -tfo_out_check(int sock) -{ -# if defined(TCP_INFO) && defined(EXIM_HAVE_TCPI_UNACKED) -struct tcp_info tinfo; -socklen_t len = sizeof(tinfo); - -if (getsockopt(sock, IPPROTO_TCP, TCP_INFO, &tinfo, &len) == 0) - { - /* This is a somewhat dubious detection method; totally undocumented so likely - to fail in future kernels. There seems to be no documented way. */ - - if (tinfo.tcpi_unacked > 1) - { - DEBUG(D_transport|D_v) debug_printf("TCP_FASTOPEN mode connection\n"); - tcp_out_fastopen = TRUE; - } - } -# endif -} -#endif - - /* Arguments as for smtp_connect(), plus early_data if non-NULL, data to be sent - preferably in the TCP SYN segment @@ -278,9 +254,6 @@ else return -1; } if (ob->keepalive) ip_keepalive(sock, host->address, TRUE); -#ifdef TCP_FASTOPEN - tfo_out_check(sock); -#endif return sock; } } |