[PATCH] making ngx_http_upstream_test_connect catch "connection refused" with kqueue

agentzh agentzh at gmail.com
Tue Nov 6 06:18:28 UTC 2012


Hello!

smallfish and I both ran into a small issue with the
ngx_http_upstream_test_connect which does not catch errors like
"Connection refused" when kqueue is used.

The current logic only checks c->write->pending_eof but this error
actually produced a read event on (at least) both Mac OS X and
FreeBSD.

I've attached a simple patch (for nginx 1.2.4) to fix this by checking
both the read and write events.

To reproduce the issue, please consider the following Nginx
configuration snippet (assuming nothing is listening on the local port
1234):

    location = /t {
        proxy_pass http://127.0.0.1:1234/;
    }

Accessing /t gives the following message in error.log:

    [error] 28474#0: *1 kevent() reported about an closed connection
(61: Connection refused) while reading response header from upstream

We can see that ngx_http_upstream missed it in
ngx_http_upstream_test_connect but caught it when reading the
(upstream) response header.

After applying my patch, Nginx can now catch it in the context of connecting:

    [error] 34067#0: *1 kevent() reported that connect() failed (61:
Connection refused) while connecting to upstream

Best regards,
-agentzh

--- nginx-1.2.4/src/http/ngx_http_upstream.c	2012-08-06 10:34:08.000000000 -0700
+++ nginx-1.2.4-patched/src/http/ngx_http_upstream.c	2012-11-05
21:17:38.000000000 -0800
@@ -1808,10 +1808,22 @@ ngx_http_upstream_test_connect(ngx_conne

 #if (NGX_HAVE_KQUEUE)

+    ngx_event_t *ev;
+
     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT)  {
         if (c->write->pending_eof) {
+            ev = c->write;
+
+        } else if (c->read->pending_eof) {
+            ev = c->read;
+
+        } else {
+            ev = NULL;
+        }
+
+        if (ev) {
             c->log->action = "connecting to upstream";
-            (void) ngx_connection_error(c, c->write->kq_errno,
+            (void) ngx_connection_error(c, ev->kq_errno,
                                     "kevent() reported that connect() failed");
             return NGX_ERROR;
         }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nginx-1.2.4-upstream_test_connect_kqueue.patch
Type: application/octet-stream
Size: 854 bytes
Desc: not available
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20121105/b84b3ee7/attachment.obj>


More information about the nginx-devel mailing list