aboutsummaryrefslogtreecommitdiff
path: root/src/core/ngx_cycle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/ngx_cycle.c')
-rw-r--r--src/core/ngx_cycle.c156
1 files changed, 142 insertions, 14 deletions
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index 3a1c00e65..57806437a 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -39,18 +39,24 @@ static ngx_str_t error_log = ngx_null_string;
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 *old_cycle)
}
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 *old_cycle)
}
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 *old_cycle)
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 *old_cycle)
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, ngx_uid_t user)
break;
}
part = part->next;
+ file = part->elts;
i = 0;
}