From 996a98d33f790a1e6af927c02318649feec6061b Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Thu, 31 Dec 2020 21:52:02 +0000 Subject: [PATCH 1/1] TFO: better observability (slightly) on FreeBSD --- src/src/smtp_out.c | 32 +++++++++++++++++++--------- test/runtest | 2 +- test/scripts/1990-TCP-Fast-Open/1990 | 15 +++++++++++++ 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index 0bf619795..bb7a0e3b3 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -159,20 +159,32 @@ tfo_out_check(int sock) { # ifdef __FreeBSD__ struct tcp_info tinfo; -int val; -socklen_t len = sizeof(val); +socklen_t len = sizeof(tinfo); -/* The observability as of 12.1 is not useful as a client, only telling us that -a TFO option was used on SYN. It could have been a TFO-R, or ignored by the -server. */ +/* A getsockopt TCP_FASTOPEN unfortunately returns "was-used" for a TFO/R as +well as a TFO/C. Use what we can of the Linux hack below; reliability issues ditto. */ +switch (tcp_out_fastopen) + { + case TFO_ATTEMPTED_NODATA: + if ( getsockopt(sock, IPPROTO_TCP, TCP_INFO, &tinfo, &len) == 0 + && tinfo.tcpi_state == TCPS_SYN_SENT + && tinfo.__tcpi_unacked > 0 + ) + { + DEBUG(D_transport|D_v) + debug_printf("TCP_FASTOPEN tcpi_unacked %d\n", tinfo.__tcpi_unacked); + tcp_out_fastopen = TFO_USED_NODATA; + } + break; + /* + case TFO_ATTEMPTED_DATA: + case TFO_ATTEMPTED_DATA: + if (tinfo.tcpi_options & TCPI_OPT_SYN_DATA) XXX no equvalent as of 12.2 + */ + } -/* -if (tcp_out_fastopen == TFO_ATTEMPTED_NODATA || tcp_out_fastopen == TFO_ATTEMPTED_DATA) - if (getsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN, &val, &len) == 0 && val != 0) {} -*/ switch (tcp_out_fastopen) { - case TFO_ATTEMPTED_NODATA: tcp_out_fastopen = TFO_USED_NODATA; break; case TFO_ATTEMPTED_DATA: tcp_out_fastopen = TFO_USED_DATA; break; default: break; /* compiler quietening */ } diff --git a/test/runtest b/test/runtest index b5ace4ee3..1e604e1cd 100755 --- a/test/runtest +++ b/test/runtest @@ -3112,7 +3112,7 @@ if (defined $parm_trusted_config_list) open(TCL, $parm_trusted_config_list) or die "Can't open $parm_trusted_config_list: $!\n"; my $test_config = getcwd() . '/test-config'; die "Can't find '$test_config' in TRUSTED_CONFIG_LIST $parm_trusted_config_list." - if not grep { /^\Q$test_config\E$/ } ; + if not grep { /^\Q$test_config\E$/ } ; } else { diff --git a/test/scripts/1990-TCP-Fast-Open/1990 b/test/scripts/1990-TCP-Fast-Open/1990 index 80059e685..d2c7b75f9 100644 --- a/test/scripts/1990-TCP-Fast-Open/1990 +++ b/test/scripts/1990-TCP-Fast-Open/1990 @@ -27,6 +27,14 @@ # 'net.inet.tcp.fastopen.server_enable=1' in /etc/sysctl.conf # Seems to always claim TFO used by transport, if tried. # +# FreeBSD: tried this setup, but we only get the banner captured 100ms after 3rd-ack: +# #kenv net.inet.ip.fw.default_to_accept=1 +# #kldload ipfw dummynet +# #ipfw add 00097 pipe 1 ip from 127.0.0.1 to 127.0.0.1 +# #ipfw pipe 1 config delay 50ms +# Also, the VM managed to lose the ipv4 & 6 addrs on its main interface +# after a while - so not usable in production +# sudo perl system ("tc qdisc add dev lo root netem delay 50ms"); **** @@ -50,7 +58,14 @@ system ("[ -e /proc/sys/net/ipv4/tcp_fastopen_blackhole_timeout_sec ] && echo 0 # # First clear any previously-obtained cookie: sudo perl +open(INFO, "-|", "/usr/bin/uname -s"); +$_ = ; +if (/^FreeBSD/) { +system("sysctl net.inet.tcp.fastopen.client_enable=0"); system("sysctl net.inet.tcp.fastopen.client_enable=1"); +} else { system ("ip tcp_metrics delete 127.0.0.1"); +} + **** # # -- 2.30.2