From fb05276aaee4c27b6f20fb1f32290ee40a929064 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Fri, 21 Oct 2016 00:26:14 +0100 Subject: [PATCH] TCP Fast Open --- doc/doc-docbook/spec.xfpt | 21 +++++++++- doc/doc-txt/NewStuff | 9 +++++ doc/doc-txt/OptionLists.txt | 1 + src/src/daemon.c | 18 +++++---- src/src/functions.h | 2 +- src/src/globals.c | 3 ++ src/src/globals.h | 3 ++ src/src/ip.c | 34 +++++++++++++++-- src/src/routers/iplookup.c | 14 ++++--- src/src/smtp_in.c | 2 - src/src/smtp_out.c | 17 +++++---- src/src/transports/appendfile.c | 9 ++--- src/src/transports/smtp.c | 4 +- src/src/transports/smtp.h | 1 + src/src/verify.c | 14 ++----- test/confs/2052 | 67 ++++++++++++++++++++++++++++++++ test/confs/2152 | 68 +++++++++++++++++++++++++++++++++ test/log/2052 | 13 +++++++ test/log/2152 | 9 +++++ test/scripts/2000-GnuTLS/2052 | 22 +++++++++++ test/scripts/2100-OpenSSL/2152 | 21 ++++++++++ test/stderr/0388 | 6 ++- test/stderr/0398 | 3 +- test/stderr/0432 | 9 +++-- test/stderr/5403 | 3 +- test/stderr/5410 | 9 +++-- test/stderr/5420 | 9 +++-- test/stderr/5840 | 3 +- test/stdout/0572 | 1 + 29 files changed, 336 insertions(+), 59 deletions(-) create mode 100644 test/confs/2052 create mode 100644 test/confs/2152 create mode 100644 test/log/2052 create mode 100644 test/log/2152 create mode 100644 test/scripts/2000-GnuTLS/2052 create mode 100644 test/scripts/2100-OpenSSL/2152 diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 45d845718..478b5e1a4 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -23986,11 +23986,30 @@ unauthenticated. See also &%hosts_require_auth%&, and chapter .cindex CHUNKING "enabling, in client" .cindex BDAT "SMTP command" .cindex "RFC 3030" "CHUNKING" -This option provides a list of server to which, provided they announce +This option provides a list of servers to which, provided they announce CHUNKING support, Exim will attempt to use BDAT commands rather than DATA. BDAT will not be used in conjuction with a transport filter. .wen +.new +.option hosts_try_fastopen smtp "host list!!" unset +.option "fast open, TCP" "enabling, in client" +.option "TCP Fast Open" "enabling, in client" +.option "RFC 7413" "TCP Fast Open" +This option provides a list of servers to which, provided +the facility is supported by this system, Exim will attempt to +perform a TCP Fast Open. +No data is sent on the SYN segment but, if the remote server also +supports the facility, it can send its SMTP banner immediately after +the SYN,ACK segment. This can save up to one round-trip time. + +The facility is only active for previously-contacted servers, +as the initiator must present a cookie in the SYN segment. + +On (at least some) current Linux distributions the facility must be enabled +in the kernel by the sysadmin before the support is usable. +.wen + .option hosts_try_prdr smtp "host list&!!" * .cindex "PRDR" "enabling, optional in client" This option provides a list of servers to which, provided they announce diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index cca958f79..83ee4c3af 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -54,6 +54,15 @@ Version 4.88 14. If built with EXPERIMENTAL_QUEUEFILE, a queuefile transport, for writing out copies of the message spool files for use by 3rd-party scanners. +15. A new option on the smtp transport, hosts_try_fastopen. If the system + supports it (on Linux it must be enabled in the kernel by the sysadmin) + try to use RFC 7413 "TCP Fast Open". No data is sent on the SYN segment + but it permits a peer that also supports the facility to send its SMTP + banner immediately after the SYN,ACK segment rather then waiting for + another ACK - so saving up to one roundtrip time. Because it requires + previous communication with the peer (we save a cookie from it) this + will only become active on frequently-contected destinations. + Version 4.87 ------------ diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt index 53c07436a..dc16b6dee 100644 --- a/doc/doc-txt/OptionLists.txt +++ b/doc/doc-txt/OptionLists.txt @@ -300,6 +300,7 @@ hosts_require_ocsp host list unset smtp hosts_require_tls host list unset smtp 3.20 hosts_treat_as_local domain list unset main 1.95 hosts_try_auth host list unset smtp 4.00 +hosts_try_fastopen host list unset smtp 4.88 hosts_try_prdr host list unset smtp 4.82 if experimental_prdr ibase_servers string unset main 4.23 ignore_bounce_errors_after time 0s main 4.00 diff --git a/src/src/daemon.c b/src/src/daemon.c index a22ac8d68..2efaeba95 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -932,8 +932,6 @@ DEBUG(D_any|D_v) debug_selector |= D_pid; if (inetd_wait_mode) { - int on = 1; - listen_socket_count = 1; listen_sockets = store_get(sizeof(int)); (void) close(3); @@ -1364,7 +1362,6 @@ the listening sockets if required. */ if (daemon_listen && !inetd_wait_mode) { int sk; - int on = 1; ip_address_item *ipa; /* For each IP address, create a socket, bind it to the appropriate port, and @@ -1466,13 +1463,18 @@ if (daemon_listen && !inetd_wait_mode) } DEBUG(D_any) - { if (wildcard) debug_printf("listening on all interfaces (IPv%c) port %d\n", - (af == AF_INET6)? '6' : '4', ipa->port); + af == AF_INET6 ? '6' : '4', ipa->port); else debug_printf("listening on %s port %d\n", ipa->address, ipa->port); - } + +#ifdef TCP_FASTOPEN + if (setsockopt(listen_sockets[sk], SOL_TCP, TCP_FASTOPEN, &smtp_connect_backlog, + sizeof(smtp_connect_backlog))) + log_write(0, LOG_MAIN|LOG_PANIC, "failed to set socket FASTOPEN: %s", + strerror(errno)); +#endif /* Start listening on the bound socket, establishing the maximum backlog of connections that is allowed. On success, continue to the next address. */ @@ -1487,8 +1489,8 @@ if (daemon_listen && !inetd_wait_mode) if (!check_special_case(errno, addresses, ipa, TRUE)) log_write(0, LOG_PANIC_DIE, "listen() failed on interface %s: %s", - wildcard? ((af == AF_INET6)? US"(any IPv6)" : US"(any IPv4)") : - ipa->address, + wildcard + ? af == AF_INET6 ? US"(any IPv6)" : US"(any IPv4)" : ipa->address, strerror(errno)); DEBUG(D_any) debug_printf("wildcard IPv4 listen() failed after IPv6 " diff --git a/src/src/functions.h b/src/src/functions.h index dad00c971..05386d105 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -226,7 +226,7 @@ extern uschar *imap_utf7_encode(uschar *, const uschar *, extern void invert_address(uschar *, uschar *); extern int ip_addr(void *, int, const uschar *, int); extern int ip_bind(int, int, uschar *, int); -extern int ip_connect(int, int, const uschar *, int, int); +extern int ip_connect(int, int, const uschar *, int, int, BOOL); extern int ip_connectedsocket(int, const uschar *, int, int, int, host_item *, uschar **); extern int ip_get_address_family(int); diff --git a/src/src/globals.c b/src/src/globals.c index b5ac6ceaf..dcdd6f880 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -990,6 +990,9 @@ BOOL no_mbox_unspool = FALSE; #endif BOOL no_multiline_responses = FALSE; +const int on = 1; /* for setsockopt */ +const int off = 0; + uid_t original_euid; gid_t originator_gid; uschar *originator_login = NULL; diff --git a/src/src/globals.h b/src/src/globals.h index 6e89dde1b..3e91c427d 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -611,6 +611,9 @@ extern BOOL no_mbox_unspool; /* don't unlink files in /scan directory #endif extern BOOL no_multiline_responses; /* For broken clients */ +extern const int on; /* For setsockopt */ +extern const int off; + extern optionlist optionlist_auths[]; /* These option lists are made */ extern int optionlist_auths_size; /* global so that readconf can */ extern optionlist optionlist_routers[]; /* see them for printing out */ diff --git a/src/src/ip.c b/src/src/ip.c index 04b86060f..b744f5d4c 100644 --- a/src/src/ip.c +++ b/src/src/ip.c @@ -175,12 +175,14 @@ Arguments: address the remote address, in text form port the remote port timeout a timeout (zero for indefinite timeout) + fastopen TRUE iff TCP_FASTOPEN can be used Returns: 0 on success; -1 on failure, with errno set */ int -ip_connect(int sock, int af, const uschar *address, int port, int timeout) +ip_connect(int sock, int af, const uschar *address, int port, int timeout, + BOOL fastopen) { struct sockaddr_in s_in4; struct sockaddr *s_ptr; @@ -221,7 +223,31 @@ timer, thereby allowing the inbuilt OS timeout to operate. */ callout_address = string_sprintf("[%s]:%d", address, port); sigalrm_seen = FALSE; if (timeout > 0) alarm(timeout); -rc = connect(sock, s_ptr, s_len); + +#ifdef TCP_FASTOPEN +/* 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. +*/ + +if (fastopen) + { + if ( (rc = sendto(sock, NULL, 0, MSG_FASTOPEN, s_ptr, s_len)) < 0 + && errno == EOPNOTSUPP + ) + { + log_write(0, LOG_MAIN|LOG_PANIC, + "Tried TCP Fast Open but apparently not enabled by sysctl"); + rc = connect(sock, s_ptr, s_len); + } + } +else +#endif + rc = connect(sock, s_ptr, s_len); + save_errno = errno; alarm(0); @@ -319,7 +345,7 @@ else /* Try to connect to the server - test each IP till one works */ -for (h = &shost; h != NULL; h = h->next) +for (h = &shost; h; h = h->next) { fd = Ustrchr(h->address, ':') != 0 ? fd6 < 0 ? (fd6 = ip_socket(type, af = AF_INET6)) : fd6 @@ -332,7 +358,7 @@ for (h = &shost; h != NULL; h = h->next) } for(port = portlo; port <= porthi; port++) - if (ip_connect(fd, af, h->address, port, timeout) == 0) + if (ip_connect(fd, af, h->address, port, timeout, type == SOCK_STREAM) == 0) { if (fd != fd6) close(fd6); if (fd != fd4) close(fd4); diff --git a/src/src/routers/iplookup.c b/src/src/routers/iplookup.c index 310e4d66d..e6a35a7f3 100644 --- a/src/src/routers/iplookup.c +++ b/src/src/routers/iplookup.c @@ -191,7 +191,7 @@ being a host list. */ listptr = ob->hosts; while ((hostname = string_nextinlist(&listptr, &sep, host_buffer, - sizeof(host_buffer))) != NULL) + sizeof(host_buffer)))) { host_item *h; @@ -214,19 +214,20 @@ while ((hostname = string_nextinlist(&listptr, &sep, host_buffer, /* Loop for possible multiple IP addresses for the given name. */ - for (h = host; h != NULL; h = h->next) + for (h = host; h; h = h->next) { int host_af, query_socket; /* Skip any hosts for which we have no address */ - if (h->address == NULL) continue; + if (!h->address) continue; /* Create a socket, for UDP or TCP, as configured. IPv6 addresses are detected by checking for a colon in the address. */ host_af = (Ustrchr(h->address, ':') != NULL)? AF_INET6 : AF_INET; - query_socket = ip_socket((ob->protocol == ip_udp)? SOCK_DGRAM:SOCK_STREAM, + + query_socket = ip_socket(ob->protocol == ip_udp ? SOCK_DGRAM:SOCK_STREAM, host_af); if (query_socket < 0) { @@ -240,7 +241,8 @@ while ((hostname = string_nextinlist(&listptr, &sep, host_buffer, here only for TCP calls; for a UDP socket, "connect" always works (the router will timeout later on the read call). */ - if (ip_connect(query_socket, host_af, h->address,ob->port, ob->timeout) < 0) + if (ip_connect(query_socket, host_af, h->address,ob->port, ob->timeout, + ob->protocol != ip_udp) < 0) { close(query_socket); DEBUG(D_route) @@ -282,7 +284,7 @@ while ((hostname = string_nextinlist(&listptr, &sep, host_buffer, /* If h == NULL we have tried all the IP addresses and failed on all of them, so we must continue to try more host names. Otherwise we have succeeded. */ - if (h != NULL) break; + if (h) break; } diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 9282352ac..bc6583da1 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -143,8 +143,6 @@ static BOOL pipelining_advertised; static BOOL rcpt_smtp_response_same; static BOOL rcpt_in_progress; static int nonmail_command_count; -static int off = 0; -static int on = 1; static BOOL smtp_exit_function_called = 0; #ifdef SUPPORT_I18N static BOOL smtputf8_advertised; diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index 5ab15cb5f..0c655e260 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -41,10 +41,9 @@ const uschar * expint; uschar *iface; int sep = 0; -if (istring == NULL) return TRUE; +if (!istring) return TRUE; -expint = expand_string(istring); -if (expint == NULL) +if (!(expint = expand_string(istring))) { if (expand_string_forcedfail) return TRUE; addr->transport_return = PANIC; @@ -57,7 +56,7 @@ while (isspace(*expint)) expint++; if (*expint == 0) return TRUE; while ((iface = string_nextinlist(&expint, &sep, big_buffer, - big_buffer_size)) != NULL) + big_buffer_size))) { if (string_is_ip_address(iface, NULL) == 0) { @@ -72,7 +71,7 @@ while ((iface = string_nextinlist(&expint, &sep, big_buffer, break; } -if (iface != NULL) *interface = string_copy(iface); +if (iface) *interface = string_copy(iface); return TRUE; } @@ -152,8 +151,8 @@ int dscp_value; int dscp_level; int dscp_option; int sock; -int on = 1; int save_errno = 0; +BOOL fastopen = FALSE; #ifndef DISABLE_EVENT deliver_host_address = host->address; @@ -186,6 +185,10 @@ if (dscp && dscp_lookup(dscp, host_af, &dscp_level, &dscp_option, &dscp_value)) (void) setsockopt(sock, dscp_level, dscp_option, &dscp_value, sizeof(dscp_value)); } +#ifdef TCP_FASTOPEN +if (verify_check_given_host (&ob->hosts_try_fastopen, host) == OK) fastopen = TRUE; +#endif + /* Bind to a specific interface if requested. Caller must ensure the interface is the same type (IPv4 or IPv6) as the outgoing address. */ @@ -200,7 +203,7 @@ if (interface && ip_bind(sock, host_af, interface, 0) < 0) /* Connect to the remote host, and add keepalive to the socket before returning it, if requested. */ -else if (ip_connect(sock, host_af, host->address, port, timeout) < 0) +else if (ip_connect(sock, host_af, host->address, port, timeout, fastopen) < 0) save_errno = errno; /* Either bind() or connect() failed */ diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index c9d150525..884452208 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -619,19 +619,18 @@ if (host_find_byname(&host, NULL, 0, NULL, FALSE) == HOST_FIND_FAILED) host.address = US"127.0.0.1"; -for (h = &host; h != NULL; h = h->next) +for (h = &host; h; h = h->next) { int sock, rc; - int host_af = (Ustrchr(h->address, ':') != NULL)? AF_INET6 : AF_INET; + int host_af = Ustrchr(h->address, ':') != NULL ? AF_INET6 : AF_INET; DEBUG(D_transport) debug_printf("calling comsat on %s\n", h->address); - sock = ip_socket(SOCK_DGRAM, host_af); - if (sock < 0) continue; + if ((sock = ip_socket(SOCK_DGRAM, host_af)) < 0) continue; /* Connect never fails for a UDP socket, so don't set a timeout. */ - (void)ip_connect(sock, host_af, h->address, ntohs(sp->s_port), 0); + (void)ip_connect(sock, host_af, h->address, ntohs(sp->s_port), 0, FALSE); rc = send(sock, buffer, Ustrlen(buffer) + 1, 0); (void)close(sock); diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 278349b4a..6c6a10266 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -124,6 +124,8 @@ optionlist smtp_transport_options[] = { { "hosts_try_dane", opt_stringptr, (void *)offsetof(smtp_transport_options_block, hosts_try_dane) }, #endif + { "hosts_try_fastopen", opt_stringptr, + (void *)offsetof(smtp_transport_options_block, hosts_try_fastopen) }, #ifndef DISABLE_PRDR { "hosts_try_prdr", opt_stringptr, (void *)offsetof(smtp_transport_options_block, hosts_try_prdr) }, @@ -209,6 +211,7 @@ smtp_transport_options_block smtp_transport_option_defaults = { NULL, /* hosts_try_dane */ NULL, /* hosts_require_dane */ #endif + NULL, /* hosts_try_fastopen */ #ifndef DISABLE_PRDR US"*", /* hosts_try_prdr */ #endif @@ -286,7 +289,6 @@ static uschar *smtp_command; /* Points to last cmd for error messages */ static uschar *mail_command; /* Points to MAIL cmd for error messages */ static BOOL update_waiting; /* TRUE to update the "wait" database */ static BOOL pipelining_active; /* current transaction is in pipe mode */ -static int off = 0; /* for use by setsockopt */ /************************************************* diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h index d3666ae78..c8df38ab4 100644 --- a/src/src/transports/smtp.h +++ b/src/src/transports/smtp.h @@ -26,6 +26,7 @@ typedef struct { uschar *hosts_try_dane; uschar *hosts_require_dane; #endif + uschar *hosts_try_fastopen; #ifndef DISABLE_PRDR uschar *hosts_try_prdr; #endif diff --git a/src/src/verify.c b/src/src/verify.c index f8f1809cb..aa7988cef 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -41,7 +41,6 @@ static tree_node *dnsbl_cache = NULL; static uschar cutthrough_response(char, uschar **); -static int off = 0; /* for use by setsockopt */ /************************************************* @@ -2909,9 +2908,8 @@ DEBUG(D_ident) debug_printf("doing ident callback\n"); to the incoming interface address. If the sender host address is an IPv6 address, the incoming interface address will also be IPv6. */ -host_af = (Ustrchr(sender_host_address, ':') == NULL)? AF_INET : AF_INET6; -sock = ip_socket(SOCK_STREAM, host_af); -if (sock < 0) return; +host_af = Ustrchr(sender_host_address, ':') == NULL ? AF_INET : AF_INET6; +if ((sock = ip_socket(SOCK_STREAM, host_af)) < 0) return; if (ip_bind(sock, host_af, interface_address, 0) < 0) { @@ -2920,19 +2918,15 @@ if (ip_bind(sock, host_af, interface_address, 0) < 0) goto END_OFF; } -if (ip_connect(sock, host_af, sender_host_address, port, rfc1413_query_timeout) - < 0) +if (ip_connect(sock, host_af, sender_host_address, port, + rfc1413_query_timeout, TRUE) < 0) { if (errno == ETIMEDOUT && LOGGING(ident_timeout)) - { log_write(0, LOG_MAIN, "ident connection to %s timed out", sender_host_address); - } else - { DEBUG(D_ident) debug_printf("ident connection to %s failed: %s\n", sender_host_address, strerror(errno)); - } goto END_OFF; } diff --git a/test/confs/2052 b/test/confs/2052 new file mode 100644 index 000000000..fd1f4d1c0 --- /dev/null +++ b/test/confs/2052 @@ -0,0 +1,67 @@ +# Exim test configuration 2052 +# as per 2000 but with TCP Fast Open + +SERVER= + +.include DIR/aux-var/tls_conf_prefix + +primary_hostname = myhost.test.ex + +# ----- Main settings ----- + +acl_smtp_rcpt = accept + +log_selector = +tls_peerdn + +queue_only +queue_run_in_order + +tls_advertise_hosts = * +# needed to force generation +tls_dhparam = historic + +# Set certificate only if server + +tls_certificate = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail} +tls_privatekey = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail} + +tls_verify_hosts = * +tls_verify_certificates = ${if eq {SERVER}{server}{DIR/aux-fixed/cert2}fail} + + +# ----- Routers ----- + +begin routers + +client: + driver = accept + condition = ${if eq {SERVER}{server}{no}{yes}} + retry_use_local_part + transport = send_to_server + + +# ----- Transports ----- + +begin transports + +send_to_server: + driver = smtp + allow_localhost + hosts = 127.0.0.1 + port = PORT_D + hosts_try_fastopen = * + tls_certificate = DIR/aux-fixed/cert2 + tls_privatekey = DIR/aux-fixed/cert2 + tls_verify_certificates = DIR/aux-fixed/cert2 + tls_try_verify_hosts = + + +# ----- Retry ----- + + +begin retry + +* * F,5d,10s + + +# End diff --git a/test/confs/2152 b/test/confs/2152 new file mode 100644 index 000000000..a8b6c15f1 --- /dev/null +++ b/test/confs/2152 @@ -0,0 +1,68 @@ +# Exim test configuration 2152 +# as per 2100 but with TCP Fast Open + +SERVER= + +.include DIR/aux-var/tls_conf_prefix + +primary_hostname = myhost.test.ex + +.ifdef _HAVE_TLS +# that was purely to trigger the lazy-create of builtin macros +.endif +# ----- Main settings ----- + +acl_smtp_rcpt = accept + +log_selector = +tls_peerdn + +queue_only +queue_run_in_order + +tls_advertise_hosts = * + +# Set certificate only if server + +tls_certificate = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail} +tls_privatekey = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail} + +tls_verify_hosts = * +tls_verify_certificates = ${if eq {SERVER}{server}{DIR/aux-fixed/cert2}fail} + + +# ----- Routers ----- + +begin routers + +client: + driver = accept + condition = ${if eq {SERVER}{server}{no}{yes}} + retry_use_local_part + transport = send_to_server + + +# ----- Transports ----- + +begin transports + +send_to_server: + driver = smtp + allow_localhost + hosts = 127.0.0.1 + port = PORT_D + hosts_try_fastopen = * + tls_certificate = DIR/aux-fixed/cert2 + tls_privatekey = DIR/aux-fixed/cert2 + tls_verify_certificates = DIR/aux-fixed/cert2 + tls_try_verify_hosts = : + + +# ----- Retry ----- + + +begin retry + +* * F,5d,10s + + +# End diff --git a/test/log/2052 b/test/log/2052 new file mode 100644 index 000000000..68c88a330 --- /dev/null +++ b/test/log/2052 @@ -0,0 +1,13 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 Start queue run: pid=pppp -qf +1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (certificate verification failed): certificate invalid +1999-03-02 09:44:33 10HmaX-0005vi-00 TLS session failure: delivering unencrypted to 127.0.0.1 [127.0.0.1] (not in hosts_require_tls) +1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaY-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 End queue run: pid=pppp -qf + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 +1999-03-02 09:44:33 TLS error on connection from localhost [127.0.0.1] (recv): A TLS fatal alert has been received.: Certificate is bad +1999-03-02 09:44:33 TLS error on connection from localhost [127.0.0.1] (send): The specified session has been invalidated for some reason. +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex diff --git a/test/log/2152 b/test/log/2152 new file mode 100644 index 000000000..1ed6351ff --- /dev/null +++ b/test/log/2152 @@ -0,0 +1,9 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 Start queue run: pid=pppp -qf +1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmaY-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 End queue run: pid=pppp -qf + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmaX-0005vi-00@myhost.test.ex diff --git a/test/scripts/2000-GnuTLS/2052 b/test/scripts/2000-GnuTLS/2052 new file mode 100644 index 000000000..fa76b4849 --- /dev/null +++ b/test/scripts/2000-GnuTLS/2052 @@ -0,0 +1,22 @@ +# TLS client: TLS setup fails - retry in clear (with fastopen) +# +# If all works you'll not see any difference. To enable in the +# kernel, 'sudo sh -c "echo 3 > /proc/sys/net/ipv4/tcp_fastopen"'. +# A packet capture on the loopback interface will show the TFU +# option on the SYN, but the fast-output SMTP banner will not +# be seen unless you also deliberately emulate a long path: +# 'sudo tc qdisc add dev lo root netem delay 100ms' +# +# If the client-side is disabled in the kernel, Exim logs +# will become noisy. +# +gnutls +exim -DSERVER=server -bd -oX PORT_D +**** +exim CALLER@test.ex +Testing +**** +exim -qf +**** +killdaemon +no_msglog_check diff --git a/test/scripts/2100-OpenSSL/2152 b/test/scripts/2100-OpenSSL/2152 new file mode 100644 index 000000000..329e42051 --- /dev/null +++ b/test/scripts/2100-OpenSSL/2152 @@ -0,0 +1,21 @@ +# TLS client: TLS setup fails - retry in clear (with fastopen) +# +# If all works you'll not see any difference. To enable in the +# kernel, 'sudo sh -c "echo 3 > /proc/sys/net/ipv4/tcp_fastopen"'. +# A packet capture on the loopback interface will show the TFU +# option on the SYN, but the fast-output SMTP banner will not +# be seen unless you also deliberately emulate a long path: +# 'sudo tc qdisc add dev lo root netem delay 100ms' +# +# If the client-side is disabled in the kernel, Exim logs +# will become noisy. +# +exim -DSERVER=server -bd -oX PORT_D +**** +exim CALLER@test.ex +Testing +**** +exim -qf +**** +killdaemon +no_msglog_check diff --git a/test/stderr/0388 b/test/stderr/0388 index 92b3f23e1..f8866380e 100644 --- a/test/stderr/0388 +++ b/test/stderr/0388 @@ -81,7 +81,8 @@ returned from EXIM_DBOPEN no retry data available 127.0.0.1 in serialize_hosts? no (option unset) set_process_info: pppp delivering 10HmaX-0005vi-00 to 127.0.0.1 [127.0.0.1] (x@y) -Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected +Connecting to 127.0.0.1 [127.0.0.1]:1224 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +connected SMTP<< 220 Server ready 127.0.0.1 in hosts_avoid_esmtp? no (option unset) SMTP>> EHLO myhost.test.ex @@ -112,7 +113,8 @@ returned from EXIM_DBOPEN no retry data available V4NET.0.0.0 in serialize_hosts? no (option unset) set_process_info: pppp delivering 10HmaX-0005vi-00 to V4NET.0.0.0 [V4NET.0.0.0] (x@y) -Connecting to V4NET.0.0.0 [V4NET.0.0.0]:1224 ... failed: Network Error +Connecting to V4NET.0.0.0 [V4NET.0.0.0]:1224 ... V4NET.0.0.0 in hosts_try_fastopen? no (option unset) +failed: Network Error LOG: MAIN H=V4NET.0.0.0 [V4NET.0.0.0] Network Error set_process_info: pppp delivering 10HmaX-0005vi-00: just tried V4NET.0.0.0 [V4NET.0.0.0] for x@y: result DEFER diff --git a/test/stderr/0398 b/test/stderr/0398 index 3e3994b99..1dcb998f7 100644 --- a/test/stderr/0398 +++ b/test/stderr/0398 @@ -129,7 +129,8 @@ dbfn_read: key=qq@remote callout cache: no address record found for qq@remote closed hints database and lockfile interface=NULL port=1224 -Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected +Connecting to 127.0.0.1 [127.0.0.1]:1224 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +connected SMTP<< 220 Server ready 127.0.0.1 in hosts_avoid_esmtp? no (option unset) SMTP>> EHLO mail.test.ex diff --git a/test/stderr/0432 b/test/stderr/0432 index 2fe0ca868..76111d5d7 100644 --- a/test/stderr/0432 +++ b/test/stderr/0432 @@ -90,7 +90,8 @@ dbfn_read: key=x@y callout cache: no address record found for x@y closed hints database and lockfile interface=NULL port=1224 -Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected +Connecting to 127.0.0.1 [127.0.0.1]:1224 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +connected SMTP<< 220 server ready 127.0.0.1 in hosts_avoid_esmtp? no (option unset) SMTP>> EHLO myhost.test.ex @@ -255,7 +256,8 @@ MUNGED: ::1 will be omitted in what follows >>> callout cache: no domain record found for b >>> callout cache: no address record found for a@b >>> interface=NULL port=1224 ->>> Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected +>>> Connecting to 127.0.0.1 [127.0.0.1]:1224 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +>>> connected >>> SMTP<< 220 server ready >>> 127.0.0.1 in hosts_avoid_esmtp? no (option unset) >>> SMTP>> EHLO myhost.test.ex @@ -300,7 +302,8 @@ MUNGED: ::1 will be omitted in what follows >>> callout cache: no domain record found for q >>> callout cache: no address record found for p1@q >>> interface=NULL port=1224 ->>> Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected +>>> Connecting to 127.0.0.1 [127.0.0.1]:1224 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +>>> connected >>> SMTP<< 220 server ready >>> 127.0.0.1 in hosts_avoid_esmtp? no (option unset) >>> SMTP>> EHLO myhost.test.ex diff --git a/test/stderr/5403 b/test/stderr/5403 index dfb5a97e4..0ae10f727 100644 --- a/test/stderr/5403 +++ b/test/stderr/5403 @@ -69,7 +69,8 @@ MUNGED: ::1 will be omitted in what follows >>> Attempting full verification using callout >>> callout cache: disabled by no_cache >>> interface=ip4.ip4.ip4.ip4 port=1224 ->>> Connecting to 127.0.0.1 [127.0.0.1]:1224 from ip4.ip4.ip4.ip4 ... connected +>>> Connecting to 127.0.0.1 [127.0.0.1]:1224 from ip4.ip4.ip4.ip4 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +>>> connected >>> SMTP<< 220 server ready >>> 127.0.0.1 in hosts_avoid_esmtp? no (option unset) >>> SMTP>> EHLO myhost.test.ex diff --git a/test/stderr/5410 b/test/stderr/5410 index 7916518b7..e7323f581 100644 --- a/test/stderr/5410 +++ b/test/stderr/5410 @@ -49,7 +49,8 @@ considering: $local_part expanding: $local_part result: userx domain.com in "*"? yes (matched "*") -Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... connected +Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +connected considering: $primary_hostname expanding: $primary_hostname result: myhost.test.ex @@ -313,7 +314,8 @@ considering: $local_part expanding: $local_part result: usery domain.com in "*"? yes (matched "*") -Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... connected +Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +connected considering: $primary_hostname expanding: $primary_hostname result: myhost.test.ex @@ -544,7 +546,8 @@ considering: $local_part expanding: $local_part result: usery domain.com in "*"? yes (matched "*") -Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... connected +Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +connected considering: $primary_hostname expanding: $primary_hostname result: myhost.test.ex diff --git a/test/stderr/5420 b/test/stderr/5420 index a12451575..684629e68 100644 --- a/test/stderr/5420 +++ b/test/stderr/5420 @@ -49,7 +49,8 @@ considering: $local_part expanding: $local_part result: userx domain.com in "*"? yes (matched "*") -Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... connected +Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +connected considering: $primary_hostname expanding: $primary_hostname result: myhost.test.ex @@ -312,7 +313,8 @@ considering: $local_part expanding: $local_part result: usery domain.com in "*"? yes (matched "*") -Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... connected +Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +connected considering: $primary_hostname expanding: $primary_hostname result: myhost.test.ex @@ -543,7 +545,8 @@ considering: $local_part expanding: $local_part result: usery domain.com in "*"? yes (matched "*") -Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... connected +Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... 127.0.0.1 in hosts_try_fastopen? no (option unset) +connected considering: $primary_hostname expanding: $primary_hostname result: myhost.test.ex diff --git a/test/stderr/5840 b/test/stderr/5840 index b4b035a29..29ca2804a 100644 --- a/test/stderr/5840 +++ b/test/stderr/5840 @@ -18,7 +18,8 @@ >>> callout cache: no domain record found for dane256ee.test.ex >>> callout cache: no address record found for CALLER@dane256ee.test.ex >>> interface=NULL port=1225 ->>> Connecting to dane256ee.test.ex [ip4.ip4.ip4.ip4]:1225 ... connected +>>> Connecting to dane256ee.test.ex [ip4.ip4.ip4.ip4]:1225 ... ip4.ip4.ip4.ip4 in hosts_try_fastopen? no (option unset) +>>> connected MUNGED: ::1 will be omitted in what follows >>> get[host|ipnode]byname[2] looked up these IP addresses: >>> name=thishost.test.ex address=127.0.0.1 diff --git a/test/stdout/0572 b/test/stdout/0572 index 12cd05b78..d50a643b4 100644 --- a/test/stdout/0572 +++ b/test/stdout/0572 @@ -58,6 +58,7 @@ no_hosts_randomize hosts_require_auth = hosts_try_auth = hosts_try_chunking = * +hosts_try_fastopen = hosts_try_prdr = * interface = ip4.ip4.ip4.ip4 keepalive -- 2.30.2