On Fri, Jun 14, 2019 at 03:17:44PM +0300, anzelmooo . wrote: > Jun 14 09:36:26 mx1 postfix/smtp[6409]: 488845290: to=<us...@onmicrosoft.com>, > relay=host.mail.protection.outlook.com[ip.ip.ip.ip]:25, delay=1.7, > delays=0.01/0/0.34/1.4, dsn=2.6.0, status=sent (250 2.6.0 <msgid2> > [InternalId=1234, Hostname=host.prod.outlook.com] 111697 bytes in 0.722, > 151.051 KB/sec Queued mail for delivery) > Jun 14 09:41:26 mx1 postfix/qmgr[2699]: 488845290: removed
Note the 5 minute (300s) delay. On Fri, Jun 14, 2019 at 09:25:01AM -0400, Wietse Venema wrote: > If you want to debug this, you can log the SMTP session (debug_peer_list > = example.com) and see if the remote server delays its QUIT response. > That could explain the 5s delay. That was 5 minutes, and given the Postfix default: smtp_quit_timeout = 300s the QUIT hypothesis is in the right ballpark. > Such delays should not be a problem with the default setting > "smtp_skip_quit_response = yes", but maybe RedHat has changed that. But I doubt Redhat changed this. Another plausible hypothesis is: smtp_starttls_timeout = 300s which 2.6 also applies to the 2-way TLS session shutdown. Perhaps after "QUIT", the TCP session appears to stay up with no close notify from the server before the timeout. There may be relevant changes in the RedHat SSL stack. It would be good to see the TLS log messages (which don't have the queue-id, but have the same process-id as the smtp delivery agent) and are logged shortly before delivery success. This would confirm use of TLS and protocol details. By the way, already in RF2246 (TLS 1.0), there is no requirement to wait for the peer's close-notify. If the application protocol provides sufficient session termination signalling, then there's no need to duplicate that at the TLS close-notify layer. https://tools.ietf.org/html/rfc2246#section-7.2.1 https://tools.ietf.org/html/rfc4346#section-7.2.1 https://tools.ietf.org/html/rfc5246#section-7.2.1 Unless some other fatal alert has been transmitted, each party is required to send a close_notify alert before closing the write side of the connection. The other party MUST respond with a close_notify alert of its own and close down the connection immediately, discarding any pending writes. It is not required for the initiator of the close to wait for the responding close_notify alert before closing the read side of the connection. Therefore, we should probably eliminate the second tls_bio_shutdown() call from tls_session_stop(). -- Viktor. --- src/tls/tls_session.c +++ src/tls/tls_session.c @@ -95,18 +95,13 @@ void tls_session_stop(TLS_APPL_STATE *unused_ctx, VSTREAM *stream, int timeou msg_panic("%s: stream has no active TLS context", myname); /* - * Perform SSL_shutdown() twice, as the first attempt will send out the - * shutdown alert but it will not wait for the peer's shutdown alert. - * Therefore, when we are the first party to send the alert, we must call - * SSL_shutdown() again. On failure we don't want to resume the session, - * so we will not perform SSL_shutdown() and the session will be removed - * as being bad. + * Perform SSL_shutdown(), sending out the shutdown alert without waiting + * for the peer's shutdown alert. On failure we don't want to resume the + * session, so we will not perform SSL_shutdown() and the session will be + * removed as being bad. */ - if (!failure) { - retval = tls_bio_shutdown(vstream_fileno(stream), timeout, TLScontext); - if (retval == 0) - tls_bio_shutdown(vstream_fileno(stream), timeout, TLScontext); - } + if (!failure) + (void) tls_bio_shutdown(vstream_fileno(stream), timeout, TLScontext); tls_free_context(TLScontext); tls_stream_stop(stream); }