diff options
author | Igor Sysoev <igor@sysoev.ru> | 2005-09-23 15:02:22 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2005-09-23 15:02:22 +0400 |
commit | 31eb8c015d58a5b36b9578d4ee6c217e16cb776f (patch) | |
tree | 28ebccc10deba4132e05414aac1874d5013fdf58 /src/event | |
parent | f44a1f5f579e19441db2d477a7c81d8894ba2262 (diff) |
nginx-0.2.0-RELEASE importrelease-0.2.0
*) The pid-file names used during online upgrade was changed and now is
not required a manual rename operation. The old master process adds
the ".oldbin" suffix to its pid-file and executes a new binary file.
The new master process creates usual pid-file without the ".newbin"
suffix. If the master process exits, then old master process renames
back its pid-file with the ".oldbin" suffix to the pid-file without
suffix.
*) Change: the "worker_connections" directive, new name of the
"connections" directive; now the directive specifies maximum number
of connections, but not maximum socket descriptor number.
*) Feature: SSL supports the session cache inside one worker process.
*) Feature: the "satisfy_any" directive.
*) Change: the ngx_http_access_module and ngx_http_auth_basic_module do
not run for subrequests.
*) Feature: the "worker_rlimit_nofile" and "worker_rlimit_sigpending"
directives.
*) Bugfix: if all backend using in load-balancing failed after one
error, then nginx did not try do connect to them during 60 seconds.
*) Bugfix: in IMAP/POP3 command argument parsing.
Thanks to Rob Mueller.
*) Bugfix: errors while using SSL in IMAP/POP3 proxy.
*) Bugfix: errors while using SSI and gzipping.
*) Bugfix: the "Expires" and "Cache-Control" header lines were omitted
from the 304 responses.
Thanks to Alexandr Kukushkin.
Diffstat (limited to 'src/event')
-rw-r--r-- | src/event/modules/ngx_devpoll_module.c | 26 | ||||
-rw-r--r-- | src/event/modules/ngx_poll_module.c | 12 | ||||
-rw-r--r-- | src/event/modules/ngx_rtsig_module.c | 10 | ||||
-rw-r--r-- | src/event/ngx_event.c | 174 | ||||
-rw-r--r-- | src/event/ngx_event.h | 39 | ||||
-rw-r--r-- | src/event/ngx_event_accept.c | 311 | ||||
-rw-r--r-- | src/event/ngx_event_acceptex.c | 155 | ||||
-rw-r--r-- | src/event/ngx_event_connect.c | 122 | ||||
-rw-r--r-- | src/event/ngx_event_connect.h | 3 | ||||
-rw-r--r-- | src/event/ngx_event_openssl.c | 138 | ||||
-rw-r--r-- | src/event/ngx_event_openssl.h | 6 |
11 files changed, 523 insertions, 473 deletions
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c index 413b0def4..5faa1fbcd 100644 --- a/src/event/modules/ngx_devpoll_module.c +++ b/src/event/modules/ngx_devpoll_module.c @@ -177,7 +177,7 @@ ngx_devpoll_init(ngx_cycle_t *cycle) ngx_event_actions = ngx_devpoll_module_ctx.actions; - ngx_event_flags = NGX_USE_LEVEL_EVENT; + ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_FD_EVENT; return NGX_OK; } @@ -449,10 +449,10 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle) lock = 1; for (i = 0; i < events; i++) { - c = &ngx_cycle->connections[event_list[i].fd]; + c = ngx_cycle->files[event_list[i].fd]; if (c->fd == -1) { - if (ngx_cycle->read_events[event_list[i].fd].closed) { + if (c->read->closed) { continue; } @@ -460,26 +460,6 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle) continue; } -#if 0 - if (c->fd == -1) { - old_cycle = ngx_old_cycles.elts; - for (j = 0; j < ngx_old_cycles.nelts; j++) { - if (old_cycle[j] == NULL) { - continue; - } - c = &old_cycle[j]->connections[event_list[i].fd]; - if (c->fd != -1) { - break; - } - } - } - - if (c->fd == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "unknown cycle"); - exit(1); - } -#endif - revents = event_list[i].revents; ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c index 68d592cca..7de0e4ba6 100644 --- a/src/event/modules/ngx_poll_module.c +++ b/src/event/modules/ngx_poll_module.c @@ -109,7 +109,9 @@ ngx_poll_init(ngx_cycle_t *cycle) ngx_event_actions = ngx_poll_module_ctx.actions; - ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_ONESHOT_EVENT; + ngx_event_flags = NGX_USE_LEVEL_EVENT + |NGX_USE_ONESHOT_EVENT + |NGX_USE_FD_EVENT; return NGX_OK; } @@ -229,7 +231,7 @@ ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags) event_list[ev->index] = event_list[nevents]; - c = &ngx_cycle->connections[event_list[nevents].fd]; + c = ngx_cycle->files[event_list[nevents].fd]; if (c->fd == -1) { cycle = ngx_old_cycles.elts; @@ -237,7 +239,7 @@ ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags) if (cycle[i] == NULL) { continue; } - c = &cycle[i]->connections[event_list[nevents].fd]; + c = cycle[i]->files[event_list[nevents].fd]; if (c->fd != -1) { break; } @@ -425,7 +427,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle) continue; } - c = &ngx_cycle->connections[event_list[i].fd]; + c = ngx_cycle->files[event_list[i].fd]; if (c->fd == -1) { old_cycle = ngx_old_cycles.elts; @@ -433,7 +435,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle) if (old_cycle[n] == NULL) { continue; } - c = &old_cycle[n]->connections[event_list[i].fd]; + c = old_cycle[n]->files[event_list[i].fd]; if (c->fd != -1) { break; } diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c index 69792c67c..92e33a013 100644 --- a/src/event/modules/ngx_rtsig_module.c +++ b/src/event/modules/ngx_rtsig_module.c @@ -165,7 +165,9 @@ ngx_rtsig_init(ngx_cycle_t *cycle) ngx_event_actions = ngx_rtsig_module_ctx.actions; - ngx_event_flags = NGX_USE_RTSIG_EVENT|NGX_USE_GREEDY_EVENT; + ngx_event_flags = NGX_USE_RTSIG_EVENT + |NGX_USE_GREEDY_EVENT + |NGX_USE_FD_EVENT; return NGX_OK; } @@ -428,7 +430,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle) /* TODO: old_cycles */ - c = &ngx_cycle->connections[si.si_fd]; + c = ngx_cycle->files[si.si_fd]; instance = signo - rtscf->signo; @@ -596,7 +598,7 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle) break; } - c = &cycle->connections[overflow_current++]; + c = cycle->files[overflow_current++]; if (c->fd == -1) { continue; @@ -652,7 +654,7 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle) } for (i = 0; i < n; i++) { - c = &cycle->connections[overflow_list[i].fd]; + c = cycle->files[overflow_list[i].fd]; rev = c->read; diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index 5557c340d..eaca46746 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -113,6 +113,13 @@ static ngx_conf_post_t ngx_accept_mutex_post = { ngx_accept_mutex_check } ; static ngx_command_t ngx_event_core_commands[] = { + { ngx_string("worker_connections"), + NGX_EVENT_CONF|NGX_CONF_TAKE1, + ngx_event_connections, + 0, + 0, + NULL }, + { ngx_string("connections"), NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_event_connections, @@ -322,13 +329,15 @@ ngx_handle_write_event(ngx_event_t *wev, size_t lowat) static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle) { -#if !(NGX_WIN32) - - size_t size; void ***cf; + ngx_event_conf_t *ecf; +#if !(NGX_WIN32) char *shared; + size_t size; + ngx_int_t limit; + struct rlimit rlmt; ngx_core_conf_t *ccf; - ngx_event_conf_t *ecf; +#endif cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module); @@ -343,9 +352,30 @@ ngx_event_module_init(ngx_cycle_t *cycle) ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "using the \"%s\" event method", ecf->name); +#if !(NGX_WIN32) ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); + if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "getrlimit(RLIMIT_NOFILE) failed, ignored"); + + } else { + if (ecf->connections > (ngx_uint_t) rlmt.rlim_cur + && (ccf->rlimit_nofile == NGX_CONF_UNSET + || ecf->connections > (ngx_uint_t) ccf->rlimit_nofile)) + { + limit = (ccf->rlimit_nofile == NGX_CONF_UNSET) ? + (ngx_int_t) rlmt.rlim_cur : ccf->rlimit_nofile; + + ngx_log_error(NGX_LOG_WARN, cycle->log, 0, + "%ui worker_connections are more than " + "open file resource limit: %i", + ecf->connections, limit); + } + } + + if (ccf->master == 0 || ngx_accept_mutex_ptr) { return NGX_OK; } @@ -390,7 +420,7 @@ ngx_event_module_init(ngx_cycle_t *cycle) "counter: %p, %d", ngx_connection_counter, *ngx_connection_counter); -#endif +#endif /* !(NGX_WIN32) */ return NGX_OK; } @@ -400,15 +430,16 @@ static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle) { ngx_uint_t m, i; - ngx_socket_t fd; ngx_event_t *rev, *wev; - ngx_listening_t *s; - ngx_connection_t *c; + ngx_listening_t *ls; + ngx_connection_t *c, *next, *old; ngx_core_conf_t *ccf; ngx_event_conf_t *ecf; ngx_event_module_t *module; #if (NGX_WIN32) ngx_iocp_conf_t *iocpcf; +#else + struct rlimit rlmt; #endif ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); @@ -449,28 +480,42 @@ ngx_event_process_init(ngx_cycle_t *cycle) } } - cycle->connections = ngx_alloc(sizeof(ngx_connection_t) * ecf->connections, - cycle->log); - if (cycle->connections == NULL) { - return NGX_ERROR; +#if !(NGX_WIN32) + + if (ngx_event_flags & NGX_USE_FD_EVENT) { + + if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "getrlimit(RLIMIT_NOFILE) failed"); + return NGX_ERROR; + } + + cycle->files_n = (ngx_uint_t) rlmt.rlim_cur; + + cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n, + cycle->log); + if (cycle->files == NULL) { + return NGX_ERROR; + } } - c = cycle->connections; - for (i = 0; i < cycle->connection_n; i++) { - c[i].fd = (ngx_socket_t) -1; - c[i].data = NULL; -#if (NGX_THREADS) - c[i].lock = 0; #endif + + cycle->connections0 = ngx_alloc(sizeof(ngx_connection_t) * ecf->connections, + cycle->log); + if (cycle->connections0 == NULL) { + return NGX_ERROR; } - cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections, + c = cycle->connections0; + + cycle->read_events0 = ngx_alloc(sizeof(ngx_event_t) * ecf->connections, cycle->log); - if (cycle->read_events == NULL) { + if (cycle->read_events0 == NULL) { return NGX_ERROR; } - rev = cycle->read_events; + rev = cycle->read_events0; for (i = 0; i < cycle->connection_n; i++) { rev[i].closed = 1; rev[i].instance = 1; @@ -480,13 +525,13 @@ ngx_event_process_init(ngx_cycle_t *cycle) #endif } - cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections, + cycle->write_events0 = ngx_alloc(sizeof(ngx_event_t) * ecf->connections, cycle->log); - if (cycle->write_events == NULL) { + if (cycle->write_events0 == NULL) { return NGX_ERROR; } - wev = cycle->write_events; + wev = cycle->write_events0; for (i = 0; i < cycle->connection_n; i++) { wev[i].closed = 1; #if (NGX_THREADS) @@ -495,40 +540,56 @@ ngx_event_process_init(ngx_cycle_t *cycle) #endif } - /* for each listening socket */ + i = cycle->connection_n; + next = NULL; - s = cycle->listening.elts; - for (i = 0; i < cycle->listening.nelts; i++) { + do { + i--; - fd = s[i].fd; + c[i].data = next; + c[i].read = &cycle->read_events0[i]; + c[i].write = &cycle->write_events0[i]; + c[i].fd = (ngx_socket_t) -1; -#if (NGX_WIN32) - /* - * Winsock assignes a socket number divisible by 4 - * so to find a connection we divide a socket number by 4. - */ + next = &c[i]; - fd /= 4; +#if (NGX_THREADS) + c[i].lock = 0; #endif + } while (i); - c = &cycle->connections[fd]; - rev = &cycle->read_events[fd]; - wev = &cycle->write_events[fd]; + cycle->free_connections = next; + cycle->free_connection_n = ecf->connections; - ngx_memzero(c, sizeof(ngx_connection_t)); - ngx_memzero(rev, sizeof(ngx_event_t)); - ngx_memzero(wev, sizeof(ngx_event_t)); + /* for each listening socket */ - c->fd = s[i].fd; - c->listening = &s[i]; + ls = cycle->listening.elts; + for (i = 0; i < cycle->listening.nelts; i++) { - c->ctx = s[i].ctx; - c->servers = s[i].servers; - c->log = s[i].log; - c->read = rev; + c = ngx_get_connection(ls[i].fd, cycle->log); + + if (c == NULL) { + return NGX_ERROR; + } + + rev = c->read; + wev = c->write; - /* required by iocp in "c->write->active = 1" */ + ngx_memzero(c, sizeof(ngx_connection_t)); + + c->read = rev; c->write = wev; + c->fd = ls[i].fd; + c->log = &ls[i].log; + + c->listening = &ls[i]; + ls[i].connection = c; + + c->ctx = ls[i].ctx; + c->servers = ls[i].servers; + + ngx_memzero(rev, sizeof(ngx_event_t)); + ngx_memzero(wev, sizeof(ngx_event_t)); /* required by poll */ wev->index = NGX_INVALID_INDEX; @@ -542,24 +603,26 @@ ngx_event_process_init(ngx_cycle_t *cycle) rev->accept = 1; #if (NGX_HAVE_DEFERRED_ACCEPT) - rev->deferred_accept = s[i].deferred_accept; + rev->deferred_accept = ls[i].deferred_accept; #endif if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) { - if (s[i].remain) { + if (ls[i].previous) { /* * delete the old accept events that were bound to * the old cycle read events array */ - if (ngx_del_event(&cycle->old_cycle->read_events[fd], - NGX_READ_EVENT, NGX_CLOSE_EVENT) == NGX_ERROR) + old = ls[i].previous->connection; + + if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT) + == NGX_ERROR) { return NGX_ERROR; } - cycle->old_cycle->connections[fd].fd = (ngx_socket_t) -1; + old->fd = (ngx_socket_t) -1; } } @@ -572,9 +635,11 @@ ngx_event_process_init(ngx_cycle_t *cycle) return NGX_ERROR; } + ls[i].log.handler = ngx_acceptex_log_error; + iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module); - if (ngx_event_post_acceptex(&s[i], iocpcf->post_acceptex) - == NGX_ERROR) + if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex) + == NGX_ERROR) { return NGX_ERROR; } @@ -607,6 +672,7 @@ ngx_event_process_init(ngx_cycle_t *cycle) } #endif + } return NGX_OK; diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index 3e93bf778..eee165e81 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -218,63 +218,69 @@ extern ngx_event_actions_t ngx_event_actions; /* - * The event filter requires to read/write the whole data - + * The event filter requires to read/write the whole data: * select, poll, /dev/poll, kqueue, epoll. */ #define NGX_USE_LEVEL_EVENT 0x00000001 /* * The event filter is deleted after a notification without an additional - * syscall - select, poll, kqueue, epoll, Solaris 10's event ports. + * syscall: select, poll, kqueue, epoll, Solaris 10's event ports. */ #define NGX_USE_ONESHOT_EVENT 0x00000002 /* - * The event filter notifies only the changes and an initial level - + * The event filter notifies only the changes and an initial level: * kqueue, epoll. */ #define NGX_USE_CLEAR_EVENT 0x00000004 /* - * The event filter has kqueue features - the eof flag, errno, + * The event filter has kqueue features: the eof flag, errno, * available data, etc. */ -#define NGX_USE_KQUEUE_EVENT 0x00000008 +#define NGX_USE_KQUEUE_EVENT 0x00000008 /* - * The event filter supports low water mark - kqueue's NOTE_LOWAT. + * The event filter supports low water mark: kqueue's NOTE_LOWAT. * kqueue in FreeBSD 4.1-4.2 has no NOTE_LOWAT so we need a separate flag. */ -#define NGX_USE_LOWAT_EVENT 0x00000010 +#define NGX_USE_LOWAT_EVENT 0x00000010 /* - * The event filter requires to do i/o operation until EAGAIN - + * The event filter requires to do i/o operation until EAGAIN: * epoll, rt signals. */ -#define NGX_USE_GREEDY_EVENT 0x00000020 +#define NGX_USE_GREEDY_EVENT 0x00000020 /* - * The event filter is epoll, + * The event filter is epoll. */ #define NGX_USE_EPOLL_EVENT 0x00000040 /* - * No need to add or delete the event filters - rt signals. + * No need to add or delete the event filters: rt signals. */ #define NGX_USE_RTSIG_EVENT 0x00000080 /* - * No need to add or delete the event filters - overlapped, aio_read, + * No need to add or delete the event filters: overlapped, aio_read, * aioread, io_submit. */ #define NGX_USE_AIO_EVENT 0x00000100 /* - * Need to add socket or handle only once - i/o completion port. + * Need to add socket or handle only once: i/o completion port. * It also requires NGX_HAVE_AIO and NGX_USE_AIO_EVENT to be set. */ #define NGX_USE_IOCP_EVENT 0x00000200 +/* + * The event filter has no opaque data and requires file descriptors table: + * poll, /dev/poll, rt signals. + */ +#define NGX_USE_FD_EVENT 0x00000400 + /* @@ -391,13 +397,14 @@ extern ngx_event_actions_t ngx_event_actions; #define ngx_del_timer ngx_event_del_timer +extern ngx_os_io_t ngx_io; + #define ngx_recv ngx_io.recv #define ngx_recv_chain ngx_io.recv_chain #define ngx_send ngx_io.send #define ngx_send_chain ngx_io.send_chain - #define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */ #define NGX_EVENT_CONF 0x02000000 @@ -471,6 +478,7 @@ void ngx_event_accept(ngx_event_t *ev); ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle); ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle); ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle); +u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len); ngx_int_t ngx_handle_read_event(ngx_event_t *rev, u_int flags); @@ -479,7 +487,8 @@ ngx_int_t ngx_handle_write_event(ngx_event_t *wev, size_t lowat); #if (NGX_WIN32) void ngx_event_acceptex(ngx_event_t *ev); -int ngx_event_post_acceptex(ngx_listening_t *ls, int n); +ngx_int_t ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n); +u_char *ngx_acceptex_log_error(ngx_log_t *log, u_char *buf, size_t len); #endif diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index 6d9f66ead..4df9dc611 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -9,26 +9,26 @@ #include <ngx_event.h> -static void ngx_close_accepted_socket(ngx_socket_t s, ngx_log_t *log); -static u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len); +/* the buffer size is enough to hold "struct sockaddr_un" */ +#define NGX_SOCKLEN 512 + + +static void ngx_close_accepted_connection(ngx_connection_t *c); void ngx_event_accept(ngx_event_t *ev) { - ngx_uint_t instance; -#if 0 - ngx_uint_t accepted; -#endif - socklen_t len; - struct sockaddr *sa; + socklen_t sl; ngx_err_t err; ngx_log_t *log; - ngx_pool_t *pool; + ngx_uint_t instance; ngx_socket_t s; ngx_event_t *rev, *wev; - ngx_connection_t *c, *ls; + ngx_listening_t *ls; + ngx_connection_t *c, *lc; ngx_event_conf_t *ecf; + char sa[NGX_SOCKLEN]; ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); @@ -39,77 +39,28 @@ ngx_event_accept(ngx_event_t *ev) ev->available = ecf->multi_accept; } - ls = ev->data; + lc = ev->data; + ls = lc->listening; + ev->ready = 0; ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "accept on %V, ready: %d", - &ls->listening->addr_text, ev->available); - - ev->ready = 0; - pool = NULL; -#if 0 - accepted = 0; -#endif + "accept on %V, ready: %d", &ls->addr_text, ev->available); do { + sl = NGX_SOCKLEN; - if (pool == NULL) { - - /* - * Create the pool before accept() to avoid the copying of - * the sockaddr. Although accept() can fail it is uncommon - * case and besides the pool can be got from the free pool list. - */ - - pool = ngx_create_pool(ls->listening->pool_size, ev->log); - if (pool == NULL) { - return; - } - } - - sa = ngx_palloc(pool, ls->listening->socklen); - if (sa == NULL) { - ngx_destroy_pool(pool); - return; - } - - log = ngx_palloc(pool, sizeof(ngx_log_t)); - if (log == NULL) { - ngx_destroy_pool(pool); - return; - } - - ngx_memcpy(log, ls->log, sizeof(ngx_log_t)); - pool->log = log; - - log->data = &ls->listening->addr_text; - log->handler = ngx_accept_log_error; - - len = ls->listening->socklen; - - s = accept(ls->fd, sa, &len); + s = accept(lc->fd, (struct sockaddr *) sa, &sl); if (s == -1) { err = ngx_socket_errno; if (err == NGX_EAGAIN) { -#if 0 - if (!(ngx_event_flags & NGX_USE_RTSIG_EVENT)) - { - ngx_log_error(NGX_LOG_NOTICE, log, err, - "EAGAIN after %d accepted connection(s)", - accepted); - } -#endif - - ngx_destroy_pool(pool); return; } ngx_log_error((err == NGX_ECONNABORTED) ? NGX_LOG_CRIT: NGX_LOG_ALERT, - ev->log, err, - "accept() on %V failed", &ls->listening->addr_text); + ev->log, err, "accept() failed"); if (err == NGX_ECONNABORTED) { if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { @@ -117,12 +68,10 @@ ngx_event_accept(ngx_event_t *ev) } if (ev->available) { - /* reuse the previously allocated pool */ continue; } } - ngx_destroy_pool(pool); return; } @@ -131,34 +80,58 @@ ngx_event_accept(ngx_event_t *ev) ngx_atomic_inc(ngx_stat_active); #endif - ngx_accept_disabled = (ngx_uint_t) s + NGX_ACCEPT_THRESHOLD - - ecf->connections; + ngx_accept_disabled = NGX_ACCEPT_THRESHOLD + - ngx_cycle->free_connection_n; + + c = ngx_get_connection(s, ev->log); + + if (c == NULL) { + if (ngx_close_socket(s) == -1) { + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, + ngx_close_socket_n " failed"); + } + + return; + } + + rev = c->read; + wev = c->write; + + ngx_memzero(c, sizeof(ngx_connection_t)); + + c->read = rev; + c->write = wev; + c->fd = s; + c->log = ev->log; - /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */ + c->pool = ngx_create_pool(ls->pool_size, ev->log); + if (c->pool == NULL) { + ngx_close_accepted_connection(c); + return; + } - if ((ngx_uint_t) s >= ecf->connections) { + c->sockaddr = ngx_palloc(c->pool, sl); + if (c->sockaddr == NULL) { + ngx_close_accepted_connection(c); + return; + } - ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "accept() on %V returned socket #%d while " - "only %d connections was configured, " - "closing the connection", - &ls->listening->addr_text, s, ecf->connections); + ngx_memcpy(c->sockaddr, sa, sl); - ngx_close_accepted_socket(s, log); - ngx_destroy_pool(pool); + log = ngx_palloc(c->pool, sizeof(ngx_log_t)); + if (log == NULL) { + ngx_close_accepted_connection(c); return; } /* set a blocking mode for aio and non-blocking mode for others */ if (ngx_inherited_nonblocking) { - if ((ngx_event_flags & NGX_USE_AIO_EVENT)) { + if (ngx_event_flags & NGX_USE_AIO_EVENT) { if (ngx_blocking(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, ngx_blocking_n " failed"); - - ngx_close_accepted_socket(s, log); - ngx_destroy_pool(pool); + ngx_close_accepted_connection(c); return; } } @@ -166,61 +139,35 @@ ngx_event_accept(ngx_event_t *ev) } else { if (!(ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_RTSIG_EVENT))) { if (ngx_nonblocking(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, ngx_nonblocking_n " failed"); - - ngx_close_accepted_socket(s, log); - ngx_destroy_pool(pool); + ngx_close_accepted_connection(c); return; } } } -#if (NGX_WIN32) - /* - * Winsock assignes a socket number divisible by 4 - * so to find a connection we divide a socket number by 4. - */ + *log = ls->log; - if (s % 4) { - ngx_log_error(NGX_LOG_EMERG, ev->log, 0, - "accept() on %V returned socket #%d, " - "not divisible by 4", - &ls->listening->addr_text, s); - exit(1); - } + c->recv = ngx_recv; + c->send = ngx_send; + c->send_chain = ngx_send_chain; - c = &ngx_cycle->connections[s / 4]; - rev = &ngx_cycle->read_events[s / 4]; - wev = &ngx_cycle->write_events[s / 4]; -#else - c = &ngx_cycle->connections[s]; - rev = &ngx_cycle->read_events[s]; - wev = &ngx_cycle->write_events[s]; -#endif + c->log = log; + c->pool->log = log; - instance = rev->instance; + c->listening = ls; + c->socklen = sl; -#if (NGX_THREADS) + c->unexpected_eof = 1; - if (*(&c->lock)) { - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "spinlock in accept, fd:%d", s); - ngx_spinlock(&c->lock, 1000); - ngx_unlock(&c->lock); - } + c->ctx = lc->ctx; + c->servers = lc->servers; -#endif + instance = rev->instance; ngx_memzero(rev, sizeof(ngx_event_t)); ngx_memzero(wev, sizeof(ngx_event_t)); - ngx_memzero(c, sizeof(ngx_connection_t)); - - c->pool = pool; - - c->listening = ls->listening; - c->sockaddr = sa; - c->socklen = len; rev->instance = !instance; wev->instance = !instance; @@ -231,12 +178,6 @@ ngx_event_accept(ngx_event_t *ev) rev->data = c; wev->data = c; - c->read = rev; - c->write = wev; - - c->fd = s; - c->unexpected_eof = 1; - wev->write = 1; wev->ready = 1; @@ -252,14 +193,6 @@ ngx_event_accept(ngx_event_t *ev) #endif } - c->ctx = ls->ctx; - c->servers = ls->servers; - - c->recv = ngx_recv; - c->send = ngx_send; - c->send_chain = ngx_send_chain; - - c->log = log; rev->log = log; wev->log = log; @@ -285,24 +218,21 @@ ngx_event_accept(ngx_event_t *ev) wev->own_lock = &c->lock; #endif - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, "accept: fd:%d c:%d", s, c->number); - if (c->listening->addr_ntop) { - c->addr_text.data = ngx_palloc(c->pool, - c->listening->addr_text_max_len); + if (ls->addr_ntop) { + c->addr_text.data = ngx_palloc(c->pool, ls->addr_text_max_len); if (c->addr_text.data == NULL) { - ngx_close_accepted_socket(s, log); - ngx_destroy_pool(pool); + ngx_close_accepted_connection(c); return; } - c->addr_text.len = ngx_sock_ntop(c->listening->family, c->sockaddr, + c->addr_text.len = ngx_sock_ntop(ls->family, c->sockaddr, c->addr_text.data, - c->listening->addr_text_max_len); + ls->addr_text_max_len); if (c->addr_text.len == 0) { - ngx_close_accepted_socket(s, log); - ngx_destroy_pool(pool); + ngx_close_accepted_connection(c); return; } } @@ -328,27 +258,20 @@ ngx_event_accept(ngx_event_t *ev) if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) { if (ngx_add_conn(c) == NGX_ERROR) { - ngx_close_accepted_socket(s, log); - ngx_destroy_pool(pool); + ngx_close_accepted_connection(c); return; } } - pool = NULL; - log->data = NULL; log->handler = NULL; - ls->listening->handler(c); + ls->handler(c); if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { ev->available--; } -#if 0 - accepted++; -#endif - } while (ev->available); } @@ -389,27 +312,22 @@ ngx_trylock_accept_mutex(ngx_cycle_t *cycle) ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle) { - ngx_uint_t i; - ngx_listening_t *s; + ngx_uint_t i; + ngx_listening_t *ls; + ngx_connection_t *c; - s = cycle->listening.elts; + ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { - /* - * we do not need to handle the Winsock sockets here (divide a socket - * number by 4) because this function would never called - * in the Winsock environment - */ + c = ls[i].connection; if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { - if (ngx_add_conn(&cycle->connections[s[i].fd]) == NGX_ERROR) { + if (ngx_add_conn(c) == NGX_ERROR) { return NGX_ERROR; } } else { - if (ngx_add_event(&cycle->read_events[s[i].fd], NGX_READ_EVENT, 0) - == NGX_ERROR) - { + if (ngx_add_event(c->read, NGX_READ_EVENT, 0) == NGX_ERROR) { return NGX_ERROR; } } @@ -422,36 +340,27 @@ ngx_enable_accept_events(ngx_cycle_t *cycle) ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle) { - ngx_uint_t i; - ngx_listening_t *s; + ngx_uint_t i; + ngx_listening_t *ls; + ngx_connection_t *c; - s = cycle->listening.elts; + ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { - /* - * we do not need to handle the Winsock sockets here (divide a socket - * number by 4) because this function would never called - * in the Winsock environment - */ + c = ls[i].connection; - if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { - if (!cycle->connections[s[i].fd].read->active) { - continue; - } + if (!c->read->active) { + continue; + } - if (ngx_del_conn(&cycle->connections[s[i].fd], NGX_DISABLE_EVENT) - == NGX_ERROR) - { + if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { + if (ngx_del_conn(c, NGX_DISABLE_EVENT) == NGX_ERROR) { return NGX_ERROR; } } else { - if (!cycle->read_events[s[i].fd].active) { - continue; - } - - if (ngx_del_event(&cycle->read_events[s[i].fd], NGX_READ_EVENT, - NGX_DISABLE_EVENT) == NGX_ERROR) + if (ngx_del_event(c->read, NGX_READ_EVENT, NGX_DISABLE_EVENT) + == NGX_ERROR) { return NGX_ERROR; } @@ -463,21 +372,33 @@ ngx_disable_accept_events(ngx_cycle_t *cycle) static void -ngx_close_accepted_socket(ngx_socket_t s, ngx_log_t *log) +ngx_close_accepted_connection(ngx_connection_t *c) { - if (ngx_close_socket(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + ngx_socket_t fd; + + ngx_free_connection(c); + + fd = c->fd; + c->fd = (ngx_socket_t) -1; + + if (ngx_close_socket(fd) == -1) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, ngx_close_socket_n " failed"); } + if (c->pool) { + ngx_destroy_pool(c->pool); + } + #if (NGX_STAT_STUB) ngx_atomic_dec(ngx_stat_active); #endif } -static u_char * +u_char * ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len) { - return ngx_snprintf(buf, len, " while accept() on %V", log->data); + return ngx_snprintf(buf, len, " while accepting new connection on %V", + log->data); } diff --git a/src/event/ngx_event_acceptex.c b/src/event/ngx_event_acceptex.c index bc2443dfd..961971424 100644 --- a/src/event/ngx_event_acceptex.c +++ b/src/event/ngx_event_acceptex.c @@ -9,12 +9,18 @@ #include <ngx_event.h> -void ngx_event_acceptex(ngx_event_t *rev) +static void ngx_close_posted_connection(ngx_connection_t *c); + + +void +ngx_event_acceptex(ngx_event_t *rev) { ngx_connection_t *c; c = rev->data; + c->log->handler = ngx_accept_log_error; + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "AcceptEx: %d", c->fd); if (rev->ovlp.error) { @@ -78,11 +84,13 @@ void ngx_event_acceptex(ngx_event_t *rev) } -int ngx_event_post_acceptex(ngx_listening_t *ls, int n) +ngx_int_t +ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n) { u_long rcvd; - ngx_int_t i; ngx_err_t err; + ngx_log_t *log; + ngx_uint_t i; ngx_event_t *rev, *wev; ngx_socket_t s; ngx_connection_t *c; @@ -93,99 +101,99 @@ int ngx_event_post_acceptex(ngx_listening_t *ls, int n) s = ngx_socket(ls->family, ls->type, 0); - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ls->log, 0, + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &ls->log, 0, ngx_socket_n " s:%d", s); if (s == -1) { - ngx_log_error(NGX_LOG_ALERT, ls->log, ngx_socket_errno, - ngx_socket_n " for AcceptEx() %s post failed", - ls->addr_text.data); + ngx_log_error(NGX_LOG_ALERT, &ls->log, ngx_socket_errno, + ngx_socket_n " failed"); return NGX_ERROR; } - /* - * Winsock assignes a socket number divisible by 4 - * so to find a connection we divide a socket number by 4. - */ + c = ngx_get_connection(s, &ls->log); - if (s % 4) { - ngx_log_error(NGX_LOG_EMERG, ls->log, 0, - ngx_socket_n - " created socket %d, not divisible by 4", s); - - exit(1); + if (c == NULL) { + return NGX_ERROR; } - c = &ngx_cycle->connections[s / 4]; - rev = &ngx_cycle->read_events[s / 4]; - wev = &ngx_cycle->write_events[s / 4]; + rev = c->read; + wev = c->write; ngx_memzero(c, sizeof(ngx_connection_t)); - ngx_memzero(rev, sizeof(ngx_event_t)); - ngx_memzero(wev, sizeof(ngx_event_t)); - - c->listening = ls; - - rev->index = NGX_INVALID_INDEX; - wev->index = NGX_INVALID_INDEX; - - rev->ovlp.event = rev; - wev->ovlp.event = wev; - rev->handler = ngx_event_acceptex; - - rev->data = c; - wev->data = c; c->read = rev; c->write = wev; - c->fd = s; - c->unexpected_eof = 1; - - rev->ready = 1; - wev->write = 1; - wev->ready = 1; - - c->ctx = ls->ctx; - c->servers = ls->servers; - - c->recv = ngx_recv; - c->send = ngx_send; - c->send_chain = ngx_send_chain; + c->log = &ls->log; - c->pool = ngx_create_pool(ls->pool_size, ls->log); + c->pool = ngx_create_pool(ls->pool_size, &ls->log); if (c->pool == NULL) { + ngx_close_posted_connection(c); + return NGX_ERROR; + } + + log = ngx_palloc(c->pool, sizeof(ngx_log_t)); + if (log == NULL) { + ngx_close_posted_connection(c); return NGX_ERROR; } - c->buffer = ngx_create_temp_buf(c->pool, - ls->post_accept_buffer_size - + 2 * (c->listening->socklen + 16)); + c->buffer = ngx_create_temp_buf(c->pool, ls->post_accept_buffer_size + + 2 * (ls->socklen + 16)); if (c->buffer == NULL) { + ngx_close_posted_connection(c); return NGX_ERROR; } c->local_sockaddr = ngx_palloc(c->pool, ls->socklen); if (c->local_sockaddr == NULL) { + ngx_close_posted_connection(c); return NGX_ERROR; } c->sockaddr = ngx_palloc(c->pool, ls->socklen); if (c->sockaddr == NULL) { + ngx_close_posted_connection(c); return NGX_ERROR; } - c->log = ngx_palloc(c->pool, sizeof(ngx_log_t)); - if (c->log == NULL) { - return NGX_ERROR; - } + *log = ls->log; + c->log = log; - ngx_memcpy(c->log, ls->log, sizeof(ngx_log_t)); - c->read->log = c->log; - c->write->log = c->log; + c->recv = ngx_recv; + c->send = ngx_send; + c->send_chain = ngx_send_chain; + + c->unexpected_eof = 1; + + c->ctx = ls->ctx; + c->servers = ls->servers; + + c->listening = ls; + + ngx_memzero(rev, sizeof(ngx_event_t)); + ngx_memzero(wev, sizeof(ngx_event_t)); + + rev->data = c; + wev->data = c; + + rev->index = NGX_INVALID_INDEX; + wev->index = NGX_INVALID_INDEX; + + rev->ovlp.event = rev; + wev->ovlp.event = wev; + rev->handler = ngx_event_acceptex; + + rev->ready = 1; + wev->write = 1; + wev->ready = 1; + + rev->log = c->log; + wev->log = c->log; if (ngx_add_event(rev, 0, NGX_IOCP_IO) == NGX_ERROR) { + ngx_close_posted_connection(c); return NGX_ERROR; } @@ -196,9 +204,10 @@ int ngx_event_post_acceptex(ngx_listening_t *ls, int n) err = ngx_socket_errno; if (err != WSA_IO_PENDING) { - ngx_log_error(NGX_LOG_ALERT, ls->log, err, + ngx_log_error(NGX_LOG_ALERT, &ls->log, err, "AcceptEx() %s falied", ls->addr_text.data); + ngx_close_posted_connection(c); return NGX_ERROR; } } @@ -206,3 +215,31 @@ int ngx_event_post_acceptex(ngx_listening_t *ls, int n) return NGX_OK; } + + +static void +ngx_close_posted_connection(ngx_connection_t *c) +{ + ngx_socket_t fd; + + ngx_free_connection(c); + + fd = c->fd; + c->fd = (ngx_socket_t) -1; + + if (ngx_close_socket(fd) == -1) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, + ngx_close_socket_n " failed"); + } + + if (c->pool) { + ngx_destroy_pool(c->pool); + } +} + + +u_char * +ngx_acceptex_log_error(ngx_log_t *log, u_char *buf, size_t len) +{ + return ngx_snprintf(buf, len, " while posting AcceptEx() on %V", log->data); +} diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c index be1d9638a..cdcb4c4c6 100644 --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -10,22 +10,18 @@ #include <ngx_event_connect.h> -#define NGX_RESOLVER_BUFSIZE 8192 - - ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc) { - int rc; - ngx_uint_t instance, level; - u_int event; - time_t now; - ngx_err_t err; - ngx_peer_t *peer; - ngx_socket_t s; - ngx_event_t *rev, *wev; - ngx_connection_t *c; - ngx_event_conf_t *ecf; + int rc; + ngx_uint_t instance, level, i; + u_int event; + time_t now; + ngx_err_t err; + ngx_peer_t *peer; + ngx_socket_t s; + ngx_event_t *rev, *wev; + ngx_connection_t *c; now = ngx_time(); @@ -47,6 +43,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) pc->connection = c; pc->cached = 1; + return NGX_OK; } @@ -102,9 +99,16 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) pc->tries--; if (pc->tries == 0) { + + /* all peers failed, mark them as live for quick recovery */ + + for (i = 0; i < pc->peers->number; i++) { + pc->peers->peer[i].fails = 0; + } + /* ngx_unlock_mutex(pc->peers->mutex); */ - return NGX_ERROR; + return NGX_BUSY; } } } @@ -124,27 +128,26 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) } - ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); - - /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */ - - if ((ngx_uint_t) s >= ecf->connections) { - - ngx_log_error(NGX_LOG_ALERT, pc->log, 0, - "socket() returned socket #%d while only %d " - "connections was configured, closing the socket", - s, ecf->connections); + c = ngx_get_connection(s, pc->log); + if (c == NULL) { if (ngx_close_socket(s) == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_close_socket_n "failed"); } - /* TODO: sleep for some time */ - return NGX_ERROR; } + rev = c->read; + wev = c->write; + + ngx_memzero(c, sizeof(ngx_connection_t)); + + c->read = rev; + c->write = wev; + c->fd = s; + c->log = pc->log; if (pc->rcvbuf) { if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, @@ -152,6 +155,8 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, "setsockopt(SO_RCVBUF) failed"); + ngx_free_connection(c); + if (ngx_close_socket(s) == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_close_socket_n " failed"); @@ -165,6 +170,8 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_nonblocking_n " failed"); + ngx_free_connection(c); + if (ngx_close_socket(s) == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_close_socket_n " failed"); @@ -173,46 +180,19 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) return NGX_ERROR; } -#if (NGX_WIN32) + c->recv = ngx_recv; + c->send = ngx_send; + c->send_chain = ngx_send_chain; - /* - * Winsock assignes a socket number divisible by 4 - * so to find a connection we divide a socket number by 4. - */ + c->log_error = pc->log_error; - if (s % 4) { - ngx_log_error(NGX_LOG_EMERG, pc->log, 0, - ngx_socket_n - " created socket %d, not divisible by 4", s); - exit(1); + if (peer->sockaddr->sa_family != AF_INET) { + c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; + c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; } - c = &ngx_cycle->connections[s / 4]; - rev = &ngx_cycle->read_events[s / 4]; - wev = &ngx_cycle->write_events[s / 4]; - -#else - - c = &ngx_cycle->connections[s]; - rev = &ngx_cycle->read_events[s]; - wev = &ngx_cycle->write_events[s]; - -#endif - instance = rev->instance; -#if (NGX_THREADS) - - if (*(&c->lock)) { - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0, - "spinlock in connect, fd:%d", s); - ngx_spinlock(&c->lock, 1000); - ngx_unlock(&c->lock); - } - -#endif - - ngx_memzero(c, sizeof(ngx_connection_t)); ngx_memzero(rev, sizeof(ngx_event_t)); ngx_memzero(wev, sizeof(ngx_event_t)); @@ -225,27 +205,11 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) rev->data = c; wev->data = c; - c->read = rev; - c->write = wev; wev->write = 1; - c->recv = ngx_recv; - c->send = ngx_send; - c->send_chain = ngx_send_chain; - - c->log = pc->log; rev->log = pc->log; wev->log = pc->log; - c->fd = s; - - c->log_error = pc->log_error; - - if (peer->sockaddr->sa_family != AF_INET) { - c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; - c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; - } - pc->connection = c; /* @@ -272,8 +236,8 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) } } - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, - "connect to %V, #%d", &peer->name, c->number); + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0, + "connect to %V, fd:%d #%d", &peer->name, s, c->number); rc = connect(s, peer->sockaddr, peer->socklen); @@ -293,7 +257,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) ngx_log_error(level, c->log, err, "connect() to %V failed", &peer->name); - return NGX_CONNECT_ERROR; + return NGX_DECLINED; } } diff --git a/src/event/ngx_event_connect.h b/src/event/ngx_event_connect.h index c8e70747c..2339bad56 100644 --- a/src/event/ngx_event_connect.h +++ b/src/event/ngx_event_connect.h @@ -13,9 +13,6 @@ #include <ngx_event.h> -#define NGX_CONNECT_ERROR -10 - - typedef struct { struct sockaddr *sockaddr; socklen_t socklen; diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index b02926a74..b7e072571 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -81,7 +81,7 @@ ngx_ssl_init(ngx_log_t *log) ngx_int_t -ngx_ssl_create_session(ngx_ssl_ctx_t *ssl_ctx, ngx_connection_t *c, +ngx_ssl_create_connection(ngx_ssl_ctx_t *ssl_ctx, ngx_connection_t *c, ngx_uint_t flags) { ngx_ssl_t *ssl; @@ -91,28 +91,28 @@ ngx_ssl_create_session(ngx_ssl_ctx_t *ssl_ctx, ngx_connection_t *c, return NGX_ERROR; } - ssl->buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE); - if (ssl->buf == NULL) { - return NGX_ERROR; - } - if (flags & NGX_SSL_BUFFER) { ssl->buffer = 1; + + ssl->buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE); + if (ssl->buf == NULL) { + return NGX_ERROR; + } } - ssl->ssl = SSL_new(ssl_ctx); + ssl->connection = SSL_new(ssl_ctx); - if (ssl->ssl == NULL) { + if (ssl->connection == NULL) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed"); return NGX_ERROR; } - if (SSL_set_fd(ssl->ssl, c->fd) == 0) { + if (SSL_set_fd(ssl->connection, c->fd) == 0) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed"); return NGX_ERROR; } - SSL_set_accept_state(ssl->ssl); + SSL_set_accept_state(ssl->connection); c->ssl = ssl; @@ -138,7 +138,7 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) for ( ;; ) { - n = SSL_read(c->ssl->ssl, buf, size); + n = SSL_read(c->ssl->connection, buf, size); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); @@ -148,13 +148,14 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) #if (NGX_DEBUG) - if (!c->ssl->handshaked && SSL_is_init_finished(c->ssl->ssl)) { + if (!c->ssl->handshaked && SSL_is_init_finished(c->ssl->connection)) + { char buf[129], *s, *d; SSL_CIPHER *cipher; c->ssl->handshaked = 1; - cipher = SSL_get_current_cipher(c->ssl->ssl); + cipher = SSL_get_current_cipher(c->ssl->connection); if (cipher) { SSL_CIPHER_description(cipher, &buf[1], 128); @@ -179,6 +180,12 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL cipher: \"%s\"", &buf[1]); + + if (SSL_session_reused(c->ssl->connection)) { + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL reused session"); + } + } else { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL no shared ciphers"); @@ -214,9 +221,10 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n) { - int sslerr; - ngx_err_t err; - char *handshake; + int sslerr; + char *handshake; + ngx_err_t err; + ngx_uint_t level; if (n > 0) { @@ -242,14 +250,14 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n) return NGX_OK; } - if (!SSL_is_init_finished(c->ssl->ssl)) { + if (!SSL_is_init_finished(c->ssl->connection)) { handshake = " in SSL handshake"; } else { handshake = ""; } - sslerr = SSL_get_error(c->ssl->ssl, n); + sslerr = SSL_get_error(c->ssl->connection, n); err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; @@ -264,7 +272,7 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n) ngx_log_error(NGX_LOG_INFO, c->log, err, "client does SSL %shandshake", - SSL_is_init_finished(c->ssl->ssl) ? "re" : ""); + SSL_is_init_finished(c->ssl->connection) ? "re" : ""); c->write->ready = 0; @@ -294,8 +302,34 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n) return NGX_ERROR; } - ngx_ssl_error(NGX_LOG_ALERT, c->log, err, - "SSL_read() failed%s", handshake); + level = NGX_LOG_CRIT; + + if (sslerr == SSL_ERROR_SYSCALL) { + + if (err == NGX_ECONNRESET + || err == NGX_EPIPE + || err == NGX_ENOTCONN + || err == NGX_ECONNREFUSED + || err == NGX_EHOSTUNREACH) + { + switch (c->log_error) { + + case NGX_ERROR_IGNORE_ECONNRESET: + case NGX_ERROR_INFO: + level = NGX_LOG_INFO; + break; + + case NGX_ERROR_ERR: + level = NGX_LOG_ERR; + break; + + default: + break; + } + } + } + + ngx_ssl_error(level, c->log, err, "SSL_read() failed%s", handshake); return NGX_ERROR; } @@ -448,12 +482,13 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) { - int n, sslerr; - ngx_err_t err; + int n, sslerr; + ngx_err_t err; + ngx_uint_t level; ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size); - n = SSL_write(c->ssl->ssl, data, size); + n = SSL_write(c->ssl->connection, data, size); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); @@ -461,13 +496,13 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) #if (NGX_DEBUG) - if (!c->ssl->handshaked && SSL_is_init_finished(c->ssl->ssl)) { + if (!c->ssl->handshaked && SSL_is_init_finished(c->ssl->connection)) { char buf[129], *s, *d; SSL_CIPHER *cipher; c->ssl->handshaked = 1; - cipher = SSL_get_current_cipher(c->ssl->ssl); + cipher = SSL_get_current_cipher(c->ssl->connection); if (cipher) { SSL_CIPHER_description(cipher, &buf[1], 128); @@ -492,6 +527,12 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL cipher: \"%s\"", &buf[1]); + + if (SSL_session_reused(c->ssl->connection)) { + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL reused session"); + } + } else { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL no shared ciphers"); @@ -521,7 +562,7 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) return n; } - sslerr = SSL_get_error(c->ssl->ssl, n); + sslerr = SSL_get_error(c->ssl->connection, n); err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; @@ -536,7 +577,7 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) ngx_log_error(NGX_LOG_INFO, c->log, err, "client does SSL %shandshake", - SSL_is_init_finished(c->ssl->ssl) ? "re" : ""); + SSL_is_init_finished(c->ssl->connection) ? "re" : ""); c->read->ready = 0; @@ -560,7 +601,34 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) c->ssl->no_rcv_shut = 1; c->ssl->no_send_shut = 1; - ngx_ssl_error(NGX_LOG_ALERT, c->log, err, "SSL_write() failed"); + level = NGX_LOG_CRIT; + + if (sslerr == SSL_ERROR_SYSCALL) { + + if (err == NGX_ECONNRESET + || err == NGX_EPIPE + || err == NGX_ENOTCONN + || err == NGX_ECONNREFUSED + || err == NGX_EHOSTUNREACH) + { + switch (c->log_error) { + + case NGX_ERROR_IGNORE_ECONNRESET: + case NGX_ERROR_INFO: + level = NGX_LOG_INFO; + break; + + case NGX_ERROR_ERR: + level = NGX_LOG_ERR; + break; + + default: + break; + } + } + } + + ngx_ssl_error(level, c->log, err, "SSL_write() failed"); return NGX_ERROR; } @@ -602,7 +670,7 @@ ngx_ssl_shutdown(ngx_connection_t *c) } if (mode) { - SSL_set_shutdown(c->ssl->ssl, mode); + SSL_set_shutdown(c->ssl->connection, mode); c->ssl->shutdown_set = 1; } } @@ -613,13 +681,14 @@ ngx_ssl_shutdown(ngx_connection_t *c) #endif for ( ;; ) { - n = SSL_shutdown(c->ssl->ssl); + n = SSL_shutdown(c->ssl->connection); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); if (n == 1 || (n == 0 && c->read->timedout)) { - SSL_free(c->ssl->ssl); + SSL_free(c->ssl->connection); c->ssl = NULL; + return NGX_OK; } @@ -632,7 +701,7 @@ ngx_ssl_shutdown(ngx_connection_t *c) } if (!again) { - sslerr = SSL_get_error(c->ssl->ssl, n); + sslerr = SSL_get_error(c->ssl->connection, n); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); @@ -660,6 +729,9 @@ ngx_ssl_shutdown(ngx_connection_t *c) ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_shutdown() failed"); + SSL_free(c->ssl->connection); + c->ssl = NULL; + return NGX_ERROR; } diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index f298aeb10..fa7f27e61 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -23,7 +23,7 @@ typedef struct { - SSL *ssl; + SSL *connection; ngx_int_t last; ngx_buf_t *buf; ngx_event_handler_pt saved_read_handler; @@ -49,8 +49,8 @@ typedef SSL_CTX ngx_ssl_ctx_t; ngx_int_t ngx_ssl_init(ngx_log_t *log); -ngx_int_t ngx_ssl_create_session(ngx_ssl_ctx_t *ctx, ngx_connection_t *c, - ngx_uint_t flags); +ngx_int_t ngx_ssl_create_connection(ngx_ssl_ctx_t *ctx, ngx_connection_t *c, + ngx_uint_t flags); #define ngx_ssl_handshake(c) NGX_OK |