Mercurial > hg > nginx-ranges
diff src/core/ngx_connection.c @ 112:408f195b3482 NGINX_0_3_3
nginx 0.3.3
*) Change: the "bl" and "af" parameters of the "listen" directive was
renamed to the "backlog" and "accept_filter".
*) Feature: the "rcvbuf" and "sndbuf" parameters of the "listen"
directive.
*) Change: the "$msec" log parameter does not require now the
additional the gettimeofday() system call.
*) Feature: the -t switch now tests the "listen" directives.
*) Bugfix: if the invalid address was specified in the "listen"
directive, then after the -HUP signal nginx left an open socket in
the CLOSED state.
*) Bugfix: the mime type may be incorrectly set to default value for
index file with variable in the name; bug appeared in 0.3.0.
*) Feature: the "timer_resolution" directive.
*) Feature: the millisecond "$upstream_response_time" log parameter.
*) Bugfix: a temporary file with client request body now is removed
just after the response header was transferred to a client.
*) Bugfix: OpenSSL 0.9.6 compatibility.
*) Bugfix: the SSL certificate and key file paths could not be relative.
*) Bugfix: the "ssl_prefer_server_ciphers" directive did not work in
the ngx_imap_ssl_module.
*) Bugfix: the "ssl_protocols" directive allowed to specify the single
protocol only.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 19 Oct 2005 00:00:00 +0400 |
parents | dad2fe8ecf08 |
children | ebca9c35e3a6 |
line wrap: on
line diff
--- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -66,13 +66,12 @@ ngx_set_inherited_sockets(ngx_cycle_t *c ngx_uint_t i; ngx_listening_t *ls; struct sockaddr_in *sin; + socklen_t olen; #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) ngx_err_t err; - socklen_t aflen; struct accept_filter_arg af; #endif #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) - socklen_t tlen; int timeout; #endif @@ -126,12 +125,38 @@ ngx_set_inherited_sockets(ngx_cycle_t *c ls[i].backlog = -1; + olen = sizeof(int); + + if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf, + &olen) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "getsockopt(SO_RCVBUF) %V failed, ignored", + &ls[i].addr_text); + + ls[i].rcvbuf = -1; + } + + olen = sizeof(int); + + if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, (void *) &ls[i].sndbuf, + &olen) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "getsockopt(SO_SNDBUF) %V failed, ignored", + &ls[i].addr_text); + + ls[i].sndbuf = -1; + } + #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) ngx_memzero(&af, sizeof(struct accept_filter_arg)); - aflen = sizeof(struct accept_filter_arg); + olen = sizeof(struct accept_filter_arg); - if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &aflen) + if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen) == -1) { err = ngx_errno; @@ -146,7 +171,7 @@ ngx_set_inherited_sockets(ngx_cycle_t *c continue; } - if (aflen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') { + if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') { continue; } @@ -162,9 +187,9 @@ ngx_set_inherited_sockets(ngx_cycle_t *c #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) timeout = 0; - tlen = sizeof(int); + olen = sizeof(int); - if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &tlen) + if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen) == -1) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, ngx_errno, @@ -188,7 +213,8 @@ ngx_set_inherited_sockets(ngx_cycle_t *c ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle) { - ngx_uint_t tries, failed, reuseaddr, i; + int reuseaddr; + ngx_uint_t i, tries, failed; ngx_err_t err; ngx_log_t *log; ngx_socket_t s; @@ -201,9 +227,9 @@ ngx_open_listening_sockets(ngx_cycle_t * log = cycle->log; - /* TODO: tries configurable */ + /* TODO: configurable try number */ - for (tries = /* STUB */ 5; tries; tries--) { + for (tries = 5 ; tries; tries--) { failed = 0; /* for each listening socket */ @@ -236,25 +262,19 @@ ngx_open_listening_sockets(ngx_cycle_t * return NGX_ERROR; } -#if (NGX_WIN32) - - /* - * Winsock assignes a socket number divisible by 4 - * so to find a connection we divide a socket number by 4. - */ - - if (s % 4) { - ngx_log_error(NGX_LOG_EMERG, log, 0, - ngx_socket_n " created socket %d", s); - return NGX_ERROR; - } -#endif - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (const void *) &reuseaddr, sizeof(int)) == -1) { + (const void *) &reuseaddr, sizeof(int)) + == -1) + { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, "setsockopt(SO_REUSEADDR) %V failed", &ls[i].addr_text); + + if (ngx_close_socket(s) == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_close_socket_n " %V failed", + &ls[i].addr_text); + return NGX_ERROR; } @@ -265,56 +285,54 @@ ngx_open_listening_sockets(ngx_cycle_t * ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, ngx_nonblocking_n " %V failed", &ls[i].addr_text); + + if (ngx_close_socket(s) == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_close_socket_n " %V failed", + &ls[i].addr_text); + return NGX_ERROR; } } -#if 0 - if (ls[i].nonblocking) { - if (ngx_nonblocking(s) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - ngx_nonblocking_n " %V failed", - &ls[i].addr_text); - return NGX_ERROR; - } - } -#endif - if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) { err = ngx_socket_errno; + + if (err == NGX_EADDRINUSE && ngx_test_config) { + continue; + } + ngx_log_error(NGX_LOG_EMERG, log, err, "bind() to %V failed", &ls[i].addr_text); - if (err != NGX_EADDRINUSE) - return NGX_ERROR; - if (ngx_close_socket(s) == -1) ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, ngx_close_socket_n " %V failed", &ls[i].addr_text); + if (err != NGX_EADDRINUSE) { + return NGX_ERROR; + } + failed = 1; + continue; } - if (listen(s, ls[i].backlog) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - "listen() to %V failed", &ls[i].addr_text); - return NGX_ERROR; - } - - /* TODO: deferred accept */ + ls[i].listen = 1; ls[i].fd = s; } - if (!failed) + if (!failed) { break; + } /* TODO: delay configurable */ ngx_log_error(NGX_LOG_NOTICE, log, 0, "try again to bind() after 500ms"); + ngx_msleep(500); } @@ -328,6 +346,143 @@ ngx_open_listening_sockets(ngx_cycle_t * void +ngx_configure_listening_socket(ngx_cycle_t *cycle) +{ + ngx_uint_t i; + ngx_listening_t *ls; + +#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 + + ls = cycle->listening.elts; + for (i = 0; i < cycle->listening.nelts; i++) { + + if (ls[i].rcvbuf != -1) { + if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, + (const void *) &ls[i].rcvbuf, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(SO_RCVBUF) %V failed, ignored", + &ls[i].addr_text); + return; + } + } + + if (ls[i].sndbuf != -1) { + if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, + (const void *) &ls[i].sndbuf, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(SO_SNDBUF) %V failed, ignored", + &ls[i].addr_text); + return; + } + } + + if (ls[i].listen) { + if (listen(ls[i].fd, ls[i].backlog) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "changing the listen() backlog to %d " + "for %V failed, ignored", + &ls[i].addr_text, ls[i].backlog); + } + } + + /* + * setting deferred mode should be last operation on socket, + * because code may prematurely continue cycle on failure + */ + +#if (NGX_HAVE_DEFERRED_ACCEPT) + +#ifdef SO_ACCEPTFILTER + + if (ls->delete_deferred) { + if (setsockopt(ls->fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0) == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "setsockopt(SO_ACCEPTFILTER, NULL) " + "for %V failed, ignored", + &ls->addr_text); + + if (ls->accept_filter) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, + "could not change the accept filter " + "to \"%s\" for %V, ignored", + ls->accept_filter, &ls->addr_text); + } + + continue; + } + + ls->deferred_accept = 0; + } + + if (ls->add_deferred) { + ngx_memzero(&af, sizeof(struct accept_filter_arg)); + (void) ngx_cpystrn((u_char *) af.af_name, + (u_char *) ls->accept_filter, 16); + + if (setsockopt(ls->fd, SOL_SOCKET, SO_ACCEPTFILTER, + &af, sizeof(struct accept_filter_arg)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "setsockopt(SO_ACCEPTFILTER, \"%s\") " + " for %V failed, ignored", + ls->accept_filter, &ls->addr_text); + continue; + } + + ls->deferred_accept = 1; + } + +#endif + +#ifdef TCP_DEFER_ACCEPT + + if (ls->add_deferred || ls->delete_deferred) { + + if (ls->add_deferred) { + timeout = (int) (ls->post_accept_timeout / 1000); + + } else { + timeout = 0; + } + + if (setsockopt(ls->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, + &timeout, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, " + "ignored", + timeout, &ls->addr_text); + + continue; + } + } + + if (ls->add_deferred) { + ls->deferred_accept = 1; + } + +#endif + +#endif /* NGX_HAVE_DEFERRED_ACCEPT */ + } + + return; +} + + +void ngx_close_listening_sockets(ngx_cycle_t *cycle) { ngx_uint_t i; @@ -361,6 +516,9 @@ ngx_close_listening_sockets(ngx_cycle_t c->fd = (ngx_socket_t) -1; + ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, + "close listening %V #%d ", &ls[i].addr_text, ls[i].fd); + if (ngx_close_socket(ls[i].fd) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno, ngx_close_socket_n " %V failed", &ls[i].addr_text); @@ -495,27 +653,26 @@ ngx_close_connection(ngx_connection_t *c * before we clean the connection */ - if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_OK) { + ngx_mutex_lock(ngx_posted_events_mutex); - if (c->read->prev) { - ngx_delete_posted_event(c->read); - } + if (c->read->prev) { + ngx_delete_posted_event(c->read); + } - if (c->write->prev) { - ngx_delete_posted_event(c->write); - } + if (c->write->prev) { + ngx_delete_posted_event(c->write); + } - c->read->closed = 1; - c->write->closed = 1; + c->read->closed = 1; + c->write->closed = 1; - if (c->single_connection) { - ngx_unlock(&c->lock); - c->read->locked = 0; - c->write->locked = 0; - } + if (c->single_connection) { + ngx_unlock(&c->lock); + c->read->locked = 0; + c->write->locked = 0; + } - ngx_mutex_unlock(ngx_posted_events_mutex); - } + ngx_mutex_unlock(ngx_posted_events_mutex); #else