mirror of https://github.com/openresty/openresty
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2047 lines
64 KiB
C
2047 lines
64 KiB
C
diff --git a/src/auto/cc/gcc b/src/auto/cc/gcc
|
|
index a5ca336..52de374 100644
|
|
--- a/src/auto/cc/gcc
|
|
+++ b/src/auto/cc/gcc
|
|
@@ -48,9 +48,9 @@ esac
|
|
|
|
# optimizations
|
|
|
|
-#NGX_GCC_OPT="-O2"
|
|
+NGX_GCC_OPT="-O2 -D_FORTIFY_SOURCE=2"
|
|
#NGX_GCC_OPT="-Os"
|
|
-NGX_GCC_OPT="-O"
|
|
+#NGX_GCC_OPT="-O"
|
|
|
|
#CFLAGS="$CFLAGS -fomit-frame-pointer"
|
|
|
|
@@ -174,6 +174,10 @@ CFLAGS="$CFLAGS -g"
|
|
# DragonFly's gcc3 generates DWARF
|
|
#CFLAGS="$CFLAGS -g -gstabs"
|
|
|
|
+# required by Intel SDL
|
|
+CFLAGS="$CFLAGS -fstack-protector -fPIE -fPIC -Wformat -Wformat-security"
|
|
+CORE_LINK="-z noexecstack -z relro -z now -pie"
|
|
+
|
|
if [ ".$CPP" = "." ]; then
|
|
CPP="$CC -E"
|
|
fi
|
|
diff --git a/src/src/core/nginx.c b/src/src/core/nginx.c
|
|
index aa4986b..12ca7be 100644
|
|
--- a/src/src/core/nginx.c
|
|
+++ b/src/src/core/nginx.c
|
|
@@ -182,6 +182,10 @@ ngx_module_t ngx_core_module = {
|
|
static ngx_uint_t ngx_show_help;
|
|
static ngx_uint_t ngx_show_version;
|
|
static ngx_uint_t ngx_show_configure;
|
|
+/* indicate that nginx start without ngx_ssl_init()
|
|
+ * which will involve OpenSSL configuration file to
|
|
+ * start OpenSSL engine */
|
|
+static ngx_uint_t ngx_no_ssl_init;
|
|
static u_char *ngx_prefix;
|
|
static u_char *ngx_conf_file;
|
|
static u_char *ngx_conf_params;
|
|
@@ -200,6 +204,7 @@ main(int argc, char *const *argv)
|
|
ngx_cycle_t *cycle, init_cycle;
|
|
ngx_conf_dump_t *cd;
|
|
ngx_core_conf_t *ccf;
|
|
+ ngx_int_t ret_int_num;
|
|
|
|
ngx_debug_init();
|
|
|
|
@@ -236,7 +241,8 @@ main(int argc, char *const *argv)
|
|
|
|
/* STUB */
|
|
#if (NGX_OPENSSL)
|
|
- ngx_ssl_init(log);
|
|
+ if(!ngx_no_ssl_init)
|
|
+ ngx_ssl_init(log);
|
|
#endif
|
|
|
|
/*
|
|
@@ -246,6 +252,7 @@ main(int argc, char *const *argv)
|
|
|
|
ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
|
|
init_cycle.log = log;
|
|
+ init_cycle.no_ssl_init = ngx_no_ssl_init;
|
|
ngx_cycle = &init_cycle;
|
|
|
|
init_cycle.pool = ngx_create_pool(1024, log);
|
|
@@ -324,7 +331,9 @@ main(int argc, char *const *argv)
|
|
}
|
|
|
|
if (ngx_signal) {
|
|
- return ngx_signal_process(cycle, ngx_signal);
|
|
+ ret_int_num = ngx_signal_process(cycle, ngx_signal);
|
|
+ ngx_destroy_pool(cycle->pool);
|
|
+ return ret_int_num;
|
|
}
|
|
|
|
ngx_os_status(cycle->log);
|
|
@@ -344,7 +353,7 @@ main(int argc, char *const *argv)
|
|
}
|
|
|
|
if (!ngx_inherited && ccf->daemon) {
|
|
- if (ngx_daemon(cycle->log) != NGX_OK) {
|
|
+ if (ngx_daemon(cycle) != NGX_OK) {
|
|
return 1;
|
|
}
|
|
|
|
@@ -773,11 +782,13 @@ ngx_get_options(int argc, char *const *argv)
|
|
|
|
case 't':
|
|
ngx_test_config = 1;
|
|
+ ngx_no_ssl_init = 1;
|
|
break;
|
|
|
|
case 'T':
|
|
ngx_test_config = 1;
|
|
ngx_dump_config = 1;
|
|
+ ngx_no_ssl_init = 1;
|
|
break;
|
|
|
|
case 'q':
|
|
@@ -827,6 +838,7 @@ ngx_get_options(int argc, char *const *argv)
|
|
return NGX_ERROR;
|
|
|
|
case 's':
|
|
+ ngx_no_ssl_init = 1;
|
|
if (*p) {
|
|
ngx_signal = (char *) p;
|
|
|
|
@@ -852,6 +864,7 @@ ngx_get_options(int argc, char *const *argv)
|
|
|
|
default:
|
|
ngx_log_stderr(0, "invalid option: \"%c\"", *(p - 1));
|
|
+ ngx_no_ssl_init = 1;
|
|
return NGX_ERROR;
|
|
}
|
|
}
|
|
diff --git a/src/src/core/ngx_buf.h b/src/src/core/ngx_buf.h
|
|
index 12781a7..bcc5912 100644
|
|
--- a/src/src/core/ngx_buf.h
|
|
+++ b/src/src/core/ngx_buf.h
|
|
@@ -137,7 +137,7 @@ typedef struct {
|
|
&& !ngx_buf_in_memory(b) && !b->in_file && !b->flush && !b->last_buf)
|
|
|
|
#define ngx_buf_size(b) \
|
|
- (ngx_buf_in_memory(b) ? (off_t) (b->last - b->pos): \
|
|
+ (ngx_buf_in_memory(b) ? (off_t) (unsigned) (b->last - b->pos): \
|
|
(b->file_last - b->file_pos))
|
|
|
|
ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size);
|
|
diff --git a/src/src/core/ngx_conf_file.h b/src/src/core/ngx_conf_file.h
|
|
index 213611f..9596341 100644
|
|
--- a/src/src/core/ngx_conf_file.h
|
|
+++ b/src/src/core/ngx_conf_file.h
|
|
@@ -129,6 +129,7 @@ struct ngx_conf_s {
|
|
|
|
ngx_conf_handler_pt handler;
|
|
char *handler_conf;
|
|
+ ngx_flag_t no_ssl_init;
|
|
};
|
|
|
|
|
|
diff --git a/src/src/core/ngx_connection.c b/src/src/core/ngx_connection.c
|
|
index 9a74758..f39d358 100644
|
|
--- a/src/src/core/ngx_connection.c
|
|
+++ b/src/src/core/ngx_connection.c
|
|
@@ -986,7 +986,14 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
|
|
* for closed shared listening sockets unless
|
|
* the events was explicitly deleted
|
|
*/
|
|
-
|
|
+#if (NGX_SSL)
|
|
+ if (c->asynch && ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
ngx_del_event(c->read, NGX_READ_EVENT, 0);
|
|
|
|
} else {
|
|
@@ -1035,6 +1042,9 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
|
|
{
|
|
ngx_uint_t instance;
|
|
ngx_event_t *rev, *wev;
|
|
+#if (NGX_SSL)
|
|
+ ngx_event_t *aev;
|
|
+#endif
|
|
ngx_connection_t *c;
|
|
|
|
/* disable warning: Win32 SOCKET is u_int while UNIX socket is int */
|
|
@@ -1071,11 +1081,18 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
|
|
|
|
rev = c->read;
|
|
wev = c->write;
|
|
+#if (NGX_SSL)
|
|
+ aev = c->async;
|
|
+#endif
|
|
|
|
ngx_memzero(c, sizeof(ngx_connection_t));
|
|
|
|
c->read = rev;
|
|
c->write = wev;
|
|
+#if (NGX_SSL)
|
|
+ c->async = aev;
|
|
+#endif
|
|
+
|
|
c->fd = s;
|
|
c->log = log;
|
|
|
|
@@ -1083,17 +1100,32 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
|
|
|
|
ngx_memzero(rev, sizeof(ngx_event_t));
|
|
ngx_memzero(wev, sizeof(ngx_event_t));
|
|
+#if (NGX_SSL)
|
|
+ ngx_memzero(aev, sizeof(ngx_event_t));
|
|
+#endif
|
|
|
|
rev->instance = !instance;
|
|
wev->instance = !instance;
|
|
+#if (NGX_SSL)
|
|
+ aev->instance = !instance;
|
|
+#endif
|
|
|
|
rev->index = NGX_INVALID_INDEX;
|
|
wev->index = NGX_INVALID_INDEX;
|
|
+#if (NGX_SSL)
|
|
+ aev->index = NGX_INVALID_INDEX;
|
|
+#endif
|
|
|
|
rev->data = c;
|
|
wev->data = c;
|
|
+#if (NGX_SSL)
|
|
+ aev->data = c;
|
|
+#endif
|
|
|
|
wev->write = 1;
|
|
+#if (NGX_SSL)
|
|
+ aev->async = 1;
|
|
+#endif
|
|
|
|
return c;
|
|
}
|
|
@@ -1132,11 +1164,32 @@ ngx_close_connection(ngx_connection_t *c)
|
|
ngx_del_timer(c->write);
|
|
}
|
|
|
|
+#if (NGX_SSL)
|
|
+ if (c->async->timer_set) {
|
|
+ ngx_del_timer(c->async);
|
|
+ }
|
|
+
|
|
+ if (c->asynch && ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
if (!c->shared) {
|
|
if (ngx_del_conn) {
|
|
ngx_del_conn(c, NGX_CLOSE_EVENT);
|
|
|
|
} else {
|
|
+#if (NGX_SSL)
|
|
+ if (c->asynch && ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
if (c->read->active || c->read->disabled) {
|
|
ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
|
|
}
|
|
@@ -1155,8 +1208,17 @@ ngx_close_connection(ngx_connection_t *c)
|
|
ngx_delete_posted_event(c->write);
|
|
}
|
|
|
|
+#if (NGX_SSL)
|
|
+ if (c->async->posted) {
|
|
+ ngx_delete_posted_event(c->async);
|
|
+ }
|
|
+#endif
|
|
+
|
|
c->read->closed = 1;
|
|
c->write->closed = 1;
|
|
+#if (NGX_SSL)
|
|
+ c->async->closed = 1;
|
|
+#endif
|
|
|
|
ngx_reusable_connection(c, 0);
|
|
|
|
@@ -1166,6 +1228,9 @@ ngx_close_connection(ngx_connection_t *c)
|
|
|
|
fd = c->fd;
|
|
c->fd = (ngx_socket_t) -1;
|
|
+#if (NGX_SSL)
|
|
+ c->async_fd = (ngx_socket_t) -1;
|
|
+#endif
|
|
|
|
if (c->shared) {
|
|
return;
|
|
diff --git a/src/src/core/ngx_connection.h b/src/src/core/ngx_connection.h
|
|
index e4dfe58..e746698 100644
|
|
--- a/src/src/core/ngx_connection.h
|
|
+++ b/src/src/core/ngx_connection.h
|
|
@@ -122,9 +122,14 @@ struct ngx_connection_s {
|
|
void *data;
|
|
ngx_event_t *read;
|
|
ngx_event_t *write;
|
|
+#if (NGX_SSL)
|
|
+ ngx_event_t *async;
|
|
+#endif
|
|
|
|
ngx_socket_t fd;
|
|
-
|
|
+#if (NGX_SSL)
|
|
+ ngx_socket_t async_fd;
|
|
+#endif
|
|
ngx_recv_pt recv;
|
|
ngx_send_pt send;
|
|
ngx_recv_chain_pt recv_chain;
|
|
@@ -149,6 +154,7 @@ struct ngx_connection_s {
|
|
|
|
#if (NGX_SSL || NGX_COMPAT)
|
|
ngx_ssl_connection_t *ssl;
|
|
+ ngx_flag_t asynch;
|
|
#endif
|
|
|
|
struct sockaddr *local_sockaddr;
|
|
@@ -181,7 +187,9 @@ struct ngx_connection_s {
|
|
unsigned tcp_nopush:2; /* ngx_connection_tcp_nopush_e */
|
|
|
|
unsigned need_last_buf:1;
|
|
-
|
|
+#if (NGX_SSL)
|
|
+ unsigned num_async_fds:8;
|
|
+#endif
|
|
#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT)
|
|
unsigned busy_count:2;
|
|
#endif
|
|
diff --git a/src/src/core/ngx_cycle.c b/src/src/core/ngx_cycle.c
|
|
index 675a506..37e7eac 100644
|
|
--- a/src/src/core/ngx_cycle.c
|
|
+++ b/src/src/core/ngx_cycle.c
|
|
@@ -81,6 +81,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
|
cycle->pool = pool;
|
|
cycle->log = log;
|
|
cycle->old_cycle = old_cycle;
|
|
+ cycle->no_ssl_init = old_cycle->no_ssl_init;
|
|
|
|
cycle->conf_prefix.len = old_cycle->conf_prefix.len;
|
|
cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);
|
|
@@ -261,6 +262,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
|
conf.log = log;
|
|
conf.module_type = NGX_CORE_MODULE;
|
|
conf.cmd_type = NGX_MAIN_CONF;
|
|
+ conf.no_ssl_init = cycle->no_ssl_init;
|
|
|
|
#if 0
|
|
log->log_level = NGX_LOG_DEBUG_ALL;
|
|
@@ -962,6 +964,7 @@ ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
|
|
len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;
|
|
|
|
if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) {
|
|
+ ngx_close_file(file.fd);
|
|
return NGX_ERROR;
|
|
}
|
|
}
|
|
diff --git a/src/src/core/ngx_cycle.h b/src/src/core/ngx_cycle.h
|
|
index c342365..fb37394 100644
|
|
--- a/src/src/core/ngx_cycle.h
|
|
+++ b/src/src/core/ngx_cycle.h
|
|
@@ -79,6 +79,9 @@ struct ngx_cycle_s {
|
|
ngx_connection_t *connections;
|
|
ngx_event_t *read_events;
|
|
ngx_event_t *write_events;
|
|
+#if (NGX_SSL)
|
|
+ ngx_event_t *async_events;
|
|
+#endif
|
|
|
|
ngx_cycle_t *old_cycle;
|
|
|
|
@@ -88,6 +91,7 @@ struct ngx_cycle_s {
|
|
ngx_str_t prefix;
|
|
ngx_str_t lock_file;
|
|
ngx_str_t hostname;
|
|
+ ngx_flag_t no_ssl_init;
|
|
|
|
ngx_log_intercept_pt intercept_error_log_handler;
|
|
void *intercept_error_log_data;
|
|
diff --git a/src/src/core/ngx_string.h b/src/src/core/ngx_string.h
|
|
index 882ae7c..e0a32fa 100644
|
|
--- a/src/src/core/ngx_string.h
|
|
+++ b/src/src/core/ngx_string.h
|
|
@@ -96,6 +96,16 @@ void *ngx_memcpy(void *dst, const void *src, size_t n);
|
|
|
|
#else
|
|
|
|
+#if (NGX_SECURE_MEM)
|
|
+
|
|
+#define _MIN_(a,b) (((a)<(b))?(a):(b))
|
|
+#define MEMCPY_S(dest, src, dest_sz, src_sz) \
|
|
+ memcpy((void *)(dest), (void *) (src), (size_t)_MIN_(dest_sz, src_sz))
|
|
+#define ngx_memcpy(dst, src, n) (void) MEMCPY_S(dst, src, n, n)
|
|
+#define ngx_cpymem(dst, src, n) (((u_char *) MEMCPY_S(dst, src, n, n)) + (n))
|
|
+
|
|
+#else
|
|
+
|
|
/*
|
|
* gcc3, msvc, and icc7 compile memcpy() to the inline "rep movs".
|
|
* gcc3 compiles memcpy(d, s, 4) to the inline "mov"es.
|
|
@@ -104,8 +114,9 @@ void *ngx_memcpy(void *dst, const void *src, size_t n);
|
|
#define ngx_memcpy(dst, src, n) (void) memcpy(dst, src, n)
|
|
#define ngx_cpymem(dst, src, n) (((u_char *) memcpy(dst, src, n)) + (n))
|
|
|
|
-#endif
|
|
+#endif /* NGX_SECURE_MEM */
|
|
|
|
+#endif /* NGX_MEMCPY_LIMIT */
|
|
|
|
#if ( __INTEL_COMPILER >= 800 )
|
|
|
|
diff --git a/src/src/event/modules/ngx_devpoll_module.c b/src/src/event/modules/ngx_devpoll_module.c
|
|
index ee9f854..9dd2df3 100644
|
|
--- a/src/src/event/modules/ngx_devpoll_module.c
|
|
+++ b/src/src/event/modules/ngx_devpoll_module.c
|
|
@@ -94,6 +94,8 @@ static ngx_event_module_t ngx_devpoll_module_ctx = {
|
|
ngx_devpoll_process_events, /* process the events */
|
|
ngx_devpoll_init, /* init the events */
|
|
ngx_devpoll_done, /* done the events */
|
|
+ NULL, /* add an async conn */
|
|
+ NULL /* del an async conn */
|
|
}
|
|
|
|
};
|
|
diff --git a/src/src/event/modules/ngx_epoll_module.c b/src/src/event/modules/ngx_epoll_module.c
|
|
index 76aee08..ab5f7e3 100644
|
|
--- a/src/src/event/modules/ngx_epoll_module.c
|
|
+++ b/src/src/event/modules/ngx_epoll_module.c
|
|
@@ -122,6 +122,11 @@ static ngx_int_t ngx_epoll_notify(ngx_event_handler_pt handler);
|
|
#endif
|
|
static ngx_int_t ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
|
ngx_uint_t flags);
|
|
+#if (NGX_SSL)
|
|
+static ngx_int_t ngx_epoll_add_async_connection(ngx_connection_t *c);
|
|
+static ngx_int_t ngx_epoll_del_async_connection(ngx_connection_t *c,
|
|
+ ngx_uint_t flags);
|
|
+#endif
|
|
|
|
#if (NGX_HAVE_FILE_AIO)
|
|
static void ngx_epoll_eventfd_handler(ngx_event_t *ev);
|
|
@@ -196,6 +201,13 @@ static ngx_event_module_t ngx_epoll_module_ctx = {
|
|
ngx_epoll_process_events, /* process the events */
|
|
ngx_epoll_init, /* init the events */
|
|
ngx_epoll_done, /* done the events */
|
|
+#if (NGX_SSL)
|
|
+ ngx_epoll_add_async_connection, /* add an async conn */
|
|
+ ngx_epoll_del_async_connection /* del an async conn */
|
|
+#else
|
|
+ NULL, /* add an async conn */
|
|
+ NULL /* del an async conn */
|
|
+#endif
|
|
}
|
|
};
|
|
|
|
@@ -626,7 +638,7 @@ ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
|
|
|
if (epoll_ctl(ep, op, c->fd, &ee) == -1) {
|
|
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
|
|
- "epoll_ctl(%d, %d) failed", op, c->fd);
|
|
+ "socket add event epoll_ctl(%d, %d) failed", op, c->fd);
|
|
return NGX_ERROR;
|
|
}
|
|
|
|
@@ -687,7 +699,7 @@ ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
|
|
|
if (epoll_ctl(ep, op, c->fd, &ee) == -1) {
|
|
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
|
|
- "epoll_ctl(%d, %d) failed", op, c->fd);
|
|
+ "socket del event epoll_ctl(%d, %d) failed", op, c->fd);
|
|
return NGX_ERROR;
|
|
}
|
|
|
|
@@ -710,7 +722,7 @@ ngx_epoll_add_connection(ngx_connection_t *c)
|
|
|
|
if (epoll_ctl(ep, EPOLL_CTL_ADD, c->fd, &ee) == -1) {
|
|
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
|
|
- "epoll_ctl(EPOLL_CTL_ADD, %d) failed", c->fd);
|
|
+ "socket add_conn epoll_ctl(EPOLL_CTL_ADD, %d) failed", c->fd);
|
|
return NGX_ERROR;
|
|
}
|
|
|
|
@@ -748,7 +760,7 @@ ngx_epoll_del_connection(ngx_connection_t *c, ngx_uint_t flags)
|
|
|
|
if (epoll_ctl(ep, op, c->fd, &ee) == -1) {
|
|
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
|
|
- "epoll_ctl(%d, %d) failed", op, c->fd);
|
|
+ "socket del conn epoll_ctl(%d, %d) failed", op, c->fd);
|
|
return NGX_ERROR;
|
|
}
|
|
|
|
@@ -758,6 +770,53 @@ ngx_epoll_del_connection(ngx_connection_t *c, ngx_uint_t flags)
|
|
return NGX_OK;
|
|
}
|
|
|
|
+#if (NGX_SSL)
|
|
+static ngx_int_t
|
|
+ngx_epoll_add_async_connection(ngx_connection_t *c)
|
|
+{
|
|
+ struct epoll_event ee;
|
|
+
|
|
+ ee.events = EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP;
|
|
+ ee.data.ptr = (void *) ((uintptr_t) c | (c->async->async << 1) | c->async->instance);
|
|
+
|
|
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "epoll add async connection: fd:%d ev:%08XD", c->async_fd, ee.events);
|
|
+ if (epoll_ctl(ep, EPOLL_CTL_ADD, c->async_fd, &ee) == -1) {
|
|
+ ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
|
|
+ "async add conn epoll_ctl(EPOLL_CTL_ADD, %d) failed", c->async_fd);
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+
|
|
+ c->async->active = 1;
|
|
+
|
|
+ return NGX_OK;
|
|
+}
|
|
+
|
|
+
|
|
+static ngx_int_t
|
|
+ngx_epoll_del_async_connection(ngx_connection_t *c, ngx_uint_t flags)
|
|
+{
|
|
+ int op;
|
|
+ struct epoll_event ee;
|
|
+
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "epoll del async connection: fd:%d", c->async_fd);
|
|
+
|
|
+ op = EPOLL_CTL_DEL;
|
|
+ ee.events = 0;
|
|
+ ee.data.ptr = NULL;
|
|
+ if (epoll_ctl(ep, op, c->async_fd, &ee) == -1) {
|
|
+ ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
|
|
+ "async del conn epoll_ctl(%d, %d) failed", op, c->async_fd);
|
|
+ c->async_fd = -1;
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+ c->async_fd = -1;
|
|
+ c->async->active = 0;
|
|
+
|
|
+ return NGX_OK;
|
|
+}
|
|
+#endif
|
|
|
|
#if (NGX_HAVE_EVENTFD)
|
|
|
|
@@ -791,6 +850,10 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
|
ngx_event_t *rev, *wev;
|
|
ngx_queue_t *queue;
|
|
ngx_connection_t *c;
|
|
+#if (NGX_SSL)
|
|
+ ngx_int_t async;
|
|
+ ngx_event_t *aev;
|
|
+#endif
|
|
|
|
/* NGX_TIMER_INFINITE == INFTIM */
|
|
|
|
@@ -837,7 +900,12 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
|
c = event_list[i].data.ptr;
|
|
|
|
instance = (uintptr_t) c & 1;
|
|
+#if (NGX_SSL)
|
|
+ async = ((uintptr_t) c & 2) >> 1;
|
|
+ c = (ngx_connection_t *) ((uintptr_t) c & (uintptr_t) ~3);
|
|
+#else
|
|
c = (ngx_connection_t *) ((uintptr_t) c & (uintptr_t) ~1);
|
|
+#endif
|
|
|
|
rev = c->read;
|
|
|
|
@@ -880,7 +948,11 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
|
}
|
|
#endif
|
|
|
|
+#if (NGX_SSL)
|
|
+ if ((revents & EPOLLIN) && rev->active && !async) {
|
|
+#else
|
|
if ((revents & EPOLLIN) && rev->active) {
|
|
+#endif
|
|
|
|
#if (NGX_HAVE_EPOLLRDHUP)
|
|
if (revents & EPOLLRDHUP) {
|
|
@@ -905,7 +977,11 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
|
|
|
wev = c->write;
|
|
|
|
+#if (NGX_SSL)
|
|
+ if ((revents & EPOLLOUT) && wev->active && !async) {
|
|
+#else
|
|
if ((revents & EPOLLOUT) && wev->active) {
|
|
+#endif
|
|
|
|
if (c->fd == -1 || wev->instance != instance) {
|
|
|
|
@@ -931,6 +1007,33 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
|
wev->handler(wev);
|
|
}
|
|
}
|
|
+
|
|
+#if (NGX_SSL)
|
|
+ aev = c->async;
|
|
+
|
|
+ if ((revents & EPOLLIN) && aev->active && async) {
|
|
+
|
|
+ if (c->async_fd == -1 || aev->instance!= instance) {
|
|
+ /*
|
|
+ * the stale event from a file descriptor
|
|
+ * that was just closed in this iteration
|
|
+ */
|
|
+
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
|
+ "epoll: stale event %p", c);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ aev->ready = 1;
|
|
+
|
|
+ if (flags & NGX_POST_EVENTS) {
|
|
+ ngx_post_event(aev, &ngx_posted_events);
|
|
+
|
|
+ } else {
|
|
+ aev->handler(aev);
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
}
|
|
|
|
return NGX_OK;
|
|
diff --git a/src/src/event/modules/ngx_eventport_module.c b/src/src/event/modules/ngx_eventport_module.c
|
|
index e723f92..ef25fd0 100644
|
|
--- a/src/src/event/modules/ngx_eventport_module.c
|
|
+++ b/src/src/event/modules/ngx_eventport_module.c
|
|
@@ -185,6 +185,8 @@ static ngx_event_module_t ngx_eventport_module_ctx = {
|
|
ngx_eventport_process_events, /* process the events */
|
|
ngx_eventport_init, /* init the events */
|
|
ngx_eventport_done, /* done the events */
|
|
+ NULL, /* add an async conn */
|
|
+ NULL /* del an async conn */
|
|
}
|
|
|
|
};
|
|
diff --git a/src/src/event/modules/ngx_kqueue_module.c b/src/src/event/modules/ngx_kqueue_module.c
|
|
index 9c7244c..c775077 100644
|
|
--- a/src/src/event/modules/ngx_kqueue_module.c
|
|
+++ b/src/src/event/modules/ngx_kqueue_module.c
|
|
@@ -92,7 +92,9 @@ static ngx_event_module_t ngx_kqueue_module_ctx = {
|
|
#endif
|
|
ngx_kqueue_process_events, /* process the events */
|
|
ngx_kqueue_init, /* init the events */
|
|
- ngx_kqueue_done /* done the events */
|
|
+ ngx_kqueue_done, /* done the events */
|
|
+ NULL, /* add an async conn */
|
|
+ NULL /* del an async conn */
|
|
}
|
|
|
|
};
|
|
diff --git a/src/src/event/modules/ngx_poll_module.c b/src/src/event/modules/ngx_poll_module.c
|
|
index 4e03dab..c679d92 100644
|
|
--- a/src/src/event/modules/ngx_poll_module.c
|
|
+++ b/src/src/event/modules/ngx_poll_module.c
|
|
@@ -42,7 +42,9 @@ static ngx_event_module_t ngx_poll_module_ctx = {
|
|
NULL, /* trigger a notify */
|
|
ngx_poll_process_events, /* process the events */
|
|
ngx_poll_init, /* init the events */
|
|
- ngx_poll_done /* done the events */
|
|
+ ngx_poll_done, /* done the events */
|
|
+ NULL, /* add an async conn */
|
|
+ NULL /* del an async conn */
|
|
}
|
|
|
|
};
|
|
diff --git a/src/src/event/modules/ngx_select_module.c b/src/src/event/modules/ngx_select_module.c
|
|
index 0644621..4e64a32 100644
|
|
--- a/src/src/event/modules/ngx_select_module.c
|
|
+++ b/src/src/event/modules/ngx_select_module.c
|
|
@@ -50,7 +50,9 @@ static ngx_event_module_t ngx_select_module_ctx = {
|
|
NULL, /* trigger a notify */
|
|
ngx_select_process_events, /* process the events */
|
|
ngx_select_init, /* init the events */
|
|
- ngx_select_done /* done the events */
|
|
+ ngx_select_done, /* done the events */
|
|
+ NULL, /* add an async conn */
|
|
+ NULL /* del an async conn */
|
|
}
|
|
|
|
};
|
|
diff --git a/src/src/event/modules/ngx_win32_select_module.c b/src/src/event/modules/ngx_win32_select_module.c
|
|
index a98a83f..738a96f 100644
|
|
--- a/src/src/event/modules/ngx_win32_select_module.c
|
|
+++ b/src/src/event/modules/ngx_win32_select_module.c
|
|
@@ -51,7 +51,9 @@ static ngx_event_module_t ngx_select_module_ctx = {
|
|
NULL, /* trigger a notify */
|
|
ngx_select_process_events, /* process the events */
|
|
ngx_select_init, /* init the events */
|
|
- ngx_select_done /* done the events */
|
|
+ ngx_select_done, /* done the events */
|
|
+ NULL, /* add an async conn */
|
|
+ NULL /* del an async conn */
|
|
}
|
|
|
|
};
|
|
diff --git a/src/src/event/ngx_event.c b/src/src/event/ngx_event.c
|
|
index 4853945..39cc7e5 100644
|
|
--- a/src/src/event/ngx_event.c
|
|
+++ b/src/src/event/ngx_event.c
|
|
@@ -170,7 +170,7 @@ static ngx_event_module_t ngx_event_core_module_ctx = {
|
|
ngx_event_core_create_conf, /* create configuration */
|
|
ngx_event_core_init_conf, /* init configuration */
|
|
|
|
- { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
|
+ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
|
};
|
|
|
|
|
|
@@ -608,6 +608,9 @@ ngx_event_process_init(ngx_cycle_t *cycle)
|
|
{
|
|
ngx_uint_t m, i;
|
|
ngx_event_t *rev, *wev;
|
|
+#if (NGX_SSL)
|
|
+ ngx_event_t *aev;
|
|
+#endif
|
|
ngx_listening_t *ls;
|
|
ngx_connection_t *c, *next, *old;
|
|
ngx_core_conf_t *ccf;
|
|
@@ -751,6 +754,20 @@ ngx_event_process_init(ngx_cycle_t *cycle)
|
|
wev[i].closed = 1;
|
|
}
|
|
|
|
+#if (NGX_SSL)
|
|
+ cycle->async_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
|
|
+ cycle->log);
|
|
+ if (cycle->async_events == NULL) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+
|
|
+ aev = cycle->async_events;
|
|
+ for (i = 0; i < cycle->connection_n; i++) {
|
|
+ aev[i].closed = 1;
|
|
+ aev[i].instance = 1;
|
|
+ }
|
|
+#endif
|
|
+
|
|
i = cycle->connection_n;
|
|
next = NULL;
|
|
|
|
@@ -761,6 +778,10 @@ ngx_event_process_init(ngx_cycle_t *cycle)
|
|
c[i].read = &cycle->read_events[i];
|
|
c[i].write = &cycle->write_events[i];
|
|
c[i].fd = (ngx_socket_t) -1;
|
|
+#if (NGX_SSL)
|
|
+ c[i].async = &cycle->async_events[i];
|
|
+ c[i].async_fd = (ngx_socket_t) -1;
|
|
+#endif
|
|
|
|
next = &c[i];
|
|
} while (i);
|
|
diff --git a/src/src/event/ngx_event.h b/src/src/event/ngx_event.h
|
|
index 19fec68..dc856b1 100644
|
|
--- a/src/src/event/ngx_event.h
|
|
+++ b/src/src/event/ngx_event.h
|
|
@@ -32,6 +32,10 @@ struct ngx_event_s {
|
|
|
|
unsigned write:1;
|
|
|
|
+#if (NGX_SSL)
|
|
+ unsigned async:1;
|
|
+#endif
|
|
+
|
|
unsigned accept:1;
|
|
|
|
/* used to detect the stale events in kqueue and epoll */
|
|
@@ -108,6 +112,9 @@ struct ngx_event_s {
|
|
#endif
|
|
|
|
ngx_event_handler_pt handler;
|
|
+#if (NGX_SSL)
|
|
+ ngx_event_handler_pt saved_handler;
|
|
+#endif
|
|
|
|
|
|
#if (NGX_HAVE_IOCP)
|
|
@@ -191,6 +198,9 @@ typedef struct {
|
|
|
|
ngx_int_t (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
|
|
void (*done)(ngx_cycle_t *cycle);
|
|
+
|
|
+ ngx_int_t (*add_async_conn)(ngx_connection_t *c);
|
|
+ ngx_int_t (*del_async_conn)(ngx_connection_t *c, ngx_uint_t flags);
|
|
} ngx_event_actions_t;
|
|
|
|
|
|
@@ -415,6 +425,8 @@ extern ngx_uint_t ngx_use_epoll_rdhup;
|
|
#define ngx_del_event ngx_event_actions.del
|
|
#define ngx_add_conn ngx_event_actions.add_conn
|
|
#define ngx_del_conn ngx_event_actions.del_conn
|
|
+#define ngx_add_async_conn ngx_event_actions.add_async_conn
|
|
+#define ngx_del_async_conn ngx_event_actions.del_async_conn
|
|
|
|
#define ngx_notify ngx_event_actions.notify
|
|
|
|
diff --git a/src/src/event/ngx_event_accept.c b/src/src/event/ngx_event_accept.c
|
|
index 7756370..dc22320 100644
|
|
--- a/src/src/event/ngx_event_accept.c
|
|
+++ b/src/src/event/ngx_event_accept.c
|
|
@@ -249,6 +249,9 @@ ngx_event_accept(ngx_event_t *ev)
|
|
|
|
rev->log = log;
|
|
wev->log = log;
|
|
+#if (NGX_SSL)
|
|
+ c->async->log = log;
|
|
+#endif
|
|
|
|
/*
|
|
* TODO: MT: - ngx_atomic_fetch_add()
|
|
@@ -735,6 +738,15 @@ ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all)
|
|
|
|
#endif
|
|
|
|
+#if (NGX_SSL)
|
|
+ if (c->asynch && ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
if (ngx_del_event(c->read, NGX_READ_EVENT, NGX_DISABLE_EVENT)
|
|
== NGX_ERROR)
|
|
{
|
|
diff --git a/src/src/event/ngx_event_openssl.c b/src/src/event/ngx_event_openssl.c
|
|
index 7ca1abc..347607d 100644
|
|
--- a/src/src/event/ngx_event_openssl.c
|
|
+++ b/src/src/event/ngx_event_openssl.c
|
|
@@ -69,6 +69,10 @@ static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
|
|
static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
|
static void ngx_openssl_exit(ngx_cycle_t *cycle);
|
|
|
|
+static void ngx_ssl_handshake_async_handler(ngx_event_t * aev);
|
|
+static void ngx_ssl_read_async_handler(ngx_event_t * aev);
|
|
+static void ngx_ssl_write_async_handler(ngx_event_t * aev);
|
|
+static void ngx_ssl_shutdown_async_handler(ngx_event_t *aev);
|
|
|
|
static ngx_command_t ngx_openssl_commands[] = {
|
|
|
|
@@ -116,6 +120,15 @@ int ngx_ssl_certificate_name_index;
|
|
int ngx_ssl_stapling_index;
|
|
|
|
|
|
+static void
|
|
+ngx_ssl_empty_handler(ngx_event_t *aev)
|
|
+{
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, aev->log, 0, "ssl empty handler");
|
|
+
|
|
+ return;
|
|
+}
|
|
+
|
|
+
|
|
ngx_int_t
|
|
ngx_ssl_init(ngx_log_t *log)
|
|
{
|
|
@@ -342,6 +355,10 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
|
|
SSL_CTX_set_mode(ssl->ctx, SSL_MODE_NO_AUTO_CHAIN);
|
|
#endif
|
|
|
|
+ if(ssl->asynch) {
|
|
+ SSL_CTX_set_mode(ssl->ctx, SSL_MODE_ASYNC);
|
|
+ }
|
|
+
|
|
SSL_CTX_set_read_ahead(ssl->ctx, 1);
|
|
|
|
SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback);
|
|
@@ -1202,6 +1219,7 @@ ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
|
|
}
|
|
|
|
c->ssl = sc;
|
|
+ c->asynch = ssl->asynch;
|
|
|
|
return NGX_OK;
|
|
}
|
|
@@ -1220,6 +1238,78 @@ ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session)
|
|
return NGX_OK;
|
|
}
|
|
|
|
+ngx_int_t
|
|
+ngx_ssl_async_process_fds(ngx_connection_t *c)
|
|
+{
|
|
+ OSSL_ASYNC_FD *add_fds = NULL;
|
|
+ OSSL_ASYNC_FD *del_fds = NULL;
|
|
+ size_t num_add_fds = 0;
|
|
+ size_t num_del_fds = 0;
|
|
+ unsigned loop = 0;
|
|
+
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "ngx_ssl_async_process_fds called");
|
|
+
|
|
+ if (!ngx_del_async_conn || !ngx_add_async_conn) {
|
|
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
|
|
+ "Async notifications not supported");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ SSL_get_changed_async_fds(c->ssl->connection, NULL, &num_add_fds,
|
|
+ NULL, &num_del_fds);
|
|
+
|
|
+ if (num_add_fds) {
|
|
+ add_fds = ngx_alloc(num_add_fds * sizeof(OSSL_ASYNC_FD), c->log);
|
|
+ if (add_fds == NULL) {
|
|
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
|
|
+ "Memory Allocation Error");
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (num_del_fds) {
|
|
+ del_fds = ngx_alloc(num_del_fds * sizeof(OSSL_ASYNC_FD), c->log);
|
|
+ if (del_fds == NULL) {
|
|
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
|
|
+ "Memory Allocation Error");
|
|
+ if (add_fds)
|
|
+ ngx_free(add_fds);
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ SSL_get_changed_async_fds(c->ssl->connection, add_fds, &num_add_fds,
|
|
+ del_fds, &num_del_fds);
|
|
+
|
|
+ if (num_del_fds) {
|
|
+ for (loop = 0; loop < num_del_fds; loop++) {
|
|
+ c->async_fd = del_fds[loop];
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, "%s: deleting fd = %d", __func__, c->async_fd);
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ if (num_add_fds) {
|
|
+ for (loop = 0; loop < num_add_fds; loop++) {
|
|
+ if (c->num_async_fds == 0) {
|
|
+ c->num_async_fds++;
|
|
+ c->async_fd = add_fds[loop];
|
|
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, "%s: adding fd = %d", __func__, c->async_fd);
|
|
+ ngx_add_async_conn(c);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (add_fds)
|
|
+ ngx_free(add_fds);
|
|
+ if (del_fds)
|
|
+ ngx_free(del_fds);
|
|
+
|
|
+ return 1;
|
|
+}
|
|
|
|
ngx_int_t
|
|
ngx_ssl_handshake(ngx_connection_t *c)
|
|
@@ -1235,6 +1325,10 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|
|
|
if (n == 1) {
|
|
|
|
+ if(c->asynch && ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+
|
|
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
|
return NGX_ERROR;
|
|
}
|
|
@@ -1316,6 +1410,10 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
|
|
|
|
if (sslerr == SSL_ERROR_WANT_READ) {
|
|
+ if (c->asynch && ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+
|
|
c->read->ready = 0;
|
|
c->read->handler = ngx_ssl_handshake_handler;
|
|
c->write->handler = ngx_ssl_handshake_handler;
|
|
@@ -1332,6 +1430,9 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|
}
|
|
|
|
if (sslerr == SSL_ERROR_WANT_WRITE) {
|
|
+ if (c->asynch && ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
c->write->ready = 0;
|
|
c->read->handler = ngx_ssl_handshake_handler;
|
|
c->write->handler = ngx_ssl_handshake_handler;
|
|
@@ -1347,6 +1448,22 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|
return NGX_AGAIN;
|
|
}
|
|
|
|
+ if (c->asynch && sslerr == SSL_ERROR_WANT_ASYNC)
|
|
+ {
|
|
+ c->async->handler = ngx_ssl_handshake_async_handler;
|
|
+ c->read->saved_handler = c->read->handler;
|
|
+ c->read->handler = ngx_ssl_empty_handler;
|
|
+
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "SSL ASYNC WANT recieved: \"%s\"", __func__);
|
|
+
|
|
+ if (ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+
|
|
+ return NGX_AGAIN;
|
|
+ }
|
|
+
|
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
if (sslerr == SSL_ERROR_WANT_X509_LOOKUP
|
|
# ifdef SSL_ERROR_PENDING_SESSION
|
|
@@ -1390,6 +1507,28 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|
}
|
|
|
|
|
|
+static void
|
|
+ngx_ssl_handshake_async_handler(ngx_event_t *aev)
|
|
+{
|
|
+ ngx_connection_t *c;
|
|
+
|
|
+ c = aev->data;
|
|
+
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "SSL handshake async handler");
|
|
+
|
|
+ aev->ready = 0;
|
|
+ aev->handler = ngx_ssl_empty_handler;
|
|
+ c->read->handler = c->read->saved_handler;
|
|
+
|
|
+ if (ngx_ssl_handshake(c) == NGX_AGAIN) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ c->ssl->handler(c);
|
|
+}
|
|
+
|
|
+
|
|
static void
|
|
ngx_ssl_handshake_handler(ngx_event_t *ev)
|
|
{
|
|
@@ -1409,6 +1548,11 @@ ngx_ssl_handshake_handler(ngx_event_t *ev)
|
|
return;
|
|
}
|
|
|
|
+ /*
|
|
+ * empty the handler of async event to avoid
|
|
+ * going back to previous ssl handshake state
|
|
+ */
|
|
+ c->async->handler = ngx_ssl_empty_handler;
|
|
c->ssl->handler(c);
|
|
}
|
|
|
|
@@ -1580,6 +1724,10 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
|
|
|
|
if (n > 0) {
|
|
|
|
+ if (c->asynch && ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+
|
|
if (c->ssl->saved_write_handler) {
|
|
|
|
c->write->handler = c->ssl->saved_write_handler;
|
|
@@ -1603,6 +1751,9 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
|
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
|
|
|
|
if (sslerr == SSL_ERROR_WANT_READ) {
|
|
+ if (c->asynch && ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
c->read->ready = 0;
|
|
return NGX_AGAIN;
|
|
}
|
|
@@ -1612,6 +1763,10 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
|
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
|
"peer started SSL renegotiation");
|
|
|
|
+ if (c->asynch && ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+
|
|
c->write->ready = 0;
|
|
|
|
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
|
@@ -1630,6 +1785,21 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
|
|
return NGX_AGAIN;
|
|
}
|
|
|
|
+ if (c->asynch && sslerr == SSL_ERROR_WANT_ASYNC) {
|
|
+ c->async->handler = ngx_ssl_read_async_handler;
|
|
+ c->read->saved_handler = c->read->handler;
|
|
+ c->read->handler = ngx_ssl_empty_handler;
|
|
+
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "SSL ASYNC WANT recieved: \"%s\"", __func__);
|
|
+
|
|
+ if (ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+
|
|
+ return NGX_AGAIN;
|
|
+ }
|
|
+
|
|
c->ssl->no_wait_shutdown = 1;
|
|
c->ssl->no_send_shutdown = 1;
|
|
|
|
@@ -1645,6 +1815,24 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
|
|
}
|
|
|
|
|
|
+static void
|
|
+ngx_ssl_read_async_handler(ngx_event_t *aev)
|
|
+{
|
|
+ ngx_connection_t *c;
|
|
+
|
|
+ c = aev->data;
|
|
+
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "SSL read async handler");
|
|
+
|
|
+ aev->ready = 0;
|
|
+ aev->handler = ngx_ssl_empty_handler;
|
|
+ c->read->handler = c->read->saved_handler;
|
|
+
|
|
+ c->read->handler(c->read);
|
|
+}
|
|
+
|
|
+
|
|
static void
|
|
ngx_ssl_write_handler(ngx_event_t *wev)
|
|
{
|
|
@@ -1835,6 +2023,10 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
|
|
|
|
if (n > 0) {
|
|
|
|
+ if (c->asynch && ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+
|
|
if (c->ssl->saved_read_handler) {
|
|
|
|
c->read->handler = c->ssl->saved_read_handler;
|
|
@@ -1860,6 +2052,9 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
|
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
|
|
|
|
if (sslerr == SSL_ERROR_WANT_WRITE) {
|
|
+ if (c->asynch && ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
c->write->ready = 0;
|
|
return NGX_AGAIN;
|
|
}
|
|
@@ -1869,6 +2064,9 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
|
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
|
"peer started SSL renegotiation");
|
|
|
|
+ if (c->asynch && ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
c->read->ready = 0;
|
|
|
|
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
|
@@ -1888,6 +2086,21 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
|
|
return NGX_AGAIN;
|
|
}
|
|
|
|
+ if(c->asynch && sslerr == SSL_ERROR_WANT_ASYNC) {
|
|
+ c->async->handler = ngx_ssl_write_async_handler;
|
|
+ c->read->saved_handler = c->read->handler;
|
|
+ c->read->handler = ngx_ssl_empty_handler;
|
|
+
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "SSL ASYNC WANT recieved: \"%s\"", __func__);
|
|
+
|
|
+ if (ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+
|
|
+ return NGX_AGAIN;
|
|
+ }
|
|
+
|
|
c->ssl->no_wait_shutdown = 1;
|
|
c->ssl->no_send_shutdown = 1;
|
|
c->write->error = 1;
|
|
@@ -1898,6 +2111,24 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
|
|
}
|
|
|
|
|
|
+static void
|
|
+ngx_ssl_write_async_handler(ngx_event_t *aev)
|
|
+{
|
|
+ ngx_connection_t *c;
|
|
+
|
|
+ c = aev->data;
|
|
+
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "SSL write async handler");
|
|
+
|
|
+ aev->ready = 0;
|
|
+ aev->handler = ngx_ssl_empty_handler;
|
|
+ c->read->handler = c->read->saved_handler;
|
|
+
|
|
+ c->write->handler(c->write);
|
|
+}
|
|
+
|
|
+
|
|
static void
|
|
ngx_ssl_read_handler(ngx_event_t *rev)
|
|
{
|
|
@@ -1926,6 +2157,10 @@ ngx_ssl_shutdown(ngx_connection_t *c)
|
|
int n, sslerr, mode;
|
|
ngx_err_t err;
|
|
|
|
+ if(!c->ssl) {
|
|
+ return NGX_OK;
|
|
+ }
|
|
+
|
|
if (SSL_in_init(c->ssl->connection)) {
|
|
/*
|
|
* OpenSSL 1.0.2f complains if SSL_shutdown() is called during
|
|
@@ -1933,6 +2168,30 @@ ngx_ssl_shutdown(ngx_connection_t *c)
|
|
* Avoid calling SSL_shutdown() if handshake wasn't completed.
|
|
*/
|
|
|
|
+ if(c->asynch) {
|
|
+ /* Check if there is inflight request.
|
|
+ * Wait till async job becomes finished.
|
|
+ */
|
|
+ if (SSL_want_async(c->ssl->connection) && !c->timedout) {
|
|
+ c->async->handler = ngx_ssl_shutdown_async_handler;
|
|
+ ngx_ssl_async_process_fds(c);
|
|
+ ngx_add_timer(c->async, 300);
|
|
+ return NGX_AGAIN;
|
|
+ }
|
|
+
|
|
+ /* Ignore errors from ngx_ssl_async_process_fds as
|
|
+ we want to carry on and close the SSL connection
|
|
+ anyway. */
|
|
+ ngx_ssl_async_process_fds(c);
|
|
+ if (ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+ ngx_del_conn(c, NGX_DISABLE_EVENT);
|
|
+ }
|
|
+
|
|
SSL_free(c->ssl->connection);
|
|
c->ssl = NULL;
|
|
|
|
@@ -1972,13 +2231,34 @@ ngx_ssl_shutdown(ngx_connection_t *c)
|
|
/* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */
|
|
|
|
if (n != 1 && ERR_peek_error()) {
|
|
+ if (c->asynch && ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
sslerr = SSL_get_error(c->ssl->connection, n);
|
|
|
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
"SSL_get_error: %d", sslerr);
|
|
}
|
|
+ else if (c->asynch && n == -1) {
|
|
+ sslerr = SSL_get_error(c->ssl->connection, n);
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "SSL_get_error async: %d", sslerr);
|
|
+ }
|
|
|
|
if (n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN) {
|
|
+ if(c->asynch) {
|
|
+ /* Ignore errors from ngx_ssl_async_process_fds as
|
|
+ we want to carry on and close the SSL connection
|
|
+ anyway. */
|
|
+ ngx_ssl_async_process_fds(c);
|
|
+ if (ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+ ngx_del_conn(c, NGX_DISABLE_EVENT);
|
|
+ }
|
|
SSL_free(c->ssl->connection);
|
|
c->ssl = NULL;
|
|
|
|
@@ -1986,9 +2266,16 @@ ngx_ssl_shutdown(ngx_connection_t *c)
|
|
}
|
|
|
|
if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
|
|
+ if (c->asynch && ngx_ssl_async_process_fds(c) == 0) {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
c->read->handler = ngx_ssl_shutdown_handler;
|
|
c->write->handler = ngx_ssl_shutdown_handler;
|
|
|
|
+ //Work around: Readd write event on shutdown;
|
|
+ c->write->ready = 0;
|
|
+ c->write->active = 0;
|
|
+
|
|
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
|
return NGX_ERROR;
|
|
}
|
|
@@ -2001,9 +2288,41 @@ ngx_ssl_shutdown(ngx_connection_t *c)
|
|
ngx_add_timer(c->read, 30000);
|
|
}
|
|
|
|
+ if (sslerr == SSL_ERROR_WANT_WRITE) {
|
|
+ ngx_add_timer(c->write, 10000);
|
|
+ }
|
|
+
|
|
return NGX_AGAIN;
|
|
}
|
|
|
|
+ if(c->asynch) {
|
|
+ if (sslerr == SSL_ERROR_WANT_ASYNC) {
|
|
+ c->async->handler = ngx_ssl_shutdown_async_handler;
|
|
+ c->read->saved_handler = ngx_ssl_shutdown_handler;
|
|
+ c->read->handler = ngx_ssl_empty_handler;
|
|
+ c->write->handler = ngx_ssl_shutdown_handler;
|
|
+
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "SSL ASYNC WANT recieved: \"%s\"", __func__);
|
|
+
|
|
+ /* Ignore errors from ngx_ssl_async_process_fds as
|
|
+ we want to carry on anyway */
|
|
+ ngx_ssl_async_process_fds(c);
|
|
+ return NGX_AGAIN;
|
|
+ }
|
|
+
|
|
+ /* Ignore errors from ngx_ssl_async_process_fds as
|
|
+ we want to carry on and close the SSL connection
|
|
+ anyway. */
|
|
+ ngx_ssl_async_process_fds(c);
|
|
+ if (ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+ ngx_del_conn(c, NGX_DISABLE_EVENT);
|
|
+ }
|
|
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
|
|
|
|
ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
|
|
@@ -2015,6 +2334,34 @@ ngx_ssl_shutdown(ngx_connection_t *c)
|
|
}
|
|
|
|
|
|
+static void
|
|
+ngx_ssl_shutdown_async_handler(ngx_event_t *aev)
|
|
+{
|
|
+ ngx_connection_t *c;
|
|
+ ngx_connection_handler_pt handler;
|
|
+
|
|
+ c = aev->data;
|
|
+ handler = c->ssl->handler;
|
|
+
|
|
+ if (aev->timedout) {
|
|
+ c->timedout = 1;
|
|
+ }
|
|
+
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, aev->log, 0,
|
|
+ "SSL shutdown async handler");
|
|
+
|
|
+ aev->ready = 0;
|
|
+ aev->handler = ngx_ssl_empty_handler;
|
|
+ c->read->handler = c->read->saved_handler;
|
|
+
|
|
+ if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ handler(c);
|
|
+}
|
|
+
|
|
+
|
|
static void
|
|
ngx_ssl_shutdown_handler(ngx_event_t *ev)
|
|
{
|
|
@@ -2034,6 +2381,11 @@ ngx_ssl_shutdown_handler(ngx_event_t *ev)
|
|
return;
|
|
}
|
|
|
|
+ /*
|
|
+ * empty the handler of async event to avoid
|
|
+ * going back to previous ssl shutdown state
|
|
+ */
|
|
+ c->async->handler = ngx_ssl_empty_handler;
|
|
handler(c);
|
|
}
|
|
|
|
@@ -4227,6 +4579,10 @@ ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|
|
|
oscf->engine = 1;
|
|
|
|
+ if(cf->no_ssl_init) {
|
|
+ return NGX_CONF_OK;
|
|
+ }
|
|
+
|
|
value = cf->args->elts;
|
|
|
|
engine = ENGINE_by_id((char *) value[1].data);
|
|
diff --git a/src/src/event/ngx_event_openssl.h b/src/src/event/ngx_event_openssl.h
|
|
index b9a3a96..e3aecd3 100644
|
|
--- a/src/src/event/ngx_event_openssl.h
|
|
+++ b/src/src/event/ngx_event_openssl.h
|
|
@@ -63,6 +63,7 @@ struct ngx_ssl_s {
|
|
SSL_CTX *ctx;
|
|
ngx_log_t *log;
|
|
size_t buffer_size;
|
|
+ ngx_flag_t asynch;
|
|
};
|
|
|
|
|
|
@@ -193,6 +194,7 @@ ngx_int_t ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session);
|
|
|
|
ngx_int_t ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name);
|
|
|
|
+#define ngx_ssl_waiting_for_async(c) SSL_waiting_for_async(c->ssl->connection)
|
|
|
|
ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool,
|
|
ngx_str_t *s);
|
|
@@ -247,7 +249,7 @@ ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c);
|
|
void ngx_cdecl ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
|
|
char *fmt, ...);
|
|
void ngx_ssl_cleanup_ctx(void *data);
|
|
-
|
|
+ngx_int_t ngx_ssl_async_process_fds(ngx_connection_t *c) ;
|
|
|
|
extern int ngx_ssl_connection_index;
|
|
extern int ngx_ssl_server_conf_index;
|
|
diff --git a/src/src/http/modules/ngx_http_memcached_module.c b/src/src/http/modules/ngx_http_memcached_module.c
|
|
index 69f28fa..8e466b6 100644
|
|
--- a/src/src/http/modules/ngx_http_memcached_module.c
|
|
+++ b/src/src/http/modules/ngx_http_memcached_module.c
|
|
@@ -533,7 +533,7 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
|
|
|
|
last += (size_t) (u->length - NGX_HTTP_MEMCACHED_END);
|
|
|
|
- if (ngx_strncmp(last, ngx_http_memcached_end, b->last - last) != 0) {
|
|
+ if (ngx_strncmp(last, ngx_http_memcached_end,(unsigned)(b->last - last)) != 0) {
|
|
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
|
|
"memcached sent invalid trailer");
|
|
|
|
diff --git a/src/src/http/modules/ngx_http_ssl_module.c b/src/src/http/modules/ngx_http_ssl_module.c
|
|
index 7d62176..47fdfae 100644
|
|
--- a/src/src/http/modules/ngx_http_ssl_module.c
|
|
+++ b/src/src/http/modules/ngx_http_ssl_module.c
|
|
@@ -43,6 +43,8 @@ static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf,
|
|
|
|
static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
|
|
void *conf);
|
|
+static char *ngx_http_ssl_enable_asynch(ngx_conf_t *cf, ngx_command_t *cmd,
|
|
+ void *conf);
|
|
static char *ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
|
|
void *conf);
|
|
static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
|
@@ -80,6 +82,13 @@ static ngx_command_t ngx_http_ssl_commands[] = {
|
|
offsetof(ngx_http_ssl_srv_conf_t, enable),
|
|
NULL },
|
|
|
|
+ { ngx_string("ssl_asynch"),
|
|
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
|
+ ngx_http_ssl_enable_asynch,
|
|
+ NGX_HTTP_SRV_CONF_OFFSET,
|
|
+ offsetof(ngx_http_ssl_srv_conf_t, enable_asynch),
|
|
+ NULL },
|
|
+
|
|
{ ngx_string("ssl_certificate"),
|
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
|
ngx_conf_set_str_array_slot,
|
|
@@ -546,6 +555,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
|
|
*/
|
|
|
|
sscf->enable = NGX_CONF_UNSET;
|
|
+ sscf->enable_asynch = NGX_CONF_UNSET;
|
|
sscf->prefer_server_ciphers = NGX_CONF_UNSET;
|
|
sscf->buffer_size = NGX_CONF_UNSET_SIZE;
|
|
sscf->verify = NGX_CONF_UNSET_UINT;
|
|
@@ -583,6 +593,17 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|
}
|
|
}
|
|
|
|
+ if (conf->enable_asynch == NGX_CONF_UNSET) {
|
|
+ if (prev->enable_asynch == NGX_CONF_UNSET) {
|
|
+ conf->enable_asynch = 0;
|
|
+
|
|
+ } else {
|
|
+ conf->enable_asynch = prev->enable_asynch;
|
|
+ conf->file = prev->file;
|
|
+ conf->line = prev->line;
|
|
+ }
|
|
+ }
|
|
+
|
|
ngx_conf_merge_value(conf->session_timeout,
|
|
prev->session_timeout, 300);
|
|
|
|
@@ -655,6 +676,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|
return NGX_CONF_ERROR;
|
|
}
|
|
|
|
+ conf->ssl.asynch = conf->enable_asynch;
|
|
} else {
|
|
|
|
if (conf->certificates == NULL) {
|
|
@@ -827,6 +849,37 @@ ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|
return NGX_CONF_OK;
|
|
}
|
|
|
|
+static char *
|
|
+ngx_http_ssl_enable_asynch(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|
+{
|
|
+ ngx_http_ssl_srv_conf_t *sscf = conf;
|
|
+
|
|
+ char *rv;
|
|
+
|
|
+ ngx_flag_t *pssl, *pssl_asynch;
|
|
+
|
|
+ rv = ngx_conf_set_flag_slot(cf, cmd, conf);
|
|
+
|
|
+ if (rv != NGX_CONF_OK) {
|
|
+ return rv;
|
|
+ }
|
|
+
|
|
+ /* If ssl_asynch on is configured, then ssl on is configured by default
|
|
+ * This will align 'ssl_asynch on;' and 'listen port ssl' diretives
|
|
+ * */
|
|
+ pssl = (ngx_flag_t *) ((char *)conf + offsetof(ngx_http_ssl_srv_conf_t, enable));
|
|
+ pssl_asynch = (ngx_flag_t *) ((char *)conf + cmd->offset);
|
|
+
|
|
+ if(*pssl_asynch && *pssl != 1) {
|
|
+ *pssl = *pssl_asynch;
|
|
+ }
|
|
+
|
|
+ sscf->file = cf->conf_file->file.name.data;
|
|
+ sscf->line = cf->conf_file->line;
|
|
+
|
|
+ return NGX_CONF_OK;
|
|
+}
|
|
+
|
|
|
|
static char *
|
|
ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|
diff --git a/src/src/http/modules/ngx_http_ssl_module.h b/src/src/http/modules/ngx_http_ssl_module.h
|
|
index 57f5941..b97417a 100644
|
|
--- a/src/src/http/modules/ngx_http_ssl_module.h
|
|
+++ b/src/src/http/modules/ngx_http_ssl_module.h
|
|
@@ -17,6 +17,8 @@
|
|
typedef struct {
|
|
ngx_flag_t enable;
|
|
|
|
+ ngx_flag_t enable_asynch;
|
|
+
|
|
ngx_ssl_t ssl;
|
|
|
|
ngx_flag_t prefer_server_ciphers;
|
|
diff --git a/src/src/http/ngx_http_request.c b/src/src/http/ngx_http_request.c
|
|
index 0de8ace..653990c 100644
|
|
--- a/src/src/http/ngx_http_request.c
|
|
+++ b/src/src/http/ngx_http_request.c
|
|
@@ -451,9 +451,21 @@ ngx_http_wait_request_handler(ngx_event_t *rev)
|
|
* We are trying to not hold c->buffer's memory for an idle connection.
|
|
*/
|
|
|
|
- if (ngx_pfree(c->pool, b->start) == NGX_OK) {
|
|
- b->start = NULL;
|
|
+ /* For the Async implementation we need the same buffer to be used
|
|
+ * again on any async calls that have not completed.
|
|
+ * As such we need to turn off this optimisation if an async request
|
|
+ * is still in progress.
|
|
+ */
|
|
+
|
|
+#if (NGX_HTTP_SSL)
|
|
+ if ((c->asynch && !ngx_ssl_waiting_for_async(c)) || !c->asynch) {
|
|
+#endif
|
|
+ if (ngx_pfree(c->pool, b->start) == NGX_OK) {
|
|
+ b->start = NULL;
|
|
+ }
|
|
+#if (NGX_HTTP_SSL)
|
|
}
|
|
+#endif
|
|
|
|
return;
|
|
}
|
|
@@ -1414,12 +1426,21 @@ ngx_http_read_request_header(ngx_http_request_t *r)
|
|
return n;
|
|
}
|
|
|
|
- if (rev->ready) {
|
|
+#if (NGX_HTTP_SSL)
|
|
+ if(c->asynch)
|
|
n = c->recv(c, r->header_in->last,
|
|
- r->header_in->end - r->header_in->last);
|
|
- } else {
|
|
- n = NGX_AGAIN;
|
|
+ r->header_in->end - r->header_in->last);
|
|
+ else {
|
|
+#endif
|
|
+ if (rev->ready) {
|
|
+ n = c->recv(c, r->header_in->last,
|
|
+ r->header_in->end - r->header_in->last);
|
|
+ } else {
|
|
+ n = NGX_AGAIN;
|
|
+ }
|
|
+#if (NGX_HTTP_SSL)
|
|
}
|
|
+#endif
|
|
|
|
if (n == NGX_AGAIN) {
|
|
if (!rev->timer_set) {
|
|
@@ -1482,8 +1503,8 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
|
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
|
|
|
if (r->state != 0
|
|
- && (size_t) (r->header_in->pos - old)
|
|
- >= cscf->large_client_header_buffers.size)
|
|
+ && (size_t) (unsigned) (r->header_in->pos - old) \
|
|
+ >= cscf->large_client_header_buffers.size)
|
|
{
|
|
return NGX_DECLINED;
|
|
}
|
|
@@ -3014,103 +3035,122 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
|
|
* c->pool and are freed too.
|
|
*/
|
|
|
|
- b = c->buffer;
|
|
-
|
|
- if (ngx_pfree(c->pool, b->start) == NGX_OK) {
|
|
+ /* For the Async implementation we need the same buffer to be used
|
|
+ * again on any async calls that have not completed.
|
|
+ * As such we need to turn off this optimisation if an async request
|
|
+ * is still in progress.
|
|
+ */
|
|
|
|
- /*
|
|
- * the special note for ngx_http_keepalive_handler() that
|
|
- * c->buffer's memory was freed
|
|
- */
|
|
+#if (NGX_HTTP_SSL)
|
|
+ if ((c->asynch && !ngx_ssl_waiting_for_async(c)) || !c->asynch) {
|
|
+#endif
|
|
+ b = c->buffer;
|
|
|
|
- b->pos = NULL;
|
|
+ if (ngx_pfree(c->pool, b->start) == NGX_OK) {
|
|
|
|
- } else {
|
|
- b->pos = b->start;
|
|
- b->last = b->start;
|
|
- }
|
|
+ /*
|
|
+ * the special note for ngx_http_keepalive_handler() that
|
|
+ * c->buffer's memory was freed
|
|
+ */
|
|
|
|
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p",
|
|
- hc->free);
|
|
+ b->pos = NULL;
|
|
|
|
- if (hc->free) {
|
|
- for (cl = hc->free; cl; /* void */) {
|
|
- ln = cl;
|
|
- cl = cl->next;
|
|
- ngx_pfree(c->pool, ln->buf->start);
|
|
- ngx_free_chain(c->pool, ln);
|
|
+ } else {
|
|
+ b->pos = b->start;
|
|
+ b->last = b->start;
|
|
}
|
|
|
|
- hc->free = NULL;
|
|
- }
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p",
|
|
+ hc->free);
|
|
|
|
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %i",
|
|
- hc->busy, hc->nbusy);
|
|
+ if (hc->free) {
|
|
+ for (cl = hc->free; cl; /* void */) {
|
|
+ ln = cl;
|
|
+ cl = cl->next;
|
|
+ ngx_pfree(c->pool, ln->buf->start);
|
|
+ ngx_free_chain(c->pool, ln);
|
|
+ }
|
|
|
|
- if (hc->busy) {
|
|
- for (cl = hc->busy; cl; /* void */) {
|
|
- ln = cl;
|
|
- cl = cl->next;
|
|
- ngx_pfree(c->pool, ln->buf->start);
|
|
- ngx_free_chain(c->pool, ln);
|
|
+ hc->free = NULL;
|
|
}
|
|
|
|
- hc->busy = NULL;
|
|
- hc->nbusy = 0;
|
|
- }
|
|
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %i",
|
|
+ hc->busy, hc->nbusy);
|
|
+
|
|
+ if (hc->busy) {
|
|
+ for (cl = hc->busy; cl; /* void */) {
|
|
+ ln = cl;
|
|
+ cl = cl->next;
|
|
+ ngx_pfree(c->pool, ln->buf->start);
|
|
+ ngx_free_chain(c->pool, ln);
|
|
+ }
|
|
+
|
|
+ hc->busy = NULL;
|
|
+ hc->nbusy = 0;
|
|
+ }
|
|
|
|
#if (NGX_HTTP_SSL)
|
|
- if (c->ssl) {
|
|
- ngx_ssl_free_buffer(c);
|
|
- }
|
|
+ if (c->ssl) {
|
|
+ ngx_ssl_free_buffer(c);
|
|
+ }
|
|
#endif
|
|
|
|
- rev->handler = ngx_http_keepalive_handler;
|
|
+ rev->handler = ngx_http_keepalive_handler;
|
|
|
|
- if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
|
|
- if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
|
|
- ngx_http_close_connection(c);
|
|
- return;
|
|
+ if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
|
|
+#if (NGX_HTTP_SSL)
|
|
+ if (c->asynch && ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+ if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
|
|
+ ngx_http_close_connection(c);
|
|
+ return;
|
|
+ }
|
|
}
|
|
- }
|
|
|
|
- c->log->action = "keepalive";
|
|
+ c->log->action = "keepalive";
|
|
|
|
- if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
|
|
- if (ngx_tcp_push(c->fd) == -1) {
|
|
- ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
|
|
- ngx_http_close_connection(c);
|
|
- return;
|
|
- }
|
|
+ if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
|
|
+ if (ngx_tcp_push(c->fd) == -1) {
|
|
+ ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
|
|
+ ngx_http_close_connection(c);
|
|
+ return;
|
|
+ }
|
|
|
|
- c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
|
|
- tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
|
|
+ c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
|
|
+ tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
|
|
|
|
- } else {
|
|
- tcp_nodelay = 1;
|
|
- }
|
|
+ } else {
|
|
+ tcp_nodelay = 1;
|
|
+ }
|
|
|
|
- if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
|
|
- ngx_http_close_connection(c);
|
|
- return;
|
|
- }
|
|
+ if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
|
|
+ ngx_http_close_connection(c);
|
|
+ return;
|
|
+ }
|
|
|
|
#if 0
|
|
- /* if ngx_http_request_t was freed then we need some other place */
|
|
- r->http_state = NGX_HTTP_KEEPALIVE_STATE;
|
|
+ /* if ngx_http_request_t was freed then we need some other place */
|
|
+ r->http_state = NGX_HTTP_KEEPALIVE_STATE;
|
|
#endif
|
|
|
|
- c->idle = 1;
|
|
- ngx_reusable_connection(c, 1);
|
|
+ c->idle = 1;
|
|
+ ngx_reusable_connection(c, 1);
|
|
|
|
- ngx_add_timer(rev, clcf->keepalive_timeout);
|
|
+ ngx_add_timer(rev, clcf->keepalive_timeout);
|
|
|
|
- if (rev->ready) {
|
|
- ngx_post_event(rev, &ngx_posted_events);
|
|
+ if (rev->ready) {
|
|
+ ngx_post_event(rev, &ngx_posted_events);
|
|
+ }
|
|
+#if (NGX_HTTP_SSL)
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
-
|
|
static void
|
|
ngx_http_keepalive_handler(ngx_event_t *rev)
|
|
{
|
|
@@ -3192,14 +3232,25 @@ ngx_http_keepalive_handler(ngx_event_t *rev)
|
|
* c->buffer's memory for a keepalive connection.
|
|
*/
|
|
|
|
- if (ngx_pfree(c->pool, b->start) == NGX_OK) {
|
|
+ /* For the Asynch implementation we need the same buffer to be used
|
|
+ * on subsequent read requests. As such we need to turn off this optimisation that
|
|
+ * frees the buffer between invocations as may end up with a buffer that is at a
|
|
+ * different address */
|
|
|
|
- /*
|
|
- * the special note that c->buffer's memory was freed
|
|
- */
|
|
+#if (NGX_HTTP_SSL)
|
|
+ if ((c->asynch && !ngx_ssl_waiting_for_async(c)) || !c->asynch) {
|
|
+#endif
|
|
+ if (ngx_pfree(c->pool, b->start) == NGX_OK) {
|
|
|
|
- b->pos = NULL;
|
|
+ /*
|
|
+ * the special note that c->buffer's memory was freed
|
|
+ */
|
|
+
|
|
+ b->pos = NULL;
|
|
+ }
|
|
+#if (NGX_HTTP_SSL)
|
|
}
|
|
+#endif
|
|
|
|
return;
|
|
}
|
|
@@ -3268,6 +3319,14 @@ ngx_http_set_lingering_close(ngx_http_request_t *r)
|
|
wev->handler = ngx_http_empty_handler;
|
|
|
|
if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
|
|
+#if (NGX_HTTP_SSL)
|
|
+ if (c->asynch && ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
|
|
ngx_http_close_request(r, 0);
|
|
return;
|
|
diff --git a/src/src/http/ngx_http_upstream.c b/src/src/http/ngx_http_upstream.c
|
|
index 2d14067..3746224 100644
|
|
--- a/src/src/http/ngx_http_upstream.c
|
|
+++ b/src/src/http/ngx_http_upstream.c
|
|
@@ -938,7 +938,8 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|
|
|
case NGX_DECLINED:
|
|
|
|
- if ((size_t) (u->buffer.end - u->buffer.start) < u->conf->buffer_size) {
|
|
+ if ((size_t) (unsigned) (u->buffer.end - u->buffer.start) \
|
|
+ < u->conf->buffer_size) {
|
|
u->buffer.start = NULL;
|
|
|
|
} else {
|
|
@@ -1314,7 +1315,14 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
|
|
if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && ev->active) {
|
|
|
|
event = ev->write ? NGX_WRITE_EVENT : NGX_READ_EVENT;
|
|
-
|
|
+#if (NGX_HTTP_SSL)
|
|
+ if (c->asynch && ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
if (ngx_del_event(ev, event, 0) != NGX_OK) {
|
|
ngx_http_upstream_finalize_request(r, u,
|
|
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
@@ -1441,7 +1449,14 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
|
|
if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && ev->active) {
|
|
|
|
event = ev->write ? NGX_WRITE_EVENT : NGX_READ_EVENT;
|
|
-
|
|
+#if (NGX_HTTP_SSL)
|
|
+ if (c->asynch && ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
if (ngx_del_event(ev, event, 0) != NGX_OK) {
|
|
ngx_http_upstream_finalize_request(r, u,
|
|
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
@@ -4353,7 +4368,8 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
|
}
|
|
}
|
|
|
|
- ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
|
|
+ if (u->pipe)
|
|
+ ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
|
|
}
|
|
|
|
#endif
|
|
diff --git a/src/src/os/unix/ngx_daemon.c b/src/src/os/unix/ngx_daemon.c
|
|
index ab67211..1834922 100644
|
|
--- a/src/src/os/unix/ngx_daemon.c
|
|
+++ b/src/src/os/unix/ngx_daemon.c
|
|
@@ -10,26 +10,27 @@
|
|
|
|
|
|
ngx_int_t
|
|
-ngx_daemon(ngx_log_t *log)
|
|
+ngx_daemon(ngx_cycle_t *cycle)
|
|
{
|
|
int fd;
|
|
|
|
switch (fork()) {
|
|
case -1:
|
|
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed");
|
|
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "fork() failed");
|
|
return NGX_ERROR;
|
|
|
|
case 0:
|
|
break;
|
|
|
|
default:
|
|
+ ngx_destroy_pool(cycle->pool);
|
|
exit(0);
|
|
}
|
|
|
|
ngx_pid = ngx_getpid();
|
|
|
|
if (setsid() == -1) {
|
|
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed");
|
|
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setsid() failed");
|
|
return NGX_ERROR;
|
|
}
|
|
|
|
@@ -37,31 +38,31 @@ ngx_daemon(ngx_log_t *log)
|
|
|
|
fd = open("/dev/null", O_RDWR);
|
|
if (fd == -1) {
|
|
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
|
|
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
|
|
"open(\"/dev/null\") failed");
|
|
return NGX_ERROR;
|
|
}
|
|
|
|
if (dup2(fd, STDIN_FILENO) == -1) {
|
|
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed");
|
|
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "dup2(STDIN) failed");
|
|
return NGX_ERROR;
|
|
}
|
|
|
|
if (dup2(fd, STDOUT_FILENO) == -1) {
|
|
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed");
|
|
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "dup2(STDOUT) failed");
|
|
return NGX_ERROR;
|
|
}
|
|
|
|
#if 0
|
|
if (dup2(fd, STDERR_FILENO) == -1) {
|
|
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed");
|
|
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "dup2(STDERR) failed");
|
|
return NGX_ERROR;
|
|
}
|
|
#endif
|
|
|
|
if (fd > STDERR_FILENO) {
|
|
if (close(fd) == -1) {
|
|
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed");
|
|
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "close() failed");
|
|
return NGX_ERROR;
|
|
}
|
|
}
|
|
diff --git a/src/src/os/unix/ngx_os.h b/src/src/os/unix/ngx_os.h
|
|
index 3b32819..8249508 100644
|
|
--- a/src/src/os/unix/ngx_os.h
|
|
+++ b/src/src/os/unix/ngx_os.h
|
|
@@ -39,7 +39,7 @@ ngx_int_t ngx_os_init(ngx_log_t *log);
|
|
void ngx_os_status(ngx_log_t *log);
|
|
ngx_int_t ngx_os_specific_init(ngx_log_t *log);
|
|
void ngx_os_specific_status(ngx_log_t *log);
|
|
-ngx_int_t ngx_daemon(ngx_log_t *log);
|
|
+ngx_int_t ngx_daemon(ngx_cycle_t *log);
|
|
ngx_int_t ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_pid_t pid);
|
|
|
|
|
|
diff --git a/src/src/os/unix/ngx_process_cycle.c b/src/src/os/unix/ngx_process_cycle.c
|
|
index 8a4ecbf..a01c47f 100644
|
|
--- a/src/src/os/unix/ngx_process_cycle.c
|
|
+++ b/src/src/os/unix/ngx_process_cycle.c
|
|
@@ -9,7 +9,7 @@
|
|
#include <ngx_core.h>
|
|
#include <ngx_event.h>
|
|
#include <ngx_channel.h>
|
|
-
|
|
+#include <openssl/rand.h>
|
|
|
|
static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n,
|
|
ngx_int_t type);
|
|
@@ -684,6 +684,13 @@ ngx_reap_children(ngx_cycle_t *cycle)
|
|
&& !ngx_terminate
|
|
&& !ngx_quit)
|
|
{
|
|
+#if (NGX_SSL)
|
|
+ /* Delay added to give Quickassist Driver time to cleanup
|
|
+ * if worker exit with non-zero code. */
|
|
+ if(ngx_processes[i].status != 0) {
|
|
+ usleep(2000000);
|
|
+ }
|
|
+#endif
|
|
if (ngx_spawn_process(cycle, ngx_processes[i].proc,
|
|
ngx_processes[i].data,
|
|
ngx_processes[i].name, i)
|
|
@@ -1083,6 +1090,8 @@ ngx_channel_handler(ngx_event_t *ev)
|
|
return;
|
|
}
|
|
|
|
+ ngx_memzero(&ch, sizeof(ngx_channel_t));
|
|
+
|
|
c = ev->data;
|
|
|
|
ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel handler");
|
|
@@ -1096,6 +1105,14 @@ ngx_channel_handler(ngx_event_t *ev)
|
|
if (n == NGX_ERROR) {
|
|
|
|
if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
|
|
+#if (NGX_SSL)
|
|
+ if (c->asynch && ngx_del_async_conn) {
|
|
+ if (c->num_async_fds) {
|
|
+ ngx_del_async_conn(c, NGX_DISABLE_EVENT);
|
|
+ c->num_async_fds--;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
ngx_del_conn(c, 0);
|
|
}
|
|
|