diff src/event/ngx_event_accept.c @ 674:4dcaf40cc702 NGINX_1_3_0

nginx 1.3.0 *) Feature: the "debug_connection" directive now supports IPv6 addresses and the "unix:" parameter. *) Feature: the "set_real_ip_from" directive and the "proxy" parameter of the "geo" directive now support IPv6 addresses. *) Feature: the "real_ip_recursive", "geoip_proxy", and "geoip_proxy_recursive" directives. *) Feature: the "proxy_recursive" parameter of the "geo" directive. *) Bugfix: a segmentation fault might occur in a worker process if the "resolver" directive was used. *) Bugfix: a segmentation fault might occur in a worker process if the "fastcgi_pass", "scgi_pass", or "uwsgi_pass" directives were used and backend returned incorrect response. *) Bugfix: a segmentation fault might occur in a worker process if the "rewrite" directive was used and new request arguments in a replacement used variables. *) Bugfix: nginx might hog CPU if the open file resource limit was reached. *) Bugfix: nginx might loop infinitely over backends if the "proxy_next_upstream" directive with the "http_404" parameter was used and there were backup servers specified in an upstream block. *) Bugfix: adding the "down" parameter of the "server" directive might cause unneeded client redistribution among backend servers if the "ip_hash" directive was used. *) Bugfix: socket leak. Thanks to Yichun Zhang. *) Bugfix: in the ngx_http_fastcgi_module.
author Igor Sysoev <http://sysoev.ru>
date Tue, 15 May 2012 00:00:00 +0400
parents d0f7a625f27c
children
line wrap: on
line diff
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -21,6 +21,7 @@ ngx_event_accept(ngx_event_t *ev)
     socklen_t          socklen;
     ngx_err_t          err;
     ngx_log_t         *log;
+    ngx_uint_t         level;
     ngx_socket_t       s;
     ngx_event_t       *rev, *wev;
     ngx_listening_t   *ls;
@@ -31,6 +32,14 @@ ngx_event_accept(ngx_event_t *ev)
     static ngx_uint_t  use_accept4 = 1;
 #endif
 
+    if (ev->timedout) {
+        if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) {
+            return;
+        }
+
+        ev->timedout = 0;
+    }
+
     ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
 
     if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
@@ -70,10 +79,17 @@ ngx_event_accept(ngx_event_t *ev)
                 return;
             }
 
+            level = NGX_LOG_ALERT;
+
+            if (err == NGX_ECONNABORTED) {
+                level = NGX_LOG_ERR;
+
+            } else if (err == NGX_EMFILE || err == NGX_ENFILE) {
+                level = NGX_LOG_CRIT;
+            }
+
 #if (NGX_HAVE_ACCEPT4)
-            ngx_log_error((ngx_uint_t) ((err == NGX_ECONNABORTED) ?
-                                             NGX_LOG_ERR : NGX_LOG_ALERT),
-                          ev->log, err,
+            ngx_log_error(level, ev->log, err,
                           use_accept4 ? "accept4() failed" : "accept() failed");
 
             if (use_accept4 && err == NGX_ENOSYS) {
@@ -82,9 +98,7 @@ ngx_event_accept(ngx_event_t *ev)
                 continue;
             }
 #else
-            ngx_log_error((ngx_uint_t) ((err == NGX_ECONNABORTED) ?
-                                             NGX_LOG_ERR : NGX_LOG_ALERT),
-                          ev->log, err, "accept() failed");
+            ngx_log_error(level, ev->log, err, "accept() failed");
 #endif
 
             if (err == NGX_ECONNABORTED) {
@@ -97,6 +111,26 @@ ngx_event_accept(ngx_event_t *ev)
                 }
             }
 
+            if (err == NGX_EMFILE || err == NGX_ENFILE) {
+                if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle)
+                    != NGX_OK)
+                {
+                    return;
+                }
+
+                if (ngx_use_accept_mutex) {
+                    if (ngx_accept_mutex_held) {
+                        ngx_shmtx_unlock(&ngx_accept_mutex);
+                        ngx_accept_mutex_held = 0;
+                    }
+
+                    ngx_accept_disabled = 1;
+
+                } else {
+                    ngx_add_timer(ev, ecf->accept_mutex_delay);
+                }
+            }
+
             return;
         }
 
@@ -252,17 +286,56 @@ ngx_event_accept(ngx_event_t *ev)
 #if (NGX_DEBUG)
         {
 
-        in_addr_t            i;
-        ngx_event_debug_t   *dc;
-        struct sockaddr_in  *sin;
+        struct sockaddr_in   *sin;
+        ngx_cidr_t           *cidr;
+        ngx_uint_t            i;
+#if (NGX_HAVE_INET6)
+        struct sockaddr_in6  *sin6;
+        ngx_uint_t            n;
+#endif
+
+        cidr = ecf->debug_connection.elts;
+        for (i = 0; i < ecf->debug_connection.nelts; i++) {
+            if (cidr[i].family != c->sockaddr->sa_family) {
+                goto next;
+            }
+
+            switch (cidr[i].family) {
 
-        sin = (struct sockaddr_in *) sa;
-        dc = ecf->debug_connection.elts;
-        for (i = 0; i < ecf->debug_connection.nelts; i++) {
-            if ((sin->sin_addr.s_addr & dc[i].mask) == dc[i].addr) {
-                log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL;
+#if (NGX_HAVE_INET6)
+            case AF_INET6:
+                sin6 = (struct sockaddr_in6 *) c->sockaddr;
+                for (n = 0; n < 16; n++) {
+                    if ((sin6->sin6_addr.s6_addr[n]
+                        & cidr[i].u.in6.mask.s6_addr[n])
+                        != cidr[i].u.in6.addr.s6_addr[n])
+                    {
+                        goto next;
+                    }
+                }
+                break;
+#endif
+
+#if (NGX_HAVE_UNIX_DOMAIN)
+            case AF_UNIX:
+                break;
+#endif
+
+            default: /* AF_INET */
+                sin = (struct sockaddr_in *) c->sockaddr;
+                if ((sin->sin_addr.s_addr & cidr[i].u.in.mask)
+                    != cidr[i].u.in.addr)
+                {
+                    goto next;
+                }
                 break;
             }
+
+            log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL;
+            break;
+
+        next:
+            continue;
         }
 
         }
@@ -344,6 +417,10 @@ ngx_enable_accept_events(ngx_cycle_t *cy
 
         c = ls[i].connection;
 
+        if (c->read->active) {
+            continue;
+        }
+
         if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
 
             if (ngx_add_conn(c) == NGX_ERROR) {