SSL+ProxyProtocol: Fix connection hang when a header-only packet is received

Roman Arutyunyan arut at nginx.com
Mon Mar 2 18:36:03 UTC 2015


Hello James,

On Sun, Mar 01, 2015 at 06:24:28PM -0800, James Hamlin wrote:
> # HG changeset patch
> # User James Hamlin <jfhamlin at gmail.com>
> # Date 1425260813 28800
> #      Sun Mar 01 17:46:53 2015 -0800
> # Branch fix-deferred-with-proxy-protocol
> # Node ID 3835928c9e046bab0f6bc8d35d3ede468b6a07ce
> # Parent  6a7c6973d6fc3b628b38e000f0ed192c99bdfc49
> SSL+ProxyProtocol: Fix conn. hang when header-only packet received
> 
> This is a fix for a bug exposed when using deferred accept, SSL, and the proxy
> protocol.
> 
> When accept deferral is enabled (the "deferred" option on "listen"
> directives), the "ready" bit is preemptively set on the connection's "read"
> event. If the data first received contains _only_ the proxy protocol header,
> then the "ready" bit will not be cleared by the call to ngx_recv(), since the
> call does not attempt to read more than the header itself. If the first byte
> from the client has not been received by the time the posted event is run, the
> call to ngx_handle_read_event will do nothing, as "ready" will still be set,
> and the connection will time out despite later receipt of the bytes.
> 
> The fix is to clear the "ready" bit from within ngx_http_ssl_handshake when
> it is known that only the header was available.
> 
> This is not a problem when using KQUEUE, as the "ready" bit is cleared based
> on available byte tracking.
> 
> diff -r 6a7c6973d6fc -r 3835928c9e04 src/http/ngx_http_request.c
> --- a/src/http/ngx_http_request.c Fri Feb 27 16:28:31 2015 +0300
> +++ b/src/http/ngx_http_request.c Sun Mar 01 17:46:53 2015 -0800
> @@ -691,6 +691,12 @@
>          c->log->action = "SSL handshaking";
> 
>          if (n == (ssize_t) size) {
> +#if (NGX_HAVE_KQUEUE)
> +            if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) == 0)
> +#endif
> +            {
> +                rev->ready = 0;
> +            }
>              ngx_post_event(rev, &ngx_posted_events);
>              return;
>          }

Thanks for reporting the issue.
We've committed a slightly different solution for this.

http://hg.nginx.org/nginx/rev/5b549cc7f698

--
Roman



More information about the nginx-devel mailing list