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

James Hamlin jfhamlin at
Mon Mar 2 02:24:28 UTC 2015

# HG changeset patch
# User James Hamlin <jfhamlin at>
# 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

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_event_flags & NGX_USE_KQUEUE_EVENT) == 0)
+            {
+                rev->ready = 0;
+            }
             ngx_post_event(rev, &ngx_posted_events);

More information about the nginx-devel mailing list