Extra RTT on large certificates (again?)

Albert Casademont albertcasademont at gmail.com
Tue May 23 16:44:27 UTC 2017


Hi Maxim,

Yes, as we were already compiling our own nginx we apply a patch in openssl
before compilation increasing the buffer size to 5120 bytes as a workaround.

As for the patch, we already had "tcp_nodelay on" set in our http {} config
and we kept seeing the extra RTT, is this a different setting or I am
missing something?

I believe the optimal solution would be that openssl exposed an API to
dynamically adjust the buffer size, I'll try to work on that...

Best,

Albert

On Tue, May 23, 2017 at 6:02 PM, Maxim Dounin <mdounin at mdounin.ru> wrote:

> Hello!
>
> On Mon, May 22, 2017 at 10:34:11PM +0200, Albert Casademont wrote:
>
> > Seems like the openssl devs are aware of the issue and welcoming PRs,
> AFAIK
> > nothing's been done yet.
> >
> > https://mta.openssl.org/pipermail/openssl-users/2016-
> November/004835.html
>
> Thanks for the link, it confirms what I already concluded from the
> code.  As mentioned there, quick-and-dirty solution would be
> recompile OpenSSL with larger buffer size.
>
> > > Thanks for the prompt response. Yes, we're using Openssl 1.1.0e at the
> > > moment...That is unfortunate, what would you suggest doing? Report
> this to
> > > the openssl devs? An extra RTT is quite painful.
>
> With OpenSSL 1.1.0+ it is no longer possible to adjust handshake
> buffer size as nginx used to do, and OpenSSL changes are needed to
> make it possible again.
>
> Another approach might be to mitigate extra RTT using TCP_NODELAY.
> While result will be still non-optimal (as there will be
> incomplete packets), it should be better than nothing.
>
> Patch:
>
> # HG changeset patch
> # User Maxim Dounin <mdounin at mdounin.ru>
> # Date 1495555095 -10800
> #      Tue May 23 18:58:15 2017 +0300
> # Node ID 472c23c0a788646403074b359c30c4bbe860cbf6
> # Parent  7943298d4ac09aae83ca8eef09bcf0a12c310505
> SSL: set TCP_NODELAY on SSL connections earlier.
>
> With OpenSSL 1.1.0+, the workaround for handshake buffer size as introduced
> in a720f0b0e083 (ticket #413) no longer works, as OpenSSL no longer exposes
> handshake buffers, see https://github.com/openssl/
> openssl/commit/2e7dc7cd688.
> Moreover, it no longer possible to adjust handshake buffers at all now.
>
> To avoid additional RTT if handshake uses more than 4k we now set
> TCP_NODELAY
> on SSL connections before handshake.  While this still results in
> sub-optimal
> network utilization due to incomplete packets being sent, it seems to be
> better than nothing.
>
> diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
> --- a/src/http/ngx_http_request.c
> +++ b/src/http/ngx_http_request.c
> @@ -623,14 +623,16 @@ ngx_http_create_request(ngx_connection_t
>  static void
>  ngx_http_ssl_handshake(ngx_event_t *rev)
>  {
> -    u_char                   *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1];
> -    size_t                    size;
> -    ssize_t                   n;
> -    ngx_err_t                 err;
> -    ngx_int_t                 rc;
> -    ngx_connection_t         *c;
> -    ngx_http_connection_t    *hc;
> -    ngx_http_ssl_srv_conf_t  *sscf;
> +    int                        tcp_nodelay;
> +    u_char                    *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1];
> +    size_t                     size;
> +    ssize_t                    n;
> +    ngx_err_t                  err;
> +    ngx_int_t                  rc;
> +    ngx_connection_t          *c;
> +    ngx_http_connection_t     *hc;
> +    ngx_http_ssl_srv_conf_t   *sscf;
> +    ngx_http_core_loc_conf_t  *clcf;
>
>      c = rev->data;
>      hc = c->data;
> @@ -712,6 +714,36 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
>              ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0,
>                             "https ssl handshake: 0x%02Xd", buf[0]);
>
> +            clcf = ngx_http_get_module_loc_conf(hc->conf_ctx,
> +                                                ngx_http_core_module);
> +
> +            if (clcf->tcp_nodelay
> +                && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
> +            {
> +                ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
> "tcp_nodelay");
> +
> +                tcp_nodelay = 1;
> +
> +                if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
> +                               (const void *) &tcp_nodelay, sizeof(int))
> +                    == -1)
> +                {
> +#if (NGX_SOLARIS)
> +                    /* Solaris returns EINVAL if a socket has been shut
> down */
> +                    c->log_error = NGX_ERROR_IGNORE_EINVAL;
> +#endif
> +
> +                    ngx_connection_error(c, ngx_socket_errno,
> +                                         "setsockopt(TCP_NODELAY)
> failed");
> +
> +                    c->log_error = NGX_ERROR_INFO;
> +                    ngx_http_close_connection(c);
> +                    return;
> +                }
> +
> +                c->tcp_nodelay = NGX_TCP_NODELAY_SET;
> +            }
> +
>              sscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
>                                                  ngx_http_ssl_module);
>
> --
> Maxim Dounin
> http://nginx.org/
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20170523/1e75b171/attachment.html>


More information about the nginx-devel mailing list