diff src/core/ngx_cycle.c @ 72:b31656313b59 NGINX_0_1_36

nginx 0.1.36 *) Change: if the request header has duplicate the "Host", "Connection", "Content-Length", or "Authorization" lines, then nginx now returns the 400 error. *) Change: the "post_accept_timeout" directive was canceled. *) Feature: the "default", "af=", "bl=", "deferred", and "bind" parameters of the "listen" directive. *) Feature: the FreeBSD accept filters support. *) Feature: the Linux TCP_DEFER_ACCEPT support. *) Bugfix: the ngx_http_autoindex_module did not support the file names in UTF-8. *) Bugfix: the new log file can be rotated by the -USR1 signal only if the reconfiguration by the -HUP signal was made twice.
author Igor Sysoev <http://sysoev.ru>
date Wed, 15 Jun 2005 00:00:00 +0400
parents 818201e5a553
children 77969b24f355
line wrap: on
line diff
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -39,18 +39,24 @@ static ngx_str_t  error_log = ngx_null_s
 
 ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
 {
-    void               *rv;
-    ngx_uint_t          i, n, failed;
-    ngx_log_t          *log;
-    ngx_conf_t          conf;
-    ngx_pool_t         *pool;
-    ngx_cycle_t        *cycle, **old;
-    ngx_socket_t        fd;
-    ngx_list_part_t    *part;
-    ngx_open_file_t    *file;
-    ngx_listening_t    *ls, *nls;
-    ngx_core_conf_t    *ccf;
-    ngx_core_module_t  *module;
+    void                      *rv;
+    ngx_uint_t                 i, n, failed;
+    ngx_log_t                 *log;
+    ngx_conf_t                 conf;
+    ngx_pool_t                *pool;
+    ngx_cycle_t               *cycle, **old;
+    ngx_socket_t               fd;
+    ngx_list_part_t           *part;
+    ngx_open_file_t           *file;
+    ngx_listening_t           *ls, *nls;
+    ngx_core_conf_t           *ccf;
+    ngx_core_module_t         *module;
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
+    struct accept_filter_arg   af;
+#endif
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
+    int                        timeout;
+#endif
 
     log = old_cycle->log;
 
@@ -307,7 +313,7 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t 
                     }
 
                     if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr)
-                                                                     == NGX_OK)
+                        == NGX_OK)
                     {
                         fd = ls[i].fd;
 #if (NGX_WIN32)
@@ -330,8 +336,44 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t 
                         }
 
                         nls[n].fd = ls[i].fd;
-                        nls[i].remain = 1;
+                        nls[n].remain = 1;
                         ls[i].remain = 1;
+
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
+
+                        /*
+                         * FreeBSD, except the most recent versions,
+                         * can not remove accept filter
+                         */
+                        nls[n].deferred_accept = ls[i].deferred_accept;
+
+                        if (ls[i].accept_filter && nls[n].accept_filter) {
+                            if (ngx_strcmp(ls[i].accept_filter,
+                                           nls[n].accept_filter) != 0)
+                            {
+                                nls[n].delete_deferred = 1;
+                                nls[n].add_deferred = 1;
+                            }
+
+                        } else if (ls[i].accept_filter) {
+                            nls[n].delete_deferred = 1;
+
+                        } else if (nls[n].accept_filter) {
+                            nls[n].add_deferred = 1;
+                        }
+#endif
+
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
+
+                        if (ls[n].deferred_accept && !nls[n].deferred_accept) {
+                            nls[n].delete_deferred = 1;
+
+                        } else if (ls[i].deferred_accept
+                                   != nls[n].deferred_accept)
+                        {
+                            nls[n].add_deferred = 1;
+                        }
+#endif
                         break;
                     }
                 }
@@ -345,6 +387,16 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t 
             ls = cycle->listening.elts;
             for (i = 0; i < cycle->listening.nelts; i++) {
                 ls[i].open = 1;
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
+                if (ls[i].accept_filter) {
+                    ls[i].add_deferred = 1;
+                }
+#endif
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
+                if (ls[i].deferred_accept) {
+                    ls[i].add_deferred = 1;
+                }
+#endif
             }
         }
 
@@ -352,6 +404,81 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t 
             if (ngx_open_listening_sockets(cycle) == NGX_ERROR) {
                 failed = 1;
             }
+
+#if (NGX_HAVE_DEFERRED_ACCEPT)
+
+            if (!failed) {
+                ls = cycle->listening.elts;
+                for (i = 0; i < cycle->listening.nelts; i++) {
+
+#ifdef SO_ACCEPTFILTER
+                    if (ls[i].delete_deferred) {
+                        if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
+                                       NULL, 0) == -1)
+                        {
+                            ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+                                        "setsockopt(SO_ACCEPTFILTER, NULL) "
+                                        "for %V failed, ignored",
+                                        &ls[i].addr_text);
+
+                            if (ls[i].accept_filter) {
+                                ngx_log_error(NGX_LOG_ALERT, log, 0,
+                                        "could not change the accept filter "
+                                        "to \"%s\" for %V, ignored",
+                                        ls[i].accept_filter, &ls[i].addr_text);
+                            }
+
+                            continue;
+                        }
+
+                        ls[i].deferred_accept = 0;
+                    }
+
+                    if (ls[i].add_deferred) {
+                        ngx_memzero(&af, sizeof(struct accept_filter_arg));
+                        (void) ngx_cpystrn((u_char *) af.af_name,
+                                           (u_char *) ls[i].accept_filter, 16);
+
+                        if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
+                                 &af, sizeof(struct accept_filter_arg)) == -1)
+                        {
+                            ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+                                        "setsockopt(SO_ACCEPTFILTER, \"%s\") "
+                                        "for %V failed, ignored",
+                                        ls[i].accept_filter, &ls[i].addr_text);
+                            continue;
+                        }
+
+                        ls[i].deferred_accept = 1;
+                    }
+#endif
+
+#ifdef TCP_DEFER_ACCEPT
+                    if (ls[i].add_deferred || ls[i].delete_deferred) {
+                        timeout = 0;
+
+                        if (ls[i].add_deferred) {
+                            timeout = (int) (ls[i].post_accept_timeout / 1000);
+                        }
+
+                        if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
+                                       &timeout, sizeof(int)) == -1)
+                        {
+                            ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+                                        "setsockopt(TCP_DEFER_ACCEPT, %d) "
+                                        "for %V failed, ignored",
+                                        timeout, &ls[i].addr_text);
+                            continue;
+                        }
+                    }
+
+                    if (ls[i].add_deferred) {
+                        ls[i].deferred_accept = 1;
+                    }
+#endif
+                }
+            }
+#endif
         }
     }
 
@@ -682,6 +809,7 @@ void ngx_reopen_files(ngx_cycle_t *cycle
                 break;
             }
             part = part->next;
+            file = part->elts;
             i = 0;
         }