Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src/event
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2005-09-23 15:02:22 +0400
committerIgor Sysoev <igor@sysoev.ru>2005-09-23 15:02:22 +0400
commit31eb8c015d58a5b36b9578d4ee6c217e16cb776f (patch)
tree28ebccc10deba4132e05414aac1874d5013fdf58 /src/event
parentf44a1f5f579e19441db2d477a7c81d8894ba2262 (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.c26
-rw-r--r--src/event/modules/ngx_poll_module.c12
-rw-r--r--src/event/modules/ngx_rtsig_module.c10
-rw-r--r--src/event/ngx_event.c174
-rw-r--r--src/event/ngx_event.h39
-rw-r--r--src/event/ngx_event_accept.c311
-rw-r--r--src/event/ngx_event_acceptex.c155
-rw-r--r--src/event/ngx_event_connect.c122
-rw-r--r--src/event/ngx_event_connect.h3
-rw-r--r--src/event/ngx_event_openssl.c138
-rw-r--r--src/event/ngx_event_openssl.h6
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