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)
+ switch (tcp_out_fastopen)
{
- DEBUG(D_transport|D_v) debug_printf("TCP_FASTOPEN mode connection\n");
- tcp_out_fastopen = TRUE;
+ /* This is a somewhat dubious detection method; totally undocumented so likely
+ to fail in future kernels. There seems to be no documented way. What we really
+ want to know is if the server sent smtp-banner data before our ACK of his SYN,ACK
+ hit him. What this (possibly?) detects is whether we sent a TFO cookie with our
+ SYN, as distinct from a TFO request. This gets a false-positive when the server
+ key is rotated; we send the old one (which this test sees) but the server returns
+ the new one and does not send its SMTP banner before we ACK his SYN,ACK.
+ To force that rotation case:
+ '# echo -n "00000000-00000000-00000000-0000000" >/proc/sys/net/ipv4/tcp_fastopen_key'
+ The kernel seems to be counting unack'd packets. */
+
+ case 1:
+ if (tinfo.tcpi_unacked > 1)
+ {
+ DEBUG(D_transport|D_v)
+ debug_printf("TCP_FASTOPEN tcpi_unacked %d\n", tinfo.tcpi_unacked);
+ tcp_out_fastopen = 2;
+ }
+ break;
+
+#ifdef notdef /* This seems to always fire, meaning that we cannot tell
+ whether the server accepted data we sent. For now assume
+ that it did. */
+
+ /* If there was data-on-SYN but we had to retrasnmit it, declare no TFO */
+
+ case 2:
+ if (!(tinfo.tcpi_options & TCPI_OPT_SYN_DATA))
+ {
+ DEBUG(D_transport|D_v) debug_printf("TFO: had to retransmit\n");
+ tcp_out_fastopen = 0;
+ }
+ break;
+#endif
}
+
}
# endif
}
int dscp_option;
int sock;
int save_errno = 0;
+const blob * fastopen = NULL;
+
#ifndef DISABLE_EVENT
deliver_host_address = host->address;
else
{
- const blob * fastopen = NULL;
-
#ifdef TCP_FASTOPEN
if (verify_check_given_host(&ob->hosts_try_fastopen, host) == OK)
fastopen = early_data ? early_data : &tcp_fastopen_nodata;
}
if (ob->keepalive) ip_keepalive(sock, host->address, TRUE);
#ifdef TCP_FASTOPEN
- tfo_out_check(sock);
+ if (fastopen) tfo_out_check(sock);
#endif
return sock;
}