From fdasilva at ingima.com Wed Apr 1 14:02:37 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Wed, 1 Apr 2015 14:02:37 +0000 Subject: [PATCH] OCSP stapling: missing free calls. Message-ID: Hello, As I was working on this code, I see these missing calls. Regards, Filipe www.ingima.com --- # HG changeset patch # User filipe da Silva # Date 1427893508 -7200 # Wed Apr 01 15:05:08 2015 +0200 # Node ID aef78b6a0e789521c029694bf3f5f4fccfd43c69 # Parent 173561dfd5675903996975d57deb7a6f912048dc OCSP stapling: missing free calls. Missing call to X509_STORE_CTX_free when X509_STORE_CTX_init call fails. Missing call to OCSP_CERTID_free when OCSP_request_add0_id call fails. Possible leak in very particular scenarios of memory shortage. diff -r 173561dfd567 -r aef78b6a0e78 src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Tue Mar 31 17:45:50 2015 +0300 +++ b/src/event/ngx_event_openssl_stapling.c Wed Apr 01 15:05:08 2015 +0200 @@ -310,6 +310,7 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, if (X509_STORE_CTX_init(store_ctx, store, NULL, NULL) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_STORE_CTX_init() failed"); + X509_STORE_CTX_free(store_ctx); return NGX_ERROR; } @@ -1118,6 +1119,7 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp if (OCSP_request_add0_id(ocsp, id) == NULL) { ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, "OCSP_request_add0_id() failed"); + OCSP_CERTID_free(id); goto failed; } -------------- next part -------------- A non-text attachment was scrubbed... Name: 6063.patch Type: application/octet-stream Size: 1282 bytes Desc: 6063.patch URL: From vbart at nginx.com Wed Apr 1 21:09:08 2015 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 01 Apr 2015 21:09:08 +0000 Subject: [nginx] Cache: added support for reading of the header in thread... Message-ID: details: http://hg.nginx.org/nginx/rev/d698c300b9ff branches: changeset: 6063:d698c300b9ff user: Valentin Bartenev date: Wed Apr 01 03:49:17 2015 +0300 description: Cache: added support for reading of the header in thread pools. diffstat: src/http/ngx_http_cache.h | 4 + src/http/ngx_http_file_cache.c | 136 +++++++++++++++++++++++++++++++++------- 2 files changed, 115 insertions(+), 25 deletions(-) diffs (182 lines): diff -r 173561dfd567 -r d698c300b9ff src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h Tue Mar 31 17:45:50 2015 +0300 +++ b/src/http/ngx_http_cache.h Wed Apr 01 03:49:17 2015 +0300 @@ -91,6 +91,10 @@ struct ngx_http_cache_s { ngx_http_file_cache_t *file_cache; ngx_http_file_cache_node_t *node; +#if (NGX_THREADS) + ngx_thread_task_t *thread_task; +#endif + ngx_msec_t lock_timeout; ngx_msec_t lock_age; ngx_msec_t lock_time; diff -r 173561dfd567 -r d698c300b9ff src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c Tue Mar 31 17:45:50 2015 +0300 +++ b/src/http/ngx_http_file_cache.c Wed Apr 01 03:49:17 2015 +0300 @@ -23,6 +23,11 @@ static ssize_t ngx_http_file_cache_aio_r #if (NGX_HAVE_FILE_AIO) static void ngx_http_cache_aio_event_handler(ngx_event_t *ev); #endif +#if (NGX_THREADS) +static ngx_int_t ngx_http_cache_thread_handler(ngx_thread_task_t *task, + ngx_file_t *file); +static void ngx_http_cache_thread_event_handler(ngx_event_t *ev); +#endif static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c); static ngx_int_t ngx_http_file_cache_name(ngx_http_request_t *r, @@ -636,39 +641,50 @@ ngx_http_file_cache_read(ngx_http_reques static ssize_t ngx_http_file_cache_aio_read(ngx_http_request_t *r, ngx_http_cache_t *c) { -#if (NGX_HAVE_FILE_AIO) +#if (NGX_HAVE_FILE_AIO || NGX_THREADS) ssize_t n; ngx_http_core_loc_conf_t *clcf; - if (!ngx_file_aio) { - goto noaio; + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); +#endif + +#if (NGX_HAVE_FILE_AIO) + + if (clcf->aio == NGX_HTTP_AIO_ON && ngx_file_aio) { + n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool); + + if (n != NGX_AGAIN) { + c->reading = 0; + return n; + } + + c->reading = 1; + + c->file.aio->data = r; + c->file.aio->handler = ngx_http_cache_aio_event_handler; + + r->main->blocked++; + r->aio = 1; + + return NGX_AGAIN; } - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - if (clcf->aio != NGX_HTTP_AIO_ON) { - goto noaio; - } - - n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool); - - if (n != NGX_AGAIN) { - c->reading = 0; +#endif + +#if (NGX_THREADS) + + if (clcf->aio == NGX_HTTP_AIO_THREADS) { + c->file.thread_handler = ngx_http_cache_thread_handler; + c->file.thread_ctx = r; + + n = ngx_thread_read(&c->thread_task, &c->file, c->buf->pos, + c->body_start, 0, r->pool); + + c->reading = (n == NGX_AGAIN); + return n; } - c->reading = 1; - - c->file.aio->data = r; - c->file.aio->handler = ngx_http_cache_aio_event_handler; - - r->main->blocked++; - r->aio = 1; - - return NGX_AGAIN; - -noaio: - #endif return ngx_read_file(&c->file, c->buf->pos, c->body_start, 0); @@ -704,6 +720,76 @@ ngx_http_cache_aio_event_handler(ngx_eve #endif +#if (NGX_THREADS) + +static ngx_int_t +ngx_http_cache_thread_handler(ngx_thread_task_t *task, ngx_file_t *file) +{ + ngx_str_t name; + ngx_thread_pool_t *tp; + ngx_http_request_t *r; + ngx_http_core_loc_conf_t *clcf; + + r = file->thread_ctx; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + tp = clcf->thread_pool; + + if (tp == NULL) { + if (ngx_http_complex_value(r, clcf->thread_pool_value, &name) + != NGX_OK) + { + return NGX_ERROR; + } + + tp = ngx_thread_pool_get((ngx_cycle_t *) ngx_cycle, &name); + + if (tp == NULL) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "thread pool \"%V\" not found", &name); + return NGX_ERROR; + } + } + + task->event.data = r; + task->event.handler = ngx_http_cache_thread_event_handler; + + if (ngx_thread_task_post(tp, task) != NGX_OK) { + return NGX_ERROR; + } + + r->main->blocked++; + r->aio = 1; + + return NGX_OK; +} + + +static void +ngx_http_cache_thread_event_handler(ngx_event_t *ev) +{ + ngx_connection_t *c; + ngx_http_request_t *r; + + r = ev->data; + c = r->connection; + + ngx_http_set_log_request(c->log, r); + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http file cache thread: \"%V?%V\"", &r->uri, &r->args); + + r->main->blocked--; + r->aio = 0; + + r->write_event_handler(r); + + ngx_http_run_posted_requests(c); +} + +#endif + + static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c) { From mdounin at mdounin.ru Thu Apr 2 19:10:49 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 02 Apr 2015 19:10:49 +0000 Subject: [nginx] OCSP stapling: missing free calls. Message-ID: details: http://hg.nginx.org/nginx/rev/ff957cd36860 branches: changeset: 6064:ff957cd36860 user: Filipe da Silva date: Wed Apr 01 15:05:08 2015 +0200 description: OCSP stapling: missing free calls. Missing call to X509_STORE_CTX_free when X509_STORE_CTX_init fails. Missing call to OCSP_CERTID_free when OCSP_request_add0_id fails. Possible leaks in vary particular scenariis of memory shortage. diffstat: src/event/ngx_event_openssl_stapling.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (19 lines): diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -310,6 +310,7 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, if (X509_STORE_CTX_init(store_ctx, store, NULL, NULL) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_STORE_CTX_init() failed"); + X509_STORE_CTX_free(store_ctx); return NGX_ERROR; } @@ -1118,6 +1119,7 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp if (OCSP_request_add0_id(ocsp, id) == NULL) { ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, "OCSP_request_add0_id() failed"); + OCSP_CERTID_free(id); goto failed; } From mdounin at mdounin.ru Thu Apr 2 19:11:01 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 2 Apr 2015 22:11:01 +0300 Subject: [PATCH] OCSP stapling: missing free calls. In-Reply-To: References: Message-ID: <20150402191100.GB88631@mdounin.ru> Hello! On Wed, Apr 01, 2015 at 02:02:37PM +0000, Filipe DA SILVA wrote: > Hello, > > As I was working on this code, I see these missing calls. Committed with minor changes (see below), thanks. [...] > # HG changeset patch > # User filipe da Silva Nitpicking: I've capitalized the first letter of the name. > # Date 1427893508 -7200 > # Wed Apr 01 15:05:08 2015 +0200 > # Node ID aef78b6a0e789521c029694bf3f5f4fccfd43c69 > # Parent 173561dfd5675903996975d57deb7a6f912048dc > OCSP stapling: missing free calls. > > Missing call to X509_STORE_CTX_free when X509_STORE_CTX_init call fails. > Missing call to OCSP_CERTID_free when OCSP_request_add0_id call fails. > Possible leak in very particular scenarios of memory shortage. > > diff -r 173561dfd567 -r aef78b6a0e78 src/event/ngx_event_openssl_stapling.c > --- a/src/event/ngx_event_openssl_stapling.c Tue Mar 31 17:45:50 2015 +0300 > +++ b/src/event/ngx_event_openssl_stapling.c Wed Apr 01 15:05:08 2015 +0200 > @@ -310,6 +310,7 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, > if (X509_STORE_CTX_init(store_ctx, store, NULL, NULL) == 0) { > ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, > "X509_STORE_CTX_init() failed"); > + X509_STORE_CTX_free(store_ctx); > return NGX_ERROR; > } > > @@ -1118,6 +1119,7 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp > if (OCSP_request_add0_id(ocsp, id) == NULL) { > ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, > "OCSP_request_add0_id() failed"); > + OCSP_CERTID_free(id); Nitpicking: nginx code uses 4 spaces for indentation, not tabs. Fixed. > goto failed; > } -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Fri Apr 3 15:22:25 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 03 Apr 2015 15:22:25 +0000 Subject: [nginx] Configure: style. Message-ID: details: http://hg.nginx.org/nginx/rev/0daea93e86a2 branches: changeset: 6065:0daea93e86a2 user: Maxim Dounin date: Fri Apr 03 18:20:57 2015 +0300 description: Configure: style. diffstat: auto/make | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/auto/make b/auto/make --- a/auto/make +++ b/auto/make @@ -8,7 +8,7 @@ echo "creating $NGX_MAKEFILE" mkdir -p $NGX_OBJS/src/core $NGX_OBJS/src/event $NGX_OBJS/src/event/modules \ $NGX_OBJS/src/os/unix $NGX_OBJS/src/os/win32 \ $NGX_OBJS/src/http $NGX_OBJS/src/http/modules \ - $NGX_OBJS/src/http/modules/perl \ + $NGX_OBJS/src/http/modules/perl \ $NGX_OBJS/src/mail \ $NGX_OBJS/src/misc From vbart at nginx.com Mon Apr 6 08:24:03 2015 From: vbart at nginx.com (Valentin Bartenev) Date: Mon, 06 Apr 2015 08:24:03 +0000 Subject: [nginx] Used the correct type for the AIO preload handler return... Message-ID: details: http://hg.nginx.org/nginx/rev/657f6ec01da0 branches: changeset: 6066:657f6ec01da0 user: Valentin Bartenev date: Mon Apr 06 11:22:24 2015 +0300 description: Used the correct type for the AIO preload handler return value. diffstat: src/os/unix/ngx_freebsd_sendfile_chain.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (15 lines): diff -r 0daea93e86a2 -r 657f6ec01da0 src/os/unix/ngx_freebsd_sendfile_chain.c --- a/src/os/unix/ngx_freebsd_sendfile_chain.c Fri Apr 03 18:20:57 2015 +0300 +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c Mon Apr 06 11:22:24 2015 +0300 @@ -266,9 +266,9 @@ ngx_freebsd_sendfile_chain(ngx_connectio c->busy_count = 0; } - rc = aio->preload_handler(file); + n = aio->preload_handler(file); - if (rc > 0) { + if (n > 0) { send = prev_send + sent; continue; } From vbart at nginx.com Mon Apr 6 16:21:15 2015 From: vbart at nginx.com (Valentin Bartenev) Date: Mon, 06 Apr 2015 16:21:15 +0000 Subject: [nginx] Request body: always flush buffers if request buffering ... Message-ID: details: http://hg.nginx.org/nginx/rev/231a5bbd9e9c branches: changeset: 6067:231a5bbd9e9c user: Valentin Bartenev date: Mon Apr 06 19:20:36 2015 +0300 description: Request body: always flush buffers if request buffering is off. This fixes unbuffered proxying to SSL backends, since it prevents ngx_ssl_send_chain() from accumulation of request body in the SSL buffer. diffstat: src/http/ngx_http_request_body.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (19 lines): diff -r 657f6ec01da0 -r 231a5bbd9e9c src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c Mon Apr 06 11:22:24 2015 +0300 +++ b/src/http/ngx_http_request_body.c Mon Apr 06 19:20:36 2015 +0300 @@ -949,6 +949,7 @@ ngx_http_request_body_length_filter(ngx_ b->pos = cl->buf->pos; b->last = cl->buf->last; b->end = cl->buf->end; + b->flush = r->request_body_no_buffering; size = cl->buf->last - cl->buf->pos; @@ -1056,6 +1057,7 @@ ngx_http_request_body_chunked_filter(ngx b->pos = cl->buf->pos; b->last = cl->buf->last; b->end = cl->buf->end; + b->flush = r->request_body_no_buffering; *ll = tl; ll = &tl->next; From ru at nginx.com Mon Apr 6 21:07:55 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 06 Apr 2015 21:07:55 +0000 Subject: [nginx] Upstream: abbreviated SSL handshake may interact badly w... Message-ID: details: http://hg.nginx.org/nginx/rev/643f2ce02f1c branches: changeset: 6068:643f2ce02f1c user: Ruslan Ermilov date: Tue Apr 07 00:07:04 2015 +0300 description: Upstream: abbreviated SSL handshake may interact badly with Nagle. diffstat: src/http/ngx_http_upstream.c | 26 +++++++++++++++++++++++++- 1 files changed, 25 insertions(+), 1 deletions(-) diffs (43 lines): diff -r 231a5bbd9e9c -r 643f2ce02f1c src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Mon Apr 06 19:20:36 2015 +0300 +++ b/src/http/ngx_http_upstream.c Tue Apr 07 00:07:04 2015 +0300 @@ -1448,7 +1448,9 @@ static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_connection_t *c) { - ngx_int_t rc; + int tcp_nodelay; + ngx_int_t rc; + ngx_http_core_loc_conf_t *clcf; if (ngx_http_upstream_test_connect(c) != NGX_OK) { ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); @@ -1481,6 +1483,28 @@ ngx_http_upstream_ssl_init_connection(ng NGX_HTTP_INTERNAL_SERVER_ERROR); return; } + + /* abbreviated SSL handshake may interact badly with Nagle */ + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); + + tcp_nodelay = 1; + + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) == -1) + { + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + + c->tcp_nodelay = NGX_TCP_NODELAY_SET; + } } r->connection->log->action = "SSL handshaking to upstream"; From pluknet at nginx.com Mon Apr 6 22:33:43 2015 From: pluknet at nginx.com (Sergey Kandaurov) Date: Mon, 06 Apr 2015 22:33:43 +0000 Subject: [nginx] Core: fixed error handling on ngx_conf_full_name() failure. Message-ID: details: http://hg.nginx.org/nginx/rev/e37ec0a33901 branches: changeset: 6069:e37ec0a33901 user: Sergey Kandaurov date: Tue Apr 07 01:32:05 2015 +0300 description: Core: fixed error handling on ngx_conf_full_name() failure. diffstat: src/core/ngx_file.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 643f2ce02f1c -r e37ec0a33901 src/core/ngx_file.c --- a/src/core/ngx_file.c Tue Apr 07 00:07:04 2015 +0300 +++ b/src/core/ngx_file.c Tue Apr 07 01:32:05 2015 +0300 @@ -356,7 +356,7 @@ ngx_conf_set_path_slot(ngx_conf_t *cf, n } if (ngx_conf_full_name(cf->cycle, &path->name, 0) != NGX_OK) { - return NULL; + return NGX_CONF_ERROR; } path->conf_file = cf->conf_file->file.name.data; From pluknet at nginx.com Mon Apr 6 22:33:46 2015 From: pluknet at nginx.com (Sergey Kandaurov) Date: Mon, 06 Apr 2015 22:33:46 +0000 Subject: [nginx] Core: removed excessive initialization in ngx_conf_set_p... Message-ID: details: http://hg.nginx.org/nginx/rev/3f5465a33fa8 branches: changeset: 6070:3f5465a33fa8 user: Sergey Kandaurov date: Tue Apr 07 01:32:07 2015 +0300 description: Core: removed excessive initialization in ngx_conf_set_path_slot(). Level hierarchy is pre-zeroed in ngx_pcalloc() of the surrounding ngx_path_t. diffstat: src/core/ngx_file.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-) diffs (14 lines): diff -r e37ec0a33901 -r 3f5465a33fa8 src/core/ngx_file.c --- a/src/core/ngx_file.c Tue Apr 07 01:32:05 2015 +0300 +++ b/src/core/ngx_file.c Tue Apr 07 01:32:07 2015 +0300 @@ -372,10 +372,6 @@ ngx_conf_set_path_slot(ngx_conf_t *cf, n path->len += level + 1; } - while (i < 3) { - path->level[i++] = 0; - } - *slot = path; if (ngx_add_path(cf, slot) == NGX_ERROR) { From pluknet at nginx.com Mon Apr 6 22:33:49 2015 From: pluknet at nginx.com (Sergey Kandaurov) Date: Mon, 06 Apr 2015 22:33:49 +0000 Subject: [nginx] Core: limited levels of subdirectory hierarchy used for ... Message-ID: details: http://hg.nginx.org/nginx/rev/7bdd34cd2711 branches: changeset: 6071:7bdd34cd2711 user: Sergey Kandaurov date: Tue Apr 07 01:32:08 2015 +0300 description: Core: limited levels of subdirectory hierarchy used for temp files. Similar to ngx_http_file_cache_set_slot(), the last component of file->name with a fixed length of 10 bytes, as generated in ngx_create_temp_path(), is used as a source for the names of intermediate subdirectories with each one taking its own part. Ensure that the sum of specified levels with slashes fits into the length (ticket #731). diffstat: src/core/ngx_file.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r 3f5465a33fa8 -r 7bdd34cd2711 src/core/ngx_file.c --- a/src/core/ngx_file.c Tue Apr 07 01:32:07 2015 +0300 +++ b/src/core/ngx_file.c Tue Apr 07 01:32:08 2015 +0300 @@ -372,6 +372,10 @@ ngx_conf_set_path_slot(ngx_conf_t *cf, n path->len += level + 1; } + if (path->len > 10 + i) { + return "invalid value"; + } + *slot = path; if (ngx_add_path(cf, slot) == NGX_ERROR) { From ru at nginx.com Tue Apr 7 11:26:36 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 07 Apr 2015 11:26:36 +0000 Subject: [nginx] Core: guard against spinlock usage without atomic ops. Message-ID: details: http://hg.nginx.org/nginx/rev/f737e406aa68 branches: changeset: 6072:f737e406aa68 user: Ruslan Ermilov date: Thu Mar 26 14:15:06 2015 +0300 description: Core: guard against spinlock usage without atomic ops. The new thread pools code uses spinlocks. diffstat: src/core/ngx_spinlock.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 7bdd34cd2711 -r f737e406aa68 src/core/ngx_spinlock.c --- a/src/core/ngx_spinlock.c Tue Apr 07 01:32:08 2015 +0300 +++ b/src/core/ngx_spinlock.c Thu Mar 26 14:15:06 2015 +0300 @@ -42,7 +42,7 @@ ngx_spinlock(ngx_atomic_t *lock, ngx_ato #else -#if (NGX_OLD_THREADS) +#if (NGX_THREADS) #error ngx_spinlock() or ngx_atomic_cmp_set() are not defined ! From mdounin at mdounin.ru Tue Apr 7 13:03:52 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:03:52 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/8bc8eb8abfae branches: stable-1.6 changeset: 6073:8bc8eb8abfae user: Maxim Dounin date: Mon Apr 06 18:54:19 2015 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1006002 -#define NGINX_VERSION "1.6.2" +#define nginx_version 1006003 +#define NGINX_VERSION "1.6.3" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" From mdounin at mdounin.ru Tue Apr 7 13:03:55 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:03:55 +0000 Subject: [nginx] Core: fixed buffer overrun when hash max_size reached. Message-ID: details: http://hg.nginx.org/nginx/rev/dfb23e4361da branches: stable-1.6 changeset: 6074:dfb23e4361da user: Yichun Zhang date: Thu Oct 02 12:00:17 2014 -0700 description: Core: fixed buffer overrun when hash max_size reached. diffstat: src/core/ngx_hash.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff --git a/src/core/ngx_hash.c b/src/core/ngx_hash.c --- a/src/core/ngx_hash.c +++ b/src/core/ngx_hash.c @@ -312,6 +312,8 @@ ngx_hash_init(ngx_hash_init_t *hinit, ng continue; } + size--; + ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0, "could not build optimal %s, you should increase " "either %s_max_size: %i or %s_bucket_size: %i; " From mdounin at mdounin.ru Tue Apr 7 13:03:58 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:03:58 +0000 Subject: [nginx] Fixed possible buffer overrun in "too long header line" ... Message-ID: details: http://hg.nginx.org/nginx/rev/7fcfe113827d branches: stable-1.6 changeset: 6075:7fcfe113827d user: Maxim Dounin date: Wed Oct 08 17:16:04 2014 +0400 description: Fixed possible buffer overrun in "too long header line" logging. Additionally, ellipsis now always added to make it clear that the header logged is incomplete. Reported by Daniil Bondarev. diffstat: src/http/ngx_http_request.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diffs (18 lines): diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1227,12 +1227,11 @@ ngx_http_process_request_headers(ngx_eve if (len > NGX_MAX_ERROR_STR - 300) { len = NGX_MAX_ERROR_STR - 300; - p[len++] = '.'; p[len++] = '.'; p[len++] = '.'; } ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client sent too long header line: \"%*s\"", - len, r->header_name_start); + "client sent too long header line: \"%*s...\"", + len, r->header_name_start); ngx_http_finalize_request(r, NGX_HTTP_REQUEST_HEADER_TOO_LARGE); From mdounin at mdounin.ru Tue Apr 7 13:04:06 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:04:06 +0000 Subject: [nginx] SSL: logging level of "inappropriate fallback" (ticket #... Message-ID: details: http://hg.nginx.org/nginx/rev/1d6eb39d05c9 branches: stable-1.6 changeset: 6076:1d6eb39d05c9 user: Maxim Dounin date: Mon Nov 17 16:38:48 2014 +0300 description: SSL: logging level of "inappropriate fallback" (ticket #662). Patch by Erik Dubbelboer. diffstat: src/event/ngx_event_openssl.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -1614,6 +1614,9 @@ ngx_ssl_connection_error(ngx_connection_ #ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING || n == SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING /* 345 */ #endif +#ifdef SSL_R_INAPPROPRIATE_FALLBACK + || n == SSL_R_INAPPROPRIATE_FALLBACK /* 373 */ +#endif || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */ || n == SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE /* 1010 */ || n == SSL_R_SSLV3_ALERT_BAD_RECORD_MAC /* 1020 */ From mdounin at mdounin.ru Tue Apr 7 13:04:08 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:04:08 +0000 Subject: [nginx] Resolver: fixed use-after-free memory access. Message-ID: details: http://hg.nginx.org/nginx/rev/0395f788b080 branches: stable-1.6 changeset: 6077:0395f788b080 user: Ruslan Ermilov date: Thu Nov 20 15:24:40 2014 +0300 description: Resolver: fixed use-after-free memory access. In 954867a2f0a6, we switched to using resolver node as the timer event data, so make sure we do not free resolver node memory until the corresponding timer is deleted. diffstat: src/core/ngx_resolver.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (39 lines): diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -1568,8 +1568,6 @@ ngx_resolver_process_a(ngx_resolver_t *r ngx_rbtree_delete(&r->name_rbtree, &rn->node); - ngx_resolver_free_node(r, rn); - /* unlock name mutex */ while (next) { @@ -1580,6 +1578,8 @@ ngx_resolver_process_a(ngx_resolver_t *r ctx->handler(ctx); } + ngx_resolver_free_node(r, rn); + return; } @@ -2143,8 +2143,6 @@ valid: ngx_rbtree_delete(tree, &rn->node); - ngx_resolver_free_node(r, rn); - /* unlock addr mutex */ while (next) { @@ -2155,6 +2153,8 @@ valid: ctx->handler(ctx); } + ngx_resolver_free_node(r, rn); + return; } From mdounin at mdounin.ru Tue Apr 7 13:04:21 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:04:21 +0000 Subject: [nginx] SPDY: push pending data while closing a stream as with k... Message-ID: details: http://hg.nginx.org/nginx/rev/7ea6f5140ed9 branches: stable-1.6 changeset: 6078:7ea6f5140ed9 user: Valentin Bartenev date: Fri Nov 21 22:51:49 2014 +0300 description: SPDY: push pending data while closing a stream as with keepalive. This helps to avoid delays in sending the last chunk of data because of bad interaction between Nagle's algorithm on nginx side and delayed ACK on the client side. Delays could also be caused by TCP_CORK/TCP_NOPUSH if SPDY was working without SSL and sendfile() was used. diffstat: src/http/ngx_http_spdy.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 51 insertions(+), 1 deletions(-) diffs (70 lines): diff --git a/src/http/ngx_http_spdy.c b/src/http/ngx_http_spdy.c --- a/src/http/ngx_http_spdy.c +++ b/src/http/ngx_http_spdy.c @@ -3156,8 +3156,10 @@ ngx_http_spdy_close_stream_handler(ngx_e void ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc) { + int tcp_nodelay; ngx_event_t *ev; - ngx_connection_t *fc; + ngx_connection_t *c, *fc; + ngx_http_core_loc_conf_t *clcf; ngx_http_spdy_stream_t **index, *s; ngx_http_spdy_srv_conf_t *sscf; ngx_http_spdy_connection_t *sc; @@ -3183,6 +3185,54 @@ ngx_http_spdy_close_stream(ngx_http_spdy { sc->connection->error = 1; } + + } else { + c = sc->connection; + + 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"); + c->error = 1; + tcp_nodelay = 0; + + } else { + c->tcp_nopush = NGX_TCP_NOPUSH_UNSET; + tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0; + } + + } else { + tcp_nodelay = 1; + } + + clcf = ngx_http_get_module_loc_conf(stream->request, + ngx_http_core_module); + + if (tcp_nodelay + && clcf->tcp_nodelay + && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) + { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); + + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) + == -1) + { +#if (NGX_SOLARIS) + /* Solaris returns EINVAL if a socket has been shut down */ + c->log_error = NGX_ERROR_IGNORE_EINVAL; +#endif + + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + + c->log_error = NGX_ERROR_INFO; + c->error = 1; + + } else { + c->tcp_nodelay = NGX_TCP_NODELAY_SET; + } + } } if (sc->stream == stream) { From mdounin at mdounin.ru Tue Apr 7 13:04:23 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:04:23 +0000 Subject: [nginx] Fixed post_action to not trigger "header already sent" a... Message-ID: details: http://hg.nginx.org/nginx/rev/8e56f649fd0d branches: stable-1.6 changeset: 6079:8e56f649fd0d user: Maxim Dounin date: Fri Nov 28 16:57:50 2014 +0300 description: Fixed post_action to not trigger "header already sent" alert. The alert was introduced in 03ff14058272 (1.5.4), and was triggered on each post_action invocation. There is no real need to call header filters in case of post_action, so return NGX_OK from ngx_http_send_header() if r->post_action is set. diffstat: src/http/ngx_http_core_module.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1935,6 +1935,10 @@ ngx_http_send_response(ngx_http_request_ ngx_int_t ngx_http_send_header(ngx_http_request_t *r) { + if (r->post_action) { + return NGX_OK; + } + if (r->header_sent) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "header already sent"); From mdounin at mdounin.ru Tue Apr 7 13:04:31 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:04:31 +0000 Subject: [nginx] Core: fixed a race resulting in extra sem_post()'s. Message-ID: details: http://hg.nginx.org/nginx/rev/4296627f385a branches: stable-1.6 changeset: 6080:4296627f385a user: Roman Arutyunyan date: Wed Feb 04 16:22:43 2015 +0300 description: Core: fixed a race resulting in extra sem_post()'s. The mtx->wait counter was not decremented if we were able to obtain the lock right after incrementing it. This resulted in unneeded sem_post() calls, eventually leading to EOVERFLOW errors being logged, "sem_post() failed while wake shmtx (75: Value too large for defined data type)". To close the race, mtx->wait is now decremented if we obtain the lock right after incrementing it in ngx_shmtx_lock(). The result can become -1 if a concurrent ngx_shmtx_unlock() decrements mtx->wait before the added code does. However, that only leads to one extra iteration in the next call of ngx_shmtx_lock(). diffstat: src/core/ngx_shmtx.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (20 lines): diff --git a/src/core/ngx_shmtx.c b/src/core/ngx_shmtx.c --- a/src/core/ngx_shmtx.c +++ b/src/core/ngx_shmtx.c @@ -101,6 +101,7 @@ ngx_shmtx_lock(ngx_shmtx_t *mtx) (void) ngx_atomic_fetch_add(mtx->wait, 1); if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) { + (void) ngx_atomic_fetch_add(mtx->wait, -1); return; } @@ -174,7 +175,7 @@ ngx_shmtx_wakeup(ngx_shmtx_t *mtx) wait = *mtx->wait; - if (wait == 0) { + if ((ngx_atomic_int_t) wait <= 0) { return; } From mdounin at mdounin.ru Tue Apr 7 13:04:38 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:04:38 +0000 Subject: [nginx] Core: fixed potential buffer overrun when initializing h... Message-ID: details: http://hg.nginx.org/nginx/rev/12ab5cd445c0 branches: stable-1.6 changeset: 6081:12ab5cd445c0 user: Maxim Dounin date: Tue Feb 24 18:37:14 2015 +0300 description: Core: fixed potential buffer overrun when initializing hash. Initial size as calculated from the number of elements may be bigger than max_size. If this happens, make sure to set size to max_size. Reported by Chris West. diffstat: src/core/ngx_hash.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/src/core/ngx_hash.c b/src/core/ngx_hash.c --- a/src/core/ngx_hash.c +++ b/src/core/ngx_hash.c @@ -312,7 +312,7 @@ ngx_hash_init(ngx_hash_init_t *hinit, ng continue; } - size--; + size = hinit->max_size; ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0, "could not build optimal %s, you should increase " From mdounin at mdounin.ru Tue Apr 7 13:04:41 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:04:41 +0000 Subject: [nginx] Core: expose maximum values of time_t and ngx_int_t. Message-ID: details: http://hg.nginx.org/nginx/rev/51d4fde64bca branches: stable-1.6 changeset: 6082:51d4fde64bca user: Ruslan Ermilov date: Tue Mar 17 00:24:34 2015 +0300 description: Core: expose maximum values of time_t and ngx_int_t. These are needed to detect overflows. diffstat: auto/unix | 1 + src/core/ngx_config.h | 3 +++ src/os/win32/ngx_win32_config.h | 1 + 3 files changed, 5 insertions(+), 0 deletions(-) diffs (37 lines): diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -489,6 +489,7 @@ ngx_param=NGX_OFF_T_LEN; ngx_value=$ngx_ ngx_type="time_t"; . auto/types/sizeof ngx_param=NGX_TIME_T_SIZE; ngx_value=$ngx_size; . auto/types/value ngx_param=NGX_TIME_T_LEN; ngx_value=$ngx_max_len; . auto/types/value +ngx_param=NGX_MAX_TIME_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value # syscalls, libc calls and some features diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -85,8 +85,11 @@ typedef intptr_t ngx_flag_t; #if (NGX_PTR_SIZE == 4) #define NGX_INT_T_LEN NGX_INT32_LEN +#define NGX_MAX_INT_T_VALUE 2147483647 + #else #define NGX_INT_T_LEN NGX_INT64_LEN +#define NGX_MAX_INT_T_VALUE 9223372036854775807 #endif diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -175,6 +175,7 @@ typedef int sig_atomic_t #define NGX_MAX_SIZE_T_VALUE 2147483647 #define NGX_TIME_T_LEN (sizeof("-2147483648") - 1) #define NGX_TIME_T_SIZE 4 +#define NGX_MAX_TIME_T_VALUE 2147483647 #define NGX_OFF_T_LEN (sizeof("-9223372036854775807") - 1) #define NGX_MAX_OFF_T_VALUE 9223372036854775807 #define NGX_SIG_ATOMIC_T_SIZE 4 From mdounin at mdounin.ru Tue Apr 7 13:04:49 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:04:49 +0000 Subject: [nginx] Core: overflow detection in number parsing functions. Message-ID: details: http://hg.nginx.org/nginx/rev/516d8e299273 branches: stable-1.6 changeset: 6083:516d8e299273 user: Ruslan Ermilov date: Tue Mar 17 00:26:15 2015 +0300 description: Core: overflow detection in number parsing functions. diffstat: src/core/ngx_parse.c | 25 +++++++----- src/core/ngx_string.c | 99 +++++++++++++++++++++++++++++--------------------- 2 files changed, 72 insertions(+), 52 deletions(-) diffs (truncated from 317 to 300 lines): diff --git a/src/core/ngx_parse.c b/src/core/ngx_parse.c --- a/src/core/ngx_parse.c +++ b/src/core/ngx_parse.c @@ -12,10 +12,9 @@ ssize_t ngx_parse_size(ngx_str_t *line) { - u_char unit; - size_t len; - ssize_t size; - ngx_int_t scale; + u_char unit; + size_t len; + ssize_t size, scale, max; len = line->len; unit = line->data[len - 1]; @@ -24,21 +23,24 @@ ngx_parse_size(ngx_str_t *line) case 'K': case 'k': len--; + max = NGX_MAX_SIZE_T_VALUE / 1024; scale = 1024; break; case 'M': case 'm': len--; + max = NGX_MAX_SIZE_T_VALUE / (1024 * 1024); scale = 1024 * 1024; break; default: + max = NGX_MAX_SIZE_T_VALUE; scale = 1; } size = ngx_atosz(line->data, len); - if (size == NGX_ERROR) { + if (size == NGX_ERROR || size > max) { return NGX_ERROR; } @@ -51,10 +53,9 @@ ngx_parse_size(ngx_str_t *line) off_t ngx_parse_offset(ngx_str_t *line) { - u_char unit; - off_t offset; - size_t len; - ngx_int_t scale; + u_char unit; + off_t offset, scale, max; + size_t len; len = line->len; unit = line->data[len - 1]; @@ -63,27 +64,31 @@ ngx_parse_offset(ngx_str_t *line) case 'K': case 'k': len--; + max = NGX_MAX_OFF_T_VALUE / 1024; scale = 1024; break; case 'M': case 'm': len--; + max = NGX_MAX_OFF_T_VALUE / (1024 * 1024); scale = 1024 * 1024; break; case 'G': case 'g': len--; + max = NGX_MAX_OFF_T_VALUE / (1024 * 1024 * 1024); scale = 1024 * 1024 * 1024; break; default: + max = NGX_MAX_OFF_T_VALUE; scale = 1; } offset = ngx_atoof(line->data, len); - if (offset == NGX_ERROR) { + if (offset == NGX_ERROR || offset > max) { return NGX_ERROR; } diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -897,26 +897,28 @@ ngx_filename_cmp(u_char *s1, u_char *s2, ngx_int_t ngx_atoi(u_char *line, size_t n) { - ngx_int_t value; + ngx_int_t value, cutoff, cutlim; if (n == 0) { return NGX_ERROR; } + cutoff = NGX_MAX_INT_T_VALUE / 10; + cutlim = NGX_MAX_INT_T_VALUE % 10; + for (value = 0; n--; line++) { if (*line < '0' || *line > '9') { return NGX_ERROR; } + if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { + return NGX_ERROR; + } + value = value * 10 + (*line - '0'); } - if (value < 0) { - return NGX_ERROR; - - } else { - return value; - } + return value; } @@ -925,13 +927,16 @@ ngx_atoi(u_char *line, size_t n) ngx_int_t ngx_atofp(u_char *line, size_t n, size_t point) { - ngx_int_t value; + ngx_int_t value, cutoff, cutlim; ngx_uint_t dot; if (n == 0) { return NGX_ERROR; } + cutoff = NGX_MAX_INT_T_VALUE / 10; + cutlim = NGX_MAX_INT_T_VALUE % 10; + dot = 0; for (value = 0; n--; line++) { @@ -953,98 +958,107 @@ ngx_atofp(u_char *line, size_t n, size_t return NGX_ERROR; } + if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { + return NGX_ERROR; + } + value = value * 10 + (*line - '0'); point -= dot; } while (point--) { + if (value > cutoff) { + return NGX_ERROR; + } + value = value * 10; } - if (value < 0) { - return NGX_ERROR; - - } else { - return value; - } + return value; } ssize_t ngx_atosz(u_char *line, size_t n) { - ssize_t value; + ssize_t value, cutoff, cutlim; if (n == 0) { return NGX_ERROR; } + cutoff = NGX_MAX_SIZE_T_VALUE / 10; + cutlim = NGX_MAX_SIZE_T_VALUE % 10; + for (value = 0; n--; line++) { if (*line < '0' || *line > '9') { return NGX_ERROR; } + if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { + return NGX_ERROR; + } + value = value * 10 + (*line - '0'); } - if (value < 0) { - return NGX_ERROR; - - } else { - return value; - } + return value; } off_t ngx_atoof(u_char *line, size_t n) { - off_t value; + off_t value, cutoff, cutlim; if (n == 0) { return NGX_ERROR; } + cutoff = NGX_MAX_OFF_T_VALUE / 10; + cutlim = NGX_MAX_OFF_T_VALUE % 10; + for (value = 0; n--; line++) { if (*line < '0' || *line > '9') { return NGX_ERROR; } + if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { + return NGX_ERROR; + } + value = value * 10 + (*line - '0'); } - if (value < 0) { - return NGX_ERROR; - - } else { - return value; - } + return value; } time_t ngx_atotm(u_char *line, size_t n) { - time_t value; + time_t value, cutoff, cutlim; if (n == 0) { return NGX_ERROR; } + cutoff = NGX_MAX_TIME_T_VALUE / 10; + cutlim = NGX_MAX_TIME_T_VALUE % 10; + for (value = 0; n--; line++) { if (*line < '0' || *line > '9') { return NGX_ERROR; } + if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { + return NGX_ERROR; + } + value = value * 10 + (*line - '0'); } - if (value < 0) { - return NGX_ERROR; - - } else { - return value; - } + return value; } @@ -1052,13 +1066,19 @@ ngx_int_t ngx_hextoi(u_char *line, size_t n) { u_char c, ch; - ngx_int_t value; + ngx_int_t value, cutoff; if (n == 0) { return NGX_ERROR; } + cutoff = NGX_MAX_INT_T_VALUE / 16; + for (value = 0; n--; line++) { + if (value > cutoff) { + return NGX_ERROR; + } + From mdounin at mdounin.ru Tue Apr 7 13:04:56 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:04:56 +0000 Subject: [nginx] Refactored ngx_parse_time(). Message-ID: details: http://hg.nginx.org/nginx/rev/54da18a533df branches: stable-1.6 changeset: 6084:54da18a533df user: Ruslan Ermilov date: Tue Mar 17 00:26:18 2015 +0300 description: Refactored ngx_parse_time(). No functional changes. diffstat: src/core/ngx_parse.c | 4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diffs (28 lines): diff --git a/src/core/ngx_parse.c b/src/core/ngx_parse.c --- a/src/core/ngx_parse.c +++ b/src/core/ngx_parse.c @@ -121,7 +121,6 @@ ngx_parse_time(ngx_str_t *line, ngx_uint value = 0; total = 0; step = is_sec ? st_start : st_month; - scale = is_sec ? 1 : 1000; p = line->data; last = p + line->len; @@ -239,7 +238,6 @@ ngx_parse_time(ngx_str_t *line, ngx_uint } value = 0; - scale = is_sec ? 1 : 1000; while (p < last && *p == ' ') { p++; @@ -247,7 +245,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint } if (valid) { - return total + value * scale; + return total + value * (is_sec ? 1 : 1000); } return NGX_ERROR; From mdounin at mdounin.ru Tue Apr 7 13:05:04 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:05:04 +0000 Subject: [nginx] Core: overflow detection in ngx_parse_time() (ticket #732). Message-ID: details: http://hg.nginx.org/nginx/rev/8ec0f199cc81 branches: stable-1.6 changeset: 6085:8ec0f199cc81 user: Ruslan Ermilov date: Tue Mar 17 00:26:20 2015 +0300 description: Core: overflow detection in ngx_parse_time() (ticket #732). diffstat: src/core/ngx_parse.c | 53 ++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 37 insertions(+), 16 deletions(-) diffs (161 lines): diff --git a/src/core/ngx_parse.c b/src/core/ngx_parse.c --- a/src/core/ngx_parse.c +++ b/src/core/ngx_parse.c @@ -103,7 +103,8 @@ ngx_parse_time(ngx_str_t *line, ngx_uint { u_char *p, *last; ngx_int_t value, total, scale; - ngx_uint_t max, valid; + ngx_int_t max, cutoff, cutlim; + ngx_uint_t valid; enum { st_start = 0, st_year, @@ -120,6 +121,8 @@ ngx_parse_time(ngx_str_t *line, ngx_uint valid = 0; value = 0; total = 0; + cutoff = NGX_MAX_INT_T_VALUE / 10; + cutlim = NGX_MAX_INT_T_VALUE % 10; step = is_sec ? st_start : st_month; p = line->data; @@ -128,6 +131,10 @@ ngx_parse_time(ngx_str_t *line, ngx_uint while (p < last) { if (*p >= '0' && *p <= '9') { + if (value >= cutoff && (value > cutoff || *p - '0' > cutlim)) { + return NGX_ERROR; + } + value = value * 10 + (*p++ - '0'); valid = 1; continue; @@ -140,7 +147,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint return NGX_ERROR; } step = st_year; - max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 365); + max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 365); scale = 60 * 60 * 24 * 365; break; @@ -149,7 +156,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint return NGX_ERROR; } step = st_month; - max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 30); + max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 30); scale = 60 * 60 * 24 * 30; break; @@ -158,7 +165,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint return NGX_ERROR; } step = st_week; - max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 7); + max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 7); scale = 60 * 60 * 24 * 7; break; @@ -167,7 +174,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint return NGX_ERROR; } step = st_day; - max = NGX_MAX_INT32_VALUE / (60 * 60 * 24); + max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24); scale = 60 * 60 * 24; break; @@ -176,7 +183,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint return NGX_ERROR; } step = st_hour; - max = NGX_MAX_INT32_VALUE / (60 * 60); + max = NGX_MAX_INT_T_VALUE / (60 * 60); scale = 60 * 60; break; @@ -187,7 +194,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint } p++; step = st_msec; - max = NGX_MAX_INT32_VALUE; + max = NGX_MAX_INT_T_VALUE; scale = 1; break; } @@ -196,7 +203,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint return NGX_ERROR; } step = st_min; - max = NGX_MAX_INT32_VALUE / 60; + max = NGX_MAX_INT_T_VALUE / 60; scale = 60; break; @@ -205,7 +212,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint return NGX_ERROR; } step = st_sec; - max = NGX_MAX_INT32_VALUE; + max = NGX_MAX_INT_T_VALUE; scale = 1; break; @@ -214,7 +221,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint return NGX_ERROR; } step = st_last; - max = NGX_MAX_INT32_VALUE; + max = NGX_MAX_INT_T_VALUE; scale = 1; break; @@ -227,16 +234,18 @@ ngx_parse_time(ngx_str_t *line, ngx_uint max /= 1000; } - if ((ngx_uint_t) value > max) { + if (value > max) { return NGX_ERROR; } - total += value * scale; + value *= scale; - if ((ngx_uint_t) total > NGX_MAX_INT32_VALUE) { + if (total > NGX_MAX_INT_T_VALUE - value) { return NGX_ERROR; } + total += value; + value = 0; while (p < last && *p == ' ') { @@ -244,9 +253,21 @@ ngx_parse_time(ngx_str_t *line, ngx_uint } } - if (valid) { - return total + value * (is_sec ? 1 : 1000); + if (!valid) { + return NGX_ERROR; } - return NGX_ERROR; + if (!is_sec) { + if (value > NGX_MAX_INT_T_VALUE / 1000) { + return NGX_ERROR; + } + + value *= 1000; + } + + if (total > NGX_MAX_INT_T_VALUE - value) { + return NGX_ERROR; + } + + return total + value; } From mdounin at mdounin.ru Tue Apr 7 13:05:06 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:05:06 +0000 Subject: [nginx] Overflow detection in ngx_inet_addr(). Message-ID: details: http://hg.nginx.org/nginx/rev/b2a2475b2008 branches: stable-1.6 changeset: 6086:b2a2475b2008 user: Ruslan Ermilov date: Tue Mar 17 00:26:22 2015 +0300 description: Overflow detection in ngx_inet_addr(). diffstat: src/core/ngx_inet.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (32 lines): diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -27,6 +27,10 @@ ngx_inet_addr(u_char *text, size_t len) for (p = text; p < text + len; p++) { + if (octet > 255) { + return INADDR_NONE; + } + c = *p; if (c >= '0' && c <= '9') { @@ -34,7 +38,7 @@ ngx_inet_addr(u_char *text, size_t len) continue; } - if (c == '.' && octet < 256) { + if (c == '.') { addr = (addr << 8) + octet; octet = 0; n++; @@ -44,7 +48,7 @@ ngx_inet_addr(u_char *text, size_t len) return INADDR_NONE; } - if (n == 3 && octet < 256) { + if (n == 3) { addr = (addr << 8) + octet; return htonl(addr); } From mdounin at mdounin.ru Tue Apr 7 13:05:09 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:05:09 +0000 Subject: [nginx] Overflow detection in ngx_http_range_parse(). Message-ID: details: http://hg.nginx.org/nginx/rev/a77b625641c7 branches: stable-1.6 changeset: 6087:a77b625641c7 user: Ruslan Ermilov date: Tue Mar 17 00:26:24 2015 +0300 description: Overflow detection in ngx_http_range_parse(). diffstat: src/http/modules/ngx_http_range_filter_module.c | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletions(-) diffs (44 lines): diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -274,7 +274,7 @@ ngx_http_range_parse(ngx_http_request_t ngx_uint_t ranges) { u_char *p; - off_t start, end, size, content_length; + off_t start, end, size, content_length, cutoff, cutlim; ngx_uint_t suffix; ngx_http_range_t *range; @@ -282,6 +282,9 @@ ngx_http_range_parse(ngx_http_request_t size = 0; content_length = r->headers_out.content_length_n; + cutoff = NGX_MAX_OFF_T_VALUE / 10; + cutlim = NGX_MAX_OFF_T_VALUE % 10; + for ( ;; ) { start = 0; end = 0; @@ -295,6 +298,10 @@ ngx_http_range_parse(ngx_http_request_t } while (*p >= '0' && *p <= '9') { + if (start >= cutoff && (start > cutoff || *p - '0' > cutlim)) { + return NGX_HTTP_RANGE_NOT_SATISFIABLE; + } + start = start * 10 + *p++ - '0'; } @@ -321,6 +328,10 @@ ngx_http_range_parse(ngx_http_request_t } while (*p >= '0' && *p <= '9') { + if (end >= cutoff && (end > cutoff || *p - '0' > cutlim)) { + return NGX_HTTP_RANGE_NOT_SATISFIABLE; + } + end = end * 10 + *p++ - '0'; } From mdounin at mdounin.ru Tue Apr 7 13:05:26 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:05:26 +0000 Subject: [nginx] Overflow detection in ngx_http_parse_chunked(). Message-ID: details: http://hg.nginx.org/nginx/rev/b5094e26e4e5 branches: stable-1.6 changeset: 6088:b5094e26e4e5 user: Ruslan Ermilov date: Tue Mar 17 00:26:27 2015 +0300 description: Overflow detection in ngx_http_parse_chunked(). diffstat: src/http/ngx_http_parse.c | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) diffs (36 lines): diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -2104,6 +2104,10 @@ ngx_http_parse_chunked(ngx_http_request_ goto invalid; case sw_chunk_size: + if (ctx->size > NGX_MAX_OFF_T_VALUE / 16) { + goto invalid; + } + if (ch >= '0' && ch <= '9') { ctx->size = ctx->size * 16 + (ch - '0'); break; @@ -2253,6 +2257,10 @@ data: ctx->state = state; b->pos = pos; + if (ctx->size > NGX_MAX_OFF_T_VALUE - 5) { + goto invalid; + } + switch (state) { case sw_chunk_start: @@ -2289,10 +2297,6 @@ data: } - if (ctx->size < 0 || ctx->length < 0) { - goto invalid; - } - return rc; done: From mdounin at mdounin.ru Tue Apr 7 13:05:34 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 13:05:34 +0000 Subject: [nginx] Updated OpenSSL used for win32 builds. Message-ID: details: http://hg.nginx.org/nginx/rev/745d2d014123 branches: stable-1.6 changeset: 6089:745d2d014123 user: Maxim Dounin date: Mon Mar 23 02:44:41 2015 +0300 description: Updated OpenSSL used for win32 builds. diffstat: misc/GNUmakefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/misc/GNUmakefile b/misc/GNUmakefile --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -5,7 +5,7 @@ NGINX = nginx-$(VER) TEMP = tmp OBJS = objs.msvc8 -OPENSSL = openssl-1.0.1i +OPENSSL = openssl-1.0.1m ZLIB = zlib-1.2.8 PCRE = pcre-8.35 From mdounin at mdounin.ru Tue Apr 7 15:34:43 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 15:34:43 +0000 Subject: [nginx] nginx-1.6.3-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/698bcf853bbd branches: stable-1.6 changeset: 6090:698bcf853bbd user: Maxim Dounin date: Tue Apr 07 17:58:54 2015 +0300 description: nginx-1.6.3-RELEASE diffstat: docs/xml/nginx/changes.xml | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 69 insertions(+), 0 deletions(-) diffs (79 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,75 @@ + + + + +?????? ????????? tcp_nodelay ???????? ??? SPDY-??????????. + + +now the "tcp_nodelay" directive works with SPDY connections. + + + + + +? ????????? ??????.
+??????? Yichun Zhang ? ??????? ?????????. +
+ +in error handling.
+Thanks to Yichun Zhang and Daniil Bondarev. +
+
+ + + +??? ????????????? ????????? post_action +? ??? ???????? ????????? "header already sent"; +?????? ????????? ? nginx 1.5.4. + + +alerts "header already sent" appeared in logs +if the "post_action" directive was used; +the bug had appeared in 1.5.4. + + + + + +? ??? ????? ???????? ????????? "sem_post() failed". + + +alerts "sem_post() failed" might appear in logs. + + + + + +? ????????? ???-??????.
+??????? Chris West. +
+ +in hash table handling.
+Thanks to Chris West. +
+
+ + + +? ????????? ????????????? ????????????.
+??????? R?gis Leroy. +
+ +in integer overflow handling.
+Thanks to R?gis Leroy. +
+
+ +
+ + From mdounin at mdounin.ru Tue Apr 7 15:34:46 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 15:34:46 +0000 Subject: [nginx] release-1.6.3 tag Message-ID: details: http://hg.nginx.org/nginx/rev/f237ea8f8eed branches: stable-1.6 changeset: 6091:f237ea8f8eed user: Maxim Dounin date: Tue Apr 07 17:58:54 2015 +0300 description: release-1.6.3 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -372,3 +372,4 @@ fd722b890eabc600394349730a093f50dac31639 daa5384fd526a9c18fff4f5135646743628f6bc7 release-1.6.0 0cf84a39c1db6d6477a1a5b68aee345289d4d87a release-1.6.1 7dab18c28f451ce5dd58f11b9f5c8c433953ea09 release-1.6.2 +698bcf853bbd9fdb9ad567e10a810cc5fd0e003b release-1.6.3 From mdounin at mdounin.ru Tue Apr 7 15:38:32 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 15:38:32 +0000 Subject: [nginx] nginx-1.7.12-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/3ef00a71f564 branches: changeset: 6092:3ef00a71f564 user: Maxim Dounin date: Tue Apr 07 18:35:33 2015 +0300 description: nginx-1.7.12-RELEASE diffstat: docs/xml/nginx/changes.xml | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 63 insertions(+), 0 deletions(-) diffs (73 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,69 @@ + + + + +?????? ????????? tcp_nodelay ???????? ??? SSL-?????????? ? ?????????. + + +now the "tcp_nodelay" directive works with backend SSL connections. + + + + + +?????? ?????? ????? ?????????????? ??? ?????? ?????????? ?????? ? ????. + + +now thread pools can be used to read cache file headers. + + + + + +? ????????? proxy_request_buffering. + + +in the "proxy_request_buffering" directive. + + + + + +??? ????????????? ??????? ?? Linux +? ??????? ???????? ??? ????????? segmentation fault. + + +a segmentation fault might occur in a worker process +when using thread pools on Linux. + + + + + +? ????????? ?????? ??? ????????????? ????????? ssl_stapling.
+??????? Filipe da Silva. +
+ +in error handling when using the "ssl_stapling" directive.
+Thanks to Filipe da Silva. +
+
+ + + +? ?????? ngx_http_spdy_module. + + +in the ngx_http_spdy_module. + + + +
+ + From mdounin at mdounin.ru Tue Apr 7 15:38:35 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 15:38:35 +0000 Subject: [nginx] release-1.7.12 tag Message-ID: details: http://hg.nginx.org/nginx/rev/a70af6f10942 branches: changeset: 6093:a70af6f10942 user: Maxim Dounin date: Tue Apr 07 18:35:33 2015 +0300 description: release-1.7.12 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -381,3 +381,4 @@ d5ea659b8bab2d6402a2266efa691f705e84001e 34b201c1abd1e2d4faeae4650a21574771a03c0e release-1.7.9 860cfbcc4606ee36d898a9cd0c5ae8858db984d6 release-1.7.10 2b3b737b5456c05cd63d3d834f4fb4d3776953d0 release-1.7.11 +3ef00a71f56420a9c3e9cec311c9a2109a015d67 release-1.7.12 From mdounin at mdounin.ru Tue Apr 7 16:04:14 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 16:04:14 +0000 Subject: [nginx] nginx-1.6.3 changes fix Message-ID: details: http://hg.nginx.org/nginx/rev/76d66e92c66c branches: stable-1.6 changeset: 6094:76d66e92c66c user: Maxim Dounin date: Tue Apr 07 18:51:37 2015 +0300 description: nginx-1.6.3 changes fix diffstat: docs/xml/nginx/changes.xml | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,7 +5,7 @@ - + From mdounin at mdounin.ru Tue Apr 7 16:04:17 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 07 Apr 2015 16:04:17 +0000 Subject: [nginx] release-1.6.3 tag Message-ID: details: http://hg.nginx.org/nginx/rev/c94bc8f034ff branches: stable-1.6 changeset: 6095:c94bc8f034ff user: Maxim Dounin date: Tue Apr 07 18:57:56 2015 +0300 description: release-1.6.3 tag diffstat: .hgtags | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (9 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -373,3 +373,5 @@ daa5384fd526a9c18fff4f5135646743628f6bc7 0cf84a39c1db6d6477a1a5b68aee345289d4d87a release-1.6.1 7dab18c28f451ce5dd58f11b9f5c8c433953ea09 release-1.6.2 698bcf853bbd9fdb9ad567e10a810cc5fd0e003b release-1.6.3 +698bcf853bbd9fdb9ad567e10a810cc5fd0e003b release-1.6.3 +76d66e92c66c7d0df6e81288dafd625421126300 release-1.6.3 From bartw at xs4all.nl Tue Apr 7 17:39:19 2015 From: bartw at xs4all.nl (Bart Warmerdam) Date: Tue, 07 Apr 2015 19:39:19 +0200 Subject: Fix segv error when filename is zero length (data Message-ID: <9d4924c98156447e4d9324625f695c68@xs4all.nl> # HG changeset patch # User Bart Warmerdam # Date 1428423894 -7200 # Tue Apr 07 18:24:54 2015 +0200 # Branch ngx_files # Node ID 6f5542336a1a0487c8c8b05883596752019de4f5 # Parent a70af6f10942d7d21d140049b432081e8c76ba35 Change format of print string to ngx_str type. diff -r a70af6f10942 -r 6f5542336a1a src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c Tue Apr 07 18:35:33 2015 +0300 +++ b/src/os/unix/ngx_files.c Tue Apr 07 18:24:54 2015 +0200 @@ -36,7 +36,7 @@ if (n == -1) { ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, - "pread() \"%s\" failed", file->name.data); + "pread() \"%V\" failed", &file->name); return NGX_ERROR; } From mdounin at mdounin.ru Tue Apr 7 18:05:29 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 7 Apr 2015 21:05:29 +0300 Subject: Fix segv error when filename is zero length (data In-Reply-To: <9d4924c98156447e4d9324625f695c68@xs4all.nl> References: <9d4924c98156447e4d9324625f695c68@xs4all.nl> Message-ID: <20150407180529.GG88631@mdounin.ru> Hello! On Tue, Apr 07, 2015 at 07:39:19PM +0200, Bart Warmerdam wrote: > # HG changeset patch > # User Bart Warmerdam > # Date 1428423894 -7200 > # Tue Apr 07 18:24:54 2015 +0200 > # Branch ngx_files > # Node ID 6f5542336a1a0487c8c8b05883596752019de4f5 > # Parent a70af6f10942d7d21d140049b432081e8c76ba35 > Change format of print string to ngx_str type. > > diff -r a70af6f10942 -r 6f5542336a1a src/os/unix/ngx_files.c > --- a/src/os/unix/ngx_files.c Tue Apr 07 18:35:33 2015 +0300 > +++ b/src/os/unix/ngx_files.c Tue Apr 07 18:24:54 2015 +0200 > @@ -36,7 +36,7 @@ > > if (n == -1) { > ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, > - "pread() \"%s\" failed", file->name.data); > + "pread() \"%V\" failed", &file->name); > return NGX_ERROR; > } The patch looks wrong. File names are expected to be null-terminated, and if it's not true - the error is in the caller. -- Maxim Dounin http://nginx.org/ From jiakai1000 at gmail.com Wed Apr 8 04:16:50 2015 From: jiakai1000 at gmail.com (jiakai1000 at gmail.com) Date: Wed, 8 Apr 2015 12:16:50 +0800 Subject: errno bug in ngx_unix_recv(). References: Message-ID: <201504081216467170539@gmail.com> src/os/unix/ngx_recv.c in function: ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) err = ngx_socket_errno; should before ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,"recv: fd:%d %d of %d", c->fd, n, size); because ngx_log_debug3 may change errno, for example change errno from EAGAIN to EPIPE. jiakai1000 at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From jiakai1000 at gmail.com Thu Apr 9 02:25:45 2015 From: jiakai1000 at gmail.com (jiakai1000 at gmail.com) Date: Thu, 9 Apr 2015 10:25:45 +0800 Subject: errno bug in ngx_unix_recv(). Message-ID: <2015040910254057044110@gmail.com> src/os/unix/ngx_recv.c in function: ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) err = ngx_socket_errno; should before ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,"recv: fd:%d %d of %d", c->fd, n, size); because ngx_log_debug3 may change errno, for example change errno from EAGAIN to EPIPE. -------------- next part -------------- An HTML attachment was scrubbed... URL: From fdasilva at ingima.com Thu Apr 9 09:58:27 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 9 Apr 2015 09:58:27 +0000 Subject: [PATCH 1 of 6] SSL: refactoring of ngx_ssl_certificate method. Message-ID: Hi, This is the cleaned and up to date version of 'Multiple server certificate support ' patches. Reviews and comments are welcome. Regards, Filipe da Silva Ingima --- # HG changeset patch # User Filipe da Silva # Date 1428509598 -7200 # Wed Apr 08 18:13:18 2015 +0200 # Node ID b7b77cad040db2e8ba542e59183d45072b48a6be # Parent a70af6f10942d7d21d140049b432081e8c76ba35 SSL: refactoring of ngx_ssl_certificate method. Split it in two parts to prepare 'Multiple SSL certificate' support. diff -r a70af6f10942 -r b7b77cad040d src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Tue Apr 07 18:35:33 2015 +0300 +++ b/src/event/ngx_event_openssl.c Wed Apr 08 18:13:18 2015 +0200 @@ -18,6 +18,10 @@ typedef struct { } ngx_openssl_conf_t; +static ngx_int_t ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_str_t *cert); +static ngx_int_t ngx_ssl_private_key(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_str_t *key, ngx_array_t *passwords); static int ngx_ssl_password_callback(char *buf, int size, int rwflag, void *userdata); static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store); @@ -301,11 +305,26 @@ ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords) { + /* load server certificate */ + if (ngx_ssl_server_certificate(cf, ssl, cert) != NGX_OK) + { + return NGX_ERROR; + } + /* load private key */ + if (ngx_ssl_private_key(cf, ssl, key, passwords) != NGX_OK) + { + return NGX_ERROR; + } + return NGX_OK; +} + + +ngx_int_t +ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert) +{ BIO *bio; X509 *x509; u_long n; - ngx_str_t *pwd; - ngx_uint_t tries; if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { return NGX_ERROR; @@ -388,6 +407,17 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ BIO_free(bio); + return NGX_OK; +} + + +static ngx_int_t +ngx_ssl_private_key(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *key, + ngx_array_t *passwords) +{ + ngx_str_t *pwd; + ngx_uint_t tries; + if (ngx_strncmp(key->data, "engine:", sizeof("engine:") - 1) == 0) { #ifndef OPENSSL_NO_ENGINE -------------- next part -------------- A non-text attachment was scrubbed... Name: nginx_MultiCert_096.patch Type: application/octet-stream Size: 2125 bytes Desc: nginx_MultiCert_096.patch URL: From fdasilva at ingima.com Thu Apr 9 09:58:29 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 9 Apr 2015 09:58:29 +0000 Subject: [PATCH 2 of 6] SSL: introduce ngx_ssl_certificate_t array list. Message-ID: # HG changeset patch # User Filipe da Silva # Date 1428570644 -7200 # Thu Apr 09 11:10:44 2015 +0200 # Node ID 16ef1eeccdaa5c4dd3f3acbfebf5801e51a418c4 # Parent 853973b61efe9fb5d44f904dcb8baaab58ae5c84 SSL: introduce ngx_ssl_certificate_t array list. Preparation for Multiple SSL certificate support. diff -r 853973b61efe -r 16ef1eeccdaa src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Thu Apr 09 11:09:31 2015 +0200 +++ b/src/event/ngx_event_openssl.c Thu Apr 09 11:10:44 2015 +0200 @@ -18,6 +18,10 @@ typedef struct { } ngx_openssl_conf_t; +static ngx_int_t ngx_ssl_certificate_init(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_uint_t nbcerts); +static ngx_uint_t ngx_ssl_certificate_push(ngx_conf_t *cf, ngx_ssl_t *ssl, + X509 * x509); static ngx_int_t ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert); static ngx_int_t ngx_ssl_private_key(ngx_conf_t *cf, ngx_ssl_t *ssl, @@ -302,9 +306,56 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_ ngx_int_t +ngx_ssl_certificate_init(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t nbcerts) +{ + ngx_array_t *certificates; + + certificates = ngx_array_create(cf->pool, nbcerts, + sizeof(ngx_ssl_certificate_t)); + if (certificates == NULL) { + return NGX_ERROR; + } + + if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, certificates) + == 0) + { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_set_ex_data() failed"); + return NGX_ERROR; + } + + return NGX_OK; +} + + +ngx_uint_t +ngx_ssl_certificate_push(ngx_conf_t *cf, ngx_ssl_t *ssl, X509 * x509) +{ + ngx_array_t *certificates; + ngx_ssl_certificate_t *cert; + + certificates = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); + + cert = ngx_array_push(certificates); + if (cert == NULL) { + return -1; + } + + cert->x509 = x509; + + return certificates->nelts; +} + + +ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords) { + /* Init server certificate list */ + if (ngx_ssl_certificate_init(cf, ssl, 1U) != NGX_OK) + { + return NGX_ERROR; + } /* load server certificate */ if (ngx_ssl_server_certificate(cf, ssl, cert) != NGX_OK) { @@ -325,6 +376,7 @@ ngx_ssl_server_certificate(ngx_conf_t *c BIO *bio; X509 *x509; u_long n; + ngx_uint_t count; if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { return NGX_ERROR; @@ -359,11 +411,8 @@ ngx_ssl_server_certificate(ngx_conf_t *c return NGX_ERROR; } - if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "SSL_CTX_set_ex_data() failed"); + /* store cert for future use in stapling and sessions */ + if ((count = ngx_ssl_certificate_push(cf, ssl, x509)) <= 0) { X509_free(x509); BIO_free(bio); return NGX_ERROR; @@ -2161,6 +2210,9 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss STACK_OF(X509_NAME) *list; u_char buf[EVP_MAX_MD_SIZE]; + ngx_array_t *certificates; + ngx_ssl_certificate_t *certificate; + /* * Session ID context is set based on the string provided, * the server certificate, and the client CA list. @@ -2180,7 +2232,14 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss goto failed; } - cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); + certificates = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); + if (!certificates || certificates->nelts == 0) { + goto failed; + } + certificate = certificates->elts; + + /* TOFIX: not only use just first one */ + cert = certificate[0].x509; if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, diff -r 853973b61efe -r 16ef1eeccdaa src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Thu Apr 09 11:09:31 2015 +0200 +++ b/src/event/ngx_event_openssl.h Thu Apr 09 11:10:44 2015 +0200 @@ -45,6 +45,11 @@ typedef struct { typedef struct { + X509 *x509; +} ngx_ssl_certificate_t; + + +typedef struct { ngx_ssl_conn_t *connection; ngx_int_t last; diff -r 853973b61efe -r 16ef1eeccdaa src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Thu Apr 09 11:09:31 2015 +0200 +++ b/src/event/ngx_event_openssl_stapling.c Thu Apr 09 11:10:44 2015 +0200 @@ -85,6 +85,10 @@ struct ngx_ssl_ocsp_ctx_s { static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file); static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl); +static ngx_int_t ngx_ssl_stapling_issuer_lookup(ngx_conf_t *cf, + ngx_ssl_t *ssl, ngx_ssl_certificate_t *certificate); +static ngx_int_t ngx_ssl_stapling_certid_push(ngx_ssl_stapling_t *staple, + X509 *cert, X509 *issuer); static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder); @@ -257,6 +261,29 @@ failed: static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl) { + ngx_array_t *certificates; + ngx_ssl_certificate_t *certificate; + + certificates = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); + if (!certificates || certificates->nelts == 0) { + return NGX_ERROR; + } + + /* TOFIX: not only use just first one */ + certificate = certificates->elts; + + if (ngx_ssl_stapling_issuer_lookup(cf, ssl, certificate) != NGX_OK) { + return NGX_ERROR; + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_ssl_stapling_issuer_lookup(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_ssl_certificate_t *certificate) +{ int i, n, rc; X509 *cert, *issuer; X509_STORE *store; @@ -265,7 +292,7 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_stapling_t *staple; staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); - cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); + cert = certificate->x509; #if OPENSSL_VERSION_NUMBER >= 0x10001000L SSL_CTX_get_extra_chain_certs(ssl->ctx, &chain); @@ -286,8 +313,7 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, "SSL get issuer: found %p in extra certs", issuer); - staple->cert = cert; - staple->issuer = issuer; + ngx_ssl_stapling_certid_push(staple, cert, issuer); return NGX_OK; } @@ -335,6 +361,16 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, "SSL get issuer: found %p in cert store", issuer); + ngx_ssl_stapling_certid_push(staple, cert, issuer); + + return NGX_OK; +} + + +static ngx_int_t +ngx_ssl_stapling_certid_push(ngx_ssl_stapling_t *staple, + X509 *cert, X509 *issuer) +{ staple->cert = cert; staple->issuer = issuer; -------------- next part -------------- A non-text attachment was scrubbed... Name: nginx_MultiCert_097.patch Type: application/octet-stream Size: 7302 bytes Desc: nginx_MultiCert_097.patch URL: From fdasilva at ingima.com Thu Apr 9 09:58:38 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 9 Apr 2015 09:58:38 +0000 Subject: [PATCH 3 of 6] Stapling SSL: add Multiple SSL certificate support Message-ID: # HG changeset patch # User Filipe da Silva # Date 1428570686 -7200 # Thu Apr 09 11:11:26 2015 +0200 # Node ID f0020df8b2e181edba80ff8956371f9369d9880b # Parent 16ef1eeccdaa5c4dd3f3acbfebf5801e51a418c4 SSL: introduce ngx_ssl_certificate_t array list. Preparation for Multiple SSL certificate support. diff -r 16ef1eeccdaa -r f0020df8b2e1 src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Thu Apr 09 11:10:44 2015 +0200 +++ b/src/event/ngx_event_openssl_stapling.c Thu Apr 09 11:11:26 2015 +0200 @@ -28,8 +28,8 @@ typedef struct { SSL_CTX *ssl_ctx; - X509 *cert; - X509 *issuer; + ngx_array_t *certs; + ngx_array_t *issuers; time_t valid; @@ -41,8 +41,8 @@ typedef struct { typedef struct ngx_ssl_ocsp_ctx_s ngx_ssl_ocsp_ctx_t; struct ngx_ssl_ocsp_ctx_s { - X509 *cert; - X509 *issuer; + ngx_array_t *certs; + ngx_array_t *issuers; ngx_uint_t naddrs; @@ -85,6 +85,8 @@ struct ngx_ssl_ocsp_ctx_s { static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file); static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl); +static ngx_int_t ngx_ssl_stapling_issuer_init(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_int_t nbcerts); static ngx_int_t ngx_ssl_stapling_issuer_lookup(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_ssl_certificate_t *certificate); static ngx_int_t ngx_ssl_stapling_certid_push(ngx_ssl_stapling_t *staple, @@ -259,6 +261,28 @@ failed: static ngx_int_t +ngx_ssl_stapling_issuer_init(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_int_t nbcerts) +{ + ngx_ssl_stapling_t *staple; + + staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); + + staple->certs = ngx_array_create(cf->pool, nbcerts, + sizeof(ngx_ssl_certificate_t)); + + staple->issuers = ngx_array_create(cf->pool, nbcerts, + sizeof(ngx_ssl_certificate_t)); + + if (staple->certs == NULL || staple->issuers == NULL) { + staple->certs = staple->issuers = NULL; + return NGX_ERROR; + } + + return NGX_OK; +} + + +static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl) { ngx_array_t *certificates; @@ -269,6 +293,7 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, return NGX_ERROR; } + ngx_ssl_stapling_issuer_init(cf, ssl, certificates->nelts); /* TOFIX: not only use just first one */ certificate = certificates->elts; @@ -371,8 +396,19 @@ static ngx_int_t ngx_ssl_stapling_certid_push(ngx_ssl_stapling_t *staple, X509 *cert, X509 *issuer) { - staple->cert = cert; - staple->issuer = issuer; + ngx_ssl_certificate_t *item; + + item = ngx_array_push(staple->certs); + if (item == NULL) { + return NGX_ERROR; + } + item->x509 = cert; + + item = ngx_array_push(staple->issuers); + if (item == NULL) { + return NGX_ERROR; + } + item->x509 = issuer; return NGX_OK; } @@ -384,15 +420,17 @@ ngx_ssl_stapling_responder(ngx_conf_t *c ngx_url_t u; char *s; ngx_ssl_stapling_t *staple; + ngx_ssl_certificate_t *cert; STACK_OF(OPENSSL_STRING) *aia; staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); if (responder->len == 0) { - /* extract OCSP responder URL from certificate */ + /* extract OCSP responder URL from *first* certificate */ + cert = staple->certs->elts; - aia = X509_get1_ocsp(staple->cert); + aia = X509_get1_ocsp(cert->x509); if (aia == NULL) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, " @@ -538,8 +576,8 @@ ngx_ssl_stapling_update(ngx_ssl_stapling return; } - ctx->cert = staple->cert; - ctx->issuer = staple->issuer; + ctx->certs = staple->certs; + ctx->issuers = staple->issuers; ctx->addrs = staple->addrs; ctx->host = staple->host; @@ -569,6 +607,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc int n; size_t len; ngx_str_t response; + ngx_uint_t i, nelts; X509_STORE *store; STACK_OF(X509) *chain; OCSP_CERTID *id; @@ -576,6 +615,8 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc OCSP_BASICRESP *basic; ngx_ssl_stapling_t *staple; ASN1_GENERALIZEDTIME *thisupdate, *nextupdate; + ngx_ssl_certificate_t *cert; + ngx_ssl_certificate_t *issuer; staple = ctx->data; ocsp = NULL; @@ -628,15 +669,25 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc #endif if (OCSP_basic_verify(basic, chain, store, - staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY) - != 1) + staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY +#if OPENSSL_VERSION_NUMBER < 0x10000000L + /* ECDSA/SHA-2 signature verification not supported */ + | OCSP_NOSIGS +#endif + ) != 1) { ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0, "OCSP_basic_verify() failed"); goto error; } - id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer); + nelts = ctx->certs->nelts; + cert = ctx->certs->elts; + issuer = ctx->issuers->elts; + + for (i = 0; i < nelts; i++, cert++, issuer++) { + + id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509); if (id == NULL) { ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, "OCSP_cert_to_id() failed"); @@ -666,6 +717,10 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc } OCSP_CERTID_free(id); + + /* END OF 'for (i = 0;...' LOOP */ + } + OCSP_BASICRESP_free(basic); OCSP_RESPONSE_free(ocsp); @@ -722,10 +777,16 @@ error: static void ngx_ssl_stapling_cleanup(void *data) { - ngx_ssl_stapling_t *staple = data; + ngx_uint_t i, nelts; + ngx_ssl_stapling_t *staple = data; + ngx_ssl_certificate_t *issuer; - if (staple->issuer) { - X509_free(staple->issuer); + if (staple->issuers) { + issuer = staple->issuers->elts; + nelts = staple->issuers->nelts; + for (i = 0; i < nelts; i++, issuer++) { + X509_free(issuer->x509); + } } if (staple->staple.data) { @@ -1138,6 +1199,10 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp OCSP_CERTID *id; OCSP_REQUEST *ocsp; + ngx_uint_t i, nelts; + ngx_ssl_certificate_t *cert; + ngx_ssl_certificate_t *issuer; + ocsp = OCSP_REQUEST_new(); if (ocsp == NULL) { ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, @@ -1145,7 +1210,13 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp return NGX_ERROR; } - id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer); + nelts = ctx->certs->nelts; + cert = ctx->certs->elts; + issuer = ctx->issuers->elts; + + for (i = 0; i < nelts; i++, cert++, issuer++) { + + id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509); if (id == NULL) { ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, "OCSP_cert_to_id() failed"); @@ -1159,6 +1230,9 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp goto failed; } + /* END OF for ... LOOP */ + } + len = i2d_OCSP_REQUEST(ocsp, NULL); if (len <= 0) { ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, -------------- next part -------------- A non-text attachment was scrubbed... Name: nginx_MultiCert_098.patch Type: application/octet-stream Size: 7738 bytes Desc: nginx_MultiCert_098.patch URL: From fdasilva at ingima.com Thu Apr 9 09:58:39 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 9 Apr 2015 09:58:39 +0000 Subject: [PATCH 4 of 6] SSL: fix indentation of ngx_ssl_certificate_t array loops. Message-ID: # HG changeset patch # User Filipe da Silva # Date 1428509613 -7200 # Wed Apr 08 18:13:33 2015 +0200 # Node ID d79d5e0c7f3dd0151b83a6d37ae2fc4b0ecaf83f # Parent 911ce5a0980b9f82e6540de17304b31aa46de625 SSL: fix indentation of ngx_ssl_certificate_t array loops. Preparation for Multiple SSL certificate support. diff -r 911ce5a0980b -r d79d5e0c7f3d src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Wed Apr 08 18:13:33 2015 +0200 +++ b/src/event/ngx_event_openssl_stapling.c Wed Apr 08 18:13:33 2015 +0200 @@ -687,38 +687,36 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc for (i = 0; i < nelts; i++, cert++, issuer++) { - id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509); - if (id == NULL) { - ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, - "OCSP_cert_to_id() failed"); - goto error; - } + id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509); + if (id == NULL) { + ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, + "OCSP_cert_to_id() failed"); + goto error; + } - if (OCSP_resp_find_status(basic, id, &n, NULL, NULL, - &thisupdate, &nextupdate) - != 1) - { - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, - "certificate status not found in the OCSP response"); - goto error; - } + if (OCSP_resp_find_status(basic, id, &n, NULL, NULL, + &thisupdate, &nextupdate) + != 1) + { + ngx_log_error(NGX_LOG_ERR, ctx->log, 0, + "certificate status not found in the OCSP response"); + goto error; + } - if (n != V_OCSP_CERTSTATUS_GOOD) { - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, - "certificate status \"%s\" in the OCSP response", - OCSP_cert_status_str(n)); - goto error; - } + if (n != V_OCSP_CERTSTATUS_GOOD) { + ngx_log_error(NGX_LOG_ERR, ctx->log, 0, + "certificate status \"%s\" in the OCSP response", + OCSP_cert_status_str(n)); + goto error; + } - if (OCSP_check_validity(thisupdate, nextupdate, 300, -1) != 1) { - ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0, - "OCSP_check_validity() failed"); - goto error; - } + if (OCSP_check_validity(thisupdate, nextupdate, 300, -1) != 1) { + ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0, + "OCSP_check_validity() failed"); + goto error; + } - OCSP_CERTID_free(id); - - /* END OF 'for (i = 0;...' LOOP */ + OCSP_CERTID_free(id); } OCSP_BASICRESP_free(basic); @@ -1191,15 +1189,14 @@ ngx_ssl_ocsp_dummy_handler(ngx_event_t * static ngx_int_t ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx) { - int len; - u_char *p; - uintptr_t escape; - ngx_str_t binary, base64; - ngx_buf_t *b; - OCSP_CERTID *id; - OCSP_REQUEST *ocsp; - + int len; + u_char *p; + uintptr_t escape; ngx_uint_t i, nelts; + ngx_str_t binary, base64; + ngx_buf_t *b; + OCSP_CERTID *id; + OCSP_REQUEST *ocsp; ngx_ssl_certificate_t *cert; ngx_ssl_certificate_t *issuer; @@ -1216,21 +1213,20 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp for (i = 0; i < nelts; i++, cert++, issuer++) { - id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509); - if (id == NULL) { - ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, - "OCSP_cert_to_id() failed"); - goto failed; - } + id = OCSP_cert_to_id(NULL, cert->x509, issuer->x509); + if (id == NULL) { + ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, + "OCSP_cert_to_id() failed"); + goto failed; + } - if (OCSP_request_add0_id(ocsp, id) == NULL) { - ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, - "OCSP_request_add0_id() failed"); - OCSP_CERTID_free(id); - goto failed; - } + if (OCSP_request_add0_id(ocsp, id) == NULL) { + ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, + "OCSP_request_add0_id() failed"); + OCSP_CERTID_free(id); + goto failed; + } - /* END OF for ... LOOP */ } len = i2d_OCSP_REQUEST(ocsp, NULL); -------------- next part -------------- A non-text attachment was scrubbed... Name: nginx_MultiCert_099.patch Type: application/octet-stream Size: 4633 bytes Desc: nginx_MultiCert_099.patch URL: From fdasilva at ingima.com Thu Apr 9 09:58:40 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 9 Apr 2015 09:58:40 +0000 Subject: [PATCH 5 of 6] SSL: add Multiple SSL certificate support to http module. Message-ID: # HG changeset patch # User Filipe da Silva # Date 1428509613 -7200 # Wed Apr 08 18:13:33 2015 +0200 # Node ID 24cf399885b13221a498160140b3cf82cc208dc7 # Parent d79d5e0c7f3dd0151b83a6d37ae2fc4b0ecaf83f SSL: add Multiple SSL certificate support to http module. OpenSSL >= 1.0.2 required. diff -r d79d5e0c7f3d -r 24cf399885b1 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Wed Apr 08 18:13:33 2015 +0200 +++ b/src/event/ngx_event_openssl.c Wed Apr 08 18:13:33 2015 +0200 @@ -348,6 +348,42 @@ ngx_ssl_certificate_push(ngx_conf_t *cf, ngx_int_t +ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, + ngx_array_t *keys, ngx_array_t *passwords) +{ + ngx_uint_t i, j; + ngx_str_t *cert; + ngx_str_t *key; + + /* Init server certificate list */ + if (ngx_ssl_certificate_init(cf, ssl, certs->nelts) != NGX_OK) + { + return NGX_ERROR; + } + + /* Load server certificates */ + cert = certs->elts; + for (i = 0; i < certs->nelts; i++, cert++) { + if (ngx_ssl_server_certificate(cf, ssl, cert) != NGX_OK) + { + return NGX_ERROR; + } + } + + /* Load private keys */ + key = keys->elts; + for (j = 0; j < keys->nelts; j++, key++) { + if (ngx_ssl_private_key(cf, ssl, key, passwords) != NGX_OK) + { + return NGX_ERROR; + } + } + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords) { @@ -444,10 +480,22 @@ ngx_ssl_server_certificate(ngx_conf_t *c return NGX_ERROR; } +#ifdef SSL_CTX_add0_chain_cert + /* OpenSSL >=1.0.2 allows multiple server certificates in a single + * SSL_CTX to each have a different chain + */ + if (SSL_CTX_add0_chain_cert(ssl->ctx, x509) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_add0_chain_cert(\"%s\") failed", + cert->data); +#else + /*if (n == 0) { */ + /* same as count == 1 -> always true, as case is rejected by config code */ if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_add_extra_chain_cert(\"%s\") failed", cert->data); +#endif X509_free(x509); BIO_free(bio); return NGX_ERROR; diff -r d79d5e0c7f3d -r 24cf399885b1 src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Wed Apr 08 18:13:33 2015 +0200 +++ b/src/event/ngx_event_openssl.h Wed Apr 08 18:13:33 2015 +0200 @@ -129,6 +129,8 @@ ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); +ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, diff -r d79d5e0c7f3d -r 24cf399885b1 src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Wed Apr 08 18:13:33 2015 +0200 +++ b/src/event/ngx_event_openssl_stapling.c Wed Apr 08 18:13:33 2015 +0200 @@ -285,6 +285,7 @@ ngx_ssl_stapling_issuer_init(ngx_conf_t static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl) { + ngx_uint_t i, nelts; ngx_array_t *certificates; ngx_ssl_certificate_t *certificate; @@ -293,12 +294,19 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, return NGX_ERROR; } - ngx_ssl_stapling_issuer_init(cf, ssl, certificates->nelts); - /* TOFIX: not only use just first one */ + nelts = certificates->nelts; + if (ngx_ssl_stapling_issuer_init(cf, ssl, nelts) != NGX_OK) + { + return NGX_ERROR; + } + certificate = certificates->elts; - if (ngx_ssl_stapling_issuer_lookup(cf, ssl, certificate) != NGX_OK) { - return NGX_ERROR; + for (i = 0; i < nelts; i++, certificate++) { + if (ngx_ssl_stapling_issuer_lookup(cf, ssl, certificate) != NGX_OK) + { + return NGX_ERROR; + } } return NGX_OK; diff -r d79d5e0c7f3d -r 24cf399885b1 src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c Wed Apr 08 18:13:33 2015 +0200 +++ b/src/http/modules/ngx_http_ssl_module.c Wed Apr 08 18:13:33 2015 +0200 @@ -81,16 +81,16 @@ static ngx_command_t ngx_http_ssl_comma { ngx_string("ssl_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_SRV_CONF_OFFSET, - offsetof(ngx_http_ssl_srv_conf_t, certificate), + offsetof(ngx_http_ssl_srv_conf_t, certificates), NULL }, { ngx_string("ssl_certificate_key"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_SRV_CONF_OFFSET, - offsetof(ngx_http_ssl_srv_conf_t, certificate_key), + offsetof(ngx_http_ssl_srv_conf_t, certificate_keys), NULL }, { ngx_string("ssl_password_file"), @@ -505,8 +505,6 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t * set by ngx_pcalloc(): * * sscf->protocols = 0; - * sscf->certificate = { 0, NULL }; - * sscf->certificate_key = { 0, NULL }; * sscf->dhparam = { 0, NULL }; * sscf->ecdh_curve = { 0, NULL }; * sscf->client_certificate = { 0, NULL }; @@ -523,6 +521,8 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t sscf->buffer_size = NGX_CONF_UNSET_SIZE; sscf->verify = NGX_CONF_UNSET_UINT; sscf->verify_depth = NGX_CONF_UNSET_UINT; + sscf->certificates = NGX_CONF_UNSET_PTR; + sscf->certificate_keys = NGX_CONF_UNSET_PTR; sscf->passwords = NGX_CONF_UNSET_PTR; sscf->builtin_session_cache = NGX_CONF_UNSET; sscf->session_timeout = NGX_CONF_UNSET; @@ -570,8 +570,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); - ngx_conf_merge_str_value(conf->certificate, prev->certificate, ""); - ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, ""); + ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); + ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, + NULL); ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); @@ -598,7 +599,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * if (conf->enable) { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate\" is defined for " "the \"ssl\" directive in %s:%ui", @@ -606,7 +607,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * return NGX_CONF_ERROR; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined for " "the \"ssl\" directive in %s:%ui", @@ -616,18 +617,38 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * } else { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { return NGX_CONF_OK; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined " - "for certificate \"%V\"", &conf->certificate); + "for certificate \"%V\"", &conf->certificates[0]); + return NGX_CONF_ERROR; + } + if (conf->certificate_keys->nelts < conf->certificates->nelts) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "no \"ssl_certificate_key\" is defined " + "for certificate \"%V\"", + &conf->certificates[conf->certificate_keys->nelts]); return NGX_CONF_ERROR; } } +#ifndef SSL_CTX_add0_chain_cert + if (conf->certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured in " + "\"ssl_certificate\", but OpenSSL < 1.0.2 used"); + return NGX_CONF_ERROR; + } +#endif + if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) { return NGX_CONF_ERROR; } @@ -663,8 +684,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * cln->handler = ngx_ssl_cleanup_ctx; cln->data = &conf->ssl; - if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate, - &conf->certificate_key, conf->passwords) + if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, + conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; diff -r d79d5e0c7f3d -r 24cf399885b1 src/http/modules/ngx_http_ssl_module.h --- a/src/http/modules/ngx_http_ssl_module.h Wed Apr 08 18:13:33 2015 +0200 +++ b/src/http/modules/ngx_http_ssl_module.h Wed Apr 08 18:13:33 2015 +0200 @@ -32,8 +32,8 @@ typedef struct { time_t session_timeout; - ngx_str_t certificate; - ngx_str_t certificate_key; + ngx_array_t *certificates; + ngx_array_t *certificate_keys; ngx_str_t dhparam; ngx_str_t ecdh_curve; ngx_str_t client_certificate; -------------- next part -------------- A non-text attachment was scrubbed... Name: nginx_MultiCert_100.patch Type: application/octet-stream Size: 10483 bytes Desc: nginx_MultiCert_100.patch URL: From fdasilva at ingima.com Thu Apr 9 09:58:41 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 9 Apr 2015 09:58:41 +0000 Subject: [PATCH 6 of 6] SSL: add Multiple SSL certificate support to other modules. Message-ID: # HG changeset patch # User Filipe da Silva # Date 1428509613 -7200 # Wed Apr 08 18:13:33 2015 +0200 # Node ID cce55a4d8cf331ded858829da6fd19c6db6cb2ab # Parent 24cf399885b13221a498160140b3cf82cc208dc7 SSL: add Multiple SSL certificate support to other modules. OpenSSL >= 1.0.2 required. diff -r 24cf399885b1 -r cce55a4d8cf3 src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Wed Apr 08 18:13:33 2015 +0200 +++ b/src/http/modules/ngx_http_proxy_module.c Wed Apr 08 18:13:33 2015 +0200 @@ -97,8 +97,8 @@ typedef struct { ngx_uint_t ssl_verify_depth; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; - ngx_str_t ssl_certificate; - ngx_str_t ssl_certificate_key; + ngx_array_t *ssl_certificates; + ngx_array_t *ssl_certificate_keys; ngx_array_t *ssl_passwords; #endif } ngx_http_proxy_loc_conf_t; @@ -672,16 +672,16 @@ static ngx_command_t ngx_http_proxy_com { ngx_string("proxy_ssl_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate), + offsetof(ngx_http_proxy_loc_conf_t, ssl_certificates), NULL }, { ngx_string("proxy_ssl_certificate_key"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate_key), + offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate_keys), NULL }, { ngx_string("proxy_ssl_password_file"), @@ -2858,6 +2858,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ conf->upstream.ssl_verify = NGX_CONF_UNSET; conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; conf->ssl_passwords = NGX_CONF_UNSET_PTR; + conf->ssl_certificates = NGX_CONF_UNSET_PTR; + conf->ssl_certificate_keys = NGX_CONF_UNSET_PTR; #endif /* "proxy_cyclic_temp_file" is disabled */ @@ -3189,10 +3191,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t prev->ssl_trusted_certificate, ""); ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); - ngx_conf_merge_str_value(conf->ssl_certificate, - prev->ssl_certificate, ""); - ngx_conf_merge_str_value(conf->ssl_certificate_key, - prev->ssl_certificate_key, ""); + ngx_conf_merge_ptr_value(conf->ssl_certificates, + prev->ssl_certificates, NULL); + ngx_conf_merge_ptr_value(conf->ssl_certificate_keys, + prev->ssl_certificate_keys, NULL); + ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL); if (conf->ssl && ngx_http_proxy_set_ssl(cf, conf) != NGX_OK) { @@ -4279,6 +4282,7 @@ static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf) { ngx_pool_cleanup_t *cln; + ngx_str_t *oddkey; plcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t)); if (plcf->upstream.ssl == NULL) { @@ -4301,18 +4305,43 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n cln->handler = ngx_ssl_cleanup_ctx; cln->data = plcf->upstream.ssl; - if (plcf->ssl_certificate.len) { - - if (plcf->ssl_certificate_key.len == 0) { + if (plcf->ssl_certificates && plcf->ssl_certificates->nelts > 0) { + + if (!plcf->ssl_certificate_keys + || plcf->ssl_certificate_keys->nelts + < plcf->ssl_certificates->nelts) + { + + oddkey = plcf->ssl_certificates->elts; + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no \"proxy_ssl_certificate_key\" is defined " - "for certificate \"%V\"", &plcf->ssl_certificate); + "no \"proxy_ssl_certificate_key\" is defined for " + "ssl certificate \"%V\"", + oddkey[(plcf->ssl_certificate_keys) + ? plcf->ssl_certificate_keys->nelts + : 0]); + return NGX_ERROR; } - if (ngx_ssl_certificate(cf, plcf->upstream.ssl, &plcf->ssl_certificate, - &plcf->ssl_certificate_key, plcf->ssl_passwords) - != NGX_OK) +#ifndef SSL_CTX_add0_chain_cert + if (plcf->ssl_certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured " + "in \"proxy_ssl_certificate\", " + "but OpenSSL version < 1.0.2 used"); + return NGX_ERROR; + } +#endif + + if (ngx_ssl_certificates(cf, plcf->upstream.ssl, plcf->ssl_certificates, + plcf->ssl_certificate_keys, + plcf->ssl_passwords) + != NGX_OK) { return NGX_ERROR; } diff -r 24cf399885b1 -r cce55a4d8cf3 src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c Wed Apr 08 18:13:33 2015 +0200 +++ b/src/http/modules/ngx_http_uwsgi_module.c Wed Apr 08 18:13:33 2015 +0200 @@ -54,8 +54,8 @@ typedef struct { ngx_uint_t ssl_verify_depth; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; - ngx_str_t ssl_certificate; - ngx_str_t ssl_certificate_key; + ngx_array_t *ssl_certificates; + ngx_array_t *ssl_certificate_keys; ngx_array_t *ssl_passwords; #endif } ngx_http_uwsgi_loc_conf_t; @@ -517,16 +517,16 @@ static ngx_command_t ngx_http_uwsgi_comm { ngx_string("uwsgi_ssl_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate), + offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificates), NULL }, { ngx_string("uwsgi_ssl_certificate_key"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate_key), + offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate_keys), NULL }, { ngx_string("uwsgi_ssl_password_file"), @@ -1430,6 +1430,8 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_ conf->upstream.ssl_verify = NGX_CONF_UNSET; conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; conf->ssl_passwords = NGX_CONF_UNSET_PTR; + conf->ssl_certificates = NGX_CONF_UNSET_PTR; + conf->ssl_certificate_keys = NGX_CONF_UNSET_PTR; #endif /* "uwsgi_cyclic_temp_file" is disabled */ @@ -1744,11 +1746,10 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t ngx_conf_merge_str_value(conf->ssl_trusted_certificate, prev->ssl_trusted_certificate, ""); ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); - - ngx_conf_merge_str_value(conf->ssl_certificate, - prev->ssl_certificate, ""); - ngx_conf_merge_str_value(conf->ssl_certificate_key, - prev->ssl_certificate_key, ""); + ngx_conf_merge_ptr_value(conf->ssl_certificates, + prev->ssl_certificates, NULL); + ngx_conf_merge_ptr_value(conf->ssl_certificate_keys, + prev->ssl_certificate_keys, NULL); ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL); if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) { @@ -2285,6 +2286,7 @@ static ngx_int_t ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf) { ngx_pool_cleanup_t *cln; + ngx_str_t *oddkey; uwcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t)); if (uwcf->upstream.ssl == NULL) { @@ -2307,17 +2309,42 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, n cln->handler = ngx_ssl_cleanup_ctx; cln->data = uwcf->upstream.ssl; - if (uwcf->ssl_certificate.len) { - - if (uwcf->ssl_certificate_key.len == 0) { + if (uwcf->ssl_certificates && uwcf->ssl_certificates->nelts > 0) { + + if (!uwcf->ssl_certificate_keys + || uwcf->ssl_certificate_keys->nelts + < uwcf->ssl_certificates->nelts) + { + + oddkey = uwcf->ssl_certificates->elts; + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no \"uwsgi_ssl_certificate_key\" is defined " - "for certificate \"%V\"", &uwcf->ssl_certificate); + "no \"uwsgi_ssl_certificate_key\" is defined for " + "ssl certificate \"%V\"", + oddkey[(uwcf->ssl_certificate_keys) + ? uwcf->ssl_certificate_keys->nelts + : 0]); + return NGX_ERROR; } - if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, &uwcf->ssl_certificate, - &uwcf->ssl_certificate_key, uwcf->ssl_passwords) +#ifndef SSL_CTX_add0_chain_cert + if (uwcf->ssl_certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured " + "in \"uwsgi_ssl_certificate\", but " + "OpenSSL < 1.0.2 used"); + return NGX_ERROR; + } +#endif + + if (ngx_ssl_certificates(cf, uwcf->upstream.ssl, uwcf->ssl_certificates, + uwcf->ssl_certificate_keys, + uwcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; diff -r 24cf399885b1 -r cce55a4d8cf3 src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c Wed Apr 08 18:13:33 2015 +0200 +++ b/src/mail/ngx_mail_ssl_module.c Wed Apr 08 18:13:33 2015 +0200 @@ -73,16 +73,16 @@ static ngx_command_t ngx_mail_ssl_comma { ngx_string("ssl_certificate"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_ssl_conf_t, certificate), + offsetof(ngx_mail_ssl_conf_t, certificates), NULL }, { ngx_string("ssl_certificate_key"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_ssl_conf_t, certificate_key), + offsetof(ngx_mail_ssl_conf_t, certificate_keys), NULL }, { ngx_string("ssl_password_file"), @@ -238,8 +238,6 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf) * set by ngx_pcalloc(): * * scf->protocols = 0; - * scf->certificate = { 0, NULL }; - * scf->certificate_key = { 0, NULL }; * scf->dhparam = { 0, NULL }; * scf->ecdh_curve = { 0, NULL }; * scf->client_certificate = { 0, NULL }; @@ -250,6 +248,8 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf) */ scf->enable = NGX_CONF_UNSET; + scf->certificates = NGX_CONF_UNSET_PTR; + scf->certificate_keys = NGX_CONF_UNSET_PTR; scf->starttls = NGX_CONF_UNSET_UINT; scf->passwords = NGX_CONF_UNSET_PTR; scf->prefer_server_ciphers = NGX_CONF_UNSET; @@ -290,8 +290,9 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); - ngx_conf_merge_str_value(conf->certificate, prev->certificate, ""); - ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, ""); + ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); + ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, + NULL); ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); @@ -328,7 +329,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, if (*mode) { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate\" is defined for " "the \"%s\" directive in %s:%ui", @@ -336,7 +337,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined for " "the \"%s\" directive in %s:%ui", @@ -344,17 +345,24 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } + if (conf->certificate_keys->nelts < conf->certificates->nelts) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "no \"ssl_certificate_key\" is defined " + "for certificate \"%V\"", + &conf->certificates[conf->certificate_keys->nelts]); + return NGX_CONF_ERROR; + } + } else { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { return NGX_CONF_OK; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined " - "for certificate \"%V\"", - &conf->certificate); + "for certificate \"%V\"", &conf->certificates[0]); return NGX_CONF_ERROR; } } @@ -371,8 +379,21 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, cln->handler = ngx_ssl_cleanup_ctx; cln->data = &conf->ssl; - if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate, - &conf->certificate_key, conf->passwords) +#ifndef SSL_CTX_add0_chain_cert + if (conf->certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured in " + "\"ssl_certificate\", but OpenSSL < 1.0.2 used"); + return NGX_CONF_ERROR; + } +#endif + + if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, + conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; diff -r 24cf399885b1 -r cce55a4d8cf3 src/mail/ngx_mail_ssl_module.h --- a/src/mail/ngx_mail_ssl_module.h Wed Apr 08 18:13:33 2015 +0200 +++ b/src/mail/ngx_mail_ssl_module.h Wed Apr 08 18:13:33 2015 +0200 @@ -35,8 +35,8 @@ typedef struct { time_t session_timeout; - ngx_str_t certificate; - ngx_str_t certificate_key; + ngx_array_t *certificates; + ngx_array_t *certificate_keys; ngx_str_t dhparam; ngx_str_t ecdh_curve; ngx_str_t client_certificate; -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: nginx_MultiCert_101.patch Type: application/octet-stream Size: 16206 bytes Desc: nginx_MultiCert_101.patch URL: From mdounin at mdounin.ru Thu Apr 9 10:26:38 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 9 Apr 2015 13:26:38 +0300 Subject: [PATCH 1 of 6] SSL: refactoring of ngx_ssl_certificate method. In-Reply-To: References: Message-ID: <20150409102638.GN88631@mdounin.ru> Hello! On Thu, Apr 09, 2015 at 09:58:27AM +0000, Filipe DA SILVA wrote: > Hi, > > This is the cleaned and up to date version of 'Multiple server > certificate support ' patches. > > Reviews and comments are welcome. The main problem of these patches, as originally submitted by Eldar, is the approach used. It is believed that appropriate support for multiple certificates may be introduce only in recent OpenSSL versions, and there is no need to maintain list of certificates in these versions: it's already maintained by OpenSSL. -- Maxim Dounin http://nginx.org/ From fdasilva at ingima.com Thu Apr 9 16:49:06 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 9 Apr 2015 16:49:06 +0000 Subject: Multiple Cert support ( Was: RE : [PATCH 1 of 6] SSL: refactoring of ngx_ssl_certificate method. ) Message-ID: Hi Maxim. Thanks for the return. I bet you are talking about this API: https://github.com/openssl/openssl/commit/0f78819c8ccb7c526edbe90d5b619281366ce75c Should the compatibility with old OpenSSL versions before 1.0.2 remain ? A good solution would be to keep directly a list of OCSP_CERTID in the stapling context. Instead of keeping reference to cert/issuer certificates. Regards, Filipe ________________________________________ Hello! On Thu, Apr 09, 2015 at 09:58:27AM +0000, Filipe DA SILVA wrote: > Hi, > > This is the cleaned and up to date version of 'Multiple server > certificate support ' patches. > > Reviews and comments are welcome. The main problem of these patches, as originally submitted by Eldar, is the approach used. It is believed that appropriate support for multiple certificates may be introduce only in recent OpenSSL versions, and there is no need to maintain list of certificates in these versions: it's already maintained by OpenSSL. -- Maxim Dounin http://nginx.org/ _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel From calderon.thomas at gmail.com Fri Apr 10 10:00:42 2015 From: calderon.thomas at gmail.com (Thomas Calderon) Date: Fri, 10 Apr 2015 12:00:42 +0200 Subject: Issue with current PKCS#11 support Message-ID: Hi, I just tried nginx PKCS#11 support that was introduced in 1.7.9. In a Debug/Test environment I have a working setup. Namely, using "daemon off" and the instructions provided on the mailing list, I manage to establish a TLS connection using my token. However, when using "daemon on", a client connection spawn the worker_process, the PKCS#11 library gets reloaded. However, the PKCS#11 context is lost, hence the TLS connection cannot be established (further function fails since the library is not initilized, objects handles are not valid anymore, etc). Given the stack used to leverage PKCS#11 support (OpenSSL->engine_pkcs11->...), I am not sure how to fix this. Did you observe the same behavior ? Cheers, Thomas Calderon -------------- next part -------------- An HTML attachment was scrubbed... URL: From pdn at cryptopro.ru Fri Apr 10 10:30:08 2015 From: pdn at cryptopro.ru (Dmitrii Pichulin) Date: Fri, 10 Apr 2015 13:30:08 +0300 Subject: Issue with current PKCS#11 support In-Reply-To: References: Message-ID: <5527A630.4050107@cryptopro.ru> This is a common behavior for security providers that do not have own service running, which can handle objects globally. nginx loads private keys once then forks then impersonates to user in config (if set). In your case, it seems that your PKCS#11 library does not support a fork or a user change. You can try to run nginx and its worker processes by the same user (http://nginx.org/en/docs/ngx_core_module.html#user). Or you can try to find a better PKCS#11 provider. On 10.04.2015 13:00, Thomas Calderon wrote: > Hi, > > I just tried nginx PKCS#11 support that was introduced in 1.7.9. > > In a Debug/Test environment I have a working setup. Namely, using > "daemon off" and the instructions provided on the mailing list, I manage > to establish a TLS connection using my token. > > However, when using "daemon on", a client connection spawn the > worker_process, the PKCS#11 library gets reloaded. However, the PKCS#11 > context is lost, hence the TLS connection cannot be established (further > function fails since the library is not initilized, objects handles are > not valid anymore, etc). > > Given the stack used to leverage PKCS#11 support > (OpenSSL->engine_pkcs11->...), I am not sure how to fix this. > > Did you observe the same behavior ? > > Cheers, > > Thomas Calderon From mdounin at mdounin.ru Mon Apr 13 11:46:11 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 13 Apr 2015 14:46:11 +0300 Subject: Multiple Cert support ( Was: RE : [PATCH 1 of 6] SSL: refactoring of ngx_ssl_certificate method. ) In-Reply-To: References: Message-ID: <20150413114611.GZ88631@mdounin.ru> Hello! On Thu, Apr 09, 2015 at 04:49:06PM +0000, Filipe DA SILVA wrote: > Hi Maxim. > > Thanks for the return. > > I bet you are talking about this API: > https://github.com/openssl/openssl/commit/0f78819c8ccb7c526edbe90d5b619281366ce75c Yes. > Should the compatibility with old OpenSSL versions before 1.0.2 remain ? For sure - we currently support OpenSSL 0.9.7 and newer. But we don't need to support multiple certs with versions before OpenSSL 1.0.2. Just an appropriate error if user tries to configure this would be enough. (Just in case, there are two basic problems in older versions: no way to specify a chain for each certificate, and no way to find out the certificate used for a connection as needed for OCSP stapling). > A good solution would be to keep directly a list of OCSP_CERTID > in the stapling context. > Instead of keeping reference to cert/issuer certificates. I think we should attach stapling details to certificates. -- Maxim Dounin http://nginx.org/ From calderon.thomas at gmail.com Mon Apr 13 12:06:39 2015 From: calderon.thomas at gmail.com (Thomas Calderon) Date: Mon, 13 Apr 2015 14:06:39 +0200 Subject: Issue with current PKCS#11 support In-Reply-To: <5527A630.4050107@cryptopro.ru> References: <5527A630.4050107@cryptopro.ru> Message-ID: Hi, Thank you for describing the impersonation mechanism. However, stating "find a better PKCS#11 provider" is not the way to go. It seems you are making wrong assumptions related to the PKCS#11 standard, "fork" related behaviour (section 6.6.1) is described as follows: "In general, on most platforms, the previous paragraph means that an application consists of a single process. Consider a UNIX process P which becomes a Cryptoki application by calling C_Initialize, and then uses the fork() system call to create a child process C. Since P and C have separate address spaces (or will when one of them performs a write operation, if the operating system follows the copy-on-write paradigm), they are not part of the same application. Therefore, if C needs to use Cryptoki, it needs to perform its own C_Initialize call. Furthermore, if C needs to be logged into the token(s) that it will access via Cryptoki, it needs to log into them even if P already logged in, since P and C are completely separate applications. In this particular case (when C is the child of a process which is a Cryptoki application), the behavior of Cryptoki is undefined if C tries to use it without its own C_Initialize call. Ideally, such an attempt would return the value CKR_CRYPTOKI_NOT_INITIALIZED; however, because of the way fork() works, insisting on this return value might have a bad impact on the performance of libraries. Therefore, the behavior of Cryptoki in this situation is left undefined. Applications should definitely not attempt to take advantage of any potential "shortcuts" which might (or might not!) be available because of this. In the scenario specified above, C should actually call C_Initialize whether or not it needs to use Cryptoki; if it has no need to use Cryptoki, it should then call C_Finalize immediately thereafter. This (having the child immediately call C_Initialize and then C_Finalize if the parent is using Cryptoki) is considered to be good Cryptoki programming practice, since it can prevent the existence of dangling duplicate resources that were created at the time of the fork() call; however, it is not required by Cryptoki." Now, assuming a PKCS#11 provider provides a shortcut to re-initialize resources across a fork is a wrong assumption since the behaviour is left undefined. Furthermore, in most cases and given my experience with PKCS#11, you have to re-initialize the whole library (i.e., login again, find objects, etc). Is there no better way to handle this case in nginx ? Regards, Thomas Calderon On Fri, Apr 10, 2015 at 12:30 PM, Dmitrii Pichulin wrote: > This is a common behavior for security providers that do not have own > service running, which can handle objects globally. > > nginx loads private keys once then forks then impersonates to user in > config (if set). > > In your case, it seems that your PKCS#11 library does not support a fork > or a user change. > > You can try to run nginx and its worker processes by the same user ( > http://nginx.org/en/docs/ngx_core_module.html#user). > > Or you can try to find a better PKCS#11 provider. > > > On 10.04.2015 13:00, Thomas Calderon wrote: > >> Hi, >> >> I just tried nginx PKCS#11 support that was introduced in 1.7.9. >> >> In a Debug/Test environment I have a working setup. Namely, using >> "daemon off" and the instructions provided on the mailing list, I manage >> to establish a TLS connection using my token. >> >> However, when using "daemon on", a client connection spawn the >> worker_process, the PKCS#11 library gets reloaded. However, the PKCS#11 >> context is lost, hence the TLS connection cannot be established (further >> function fails since the library is not initilized, objects handles are >> not valid anymore, etc). >> >> Given the stack used to leverage PKCS#11 support >> (OpenSSL->engine_pkcs11->...), I am not sure how to fix this. >> >> Did you observe the same behavior ? >> >> Cheers, >> >> Thomas Calderon >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fdasilva at ingima.com Tue Apr 14 17:11:17 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Tue, 14 Apr 2015 17:11:17 +0000 Subject: Multiple Cert support ... Message-ID: Hi, >De : nginx-devel-bounces at nginx.org [nginx-devel-bounces at nginx.org] de la part de Maxim Dounin ... >Date d'envoi : lundi 13 avril 2015 13:46 >? : nginx-devel at nginx.org >Objet : Re: Multiple Cert support ... > >Hello! > >On Thu, Apr 09, 2015 at 04:49:06PM +0000, Filipe DA SILVA wrote: >> Hi Maxim. >> >> Thanks for the return. >> >> I bet you are talking about this API: >> https://github.com/openssl/openssl/commit/0f78819c8ccb7c526edbe90d5b619281366ce75c > >Yes. > >> Should the compatibility with old OpenSSL versions before 1.0.2 remain ? > >For sure - we currently support OpenSSL 0.9.7 and newer. > >But we don't need to support multiple certs with versions before >OpenSSL 1.0.2. Just an appropriate error if user tries to >configure this would be enough. > >(Just in case, there are two basic problems in older versions: > no way to specify a chain for each certificate, AFAIK, it's still not possible to separate its. Internally, the code is rebuilding a trust chain on each verification . See it when I wrote and debug a patch about client-verification using delegated CRL. > and no way to find >out the certificate used for a connection as needed for OCSP >stapling). This point was fixed by the commit mentioned previously. >> A good solution would be to keep directly a list of OCSP_CERTID >> in the stapling context. >> Instead of keeping reference to cert/issuer certificates. > >I think we should attach stapling details to certificates. > Great idea ! Using X509_set_ex_data/X509_get_ex_data greatly simply the code. Work is in progress. Regards, Filipe da Silva From mdounin at mdounin.ru Tue Apr 14 17:46:47 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 14 Apr 2015 20:46:47 +0300 Subject: Multiple Cert support ... In-Reply-To: References: Message-ID: <20150414174647.GL88631@mdounin.ru> Hello! On Tue, Apr 14, 2015 at 05:11:17PM +0000, Filipe DA SILVA wrote: [...] > >But we don't need to support multiple certs with versions before > >OpenSSL 1.0.2. Just an appropriate error if user tries to > >configure this would be enough. > > > >(Just in case, there are two basic problems in older versions: > > no way to specify a chain for each certificate, > > AFAIK, it's still not possible to separate its. > Internally, the code is rebuilding a trust chain on each verification . > See it when I wrote and debug a patch about client-verification using delegated CRL. The question isn't about trust chains used during client certificate verification, but about chains sent to a client during the SSL handshake. In OpenSSL 1.0.2 there is an extra chain for each algorithm-specific certificate: *) Enhance SSL/TLS certificate chain handling to support different chains for each certificate instead of one chain in the parent SSL_CTX. [Steve Henson] *) Use algorithm specific chains in SSL_CTX_use_certificate_chain_file(): this fixes a limiation in previous versions of OpenSSL. [Steve Henson] See this commits for details: https://github.com/openssl/openssl/commit/f71c6e52f769af0d2d40ed7e1dcb4fff837837a0 https://github.com/openssl/openssl/commit/a4339ea3ba045b7da038148f0d48ce25f2996971 -- Maxim Dounin http://nginx.org/ From sarah at nginx.com Tue Apr 14 18:31:32 2015 From: sarah at nginx.com (Sarah Novotny) Date: Tue, 14 Apr 2015 11:31:32 -0700 Subject: Igor's post about nginx from this morning Message-ID: <60DFB178-9DD3-4450-89E3-64FDB641AD55@nginx.com> Hello All, If you haven?t seen Igor?s post from today, yet, it?s worth a read. Here?s a teaser -- > The next 12 months herald some major new features for NGINX Open Source. The stories about NGINX and JavaScript will be realized - I have a working prototype of a JavaScript VM that is highly optimized for NGINX?s unique requirements and we?ve begun the task of embedding it within NGINX Open Source. > > Our community of module developers is vital to the success of NGINX in the open source world. We know it?s not as easy as it could be to develop for NGINX, and to address that situation, we?re beginning the implementation of a pluggable module API in the next couple of months. Our goal is to make it simpler for our developer community to create and distribute modules for NGINX, giving users more choice and flexibility to extend the NGINX open source core. We?re also establishing a developer relations team to help support the community in this transition. > > You may already have read our plan to support HTTP/2 in NGINX Open Source. We appreciate how important it is to our users that we continue to support the innovations that others are making in our space, and our HTTP/2 support will of course build on the successful SPDY implementation that has been used by a number of sites. The rest is here ? http://nginx.com/blog/nginx-open-source-reflecting-back-and-looking-ahead/ As always, NGINX?s continued growth and success is thanks to you all in the user and developer communities. If you have any questions about the developer relations team, please feel free to reach out. Sarah From ru at nginx.com Wed Apr 15 08:03:40 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 15 Apr 2015 11:03:40 +0300 Subject: about threads support in 1.7.11 breaking 3rd party modules Message-ID: <20150415080340.GB82262@lo0.su> In version 1.7.11 we have implemented threads support, please see http://nginx.org/r/aio for details. For this, we reused the NGX_THREADS macro that was unused on UNIXes since 1.0.4 (June 2011). This caused some 3rd party modules fail to compile if threads were enabled: https://lists.freebsd.org/pipermail/svn-ports-all/2015-April/090158.html The analysis have shown that breakages fall into two categories: 17 out of 20 broken modules failed to compile because they didn't include before including in some cases. The remaining 3 modules were failing because they still used the NGX_THREADS macro with some long unused code. The corresponding code can be safely removed. If you're the maintainer of the broken module, please fix it. From hungnv at opensource.com.vn Wed Apr 15 12:05:53 2015 From: hungnv at opensource.com.vn (hungnv at opensource.com.vn) Date: Wed, 15 Apr 2015 19:05:53 +0700 Subject: Update content on nginx-wiki Message-ID: Hello, I recently wrote a nginx module (https://github.com/whatvn/ngx_http_estreaming_module ) and I want to add it to 3rd party module page, I made request to create wiki account and verified already, but maybe it?s gone nowhere. Could someone from nginx can create an account for me on wiki page? Thanks, -- H?ng Email: hungnv at opensource.com.vn -------------- next part -------------- An HTML attachment was scrubbed... URL: From sarah at nginx.com Wed Apr 15 21:31:46 2015 From: sarah at nginx.com (Sarah Novotny) Date: Wed, 15 Apr 2015 14:31:46 -0700 Subject: Update content on nginx-wiki In-Reply-To: References: Message-ID: <6DD0BBC7-39C0-4760-910A-FFBEDF568A56@nginx.com> Hi Hung, I?ve enabled the account. sarah > On Apr 15, 2015, at 5:05 AM, hungnv at opensource.com.vn wrote: > > Hello, > > I recently wrote a nginx module (https://github.com/whatvn/ngx_http_estreaming_module ) and I want to add it to 3rd party module page, I made request to create wiki account and verified already, but maybe it?s gone nowhere. > Could someone from nginx can create an account for me on wiki page? > > Thanks, > > > -- > H?ng > Email: hungnv at opensource.com.vn > > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From vl at nginx.com Thu Apr 16 09:19:42 2015 From: vl at nginx.com (Vladimir Homutov) Date: Thu, 16 Apr 2015 09:19:42 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/e24f1bfdb641 branches: changeset: 6096:e24f1bfdb641 user: Vladimir Homutov date: Thu Apr 16 12:13:51 2015 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r a70af6f10942 -r e24f1bfdb641 src/core/nginx.h --- a/src/core/nginx.h Tue Apr 07 18:35:33 2015 +0300 +++ b/src/core/nginx.h Thu Apr 16 12:13:51 2015 +0300 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1007012 -#define NGINX_VERSION "1.7.12" +#define nginx_version 1007013 +#define NGINX_VERSION "1.7.13" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From vl at nginx.com Thu Apr 16 09:19:45 2015 From: vl at nginx.com (Vladimir Homutov) Date: Thu, 16 Apr 2015 09:19:45 +0000 Subject: [nginx] Core: added OpenSSL version information to "nginx -V" ou... Message-ID: details: http://hg.nginx.org/nginx/rev/8b7f062a3fe6 branches: changeset: 6097:8b7f062a3fe6 user: Vladimir Homutov date: Thu Apr 16 12:17:41 2015 +0300 description: Core: added OpenSSL version information to "nginx -V" output. diffstat: src/core/nginx.c | 21 ++++++++++++++++----- 1 files changed, 16 insertions(+), 5 deletions(-) diffs (38 lines): diff -r e24f1bfdb641 -r 8b7f062a3fe6 src/core/nginx.c --- a/src/core/nginx.c Thu Apr 16 12:13:51 2015 +0300 +++ b/src/core/nginx.c Thu Apr 16 12:17:41 2015 +0300 @@ -248,18 +248,29 @@ main(int argc, char *const *argv) } if (ngx_show_configure) { - ngx_write_stderr( + #ifdef NGX_COMPILER - "built by " NGX_COMPILER NGX_LINEFEED + ngx_write_stderr("built by " NGX_COMPILER NGX_LINEFEED); #endif + #if (NGX_SSL) + if (SSLeay() == SSLEAY_VERSION_NUMBER) { + ngx_write_stderr("built with " OPENSSL_VERSION_TEXT + NGX_LINEFEED); + } else { + ngx_write_stderr("built with " OPENSSL_VERSION_TEXT + " (running with "); + ngx_write_stderr((char *) SSLeay_version(SSLEAY_VERSION)); + ngx_write_stderr(")" NGX_LINEFEED); + } #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - "TLS SNI support enabled" NGX_LINEFEED + ngx_write_stderr("TLS SNI support enabled" NGX_LINEFEED); #else - "TLS SNI support disabled" NGX_LINEFEED + ngx_write_stderr("TLS SNI support disabled" NGX_LINEFEED); #endif #endif - "configure arguments:" NGX_CONFIGURE NGX_LINEFEED); + + ngx_write_stderr("configure arguments:" NGX_CONFIGURE NGX_LINEFEED); } if (!ngx_test_config) { From fdasilva at ingima.com Thu Apr 16 10:09:48 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 16 Apr 2015 10:09:48 +0000 Subject: Multiple Cert support ... In-Reply-To: <20150414174647.GL88631@mdounin.ru> References: <20150414174647.GL88631@mdounin.ru> Message-ID: Hi, Maxim. I forget about this feature, even if it is mentioned in the patch. The cert chain declared by ssl_certificate/SSL_CTX_extra_chain is sent to the client. But not the list provided by ssl_trusted_certificate. The patch calls to the SSL_CTX_add0_chain_cert now when available. Regards, Filipe -----Message d'origine----- De?: nginx-devel-bounces at nginx.org [mailto:nginx-devel-bounces at nginx.org] De la part de Maxim Dounin Envoy??: mardi 14 avril 2015 19:47 ??: nginx-devel at nginx.org Objet?: Re: RE : Multiple Cert support ... Hello! On Tue, Apr 14, 2015 at 05:11:17PM +0000, Filipe DA SILVA wrote: [...] > >But we don't need to support multiple certs with versions before > >OpenSSL 1.0.2. Just an appropriate error if user tries to configure > >this would be enough. > > > >(Just in case, there are two basic problems in older versions: > > no way to specify a chain for each certificate, > > AFAIK, it's still not possible to separate its. > Internally, the code is rebuilding a trust chain on each verification . > See it when I wrote and debug a patch about client-verification using delegated CRL. The question isn't about trust chains used during client certificate verification, but about chains sent to a client during the SSL handshake. In OpenSSL 1.0.2 there is an extra chain for each algorithm-specific certificate: *) Enhance SSL/TLS certificate chain handling to support different chains for each certificate instead of one chain in the parent SSL_CTX. [Steve Henson] *) Use algorithm specific chains in SSL_CTX_use_certificate_chain_file(): this fixes a limiation in previous versions of OpenSSL. [Steve Henson] See this commits for details: https://github.com/openssl/openssl/commit/f71c6e52f769af0d2d40ed7e1dcb4fff837837a0 https://github.com/openssl/openssl/commit/a4339ea3ba045b7da038148f0d48ce25f2996971 -- Maxim Dounin http://nginx.org/ _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel From fdasilva at ingima.com Thu Apr 16 10:10:09 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 16 Apr 2015 10:10:09 +0000 Subject: [PATCH 1 of 6] SSL: SSL: introduce support of new openssl 1.0.2 features. Message-ID: Hi, This is the new version of 'Multiple server certificate support ' patches. It relies on openssl to maintain a list of server certificates. Reviews and comments are welcome. Regards, Filipe da Silva Ingima --- # HG changeset patch # User Filipe da Silva # Date 1429178261 -7200 # Thu Apr 16 11:57:41 2015 +0200 # Node ID d201e4afd59eaf79419836c1dcdec83e141d3f67 # Parent 8b7f062a3fe60f01d373db6dc87f715d3c4fd214 SSL: introduce support of new openssl 1.0.2 features. - Split 'ngx_ssl_certificate' in two parts to prepare 'Multiple SSL certificate' support. - introduce 'ngx_ssl_cert_stapling_index' - add new server certificate retrieval method. - disable ngx_ssl_certificate_index when openssl 1.0.2. - derivate ssl_session_id from all certificates. diff -r 8b7f062a3fe6 -r d201e4afd59e src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Thu Apr 16 12:17:41 2015 +0300 +++ b/src/event/ngx_event_openssl.c Thu Apr 16 11:57:41 2015 +0200 @@ -18,6 +18,10 @@ typedef struct { } ngx_openssl_conf_t; +static ngx_int_t ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_str_t *cert); +static ngx_int_t ngx_ssl_private_key(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_str_t *key, ngx_array_t *passwords); static int ngx_ssl_password_callback(char *buf, int size, int rwflag, void *userdata); static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store); @@ -101,8 +105,11 @@ int ngx_ssl_connection_index; int ngx_ssl_server_conf_index; int ngx_ssl_session_cache_index; int ngx_ssl_session_ticket_keys_index; +#if OPENSSL_VERSION_NUMBER < 0x10002000L int ngx_ssl_certificate_index; +#endif int ngx_ssl_stapling_index; +int ngx_ssl_cert_stapling_index; ngx_int_t @@ -168,6 +175,7 @@ ngx_ssl_init(ngx_log_t *log) return NGX_ERROR; } +#if OPENSSL_VERSION_NUMBER < 0x10002000L ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); if (ngx_ssl_certificate_index == -1) { @@ -175,6 +183,7 @@ ngx_ssl_init(ngx_log_t *log) "SSL_CTX_get_ex_new_index() failed"); return NGX_ERROR; } +#endif ngx_ssl_stapling_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); @@ -184,6 +193,14 @@ ngx_ssl_init(ngx_log_t *log) return NGX_ERROR; } + ngx_ssl_cert_stapling_index = X509_get_ex_new_index(0, NULL, NULL, NULL, + NULL); + if (ngx_ssl_cert_stapling_index == -1) { + ngx_ssl_error(NGX_LOG_ALERT, log, 0, + "X509_get_ex_new_index() failed"); + return NGX_ERROR; + } + return NGX_OK; } @@ -297,15 +314,49 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_ } +X509* +ngx_ssl_get_server_certificate(ngx_ssl_t *ssl, ngx_flag_t first) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + int rc; + long op; + + op = first ? SSL_CERT_SET_FIRST : SSL_CERT_SET_NEXT; + rc = SSL_CTX_set_current_cert(ssl->ctx, op); + if (rc) + return (SSL_CTX_get0_certificate(ssl->ctx)); +#else + if (first) + return (SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index)); +#endif + return NULL; +} + + ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords) { + /* load server certificate */ + if (ngx_ssl_server_certificate(cf, ssl, cert) != NGX_OK) + { + return NGX_ERROR; + } + /* load private key */ + if (ngx_ssl_private_key(cf, ssl, key, passwords) != NGX_OK) + { + return NGX_ERROR; + } + return NGX_OK; +} + + +ngx_int_t +ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert) +{ BIO *bio; X509 *x509; u_long n; - ngx_str_t *pwd; - ngx_uint_t tries; if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { return NGX_ERROR; @@ -340,6 +391,7 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ return NGX_ERROR; } +#if OPENSSL_VERSION_NUMBER < 0x10002000L if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509) == 0) { @@ -349,6 +401,7 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ BIO_free(bio); return NGX_ERROR; } +#endif X509_free(x509); @@ -376,10 +429,20 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ return NGX_ERROR; } +#ifdef SSL_CTX_add0_chain_cert + /* OpenSSL >=1.0.2 allows multiple server certificates in a single + * SSL_CTX to each have a different chain + */ + if (SSL_CTX_add0_chain_cert(ssl->ctx, x509) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_add0_chain_cert(\"%s\") failed", + cert->data); +#else if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_add_extra_chain_cert(\"%s\") failed", cert->data); +#endif X509_free(x509); BIO_free(bio); return NGX_ERROR; @@ -388,6 +451,17 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ BIO_free(bio); + return NGX_OK; +} + + +static ngx_int_t +ngx_ssl_private_key(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *key, + ngx_array_t *passwords) +{ + ngx_str_t *pwd; + ngx_uint_t tries; + if (ngx_strncmp(key->data, "engine:", sizeof("engine:") - 1) == 0) { #ifndef OPENSSL_NO_ENGINE @@ -2150,8 +2224,10 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss goto failed; } - cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); - + cert = ngx_ssl_get_server_certificate(ssl, NGX_SSL_FIRST_CERT); + while (cert) { + + /* TODO: fix loop indentation */ if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_digest() failed"); @@ -2164,6 +2240,10 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss goto failed; } + /* get next server certificate, if any */ + cert = ngx_ssl_get_server_certificate(ssl, NGX_SSL_NEXT_CERT); + } + list = SSL_CTX_get_client_CA_list(ssl->ctx); if (list != NULL) { diff -r 8b7f062a3fe6 -r d201e4afd59e src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Thu Apr 16 12:17:41 2015 +0300 +++ b/src/event/ngx_event_openssl.h Thu Apr 16 11:57:41 2015 +0200 @@ -189,6 +189,10 @@ ngx_int_t ngx_ssl_get_fingerprint(ngx_co ngx_str_t *s); ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); + +#define NGX_SSL_FIRST_CERT 1 +#define NGX_SSL_NEXT_CERT 0 +X509* ngx_ssl_get_server_certificate(ngx_ssl_t *ssl, ngx_flag_t first); ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); @@ -210,6 +214,7 @@ extern int ngx_ssl_session_cache_index; extern int ngx_ssl_session_ticket_keys_index; extern int ngx_ssl_certificate_index; extern int ngx_ssl_stapling_index; +extern int ngx_ssl_cert_stapling_index; #endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */ From fdasilva at ingima.com Thu Apr 16 10:10:17 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 16 Apr 2015 10:10:17 +0000 Subject: [PATCH 2 of 6] SSL Stapling : ... Message-ID: # HG changeset patch # User Filipe da Silva # Date 1429178261 -7200 # Thu Apr 16 11:57:41 2015 +0200 # Node ID 85fb1b1e922fd95ef0df3c7f8bc9625af3054002 # Parent d201e4afd59eaf79419836c1dcdec83e141d3f67 SSL Stapling: attach stapling_t context to X509 cert, instead of ssl_ctx. Keep a common part of stapling config attached to initial SSL_CTX context. diff -r d201e4afd59e -r 85fb1b1e922f src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Thu Apr 16 11:57:41 2015 +0200 +++ b/src/event/ngx_event_openssl_stapling.c Thu Apr 16 11:57:41 2015 +0200 @@ -14,13 +14,23 @@ #if (!defined OPENSSL_NO_OCSP && defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB) +/* OCSP stapling configuration per server */ typedef struct { + /* OCSP response to staple from file */ ngx_str_t staple; ngx_msec_t timeout; ngx_resolver_t *resolver; ngx_msec_t resolver_timeout; + unsigned verify:1; +} ngx_ssl_staple_t; + + +/* OCSP stapling context per certificate */ +typedef struct { + ngx_str_t staple; /* OCSP response from responder */ + ngx_addr_t *addrs; ngx_str_t host; ngx_str_t uri; @@ -33,7 +43,6 @@ typedef struct { time_t valid; - unsigned verify:1; unsigned loading:1; } ngx_ssl_stapling_t; @@ -53,6 +62,7 @@ struct ngx_ssl_ocsp_ctx_s { ngx_resolver_t *resolver; ngx_msec_t resolver_timeout; + unsigned verify:1; ngx_msec_t timeout; @@ -83,14 +93,15 @@ struct ngx_ssl_ocsp_ctx_s { static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_str_t *file); + ngx_str_t *file, ngx_ssl_staple_t *conf); static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl); static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder); static int ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn, void *data); -static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple); +static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple, + ngx_ssl_staple_t *conf); static void ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx); static void ngx_ssl_stapling_cleanup(void *data); @@ -119,23 +130,14 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl ngx_str_t *responder, ngx_uint_t verify) { ngx_int_t rc; - ngx_pool_cleanup_t *cln; - ngx_ssl_stapling_t *staple; + ngx_ssl_staple_t *conf; - staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t)); - if (staple == NULL) { + conf = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_staple_t)); + if (conf == NULL) { return NGX_ERROR; } - cln = ngx_pool_cleanup_add(cf->pool, 0); - if (cln == NULL) { - return NGX_ERROR; - } - - cln->handler = ngx_ssl_stapling_cleanup; - cln->data = staple; - - if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_stapling_index, staple) + if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_stapling_index, conf) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, @@ -143,14 +145,13 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl return NGX_ERROR; } - staple->ssl_ctx = ssl->ctx; - staple->timeout = 60000; - staple->verify = verify; + conf->timeout = 60000; + conf->verify = verify; if (file->len) { /* use OCSP response from the file */ - if (ngx_ssl_stapling_file(cf, ssl, file) != NGX_OK) { + if (ngx_ssl_stapling_file(cf, ssl, file, conf) != NGX_OK) { return NGX_ERROR; } @@ -180,22 +181,20 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl done: SSL_CTX_set_tlsext_status_cb(ssl->ctx, ngx_ssl_certificate_status_callback); - SSL_CTX_set_tlsext_status_arg(ssl->ctx, staple); + SSL_CTX_set_tlsext_status_arg(ssl->ctx, conf); return NGX_OK; } static ngx_int_t -ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file) +ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, + ngx_ssl_staple_t *conf) { BIO *bio; int len; u_char *p, *buf; OCSP_RESPONSE *response; - ngx_ssl_stapling_t *staple; - - staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) { return NGX_ERROR; @@ -223,7 +222,8 @@ ngx_ssl_stapling_file(ngx_conf_t *cf, ng goto failed; } - buf = ngx_alloc(len, ssl->log); + /* File content buffer allocated from pool to avoid additional cleanup */ + buf = ngx_palloc(cf->pool, len); if (buf == NULL) { goto failed; } @@ -240,8 +240,8 @@ ngx_ssl_stapling_file(ngx_conf_t *cf, ng OCSP_RESPONSE_free(response); BIO_free(bio); - staple->staple.data = buf; - staple->staple.len = len; + conf->staple.data = buf; + conf->staple.len = len; return NGX_OK; @@ -263,9 +263,32 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, X509_STORE_CTX *store_ctx; STACK_OF(X509) *chain; ngx_ssl_stapling_t *staple; + ngx_pool_cleanup_t *cln; - staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); - cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); + cert = ngx_ssl_get_server_certificate(ssl, NGX_SSL_FIRST_CERT); + + staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t)); + if (staple == NULL) { + return NGX_ERROR; + } + + cln = ngx_pool_cleanup_add(cf->pool, 0); + if (cln == NULL) { + return NGX_ERROR; + } + + cln->handler = ngx_ssl_stapling_cleanup; + cln->data = staple; + + if (X509_set_ex_data(cert, ngx_ssl_cert_stapling_index, staple) + == 0) + { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "X509_set_ex_data() failed"); + return NGX_ERROR; + } + + staple->ssl_ctx = ssl->ctx; #if OPENSSL_VERSION_NUMBER >= 0x10001000L SSL_CTX_get_extra_chain_certs(ssl->ctx, &chain); @@ -348,9 +371,11 @@ ngx_ssl_stapling_responder(ngx_conf_t *c ngx_url_t u; char *s; ngx_ssl_stapling_t *staple; + X509 *cert; STACK_OF(OPENSSL_STRING) *aia; - staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); + cert = ngx_ssl_get_server_certificate(ssl, NGX_SSL_FIRST_CERT); + staple = X509_get_ex_data(cert, ngx_ssl_cert_stapling_index); if (responder->len == 0) { @@ -435,7 +460,7 @@ ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_resolver_t *resolver, ngx_msec_t resolver_timeout) { - ngx_ssl_stapling_t *staple; + ngx_ssl_staple_t *staple; staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); @@ -451,41 +476,54 @@ ngx_ssl_certificate_status_callback(ngx_ { int rc; u_char *p; + ngx_str_t resp; ngx_connection_t *c; + ngx_ssl_staple_t *conf; ngx_ssl_stapling_t *staple; + X509 *cert; c = ngx_ssl_get_connection(ssl_conn); + cert = SSL_get_certificate(ssl_conn); ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL certificate status callback"); - staple = data; + staple = X509_get_ex_data(cert, ngx_ssl_cert_stapling_index); + conf = data; rc = SSL_TLSEXT_ERR_NOACK; + resp.len = 0; - if (staple->staple.len) { - /* we have to copy ocsp response as OpenSSL will free it by itself */ + if (conf->staple.len) { + resp = conf->staple; + } + else if (staple && staple->staple.len) { + resp = staple->staple; + } - p = OPENSSL_malloc(staple->staple.len); + if (resp.len) { + /* We have to copy ocsp response as OpenSSL will free it by itself */ + p = OPENSSL_malloc(resp.len); if (p == NULL) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "OPENSSL_malloc() failed"); return SSL_TLSEXT_ERR_NOACK; } - ngx_memcpy(p, staple->staple.data, staple->staple.len); + ngx_memcpy(p, resp.data, resp.len); - SSL_set_tlsext_status_ocsp_resp(ssl_conn, p, staple->staple.len); + SSL_set_tlsext_status_ocsp_resp(ssl_conn, p, resp.len); rc = SSL_TLSEXT_ERR_OK; } - ngx_ssl_stapling_update(staple); + if (staple) + ngx_ssl_stapling_update(staple, conf); return rc; } static void -ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple) +ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple, ngx_ssl_staple_t *conf) { ngx_ssl_ocsp_ctx_t *ctx; @@ -509,10 +547,10 @@ ngx_ssl_stapling_update(ngx_ssl_stapling ctx->host = staple->host; ctx->uri = staple->uri; ctx->port = staple->port; - ctx->timeout = staple->timeout; + ctx->timeout = conf->timeout; - ctx->resolver = staple->resolver; - ctx->resolver_timeout = staple->resolver_timeout; + ctx->resolver = conf->resolver; + ctx->resolver_timeout = conf->resolver_timeout; ctx->handler = ngx_ssl_stapling_ocsp_handler; ctx->data = staple; @@ -592,7 +630,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc #endif if (OCSP_basic_verify(basic, chain, store, - staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY) + ctx->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY) != 1) { ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0, From fdasilva at ingima.com Thu Apr 16 10:10:26 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 16 Apr 2015 10:10:26 +0000 Subject: [PATCH 3 of 6] Stapling SSL: ... Message-ID: # HG changeset patch # User Filipe da Silva # Date 1429178261 -7200 # Thu Apr 16 11:57:41 2015 +0200 # Node ID 4b0a7a9e22bd09044cdbc623da815bb14d0d7b4c # Parent 85fb1b1e922fd95ef0df3c7f8bc9625af3054002 SSL Stapling: replace cert/issuer pair by certid. diff -r 85fb1b1e922f -r 4b0a7a9e22bd src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Thu Apr 16 11:57:41 2015 +0200 +++ b/src/event/ngx_event_openssl_stapling.c Thu Apr 16 11:57:41 2015 +0200 @@ -13,6 +13,7 @@ #if (!defined OPENSSL_NO_OCSP && defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB) +typedef OCSP_CERTID ngx_ssl_certid_t; /* OCSP stapling configuration per server */ typedef struct { @@ -38,8 +39,7 @@ typedef struct { SSL_CTX *ssl_ctx; - X509 *cert; - X509 *issuer; + ngx_ssl_certid_t *certid; time_t valid; @@ -50,8 +50,7 @@ typedef struct { typedef struct ngx_ssl_ocsp_ctx_s ngx_ssl_ocsp_ctx_t; struct ngx_ssl_ocsp_ctx_s { - X509 *cert; - X509 *issuer; + ngx_ssl_certid_t *certid; ngx_uint_t naddrs; @@ -304,13 +303,15 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, for (i = 0; i < n; i++) { issuer = sk_X509_value(chain, i); if (X509_check_issued(issuer, cert) == X509_V_OK) { - CRYPTO_add(&issuer->references, 1, CRYPTO_LOCK_X509); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, "SSL get issuer: found %p in extra certs", issuer); - staple->cert = cert; - staple->issuer = issuer; + staple->certid = OCSP_cert_to_id(NULL, cert, issuer); + if (!staple->certid) + { + return NGX_ERROR; + } return NGX_OK; } @@ -353,14 +354,17 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, return NGX_DECLINED; } - X509_STORE_CTX_free(store_ctx); - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, "SSL get issuer: found %p in cert store", issuer); - staple->cert = cert; - staple->issuer = issuer; + staple->certid = OCSP_cert_to_id(NULL, cert, issuer); + CRYPTO_add(&issuer->references, -1, CRYPTO_LOCK_X509); + X509_STORE_CTX_free(store_ctx); + + if (!staple->certid) { + return NGX_ERROR; + } return NGX_OK; } @@ -381,7 +385,7 @@ ngx_ssl_stapling_responder(ngx_conf_t *c /* extract OCSP responder URL from certificate */ - aia = X509_get1_ocsp(staple->cert); + aia = X509_get1_ocsp(cert); if (aia == NULL) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, " @@ -540,8 +544,7 @@ ngx_ssl_stapling_update(ngx_ssl_stapling return; } - ctx->cert = staple->cert; - ctx->issuer = staple->issuer; + ctx->certid = staple->certid; ctx->addrs = staple->addrs; ctx->host = staple->host; @@ -630,22 +633,19 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc #endif if (OCSP_basic_verify(basic, chain, store, - ctx->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY) - != 1) + ctx->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY +#if OPENSSL_VERSION_NUMBER < 0x10000000L + /* ECDSA/SHA-2 signature verification not supported */ + | OCSP_NOSIGS +#endif + ) != 1) { ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0, "OCSP_basic_verify() failed"); goto error; } - id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer); - if (id == NULL) { - ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, - "OCSP_cert_to_id() failed"); - goto error; - } - - if (OCSP_resp_find_status(basic, id, &n, NULL, NULL, + if (OCSP_resp_find_status(basic, ctx->certid, &n, NULL, NULL, &thisupdate, &nextupdate) != 1) { @@ -667,7 +667,6 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc goto error; } - OCSP_CERTID_free(id); OCSP_BASICRESP_free(basic); OCSP_RESPONSE_free(ocsp); @@ -705,10 +704,6 @@ error: staple->loading = 0; staple->valid = ngx_time() + 300; /* ssl_stapling_err_valid */ - if (id) { - OCSP_CERTID_free(id); - } - if (basic) { OCSP_BASICRESP_free(basic); } @@ -726,8 +721,8 @@ ngx_ssl_stapling_cleanup(void *data) { ngx_ssl_stapling_t *staple = data; - if (staple->issuer) { - X509_free(staple->issuer); + if (staple->certid) { + OCSP_CERTID_free(staple->certid); } if (staple->staple.data) { @@ -1147,10 +1142,10 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp return NGX_ERROR; } - id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer); + id = OCSP_CERTID_dup(ctx->certid); if (id == NULL) { ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0, - "OCSP_cert_to_id() failed"); + "OCSP_CERTID_dup() failed"); goto failed; } From fdasilva at ingima.com Thu Apr 16 10:10:47 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 16 Apr 2015 10:10:47 +0000 Subject: [PATCH 4 of 6] SSL Stapling: ... Message-ID: # HG changeset patch # User Filipe da Silva # Date 1429178261 -7200 # Thu Apr 16 11:57:41 2015 +0200 # Node ID 257767ac10541b1d94e6c93b19a1d5ebd3569abf # Parent 4b0a7a9e22bd09044cdbc623da815bb14d0d7b4c SSL Stapling: introduce Multiple Cert Management. diff -r 4b0a7a9e22bd -r 257767ac1054 src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Thu Apr 16 11:57:41 2015 +0200 +++ b/src/event/ngx_event_openssl_stapling.c Thu Apr 16 11:57:41 2015 +0200 @@ -93,9 +93,13 @@ struct ngx_ssl_ocsp_ctx_s { static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, ngx_ssl_staple_t *conf); -static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl); + +static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl, + X509 *cert); static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_str_t *responder); + ngx_str_t *responder, X509 *cert); +static ngx_int_t ngx_ssl_stapling_issuer_responder(ngx_conf_t *cf, + ngx_ssl_t *ssl, ngx_str_t *responder); static int ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn, void *data); @@ -157,17 +161,7 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl goto done; } - rc = ngx_ssl_stapling_issuer(cf, ssl); - - if (rc == NGX_DECLINED) { - return NGX_OK; - } - - if (rc != NGX_OK) { - return NGX_ERROR; - } - - rc = ngx_ssl_stapling_responder(cf, ssl, responder); + rc = ngx_ssl_stapling_issuer_responder(cf, ssl, responder); if (rc == NGX_DECLINED) { return NGX_OK; @@ -254,18 +248,55 @@ failed: static ngx_int_t -ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl) +ngx_ssl_stapling_issuer_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_str_t *responder) +{ + ngx_int_t rc, ret; + X509 *cert; + + ret = NGX_DECLINED; + cert = ngx_ssl_get_server_certificate(ssl, NGX_SSL_FIRST_CERT); + + while (cert) { + + rc = ngx_ssl_stapling_issuer(cf, ssl, cert); + + if (rc == NGX_OK) { + + rc = ngx_ssl_stapling_responder(cf, ssl, responder, cert); + + /* return OK, when one cert at least is OK */ + if (rc == NGX_OK) { + ret = NGX_OK; + } + } + + if (rc == NGX_DECLINED) { + rc = NGX_OK; + } + if (rc != NGX_OK) { + return NGX_ERROR; + } + + /* Get next certificate */ + cert = ngx_ssl_get_server_certificate(ssl, NGX_SSL_NEXT_CERT); + } + + return ret; +} + + +static ngx_int_t +ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl, X509 *cert) { int i, n, rc; - X509 *cert, *issuer; + X509 *issuer; X509_STORE *store; X509_STORE_CTX *store_ctx; STACK_OF(X509) *chain; ngx_ssl_stapling_t *staple; ngx_pool_cleanup_t *cln; - cert = ngx_ssl_get_server_certificate(ssl, NGX_SSL_FIRST_CERT); - staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t)); if (staple == NULL) { return NGX_ERROR; @@ -370,15 +401,14 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, static ngx_int_t -ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder) +ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder, + X509 *cert) { ngx_url_t u; char *s; ngx_ssl_stapling_t *staple; - X509 *cert; STACK_OF(OPENSSL_STRING) *aia; - cert = ngx_ssl_get_server_certificate(ssl, NGX_SSL_FIRST_CERT); staple = X509_get_ex_data(cert, ngx_ssl_cert_stapling_index); if (responder->len == 0) { From fdasilva at ingima.com Thu Apr 16 10:10:59 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 16 Apr 2015 10:10:59 +0000 Subject: [PATCH 5 of 6] SSL : ... Message-ID: # HG changeset patch # User Filipe da Silva # Date 1429178262 -7200 # Thu Apr 16 11:57:42 2015 +0200 # Node ID b6a6508616eec10a7d2891d97b27d3bdc784a26b # Parent 257767ac10541b1d94e6c93b19a1d5ebd3569abf SSL: introduce Multiple server Cert support. diff -r 257767ac1054 -r b6a6508616ee src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Thu Apr 16 11:57:41 2015 +0200 +++ b/src/event/ngx_event_openssl.c Thu Apr 16 11:57:42 2015 +0200 @@ -334,6 +334,36 @@ ngx_ssl_get_server_certificate(ngx_ssl_t ngx_int_t +ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, + ngx_array_t *keys, ngx_array_t *passwords) +{ + ngx_uint_t i, j; + ngx_str_t *cert; + ngx_str_t *key; + + /* Load server certificates */ + cert = certs->elts; + for (i = 0; i < certs->nelts; i++, cert++) { + if (ngx_ssl_server_certificate(cf, ssl, cert) != NGX_OK) + { + return NGX_ERROR; + } + } + + /* Load private keys */ + key = keys->elts; + for (j = 0; j < keys->nelts; j++, key++) { + if (ngx_ssl_private_key(cf, ssl, key, passwords) != NGX_OK) + { + return NGX_ERROR; + } + } + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords) { @@ -2227,18 +2257,17 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss cert = ngx_ssl_get_server_certificate(ssl, NGX_SSL_FIRST_CERT); while (cert) { - /* TODO: fix loop indentation */ - if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "X509_digest() failed"); - goto failed; - } - - if (EVP_DigestUpdate(&md, buf, len) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "EVP_DigestUpdate() failed"); - goto failed; - } + if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "X509_digest() failed"); + goto failed; + } + + if (EVP_DigestUpdate(&md, buf, len) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "EVP_DigestUpdate() failed"); + goto failed; + } /* get next server certificate, if any */ cert = ngx_ssl_get_server_certificate(ssl, NGX_SSL_NEXT_CERT); diff -r 257767ac1054 -r b6a6508616ee src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Thu Apr 16 11:57:41 2015 +0200 +++ b/src/event/ngx_event_openssl.h Thu Apr 16 11:57:42 2015 +0200 @@ -124,6 +124,8 @@ ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); +ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, diff -r 257767ac1054 -r b6a6508616ee src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c Thu Apr 16 11:57:41 2015 +0200 +++ b/src/http/modules/ngx_http_ssl_module.c Thu Apr 16 11:57:42 2015 +0200 @@ -81,16 +81,16 @@ static ngx_command_t ngx_http_ssl_comma { ngx_string("ssl_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_SRV_CONF_OFFSET, - offsetof(ngx_http_ssl_srv_conf_t, certificate), + offsetof(ngx_http_ssl_srv_conf_t, certificates), NULL }, { ngx_string("ssl_certificate_key"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_SRV_CONF_OFFSET, - offsetof(ngx_http_ssl_srv_conf_t, certificate_key), + offsetof(ngx_http_ssl_srv_conf_t, certificate_keys), NULL }, { ngx_string("ssl_password_file"), @@ -505,8 +505,6 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t * set by ngx_pcalloc(): * * sscf->protocols = 0; - * sscf->certificate = { 0, NULL }; - * sscf->certificate_key = { 0, NULL }; * sscf->dhparam = { 0, NULL }; * sscf->ecdh_curve = { 0, NULL }; * sscf->client_certificate = { 0, NULL }; @@ -523,6 +521,8 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t sscf->buffer_size = NGX_CONF_UNSET_SIZE; sscf->verify = NGX_CONF_UNSET_UINT; sscf->verify_depth = NGX_CONF_UNSET_UINT; + sscf->certificates = NGX_CONF_UNSET_PTR; + sscf->certificate_keys = NGX_CONF_UNSET_PTR; sscf->passwords = NGX_CONF_UNSET_PTR; sscf->builtin_session_cache = NGX_CONF_UNSET; sscf->session_timeout = NGX_CONF_UNSET; @@ -570,8 +570,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); - ngx_conf_merge_str_value(conf->certificate, prev->certificate, ""); - ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, ""); + ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); + ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, + NULL); ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); @@ -598,7 +599,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * if (conf->enable) { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate\" is defined for " "the \"ssl\" directive in %s:%ui", @@ -606,7 +607,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * return NGX_CONF_ERROR; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined for " "the \"ssl\" directive in %s:%ui", @@ -616,18 +617,38 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * } else { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { return NGX_CONF_OK; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined " - "for certificate \"%V\"", &conf->certificate); + "for certificate \"%V\"", &conf->certificates[0]); + return NGX_CONF_ERROR; + } + if (conf->certificate_keys->nelts < conf->certificates->nelts) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "no \"ssl_certificate_key\" is defined " + "for certificate \"%V\"", + &conf->certificates[conf->certificate_keys->nelts]); return NGX_CONF_ERROR; } } +#ifndef SSL_CTX_add0_chain_cert + if (conf->certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured in " + "\"ssl_certificate\", but OpenSSL < 1.0.2 used"); + return NGX_CONF_ERROR; + } +#endif + if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) { return NGX_CONF_ERROR; } @@ -663,8 +684,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * cln->handler = ngx_ssl_cleanup_ctx; cln->data = &conf->ssl; - if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate, - &conf->certificate_key, conf->passwords) + if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, + conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; diff -r 257767ac1054 -r b6a6508616ee src/http/modules/ngx_http_ssl_module.h --- a/src/http/modules/ngx_http_ssl_module.h Thu Apr 16 11:57:41 2015 +0200 +++ b/src/http/modules/ngx_http_ssl_module.h Thu Apr 16 11:57:42 2015 +0200 @@ -32,8 +32,8 @@ typedef struct { time_t session_timeout; - ngx_str_t certificate; - ngx_str_t certificate_key; + ngx_array_t *certificates; + ngx_array_t *certificate_keys; ngx_str_t dhparam; ngx_str_t ecdh_curve; ngx_str_t client_certificate; From fdasilva at ingima.com Thu Apr 16 10:11:19 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Thu, 16 Apr 2015 10:11:19 +0000 Subject: [PATCH 6 of 6] SSL: add Multiple SSL certificate support to other modules. In-Reply-To: References: Message-ID: # HG changeset patch # User Filipe da Silva # Date 1429178262 -7200 # Thu Apr 16 11:57:42 2015 +0200 # Node ID 951b0939ce91f1a274e00e96d1e01481b772b89d # Parent b6a6508616eec10a7d2891d97b27d3bdc784a26b SSL: add Multiple SSL certificate support to other modules. diff -r b6a6508616ee -r 951b0939ce91 src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Thu Apr 16 11:57:42 2015 +0200 +++ b/src/http/modules/ngx_http_proxy_module.c Thu Apr 16 11:57:42 2015 +0200 @@ -97,8 +97,8 @@ typedef struct { ngx_uint_t ssl_verify_depth; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; - ngx_str_t ssl_certificate; - ngx_str_t ssl_certificate_key; + ngx_array_t *ssl_certificates; + ngx_array_t *ssl_certificate_keys; ngx_array_t *ssl_passwords; #endif } ngx_http_proxy_loc_conf_t; @@ -672,16 +672,16 @@ static ngx_command_t ngx_http_proxy_com { ngx_string("proxy_ssl_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate), + offsetof(ngx_http_proxy_loc_conf_t, ssl_certificates), NULL }, { ngx_string("proxy_ssl_certificate_key"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate_key), + offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate_keys), NULL }, { ngx_string("proxy_ssl_password_file"), @@ -2858,6 +2858,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ conf->upstream.ssl_verify = NGX_CONF_UNSET; conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; conf->ssl_passwords = NGX_CONF_UNSET_PTR; + conf->ssl_certificates = NGX_CONF_UNSET_PTR; + conf->ssl_certificate_keys = NGX_CONF_UNSET_PTR; #endif /* "proxy_cyclic_temp_file" is disabled */ @@ -3189,10 +3191,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t prev->ssl_trusted_certificate, ""); ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); - ngx_conf_merge_str_value(conf->ssl_certificate, - prev->ssl_certificate, ""); - ngx_conf_merge_str_value(conf->ssl_certificate_key, - prev->ssl_certificate_key, ""); + ngx_conf_merge_ptr_value(conf->ssl_certificates, + prev->ssl_certificates, NULL); + ngx_conf_merge_ptr_value(conf->ssl_certificate_keys, + prev->ssl_certificate_keys, NULL); + ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL); if (conf->ssl && ngx_http_proxy_set_ssl(cf, conf) != NGX_OK) { @@ -4279,6 +4282,7 @@ static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf) { ngx_pool_cleanup_t *cln; + ngx_str_t *oddkey; plcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t)); if (plcf->upstream.ssl == NULL) { @@ -4301,18 +4305,43 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n cln->handler = ngx_ssl_cleanup_ctx; cln->data = plcf->upstream.ssl; - if (plcf->ssl_certificate.len) { - - if (plcf->ssl_certificate_key.len == 0) { + if (plcf->ssl_certificates && plcf->ssl_certificates->nelts > 0) { + + if (!plcf->ssl_certificate_keys + || plcf->ssl_certificate_keys->nelts + < plcf->ssl_certificates->nelts) + { + + oddkey = plcf->ssl_certificates->elts; + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"proxy_ssl_certificate_key\" is defined " - "for certificate \"%V\"", &plcf->ssl_certificate); + "for ssl certificate \"%V\"", + oddkey[(plcf->ssl_certificate_keys) + ? plcf->ssl_certificate_keys->nelts + : 0]); + return NGX_ERROR; } - if (ngx_ssl_certificate(cf, plcf->upstream.ssl, &plcf->ssl_certificate, - &plcf->ssl_certificate_key, plcf->ssl_passwords) - != NGX_OK) +#ifndef SSL_CTX_add0_chain_cert + if (plcf->ssl_certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured " + "in \"proxy_ssl_certificate\", " + "but OpenSSL version < 1.0.2 used"); + return NGX_ERROR; + } +#endif + + if (ngx_ssl_certificates(cf, plcf->upstream.ssl, plcf->ssl_certificates, + plcf->ssl_certificate_keys, + plcf->ssl_passwords) + != NGX_OK) { return NGX_ERROR; } diff -r b6a6508616ee -r 951b0939ce91 src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c Thu Apr 16 11:57:42 2015 +0200 +++ b/src/http/modules/ngx_http_uwsgi_module.c Thu Apr 16 11:57:42 2015 +0200 @@ -54,8 +54,8 @@ typedef struct { ngx_uint_t ssl_verify_depth; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; - ngx_str_t ssl_certificate; - ngx_str_t ssl_certificate_key; + ngx_array_t *ssl_certificates; + ngx_array_t *ssl_certificate_keys; ngx_array_t *ssl_passwords; #endif } ngx_http_uwsgi_loc_conf_t; @@ -517,16 +517,16 @@ static ngx_command_t ngx_http_uwsgi_comm { ngx_string("uwsgi_ssl_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate), + offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificates), NULL }, { ngx_string("uwsgi_ssl_certificate_key"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate_key), + offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate_keys), NULL }, { ngx_string("uwsgi_ssl_password_file"), @@ -1430,6 +1430,8 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_ conf->upstream.ssl_verify = NGX_CONF_UNSET; conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; conf->ssl_passwords = NGX_CONF_UNSET_PTR; + conf->ssl_certificates = NGX_CONF_UNSET_PTR; + conf->ssl_certificate_keys = NGX_CONF_UNSET_PTR; #endif /* "uwsgi_cyclic_temp_file" is disabled */ @@ -1744,11 +1746,10 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t ngx_conf_merge_str_value(conf->ssl_trusted_certificate, prev->ssl_trusted_certificate, ""); ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); - - ngx_conf_merge_str_value(conf->ssl_certificate, - prev->ssl_certificate, ""); - ngx_conf_merge_str_value(conf->ssl_certificate_key, - prev->ssl_certificate_key, ""); + ngx_conf_merge_ptr_value(conf->ssl_certificates, + prev->ssl_certificates, NULL); + ngx_conf_merge_ptr_value(conf->ssl_certificate_keys, + prev->ssl_certificate_keys, NULL); ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL); if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) { @@ -2285,6 +2286,7 @@ static ngx_int_t ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf) { ngx_pool_cleanup_t *cln; + ngx_str_t *oddkey; uwcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t)); if (uwcf->upstream.ssl == NULL) { @@ -2307,17 +2309,42 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, n cln->handler = ngx_ssl_cleanup_ctx; cln->data = uwcf->upstream.ssl; - if (uwcf->ssl_certificate.len) { - - if (uwcf->ssl_certificate_key.len == 0) { + if (uwcf->ssl_certificates && uwcf->ssl_certificates->nelts > 0) { + + if (!uwcf->ssl_certificate_keys + || uwcf->ssl_certificate_keys->nelts + < uwcf->ssl_certificates->nelts) + { + + oddkey = uwcf->ssl_certificates->elts; + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"uwsgi_ssl_certificate_key\" is defined " - "for certificate \"%V\"", &uwcf->ssl_certificate); + "for ssl certificate \"%V\"", + oddkey[(uwcf->ssl_certificate_keys) + ? uwcf->ssl_certificate_keys->nelts + : 0]); + return NGX_ERROR; } - if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, &uwcf->ssl_certificate, - &uwcf->ssl_certificate_key, uwcf->ssl_passwords) +#ifndef SSL_CTX_add0_chain_cert + if (uwcf->ssl_certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured " + "in \"uwsgi_ssl_certificate\", but " + "OpenSSL < 1.0.2 used"); + return NGX_ERROR; + } +#endif + + if (ngx_ssl_certificates(cf, uwcf->upstream.ssl, uwcf->ssl_certificates, + uwcf->ssl_certificate_keys, + uwcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; diff -r b6a6508616ee -r 951b0939ce91 src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c Thu Apr 16 11:57:42 2015 +0200 +++ b/src/mail/ngx_mail_ssl_module.c Thu Apr 16 11:57:42 2015 +0200 @@ -73,16 +73,16 @@ static ngx_command_t ngx_mail_ssl_comma { ngx_string("ssl_certificate"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_ssl_conf_t, certificate), + offsetof(ngx_mail_ssl_conf_t, certificates), NULL }, { ngx_string("ssl_certificate_key"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_ssl_conf_t, certificate_key), + offsetof(ngx_mail_ssl_conf_t, certificate_keys), NULL }, { ngx_string("ssl_password_file"), @@ -238,8 +238,6 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf) * set by ngx_pcalloc(): * * scf->protocols = 0; - * scf->certificate = { 0, NULL }; - * scf->certificate_key = { 0, NULL }; * scf->dhparam = { 0, NULL }; * scf->ecdh_curve = { 0, NULL }; * scf->client_certificate = { 0, NULL }; @@ -250,6 +248,8 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf) */ scf->enable = NGX_CONF_UNSET; + scf->certificates = NGX_CONF_UNSET_PTR; + scf->certificate_keys = NGX_CONF_UNSET_PTR; scf->starttls = NGX_CONF_UNSET_UINT; scf->passwords = NGX_CONF_UNSET_PTR; scf->prefer_server_ciphers = NGX_CONF_UNSET; @@ -290,8 +290,9 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); - ngx_conf_merge_str_value(conf->certificate, prev->certificate, ""); - ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, ""); + ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); + ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, + NULL); ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); @@ -328,7 +329,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, if (*mode) { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate\" is defined for " "the \"%s\" directive in %s:%ui", @@ -336,7 +337,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined for " "the \"%s\" directive in %s:%ui", @@ -344,17 +345,24 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } + if (conf->certificate_keys->nelts < conf->certificates->nelts) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "no \"ssl_certificate_key\" is defined " + "for certificate \"%V\"", + &conf->certificates[conf->certificate_keys->nelts]); + return NGX_CONF_ERROR; + } + } else { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { return NGX_CONF_OK; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined " - "for certificate \"%V\"", - &conf->certificate); + "for certificate \"%V\"", &conf->certificates[0]); return NGX_CONF_ERROR; } } @@ -371,8 +379,21 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, cln->handler = ngx_ssl_cleanup_ctx; cln->data = &conf->ssl; - if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate, - &conf->certificate_key, conf->passwords) +#ifndef SSL_CTX_add0_chain_cert + if (conf->certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured in " + "\"ssl_certificate\", but OpenSSL < 1.0.2 used"); + return NGX_CONF_ERROR; + } +#endif + + if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, + conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; diff -r b6a6508616ee -r 951b0939ce91 src/mail/ngx_mail_ssl_module.h --- a/src/mail/ngx_mail_ssl_module.h Thu Apr 16 11:57:42 2015 +0200 +++ b/src/mail/ngx_mail_ssl_module.h Thu Apr 16 11:57:42 2015 +0200 @@ -35,8 +35,8 @@ typedef struct { time_t session_timeout; - ngx_str_t certificate; - ngx_str_t certificate_key; + ngx_array_t *certificates; + ngx_array_t *certificate_keys; ngx_str_t dhparam; ngx_str_t ecdh_curve; ngx_str_t client_certificate; -------------- next part -------------- An HTML attachment was scrubbed... URL: From ru at nginx.com Thu Apr 16 12:21:10 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 12:21:10 +0000 Subject: [nginx] Fixed build, broken by 8b7f062a3fe6. Message-ID: details: http://hg.nginx.org/nginx/rev/ac34eff7e147 branches: changeset: 6098:ac34eff7e147 user: Ruslan Ermilov date: Thu Apr 16 15:05:40 2015 +0300 description: Fixed build, broken by 8b7f062a3fe6. Casting a "const char *" to "char *" doesn't work on older gcc versions. diffstat: src/core/nginx.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 8b7f062a3fe6 -r ac34eff7e147 src/core/nginx.c --- a/src/core/nginx.c Thu Apr 16 12:17:41 2015 +0300 +++ b/src/core/nginx.c Thu Apr 16 15:05:40 2015 +0300 @@ -260,7 +260,8 @@ main(int argc, char *const *argv) } else { ngx_write_stderr("built with " OPENSSL_VERSION_TEXT " (running with "); - ngx_write_stderr((char *) SSLeay_version(SSLEAY_VERSION)); + ngx_write_stderr((char *) (uintptr_t) + SSLeay_version(SSLEAY_VERSION)); ngx_write_stderr(")" NGX_LINEFEED); } #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME From ru at nginx.com Thu Apr 16 12:23:10 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 12:23:10 +0000 Subject: [nginx] Upstream: track the number of active connections to upst... Message-ID: details: http://hg.nginx.org/nginx/rev/6ff0ebd6fbf4 branches: changeset: 6099:6ff0ebd6fbf4 user: Ruslan Ermilov date: Fri Apr 10 13:16:23 2015 +0300 description: Upstream: track the number of active connections to upstreams. This also simplifies the implementation of the least_conn module. diffstat: src/http/modules/ngx_http_upstream_hash_module.c | 4 + src/http/modules/ngx_http_upstream_ip_hash_module.c | 2 + src/http/modules/ngx_http_upstream_least_conn_module.c | 138 ++-------------- src/http/ngx_http_upstream_round_robin.c | 11 +- src/http/ngx_http_upstream_round_robin.h | 2 + 5 files changed, 35 insertions(+), 122 deletions(-) diffs (truncated from 358 to 300 lines): diff -r ac34eff7e147 -r 6ff0ebd6fbf4 src/http/modules/ngx_http_upstream_hash_module.c --- a/src/http/modules/ngx_http_upstream_hash_module.c Thu Apr 16 15:05:40 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_hash_module.c Fri Apr 10 13:16:23 2015 +0300 @@ -262,6 +262,8 @@ ngx_http_upstream_get_hash_peer(ngx_peer pc->socklen = peer->socklen; pc->name = &peer->name; + peer->conns++; + if (now - peer->checked > peer->fail_timeout) { peer->checked = now; } @@ -562,6 +564,8 @@ ngx_http_upstream_get_chash_peer(ngx_pee pc->socklen = best->socklen; pc->name = &best->name; + best->conns++; + return NGX_OK; } diff -r ac34eff7e147 -r 6ff0ebd6fbf4 src/http/modules/ngx_http_upstream_ip_hash_module.c --- a/src/http/modules/ngx_http_upstream_ip_hash_module.c Thu Apr 16 15:05:40 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c Fri Apr 10 13:16:23 2015 +0300 @@ -242,6 +242,8 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p pc->socklen = peer->socklen; pc->name = &peer->name; + peer->conns++; + if (now - peer->checked > peer->fail_timeout) { peer->checked = now; } diff -r ac34eff7e147 -r 6ff0ebd6fbf4 src/http/modules/ngx_http_upstream_least_conn_module.c --- a/src/http/modules/ngx_http_upstream_least_conn_module.c Thu Apr 16 15:05:40 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_least_conn_module.c Fri Apr 10 13:16:23 2015 +0300 @@ -10,29 +10,10 @@ #include -typedef struct { - ngx_uint_t *conns; -} ngx_http_upstream_least_conn_conf_t; - - -typedef struct { - /* the round robin data must be first */ - ngx_http_upstream_rr_peer_data_t rrp; - - ngx_uint_t *conns; - - ngx_event_get_peer_pt get_rr_peer; - ngx_event_free_peer_pt free_rr_peer; -} ngx_http_upstream_lc_peer_data_t; - - static ngx_int_t ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us); static ngx_int_t ngx_http_upstream_get_least_conn_peer( ngx_peer_connection_t *pc, void *data); -static void ngx_http_upstream_free_least_conn_peer(ngx_peer_connection_t *pc, - void *data, ngx_uint_t state); -static void *ngx_http_upstream_least_conn_create_conf(ngx_conf_t *cf); static char *ngx_http_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -57,7 +38,7 @@ static ngx_http_module_t ngx_http_upstr NULL, /* create main configuration */ NULL, /* init main configuration */ - ngx_http_upstream_least_conn_create_conf, /* create server configuration */ + NULL, /* create server configuration */ NULL, /* merge server configuration */ NULL, /* create location configuration */ @@ -85,10 +66,6 @@ static ngx_int_t ngx_http_upstream_init_least_conn(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) { - ngx_uint_t n; - ngx_http_upstream_rr_peers_t *peers; - ngx_http_upstream_least_conn_conf_t *lcf; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "init least conn"); @@ -96,22 +73,6 @@ ngx_http_upstream_init_least_conn(ngx_co return NGX_ERROR; } - peers = us->peer.data; - - n = peers->number; - - if (peers->next) { - n += peers->next->number; - } - - lcf = ngx_http_conf_upstream_srv_conf(us, - ngx_http_upstream_least_conn_module); - - lcf->conns = ngx_pcalloc(cf->pool, sizeof(ngx_uint_t) * n); - if (lcf->conns == NULL) { - return NGX_ERROR; - } - us->peer.init = ngx_http_upstream_init_least_conn_peer; return NGX_OK; @@ -122,33 +83,14 @@ static ngx_int_t ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { - ngx_http_upstream_lc_peer_data_t *lcp; - ngx_http_upstream_least_conn_conf_t *lcf; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "init least conn peer"); - lcf = ngx_http_conf_upstream_srv_conf(us, - ngx_http_upstream_least_conn_module); - - lcp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_lc_peer_data_t)); - if (lcp == NULL) { - return NGX_ERROR; - } - - lcp->conns = lcf->conns; - - r->upstream->peer.data = &lcp->rrp; - if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { return NGX_ERROR; } r->upstream->peer.get = ngx_http_upstream_get_least_conn_peer; - r->upstream->peer.free = ngx_http_upstream_free_least_conn_peer; - - lcp->get_rr_peer = ngx_http_upstream_get_round_robin_peer; - lcp->free_rr_peer = ngx_http_upstream_free_round_robin_peer; return NGX_OK; } @@ -157,7 +99,7 @@ ngx_http_upstream_init_least_conn_peer(n static ngx_int_t ngx_http_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data) { - ngx_http_upstream_lc_peer_data_t *lcp = data; + ngx_http_upstream_rr_peer_data_t *rrp = data; time_t now; uintptr_t m; @@ -169,8 +111,8 @@ ngx_http_upstream_get_least_conn_peer(ng ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, "get least conn peer, try: %ui", pc->tries); - if (lcp->rrp.peers->single) { - return lcp->get_rr_peer(pc, &lcp->rrp); + if (rrp->peers->single) { + return ngx_http_upstream_get_round_robin_peer(pc, rrp); } pc->cached = 0; @@ -178,7 +120,7 @@ ngx_http_upstream_get_least_conn_peer(ng now = ngx_time(); - peers = lcp->rrp.peers; + peers = rrp->peers; best = NULL; total = 0; @@ -193,7 +135,7 @@ ngx_http_upstream_get_least_conn_peer(ng n = i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); - if (lcp->rrp.tried[n] & m) { + if (rrp->tried[n] & m) { continue; } @@ -217,15 +159,13 @@ ngx_http_upstream_get_least_conn_peer(ng */ if (best == NULL - || lcp->conns[i] * best->weight < lcp->conns[p] * peer->weight) + || peer->conns * best->weight < best->conns * peer->weight) { best = peer; many = 0; p = i; - } else if (lcp->conns[i] * best->weight - == lcp->conns[p] * peer->weight) - { + } else if (peer->conns * best->weight == best->conns * peer->weight) { many = 1; } } @@ -246,7 +186,7 @@ ngx_http_upstream_get_least_conn_peer(ng n = i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); - if (lcp->rrp.tried[n] & m) { + if (rrp->tried[n] & m) { continue; } @@ -256,7 +196,7 @@ ngx_http_upstream_get_least_conn_peer(ng continue; } - if (lcp->conns[i] * best->weight != lcp->conns[p] * peer->weight) { + if (peer->conns * best->weight != best->conns * peer->weight) { continue; } @@ -291,13 +231,14 @@ ngx_http_upstream_get_least_conn_peer(ng pc->socklen = best->socklen; pc->name = &best->name; - lcp->rrp.current = p; + best->conns++; + + rrp->current = p; n = p / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t)); - lcp->rrp.tried[n] |= m; - lcp->conns[p]++; + rrp->tried[n] |= m; return NGX_OK; @@ -307,18 +248,16 @@ failed: ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "get least conn peer, backup servers"); - lcp->conns += peers->number; + rrp->peers = peers->next; - lcp->rrp.peers = peers->next; - - n = (lcp->rrp.peers->number + (8 * sizeof(uintptr_t) - 1)) + n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t)); for (i = 0; i < n; i++) { - lcp->rrp.tried[i] = 0; + rrp->tried[i] = 0; } - rc = ngx_http_upstream_get_least_conn_peer(pc, lcp); + rc = ngx_http_upstream_get_least_conn_peer(pc, rrp); if (rc != NGX_BUSY) { return rc; @@ -337,47 +276,6 @@ failed: } -static void -ngx_http_upstream_free_least_conn_peer(ngx_peer_connection_t *pc, - void *data, ngx_uint_t state) -{ - ngx_http_upstream_lc_peer_data_t *lcp = data; - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, - "free least conn peer %ui %ui", pc->tries, state); - - if (lcp->rrp.peers->single) { - lcp->free_rr_peer(pc, &lcp->rrp, state); - return; - } - - lcp->conns[lcp->rrp.current]--; - - lcp->free_rr_peer(pc, &lcp->rrp, state); -} - - -static void * -ngx_http_upstream_least_conn_create_conf(ngx_conf_t *cf) -{ - ngx_http_upstream_least_conn_conf_t *conf; - - conf = ngx_pcalloc(cf->pool, - sizeof(ngx_http_upstream_least_conn_conf_t)); - if (conf == NULL) { - return NULL; - } - - /* - * set by ngx_pcalloc(): - * - * conf->conns = NULL; - */ - - return conf; From ru at nginx.com Thu Apr 16 12:23:12 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 12:23:12 +0000 Subject: [nginx] Upstream: store peers as a linked list. Message-ID: details: http://hg.nginx.org/nginx/rev/c44459611d91 branches: changeset: 6100:c44459611d91 user: Ruslan Ermilov date: Fri Apr 10 14:48:36 2015 +0300 description: Upstream: store peers as a linked list. This is an API change. diffstat: src/http/modules/ngx_http_upstream_hash_module.c | 73 ++++++----- src/http/modules/ngx_http_upstream_ip_hash_module.c | 16 +- src/http/modules/ngx_http_upstream_least_conn_module.c | 21 +- src/http/ngx_http_upstream_round_robin.c | 105 +++++++++++----- src/http/ngx_http_upstream_round_robin.h | 12 +- 5 files changed, 140 insertions(+), 87 deletions(-) diffs (truncated from 627 to 300 lines): diff -r 6ff0ebd6fbf4 -r c44459611d91 src/http/modules/ngx_http_upstream_hash_module.c --- a/src/http/modules/ngx_http_upstream_hash_module.c Fri Apr 10 13:16:23 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_hash_module.c Fri Apr 10 14:48:36 2015 +0300 @@ -211,11 +211,19 @@ ngx_http_upstream_get_hash_peer(ngx_peer if (!hp->rrp.peers->weighted) { p = hp->hash % hp->rrp.peers->number; + peer = hp->rrp.peers->peer; + for (i = 0; i < p; i++) { + peer = peer->next; + } + } else { w = hp->hash % hp->rrp.peers->total_weight; - for (i = 0; i < hp->rrp.peers->number; i++) { - w -= hp->rrp.peers->peer[i].weight; + for (peer = hp->rrp.peers->peer, i = 0; + peer; + peer = peer->next, i++) + { + w -= peer->weight; if (w < 0) { break; } @@ -234,8 +242,6 @@ ngx_http_upstream_get_hash_peer(ngx_peer ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, "get hash peer, value:%uD, peer:%ui", hp->hash, p); - peer = &hp->rrp.peers->peer[p]; - if (peer->down) { goto next; } @@ -256,7 +262,7 @@ ngx_http_upstream_get_hash_peer(ngx_peer } } - hp->rrp.current = p; + hp->rrp.current = peer; pc->sockaddr = peer->sockaddr; pc->socklen = peer->socklen; @@ -306,8 +312,7 @@ ngx_http_upstream_init_chash(ngx_conf_t points->number = 0; - for (i = 0; i < peers->number; i++) { - peer = &peers->peer[i]; + for (peer = peers->peer; peer; peer = peer->next) { server = &peer->server; /* @@ -475,7 +480,7 @@ ngx_http_upstream_get_chash_peer(ngx_pee intptr_t m; ngx_str_t *server; ngx_int_t total; - ngx_uint_t i, n; + ngx_uint_t i, n, best_i; ngx_http_upstream_rr_peer_t *peer, *best; ngx_http_upstream_chash_point_t *point; ngx_http_upstream_chash_points_t *points; @@ -501,9 +506,13 @@ ngx_http_upstream_get_chash_peer(ngx_pee hp->hash, server); best = NULL; + best_i = 0; total = 0; - for (i = 0; i < hp->rrp.peers->number; i++) { + for (peer = hp->rrp.peers->peer, i = 0; + peer; + peer = peer->next, i++) + { n = i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); @@ -512,8 +521,6 @@ ngx_http_upstream_get_chash_peer(ngx_pee continue; } - peer = &hp->rrp.peers->peer[i]; - if (peer->down) { continue; } @@ -541,32 +548,13 @@ ngx_http_upstream_get_chash_peer(ngx_pee if (best == NULL || peer->current_weight > best->current_weight) { best = peer; + best_i = i; } } if (best) { best->current_weight -= total; - - i = best - &hp->rrp.peers->peer[0]; - - hp->rrp.current = i; - - n = i / (8 * sizeof(uintptr_t)); - m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); - - hp->rrp.tried[n] |= m; - - if (now - best->checked > best->fail_timeout) { - best->checked = now; - } - - pc->sockaddr = best->sockaddr; - pc->socklen = best->socklen; - pc->name = &best->name; - - best->conns++; - - return NGX_OK; + goto found; } hp->hash++; @@ -576,6 +564,27 @@ ngx_http_upstream_get_chash_peer(ngx_pee return NGX_BUSY; } } + +found: + + hp->rrp.current = best; + + pc->sockaddr = best->sockaddr; + pc->socklen = best->socklen; + pc->name = &best->name; + + best->conns++; + + if (now - best->checked > best->fail_timeout) { + best->checked = now; + } + + n = best_i / (8 * sizeof(uintptr_t)); + m = (uintptr_t) 1 << best_i % (8 * sizeof(uintptr_t)); + + hp->rrp.tried[n] |= m; + + return NGX_OK; } diff -r 6ff0ebd6fbf4 -r c44459611d91 src/http/modules/ngx_http_upstream_ip_hash_module.c --- a/src/http/modules/ngx_http_upstream_ip_hash_module.c Fri Apr 10 13:16:23 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c Fri Apr 10 14:48:36 2015 +0300 @@ -181,11 +181,19 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p if (!iphp->rrp.peers->weighted) { p = hash % iphp->rrp.peers->number; + peer = iphp->rrp.peers->peer; + for (i = 0; i < p; i++) { + peer = peer->next; + } + } else { w = hash % iphp->rrp.peers->total_weight; - for (i = 0; i < iphp->rrp.peers->number; i++) { - w -= iphp->rrp.peers->peer[i].weight; + for (peer = iphp->rrp.peers->peer, i = 0; + peer; + peer = peer->next, i++) + { + w -= peer->weight; if (w < 0) { break; } @@ -204,8 +212,6 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, "get ip hash peer, hash: %ui %04XA", p, m); - peer = &iphp->rrp.peers->peer[p]; - /* ngx_lock_mutex(iphp->rrp.peers->mutex); */ if (peer->down) { @@ -236,7 +242,7 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p } } - iphp->rrp.current = p; + iphp->rrp.current = peer; pc->sockaddr = peer->sockaddr; pc->socklen = peer->socklen; diff -r 6ff0ebd6fbf4 -r c44459611d91 src/http/modules/ngx_http_upstream_least_conn_module.c --- a/src/http/modules/ngx_http_upstream_least_conn_module.c Fri Apr 10 13:16:23 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_least_conn_module.c Fri Apr 10 14:48:36 2015 +0300 @@ -130,7 +130,10 @@ ngx_http_upstream_get_least_conn_peer(ng p = 0; #endif - for (i = 0; i < peers->number; i++) { + for (peer = peers->peer, i = 0; + peer; + peer = peer->next, i++) + { n = i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); @@ -139,8 +142,6 @@ ngx_http_upstream_get_least_conn_peer(ng continue; } - peer = &peers->peer[i]; - if (peer->down) { continue; } @@ -181,8 +182,10 @@ ngx_http_upstream_get_least_conn_peer(ng ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "get least conn peer, many"); - for (i = p; i < peers->number; i++) { - + for (peer = best, i = p; + peer; + peer = peer->next, i++) + { n = i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); @@ -190,8 +193,6 @@ ngx_http_upstream_get_least_conn_peer(ng continue; } - peer = &peers->peer[i]; - if (peer->down) { continue; } @@ -233,7 +234,7 @@ ngx_http_upstream_get_least_conn_peer(ng best->conns++; - rrp->current = p; + rrp->current = best; n = p / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t)); @@ -266,8 +267,8 @@ failed: /* all peers failed, mark them as live for quick recovery */ - for (i = 0; i < peers->number; i++) { - peers->peer[i].fails = 0; + for (peer = peers->peer; peer; peer = peer->next) { + peer->fails = 0; } pc->name = peers->name; diff -r 6ff0ebd6fbf4 -r c44459611d91 src/http/ngx_http_upstream_round_robin.c --- a/src/http/ngx_http_upstream_round_robin.c Fri Apr 10 13:16:23 2015 +0300 +++ b/src/http/ngx_http_upstream_round_robin.c Fri Apr 10 14:48:36 2015 +0300 @@ -34,7 +34,7 @@ ngx_http_upstream_init_round_robin(ngx_c ngx_url_t u; ngx_uint_t i, j, n, w; ngx_http_upstream_server_t *server; - ngx_http_upstream_rr_peer_t *peer; + ngx_http_upstream_rr_peer_t *peer, **peerp; ngx_http_upstream_rr_peers_t *peers, *backup; us->peer.init = ngx_http_upstream_init_round_robin_peer; @@ -61,12 +61,16 @@ ngx_http_upstream_init_round_robin(ngx_c return NGX_ERROR; } - peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) - + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); + peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)); if (peers == NULL) { return NGX_ERROR; } + peer = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peer_t) * n); + if (peer == NULL) { + return NGX_ERROR; + } + peers->single = (n == 1); peers->number = n; peers->weighted = (w != n); @@ -74,7 +78,7 @@ ngx_http_upstream_init_round_robin(ngx_c peers->name = &us->host; n = 0; - peer = peers->peer; + peerp = &peers->peer; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { @@ -92,6 +96,9 @@ ngx_http_upstream_init_round_robin(ngx_c peer[n].fail_timeout = server[i].fail_timeout; From ru at nginx.com Thu Apr 16 12:23:15 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 12:23:15 +0000 Subject: [nginx] Core: read/write locks. Message-ID: details: http://hg.nginx.org/nginx/rev/682d8222c6b1 branches: changeset: 6101:682d8222c6b1 user: Ruslan Ermilov date: Sat Mar 21 14:05:08 2015 +0300 description: Core: read/write locks. diffstat: auto/sources | 2 + src/core/ngx_core.h | 1 + src/core/ngx_rwlock.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/core/ngx_rwlock.h | 21 +++++++++ 4 files changed, 136 insertions(+), 0 deletions(-) diffs (171 lines): diff -r c44459611d91 -r 682d8222c6b1 auto/sources --- a/auto/sources Fri Apr 10 14:48:36 2015 +0300 +++ b/auto/sources Sat Mar 21 14:05:08 2015 +0300 @@ -28,6 +28,7 @@ CORE_DEPS="src/core/nginx.h \ src/core/ngx_sha1.h \ src/core/ngx_rbtree.h \ src/core/ngx_radix_tree.h \ + src/core/ngx_rwlock.h \ src/core/ngx_slab.h \ src/core/ngx_times.h \ src/core/ngx_shmtx.h \ @@ -65,6 +66,7 @@ CORE_SRCS="src/core/nginx.c \ src/core/ngx_connection.c \ src/core/ngx_cycle.c \ src/core/ngx_spinlock.c \ + src/core/ngx_rwlock.c \ src/core/ngx_cpuinfo.c \ src/core/ngx_conf_file.c \ src/core/ngx_resolver.c \ diff -r c44459611d91 -r 682d8222c6b1 src/core/ngx_core.h --- a/src/core/ngx_core.h Fri Apr 10 14:48:36 2015 +0300 +++ b/src/core/ngx_core.h Sat Mar 21 14:05:08 2015 +0300 @@ -68,6 +68,7 @@ typedef void (*ngx_connection_handler_pt #endif #include #include +#include #include #include #include diff -r c44459611d91 -r 682d8222c6b1 src/core/ngx_rwlock.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/ngx_rwlock.c Sat Mar 21 14:05:08 2015 +0300 @@ -0,0 +1,112 @@ + +/* + * Copyright (C) Ruslan Ermilov + * Copyright (C) Nginx, Inc. + */ + + +#include +#include + + +#if (NGX_HAVE_ATOMIC_OPS) + + +#define NGX_RWLOCK_SPIN 2048 +#define NGX_RWLOCK_WLOCK ((ngx_atomic_uint_t) -1) + + +void +ngx_rwlock_wlock(ngx_atomic_t *lock) +{ + ngx_uint_t i, n; + + for ( ;; ) { + + if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK)) { + return; + } + + if (ngx_ncpu > 1) { + + for (n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) { + + for (i = 0; i < n; i++) { + ngx_cpu_pause(); + } + + if (*lock == 0 + && ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK)) + { + return; + } + } + } + + ngx_sched_yield(); + } +} + + +void +ngx_rwlock_rlock(ngx_atomic_t *lock) +{ + ngx_uint_t i, n; + ngx_atomic_uint_t readers; + + for ( ;; ) { + readers = *lock; + + if (readers != NGX_RWLOCK_WLOCK + && ngx_atomic_cmp_set(lock, readers, readers + 1)) + { + return; + } + + if (ngx_ncpu > 1) { + + for (n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) { + + for (i = 0; i < n; i++) { + ngx_cpu_pause(); + } + + readers = *lock; + + if (readers != NGX_RWLOCK_WLOCK + && ngx_atomic_cmp_set(lock, readers, readers + 1)) + { + return; + } + } + } + + ngx_sched_yield(); + } +} + + +void +ngx_rwlock_unlock(ngx_atomic_t *lock) +{ + ngx_atomic_uint_t readers; + + readers = *lock; + + if (readers == NGX_RWLOCK_WLOCK) { + *lock = 0; + return; + } + + for ( ;; ) { + + if (ngx_atomic_cmp_set(lock, readers, readers - 1)) { + return; + } + + readers = *lock; + } +} + + +#endif diff -r c44459611d91 -r 682d8222c6b1 src/core/ngx_rwlock.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/ngx_rwlock.h Sat Mar 21 14:05:08 2015 +0300 @@ -0,0 +1,21 @@ + +/* + * Copyright (C) Ruslan Ermilov + * Copyright (C) Nginx, Inc. + */ + + +#ifndef _NGX_RWLOCK_H_INCLUDED_ +#define _NGX_RWLOCK_H_INCLUDED_ + + +#include +#include + + +void ngx_rwlock_wlock(ngx_atomic_t *lock); +void ngx_rwlock_rlock(ngx_atomic_t *lock); +void ngx_rwlock_unlock(ngx_atomic_t *lock); + + +#endif /* _NGX_RWLOCK_H_INCLUDED_ */ From ru at nginx.com Thu Apr 16 12:23:17 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 12:23:17 +0000 Subject: [nginx] Upstreams: locking. Message-ID: details: http://hg.nginx.org/nginx/rev/3264b7828f72 branches: changeset: 6102:3264b7828f72 user: Ruslan Ermilov date: Tue Apr 14 19:01:23 2015 +0300 description: Upstreams: locking. diffstat: src/http/modules/ngx_http_upstream_hash_module.c | 16 ++++++++ src/http/modules/ngx_http_upstream_ip_hash_module.c | 11 ++--- src/http/modules/ngx_http_upstream_least_conn_module.c | 10 +++++ src/http/ngx_http_upstream_round_robin.c | 35 ++++++----------- src/http/ngx_http_upstream_round_robin.h | 7 +++ 5 files changed, 50 insertions(+), 29 deletions(-) diffs (truncated from 312 to 300 lines): diff -r 682d8222c6b1 -r 3264b7828f72 src/http/modules/ngx_http_upstream_hash_module.c --- a/src/http/modules/ngx_http_upstream_hash_module.c Sat Mar 21 14:05:08 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_hash_module.c Tue Apr 14 19:01:23 2015 +0300 @@ -176,7 +176,10 @@ ngx_http_upstream_get_hash_peer(ngx_peer ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, "get hash peer, try: %ui", pc->tries); + ngx_http_upstream_rr_peers_wlock(hp->rrp.peers); + if (hp->tries > 20 || hp->rrp.peers->single) { + ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); return hp->get_rr_peer(pc, &hp->rrp); } @@ -258,6 +261,7 @@ ngx_http_upstream_get_hash_peer(ngx_peer next: if (++hp->tries > 20) { + ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); return hp->get_rr_peer(pc, &hp->rrp); } } @@ -274,6 +278,8 @@ ngx_http_upstream_get_hash_peer(ngx_peer peer->checked = now; } + ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); + hp->rrp.tried[n] |= m; return NGX_OK; @@ -465,8 +471,13 @@ ngx_http_upstream_init_chash_peer(ngx_ht hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module); hash = ngx_crc32_long(hp->key.data, hp->key.len); + + ngx_http_upstream_rr_peers_rlock(hp->rrp.peers); + hp->hash = ngx_http_upstream_find_chash_point(hcf->points, hash); + ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); + return NGX_OK; } @@ -489,6 +500,8 @@ ngx_http_upstream_get_chash_peer(ngx_pee ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, "get consistent hash peer, try: %ui", pc->tries); + ngx_http_upstream_rr_peers_wlock(hp->rrp.peers); + pc->cached = 0; pc->connection = NULL; @@ -561,6 +574,7 @@ ngx_http_upstream_get_chash_peer(ngx_pee hp->tries++; if (hp->tries >= points->number) { + ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); return NGX_BUSY; } } @@ -579,6 +593,8 @@ found: best->checked = now; } + ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); + n = best_i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << best_i % (8 * sizeof(uintptr_t)); diff -r 682d8222c6b1 -r 3264b7828f72 src/http/modules/ngx_http_upstream_ip_hash_module.c --- a/src/http/modules/ngx_http_upstream_ip_hash_module.c Sat Mar 21 14:05:08 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c Tue Apr 14 19:01:23 2015 +0300 @@ -161,7 +161,10 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p /* TODO: cached */ + ngx_http_upstream_rr_peers_wlock(iphp->rrp.peers); + if (iphp->tries > 20 || iphp->rrp.peers->single) { + ngx_http_upstream_rr_peers_unlock(iphp->rrp.peers); return iphp->get_rr_peer(pc, &iphp->rrp); } @@ -212,8 +215,6 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, "get ip hash peer, hash: %ui %04XA", p, m); - /* ngx_lock_mutex(iphp->rrp.peers->mutex); */ - if (peer->down) { goto next_try; } @@ -230,14 +231,12 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p next_try: iphp->rrp.tried[n] |= m; - - /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */ - pc->tries--; next: if (++iphp->tries > 20) { + ngx_http_upstream_rr_peers_unlock(iphp->rrp.peers); return iphp->get_rr_peer(pc, &iphp->rrp); } } @@ -254,7 +253,7 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p peer->checked = now; } - /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */ + ngx_http_upstream_rr_peers_unlock(iphp->rrp.peers); iphp->rrp.tried[n] |= m; iphp->hash = hash; diff -r 682d8222c6b1 -r 3264b7828f72 src/http/modules/ngx_http_upstream_least_conn_module.c --- a/src/http/modules/ngx_http_upstream_least_conn_module.c Sat Mar 21 14:05:08 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_least_conn_module.c Tue Apr 14 19:01:23 2015 +0300 @@ -122,6 +122,8 @@ ngx_http_upstream_get_least_conn_peer(ng peers = rrp->peers; + ngx_http_upstream_rr_peers_wlock(peers); + best = NULL; total = 0; @@ -241,6 +243,8 @@ ngx_http_upstream_get_least_conn_peer(ng rrp->tried[n] |= m; + ngx_http_upstream_rr_peers_unlock(peers); + return NGX_OK; failed: @@ -258,11 +262,15 @@ failed: rrp->tried[i] = 0; } + ngx_http_upstream_rr_peers_unlock(peers); + rc = ngx_http_upstream_get_least_conn_peer(pc, rrp); if (rc != NGX_BUSY) { return rc; } + + ngx_http_upstream_rr_peers_wlock(peers); } /* all peers failed, mark them as live for quick recovery */ @@ -271,6 +279,8 @@ failed: peer->fails = 0; } + ngx_http_upstream_rr_peers_unlock(peers); + pc->name = peers->name; return NGX_BUSY; diff -r 682d8222c6b1 -r 3264b7828f72 src/http/ngx_http_upstream_round_robin.c --- a/src/http/ngx_http_upstream_round_robin.c Sat Mar 21 14:05:08 2015 +0300 +++ b/src/http/ngx_http_upstream_round_robin.c Tue Apr 14 19:01:23 2015 +0300 @@ -432,8 +432,7 @@ ngx_http_upstream_get_round_robin_peer(n pc->connection = NULL; peers = rrp->peers; - - /* ngx_lock_mutex(peers->mutex); */ + ngx_http_upstream_rr_peers_wlock(peers); if (peers->single) { peer = peers->peer; @@ -465,7 +464,7 @@ ngx_http_upstream_get_round_robin_peer(n peer->conns++; - /* ngx_unlock_mutex(peers->mutex); */ + ngx_http_upstream_rr_peers_unlock(peers); return NGX_OK; @@ -473,8 +472,6 @@ failed: if (peers->next) { - /* ngx_unlock_mutex(peers->mutex); */ - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers"); rrp->peers = peers->next; @@ -486,13 +483,15 @@ failed: rrp->tried[i] = 0; } + ngx_http_upstream_rr_peers_unlock(peers); + rc = ngx_http_upstream_get_round_robin_peer(pc, rrp); if (rc != NGX_BUSY) { return rc; } - /* ngx_lock_mutex(peers->mutex); */ + ngx_http_upstream_rr_peers_wlock(peers); } /* all peers failed, mark them as live for quick recovery */ @@ -501,7 +500,7 @@ failed: peer->fails = 0; } - /* ngx_unlock_mutex(peers->mutex); */ + ngx_http_upstream_rr_peers_unlock(peers); pc->name = peers->name; @@ -608,11 +607,12 @@ ngx_http_upstream_free_round_robin_peer( return; } + ngx_http_upstream_rr_peers_rlock(rrp->peers); + ngx_http_upstream_rr_peer_lock(rrp->peers, peer); + if (state & NGX_PEER_FAILED) { now = ngx_time(); - /* ngx_lock_mutex(rrp->peers->mutex); */ - peer->fails++; peer->accessed = now; peer->checked = now; @@ -629,8 +629,6 @@ ngx_http_upstream_free_round_robin_peer( peer->effective_weight = 0; } - /* ngx_unlock_mutex(rrp->peers->mutex); */ - } else { /* mark peer live if check passed */ @@ -642,11 +640,12 @@ ngx_http_upstream_free_round_robin_peer( peer->conns--; + ngx_http_upstream_rr_peer_unlock(rrp->peers, peer); + ngx_http_upstream_rr_peers_unlock(rrp->peers); + if (pc->tries) { pc->tries--; } - - /* ngx_unlock_mutex(rrp->peers->mutex); */ } @@ -664,9 +663,6 @@ ngx_http_upstream_set_round_robin_peer_s peer = rrp->current; - /* TODO: threads only mutex */ - /* ngx_lock_mutex(rrp->peers->mutex); */ - ssl_session = peer->ssl_session; rc = ngx_ssl_set_session(pc->connection, ssl_session); @@ -674,8 +670,6 @@ ngx_http_upstream_set_round_robin_peer_s ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, "set session: %p", ssl_session); - /* ngx_unlock_mutex(rrp->peers->mutex); */ - return rc; } @@ -700,14 +694,9 @@ ngx_http_upstream_save_round_robin_peer_ peer = rrp->current; - /* TODO: threads only mutex */ - /* ngx_lock_mutex(rrp->peers->mutex); */ - old_ssl_session = peer->ssl_session; peer->ssl_session = ssl_session; - /* ngx_unlock_mutex(rrp->peers->mutex); */ - if (old_ssl_session) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, diff -r 682d8222c6b1 -r 3264b7828f72 src/http/ngx_http_upstream_round_robin.h --- a/src/http/ngx_http_upstream_round_robin.h Sat Mar 21 14:05:08 2015 +0300 +++ b/src/http/ngx_http_upstream_round_robin.h Tue Apr 14 19:01:23 2015 +0300 @@ -63,6 +63,13 @@ struct ngx_http_upstream_rr_peers_s { }; From ru at nginx.com Thu Apr 16 12:23:20 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 12:23:20 +0000 Subject: [nginx] Upstream: the "zone" directive. Message-ID: details: http://hg.nginx.org/nginx/rev/79ddb0bdb273 branches: changeset: 6103:79ddb0bdb273 user: Ruslan Ermilov date: Tue Apr 14 19:01:25 2015 +0300 description: Upstream: the "zone" directive. Upstreams with the "zone" directive are kept in shared memory, with a consistent view of all worker processes. diffstat: auto/modules | 6 + auto/options | 4 + auto/sources | 5 + src/core/ngx_cycle.c | 4 +- src/core/ngx_cycle.h | 1 + src/core/ngx_rwlock.c | 8 + src/http/modules/ngx_http_upstream_zone_module.c | 213 +++++++++++++++++++++++ src/http/ngx_http_upstream.h | 4 + src/http/ngx_http_upstream_round_robin.c | 120 ++++++++++++- src/http/ngx_http_upstream_round_robin.h | 49 +++++- 10 files changed, 407 insertions(+), 7 deletions(-) diffs (truncated from 560 to 300 lines): diff -r 3264b7828f72 -r 79ddb0bdb273 auto/modules --- a/auto/modules Tue Apr 14 19:01:23 2015 +0300 +++ b/auto/modules Tue Apr 14 19:01:25 2015 +0300 @@ -391,6 +391,12 @@ if [ $HTTP_UPSTREAM_KEEPALIVE = YES ]; t HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_KEEPALIVE_SRCS" fi +if [ $HTTP_UPSTREAM_ZONE = YES ]; then + have=NGX_HTTP_UPSTREAM_ZONE . auto/have + HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_ZONE_MODULE" + HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_ZONE_SRCS" +fi + if [ $HTTP_STUB_STATUS = YES ]; then have=NGX_STAT_STUB . auto/have HTTP_MODULES="$HTTP_MODULES ngx_http_stub_status_module" diff -r 3264b7828f72 -r 79ddb0bdb273 auto/options --- a/auto/options Tue Apr 14 19:01:23 2015 +0300 +++ b/auto/options Tue Apr 14 19:01:25 2015 +0300 @@ -103,6 +103,7 @@ HTTP_UPSTREAM_HASH=YES HTTP_UPSTREAM_IP_HASH=YES HTTP_UPSTREAM_LEAST_CONN=YES HTTP_UPSTREAM_KEEPALIVE=YES +HTTP_UPSTREAM_ZONE=YES # STUB HTTP_STUB_STATUS=NO @@ -256,6 +257,7 @@ use the \"--without-http_limit_conn_modu --without-http_upstream_least_conn_module) HTTP_UPSTREAM_LEAST_CONN=NO ;; --without-http_upstream_keepalive_module) HTTP_UPSTREAM_KEEPALIVE=NO ;; + --without-http_upstream_zone_module) HTTP_UPSTREAM_ZONE=NO ;; --with-http_perl_module) HTTP_PERL=YES ;; --with-perl_modules_path=*) NGX_PERL_MODULES="$value" ;; @@ -406,6 +408,8 @@ cat << END disable ngx_http_upstream_least_conn_module --without-http_upstream_keepalive_module disable ngx_http_upstream_keepalive_module + --without-http_upstream_zone_module + disable ngx_http_upstream_zone_module --with-http_perl_module enable ngx_http_perl_module --with-perl_modules_path=PATH set Perl modules path diff -r 3264b7828f72 -r 79ddb0bdb273 auto/sources --- a/auto/sources Tue Apr 14 19:01:23 2015 +0300 +++ b/auto/sources Tue Apr 14 19:01:25 2015 +0300 @@ -513,6 +513,11 @@ HTTP_UPSTREAM_KEEPALIVE_SRCS=" \ src/http/modules/ngx_http_upstream_keepalive_module.c" +HTTP_UPSTREAM_ZONE_MODULE=ngx_http_upstream_zone_module +HTTP_UPSTREAM_ZONE_SRCS=" \ + src/http/modules/ngx_http_upstream_zone_module.c" + + MAIL_INCS="src/mail" MAIL_DEPS="src/mail/ngx_mail.h" diff -r 3264b7828f72 -r 79ddb0bdb273 src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Tue Apr 14 19:01:23 2015 +0300 +++ b/src/core/ngx_cycle.c Tue Apr 14 19:01:25 2015 +0300 @@ -441,7 +441,8 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } if (shm_zone[i].tag == oshm_zone[n].tag - && shm_zone[i].shm.size == oshm_zone[n].shm.size) + && shm_zone[i].shm.size == oshm_zone[n].shm.size + && !shm_zone[i].noreuse) { shm_zone[i].shm.addr = oshm_zone[n].shm.addr; @@ -1234,6 +1235,7 @@ ngx_shared_memory_add(ngx_conf_t *cf, ng shm_zone->shm.exists = 0; shm_zone->init = NULL; shm_zone->tag = tag; + shm_zone->noreuse = 0; return shm_zone; } diff -r 3264b7828f72 -r 79ddb0bdb273 src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h Tue Apr 14 19:01:23 2015 +0300 +++ b/src/core/ngx_cycle.h Tue Apr 14 19:01:25 2015 +0300 @@ -31,6 +31,7 @@ struct ngx_shm_zone_s { ngx_shm_t shm; ngx_shm_zone_init_pt init; void *tag; + ngx_uint_t noreuse; /* unsigned noreuse:1; */ }; diff -r 3264b7828f72 -r 79ddb0bdb273 src/core/ngx_rwlock.c --- a/src/core/ngx_rwlock.c Tue Apr 14 19:01:23 2015 +0300 +++ b/src/core/ngx_rwlock.c Tue Apr 14 19:01:25 2015 +0300 @@ -109,4 +109,12 @@ ngx_rwlock_unlock(ngx_atomic_t *lock) } +#else + +#if (NGX_HTTP_UPSTREAM_ZONE) + +#error ngx_atomic_cmp_set() is not defined! + #endif + +#endif diff -r 3264b7828f72 -r 79ddb0bdb273 src/http/modules/ngx_http_upstream_zone_module.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/http/modules/ngx_http_upstream_zone_module.c Tue Apr 14 19:01:25 2015 +0300 @@ -0,0 +1,213 @@ + +/* + * Copyright (C) Ruslan Ermilov + * Copyright (C) Nginx, Inc. + */ + + +#include +#include +#include + + +static char *ngx_http_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +static ngx_int_t ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone, + void *data); + + +static ngx_command_t ngx_http_upstream_zone_commands[] = { + + { ngx_string("zone"), + NGX_HTTP_UPS_CONF|NGX_CONF_TAKE2, + ngx_http_upstream_zone, + 0, + 0, + NULL }, + + ngx_null_command +}; + + +static ngx_http_module_t ngx_http_upstream_zone_module_ctx = { + NULL, /* preconfiguration */ + NULL, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + NULL, /* create location configuration */ + NULL /* merge location configuration */ +}; + + +ngx_module_t ngx_http_upstream_zone_module = { + NGX_MODULE_V1, + &ngx_http_upstream_zone_module_ctx, /* module context */ + ngx_http_upstream_zone_commands, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + NULL, /* init master */ + NULL, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ + NGX_MODULE_V1_PADDING +}; + + +static char * +ngx_http_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_upstream_srv_conf_t *uscf; + ssize_t size; + ngx_str_t *value; + + uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); + + value = cf->args->elts; + + if (!value[1].len) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid zone name \"%V\"", &value[1]); + return NGX_CONF_ERROR; + } + + size = ngx_parse_size(&value[2]); + + if (size == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid zone size \"%V\"", &value[2]); + return NGX_CONF_ERROR; + } + + if (size < (ssize_t) (8 * ngx_pagesize)) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "zone \"%V\" is too small", &value[1]); + return NGX_CONF_ERROR; + } + + uscf->shm_zone = ngx_shared_memory_add(cf, &value[1], size, + &ngx_http_upstream_module); + if (uscf->shm_zone == NULL) { + return NGX_CONF_ERROR; + } + + if (uscf->shm_zone->data) { + uscf = uscf->shm_zone->data; + + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "upstream \"%V\" in %s:%ui " + "is already bound to zone \"%V\"", + &uscf->host, uscf->file_name, uscf->line, + &value[1]); + return NGX_CONF_ERROR; + } + + uscf->shm_zone->init = ngx_http_upstream_init_zone; + uscf->shm_zone->data = uscf; + + uscf->shm_zone->noreuse = 1; + + return NGX_CONF_OK; +} + + +static ngx_int_t +ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data) +{ + ngx_http_upstream_srv_conf_t *ouscf = data; + + size_t len; + ngx_slab_pool_t *shpool; + ngx_http_upstream_rr_peer_t *peer, **peerp; + ngx_http_upstream_rr_peers_t *peers, *backup; + ngx_http_upstream_srv_conf_t *uscf; + + uscf = shm_zone->data; + + if (ouscf) { + ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, + "zone \"%V\" cannot be reused", &shm_zone->shm.name); + return NGX_ERROR; + } + + shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; + + if (shm_zone->shm.exists) { + return NGX_ERROR; + } + + + /* copy peers to shared memory */ + + len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len; + + shpool->log_ctx = ngx_slab_alloc(shpool, len); + if (shpool->log_ctx == NULL) { + return NGX_ERROR; + } + + ngx_sprintf(shpool->log_ctx, " in upstream zone \"%V\"%Z", + &shm_zone->shm.name); + + peers = ngx_slab_alloc(shpool, sizeof(ngx_http_upstream_rr_peers_t)); + if (peers == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(peers, uscf->peer.data, sizeof(ngx_http_upstream_rr_peers_t)); + + peers->shpool = shpool; + + for (peerp = &peers->peer; *peerp; peerp = &peer->next) { + /* pool is unlocked */ + peer = ngx_slab_calloc_locked(shpool, + sizeof(ngx_http_upstream_rr_peer_t)); + if (peer == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(peer, *peerp, sizeof(ngx_http_upstream_rr_peer_t)); + + *peerp = peer; + } + + if (peers->next == NULL) { + goto done; + } + + backup = ngx_slab_alloc(shpool, sizeof(ngx_http_upstream_rr_peers_t)); + if (backup == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(backup, peers->next, sizeof(ngx_http_upstream_rr_peers_t)); From mdounin at mdounin.ru Thu Apr 16 14:23:56 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 16 Apr 2015 17:23:56 +0300 Subject: [PATCH 1 of 6] SSL: SSL: introduce support of new openssl 1.0.2 features. In-Reply-To: References: Message-ID: <20150416142356.GV88631@mdounin.ru> Hello! On Thu, Apr 16, 2015 at 10:10:09AM +0000, Filipe DA SILVA wrote: > Hi, > > This is the new version of 'Multiple server certificate support ' patches. > > It relies on openssl to maintain a list of server certificates. > > Reviews and comments are welcome. You may want to re-read http://nginx.org/en/docs/contributing_changes.html. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Thu Apr 16 14:42:50 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 16 Apr 2015 14:42:50 +0000 Subject: [nginx] Stable branch. Message-ID: details: http://hg.nginx.org/nginx/rev/2d70fc85b3b2 branches: stable-1.8 changeset: 6104:2d70fc85b3b2 user: Maxim Dounin date: Thu Apr 16 17:00:52 2015 +0300 description: Stable branch. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1007013 -#define NGINX_VERSION "1.7.13" +#define nginx_version 1008000 +#define NGINX_VERSION "1.8.0" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From mdounin at mdounin.ru Thu Apr 16 14:42:53 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 16 Apr 2015 14:42:53 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/c1cae8b2270c branches: changeset: 6105:c1cae8b2270c user: Maxim Dounin date: Thu Apr 16 17:26:19 2015 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1007013 -#define NGINX_VERSION "1.7.13" +#define nginx_version 1009000 +#define NGINX_VERSION "1.9.0" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From pluknet at nginx.com Thu Apr 16 15:25:24 2015 From: pluknet at nginx.com (Sergey Kandaurov) Date: Thu, 16 Apr 2015 15:25:24 +0000 Subject: [nginx] Core: ensure that ngx_config.h is always included first. Message-ID: details: http://hg.nginx.org/nginx/rev/cb790d1b2d16 branches: changeset: 6106:cb790d1b2d16 user: Sergey Kandaurov date: Thu Apr 16 18:18:37 2015 +0300 description: Core: ensure that ngx_config.h is always included first. This fixes compilation of various 3rd party modules when nginx is configured with threads. diffstat: src/core/ngx_core.h | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r c1cae8b2270c -r cb790d1b2d16 src/core/ngx_core.h --- a/src/core/ngx_core.h Thu Apr 16 17:26:19 2015 +0300 +++ b/src/core/ngx_core.h Thu Apr 16 18:18:37 2015 +0300 @@ -9,6 +9,9 @@ #define _NGX_CORE_H_INCLUDED_ +#include + + typedef struct ngx_module_s ngx_module_t; typedef struct ngx_conf_s ngx_conf_t; typedef struct ngx_cycle_s ngx_cycle_t; From pluknet at nginx.com Thu Apr 16 15:57:19 2015 From: pluknet at nginx.com (Sergey Kandaurov) Date: Thu, 16 Apr 2015 18:57:19 +0300 Subject: about threads support in 1.7.11 breaking 3rd party modules In-Reply-To: <20150415080340.GB82262@lo0.su> References: <20150415080340.GB82262@lo0.su> Message-ID: On Apr 15, 2015, at 11:03 AM, Ruslan Ermilov wrote: > In version 1.7.11 we have implemented threads support, please see > http://nginx.org/r/aio for details. > > For this, we reused the NGX_THREADS macro that was unused on UNIXes > since 1.0.4 (June 2011). > > This caused some 3rd party modules fail to compile if threads were > enabled: > > https://lists.freebsd.org/pipermail/svn-ports-all/2015-April/090158.html > > The analysis have shown that breakages fall into two categories: > > 17 out of 20 broken modules failed to compile because they didn't > include before including in some cases. TWIMC, for those 3rd party modules falling into this category, we have committed a simple workaround to make users? life easier. Refer to this commit for more information: http://hg.nginx.org/nginx/rev/cb790d1b2d16 -- Sergey Kandaurov From mdounin at mdounin.ru Thu Apr 16 16:26:38 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 16 Apr 2015 16:26:38 +0000 Subject: [nginx] Core: ensure that ngx_config.h is always included first. Message-ID: details: http://hg.nginx.org/nginx/rev/db08fed33195 branches: stable-1.8 changeset: 6107:db08fed33195 user: Sergey Kandaurov date: Thu Apr 16 18:18:37 2015 +0300 description: Core: ensure that ngx_config.h is always included first. This fixes compilation of various 3rd party modules when nginx is configured with threads. diffstat: src/core/ngx_core.h | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -9,6 +9,9 @@ #define _NGX_CORE_H_INCLUDED_ +#include + + typedef struct ngx_module_s ngx_module_t; typedef struct ngx_conf_s ngx_conf_t; typedef struct ngx_cycle_s ngx_cycle_t; From ru at nginx.com Thu Apr 16 17:09:54 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 17:09:54 +0000 Subject: [nginx] Upstream: get rid of questionable micro-optimization in ... Message-ID: details: http://hg.nginx.org/nginx/rev/55dc5f7eb921 branches: changeset: 6108:55dc5f7eb921 user: Ruslan Ermilov date: Thu Apr 16 20:09:11 2015 +0300 description: Upstream: get rid of questionable micro-optimization in ip_hash. If a peer was initially skipped due to max_fails, there's no reason not to try it again if enough time has passed, and the next_upstream logic is in action. This also reduces diffs with NGINX Plus. diffstat: src/http/modules/ngx_http_upstream_ip_hash_module.c | 9 ++------- 1 files changed, 2 insertions(+), 7 deletions(-) diffs (29 lines): diff -r cb790d1b2d16 -r 55dc5f7eb921 src/http/modules/ngx_http_upstream_ip_hash_module.c --- a/src/http/modules/ngx_http_upstream_ip_hash_module.c Thu Apr 16 18:18:37 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c Thu Apr 16 20:09:11 2015 +0300 @@ -216,23 +216,18 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p "get ip hash peer, hash: %ui %04XA", p, m); if (peer->down) { - goto next_try; + goto next; } if (peer->max_fails && peer->fails >= peer->max_fails && now - peer->checked <= peer->fail_timeout) { - goto next_try; + goto next; } break; - next_try: - - iphp->rrp.tried[n] |= m; - pc->tries--; - next: if (++iphp->tries > 20) { From ru at nginx.com Thu Apr 16 20:01:58 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 20:01:58 +0000 Subject: [nginx] Removed ngx_threaded and related code. Message-ID: details: http://hg.nginx.org/nginx/rev/d588dda5ec31 branches: changeset: 6109:d588dda5ec31 user: Ruslan Ermilov date: Thu Mar 26 14:15:13 2015 +0300 description: Removed ngx_threaded and related code. diffstat: src/core/ngx_regex.c | 37 ------------------------------------- src/os/win32/ngx_process_cycle.c | 1 - src/os/win32/ngx_process_cycle.h | 1 - 3 files changed, 0 insertions(+), 39 deletions(-) diffs (85 lines): diff -r 55dc5f7eb921 -r d588dda5ec31 src/core/ngx_regex.c --- a/src/core/ngx_regex.c Thu Apr 16 20:09:11 2015 +0300 +++ b/src/core/ngx_regex.c Thu Mar 26 14:15:13 2015 +0300 @@ -80,17 +80,6 @@ ngx_regex_init(void) static ngx_inline void ngx_regex_malloc_init(ngx_pool_t *pool) { -#if (NGX_OLD_THREADS) - ngx_core_tls_t *tls; - - if (ngx_threaded) { - tls = ngx_thread_get_tls(ngx_core_tls_key); - tls->pool = pool; - return; - } - -#endif - ngx_pcre_pool = pool; } @@ -98,17 +87,6 @@ ngx_regex_malloc_init(ngx_pool_t *pool) static ngx_inline void ngx_regex_malloc_done(void) { -#if (NGX_OLD_THREADS) - ngx_core_tls_t *tls; - - if (ngx_threaded) { - tls = ngx_thread_get_tls(ngx_core_tls_key); - tls->pool = NULL; - return; - } - -#endif - ngx_pcre_pool = NULL; } @@ -253,23 +231,8 @@ static void * ngx_libc_cdecl ngx_regex_malloc(size_t size) { ngx_pool_t *pool; -#if (NGX_OLD_THREADS) - ngx_core_tls_t *tls; - - if (ngx_threaded) { - tls = ngx_thread_get_tls(ngx_core_tls_key); - pool = tls->pool; - - } else { - pool = ngx_pcre_pool; - } - -#else - pool = ngx_pcre_pool; -#endif - if (pool) { return ngx_palloc(pool, size); } diff -r 55dc5f7eb921 -r d588dda5ec31 src/os/win32/ngx_process_cycle.c --- a/src/os/win32/ngx_process_cycle.c Thu Apr 16 20:09:11 2015 +0300 +++ b/src/os/win32/ngx_process_cycle.c Thu Mar 26 14:15:13 2015 +0300 @@ -31,7 +31,6 @@ static ngx_thread_value_t __stdcall ngx_ ngx_uint_t ngx_process; ngx_pid_t ngx_pid; -ngx_uint_t ngx_threaded; ngx_uint_t ngx_inherited; ngx_pid_t ngx_new_binary; diff -r 55dc5f7eb921 -r d588dda5ec31 src/os/win32/ngx_process_cycle.h --- a/src/os/win32/ngx_process_cycle.h Thu Apr 16 20:09:11 2015 +0300 +++ b/src/os/win32/ngx_process_cycle.h Thu Mar 26 14:15:13 2015 +0300 @@ -26,7 +26,6 @@ void ngx_close_handle(HANDLE h); extern ngx_uint_t ngx_process; extern ngx_pid_t ngx_pid; -extern ngx_uint_t ngx_threaded; extern ngx_uint_t ngx_exiting; extern sig_atomic_t ngx_quit; From ru at nginx.com Thu Apr 16 20:02:02 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 20:02:02 +0000 Subject: [nginx] Removed unused thread-local-storage code. Message-ID: details: http://hg.nginx.org/nginx/rev/16c51e80128c branches: changeset: 6110:16c51e80128c user: Ruslan Ermilov date: Thu Mar 26 14:15:15 2015 +0300 description: Removed unused thread-local-storage code. diffstat: src/core/ngx_cycle.c | 4 ---- src/core/ngx_cycle.h | 12 ------------ src/os/win32/ngx_process_cycle.c | 9 --------- src/os/win32/ngx_thread.c | 24 ------------------------ src/os/win32/ngx_thread.h | 7 ------- 5 files changed, 0 insertions(+), 56 deletions(-) diffs (124 lines): diff -r d588dda5ec31 -r 16c51e80128c src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Thu Mar 26 14:15:13 2015 +0300 +++ b/src/core/ngx_cycle.c Thu Mar 26 14:15:15 2015 +0300 @@ -26,10 +26,6 @@ static ngx_event_t ngx_cleaner_event ngx_uint_t ngx_test_config; ngx_uint_t ngx_quiet_mode; -#if (NGX_OLD_THREADS) -ngx_tls_key_t ngx_core_tls_key; -#endif - /* STUB NAME */ static ngx_connection_t dumb; diff -r d588dda5ec31 -r 16c51e80128c src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h Thu Mar 26 14:15:13 2015 +0300 +++ b/src/core/ngx_cycle.h Thu Mar 26 14:15:15 2015 +0300 @@ -112,15 +112,6 @@ typedef struct { } ngx_core_conf_t; -#if (NGX_OLD_THREADS) - -typedef struct { - ngx_pool_t *pool; /* pcre's malloc() pool */ -} ngx_core_tls_t; - -#endif - - #define ngx_is_init_cycle(cycle) (cycle->conf_ctx == NULL) @@ -141,9 +132,6 @@ extern ngx_array_t ngx_old_cy extern ngx_module_t ngx_core_module; extern ngx_uint_t ngx_test_config; extern ngx_uint_t ngx_quiet_mode; -#if (NGX_OLD_THREADS) -extern ngx_tls_key_t ngx_core_tls_key; -#endif #endif /* _NGX_CYCLE_H_INCLUDED_ */ diff -r d588dda5ec31 -r 16c51e80128c src/os/win32/ngx_process_cycle.c --- a/src/os/win32/ngx_process_cycle.c Thu Mar 26 14:15:13 2015 +0300 +++ b/src/os/win32/ngx_process_cycle.c Thu Mar 26 14:15:15 2015 +0300 @@ -253,7 +253,6 @@ ngx_master_process_cycle(ngx_cycle_t *cy static void ngx_process_init(ngx_cycle_t *cycle) { - ngx_err_t err; ngx_core_conf_t *ccf; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); @@ -264,14 +263,6 @@ ngx_process_init(ngx_cycle_t *cycle) /* fatal */ exit(2); } - - err = ngx_thread_key_create(&ngx_core_tls_key); - if (err != 0) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, err, - ngx_thread_key_create_n " failed"); - /* fatal */ - exit(2); - } } diff -r d588dda5ec31 -r 16c51e80128c src/os/win32/ngx_thread.c --- a/src/os/win32/ngx_thread.c Thu Mar 26 14:15:13 2015 +0300 +++ b/src/os/win32/ngx_thread.c Thu Mar 26 14:15:15 2015 +0300 @@ -43,27 +43,3 @@ ngx_init_threads(int n, size_t size, ngx return NGX_OK; } - - -ngx_err_t -ngx_thread_key_create(ngx_tls_key_t *key) -{ - *key = TlsAlloc(); - - if (*key == TLS_OUT_OF_INDEXES) { - return ngx_errno; - } - - return 0; -} - - -ngx_err_t -ngx_thread_set_tls(ngx_tls_key_t *key, void *data) -{ - if (TlsSetValue(*key, data) == 0) { - return ngx_errno; - } - - return 0; -} diff -r d588dda5ec31 -r 16c51e80128c src/os/win32/ngx_thread.h --- a/src/os/win32/ngx_thread.h Thu Mar 26 14:15:13 2015 +0300 +++ b/src/os/win32/ngx_thread.h Thu Mar 26 14:15:15 2015 +0300 @@ -14,7 +14,6 @@ typedef HANDLE ngx_tid_t; -typedef DWORD ngx_tls_key_t; typedef DWORD ngx_thread_value_t; @@ -22,12 +21,6 @@ ngx_err_t ngx_create_thread(ngx_tid_t *t ngx_thread_value_t (__stdcall *func)(void *arg), void *arg, ngx_log_t *log); ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle); -ngx_err_t ngx_thread_key_create(ngx_tls_key_t *key); -#define ngx_thread_key_create_n "TlsAlloc()" -ngx_err_t ngx_thread_set_tls(ngx_tls_key_t *key, void *data); -#define ngx_thread_set_tls_n "TlsSetValue()" -#define ngx_thread_get_tls TlsGetValue - #define ngx_log_tid GetCurrentThreadId() #define NGX_TID_T_FMT "%ud" From ru at nginx.com Thu Apr 16 20:02:04 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 20:02:04 +0000 Subject: [nginx] Removed "worker_threads" and "thread_stack_size" directi... Message-ID: details: http://hg.nginx.org/nginx/rev/537259db5af4 branches: changeset: 6111:537259db5af4 user: Ruslan Ermilov date: Thu Mar 26 14:15:17 2015 +0300 description: Removed "worker_threads" and "thread_stack_size" directives. diffstat: src/core/nginx.c | 31 ------------------------------- src/core/ngx_cycle.h | 6 ------ src/os/win32/ngx_process_cycle.c | 21 --------------------- src/os/win32/ngx_thread.c | 17 +---------------- src/os/win32/ngx_thread.h | 4 ---- 5 files changed, 1 insertions(+), 78 deletions(-) diffs (178 lines): diff -r 16c51e80128c -r 537259db5af4 src/core/nginx.c --- a/src/core/nginx.c Thu Mar 26 14:15:15 2015 +0300 +++ b/src/core/nginx.c Thu Mar 26 14:15:17 2015 +0300 @@ -139,24 +139,6 @@ static ngx_command_t ngx_core_commands[ 0, NULL }, -#if (NGX_OLD_THREADS) - - { ngx_string("worker_threads"), - NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_core_conf_t, worker_threads), - NULL }, - - { ngx_string("thread_stack_size"), - NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - 0, - offsetof(ngx_core_conf_t, thread_stack_size), - NULL }, - -#endif - ngx_null_command }; @@ -971,11 +953,6 @@ ngx_core_module_create_conf(ngx_cycle_t ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT; ccf->group = (ngx_gid_t) NGX_CONF_UNSET_UINT; -#if (NGX_OLD_THREADS) - ccf->worker_threads = NGX_CONF_UNSET; - ccf->thread_stack_size = NGX_CONF_UNSET_SIZE; -#endif - if (ngx_array_init(&ccf->env, cycle->pool, 1, sizeof(ngx_str_t)) != NGX_OK) { @@ -1012,14 +989,6 @@ ngx_core_module_init_conf(ngx_cycle_t *c #endif -#if (NGX_OLD_THREADS) - - ngx_conf_init_value(ccf->worker_threads, 0); - ngx_threads_n = ccf->worker_threads; - ngx_conf_init_size_value(ccf->thread_stack_size, 2 * 1024 * 1024); - -#endif - if (ccf->pid.len == 0) { ngx_str_set(&ccf->pid, NGX_PID_PATH); diff -r 16c51e80128c -r 537259db5af4 src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h Thu Mar 26 14:15:15 2015 +0300 +++ b/src/core/ngx_cycle.h Thu Mar 26 14:15:17 2015 +0300 @@ -103,12 +103,6 @@ typedef struct { ngx_array_t env; char **environment; - -#if (NGX_OLD_THREADS) - ngx_int_t worker_threads; - size_t thread_stack_size; -#endif - } ngx_core_conf_t; diff -r 16c51e80128c -r 537259db5af4 src/os/win32/ngx_process_cycle.c --- a/src/os/win32/ngx_process_cycle.c Thu Mar 26 14:15:15 2015 +0300 +++ b/src/os/win32/ngx_process_cycle.c Thu Mar 26 14:15:17 2015 +0300 @@ -11,7 +11,6 @@ #include -static void ngx_process_init(ngx_cycle_t *cycle); static void ngx_console_init(ngx_cycle_t *cycle); static int __stdcall ngx_console_handler(u_long type); static ngx_int_t ngx_create_signal_events(ngx_cycle_t *cycle); @@ -69,8 +68,6 @@ ngx_master_process_cycle(ngx_cycle_t *cy ngx_uint_t live; HANDLE events[MAXIMUM_WAIT_OBJECTS]; - ngx_process_init(cycle); - ngx_sprintf((u_char *) ngx_master_process_event_name, "ngx_master_%s%Z", ngx_unique); @@ -251,22 +248,6 @@ ngx_master_process_cycle(ngx_cycle_t *cy static void -ngx_process_init(ngx_cycle_t *cycle) -{ - ngx_core_conf_t *ccf; - - ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); - - if (ngx_init_threads(ngx_threads_n, ccf->thread_stack_size, cycle) - != NGX_OK) - { - /* fatal */ - exit(2); - } -} - - -static void ngx_console_init(ngx_cycle_t *cycle) { ngx_core_conf_t *ccf; @@ -1016,8 +997,6 @@ ngx_single_process_cycle(ngx_cycle_t *cy { ngx_tid_t tid; - ngx_process_init(cycle); - ngx_console_init(cycle); if (ngx_create_signal_events(cycle) != NGX_OK) { diff -r 16c51e80128c -r 537259db5af4 src/os/win32/ngx_thread.c --- a/src/os/win32/ngx_thread.c Thu Mar 26 14:15:15 2015 +0300 +++ b/src/os/win32/ngx_thread.c Thu Mar 26 14:15:17 2015 +0300 @@ -9,12 +9,6 @@ #include -ngx_int_t ngx_threads_n; - - -static size_t stack_size; - - ngx_err_t ngx_create_thread(ngx_tid_t *tid, ngx_thread_value_t (__stdcall *func)(void *arg), void *arg, ngx_log_t *log) @@ -22,7 +16,7 @@ ngx_create_thread(ngx_tid_t *tid, u_long id; ngx_err_t err; - *tid = CreateThread(NULL, stack_size, func, arg, 0, &id); + *tid = CreateThread(NULL, 0, func, arg, 0, &id); if (*tid != NULL) { ngx_log_error(NGX_LOG_NOTICE, log, 0, @@ -34,12 +28,3 @@ ngx_create_thread(ngx_tid_t *tid, ngx_log_error(NGX_LOG_ALERT, log, err, "CreateThread() failed"); return err; } - - -ngx_int_t -ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle) -{ - stack_size = size; - - return NGX_OK; -} diff -r 16c51e80128c -r 537259db5af4 src/os/win32/ngx_thread.h --- a/src/os/win32/ngx_thread.h Thu Mar 26 14:15:15 2015 +0300 +++ b/src/os/win32/ngx_thread.h Thu Mar 26 14:15:17 2015 +0300 @@ -19,13 +19,9 @@ typedef DWORD ngx_thread_value_t; ngx_err_t ngx_create_thread(ngx_tid_t *tid, ngx_thread_value_t (__stdcall *func)(void *arg), void *arg, ngx_log_t *log); -ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle); #define ngx_log_tid GetCurrentThreadId() #define NGX_TID_T_FMT "%ud" -extern ngx_int_t ngx_threads_n; - - #endif /* _NGX_THREAD_H_INCLUDED_ */ From ru at nginx.com Thu Apr 16 20:02:12 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 20:02:12 +0000 Subject: [nginx] Removed NGX_OLD_THREADS from select and poll modules. Message-ID: details: http://hg.nginx.org/nginx/rev/8c79c506ea20 branches: changeset: 6112:8c79c506ea20 user: Ruslan Ermilov date: Thu Mar 26 14:20:07 2015 +0300 description: Removed NGX_OLD_THREADS from select and poll modules. These modules can't be compiled on win32. diffstat: src/event/modules/ngx_poll_module.c | 10 ---------- src/event/modules/ngx_select_module.c | 10 ---------- 2 files changed, 0 insertions(+), 20 deletions(-) diffs (38 lines): diff -r 537259db5af4 -r 8c79c506ea20 src/event/modules/ngx_poll_module.c --- a/src/event/modules/ngx_poll_module.c Thu Mar 26 14:15:17 2015 +0300 +++ b/src/event/modules/ngx_poll_module.c Thu Mar 26 14:20:07 2015 +0300 @@ -413,15 +413,5 @@ ngx_poll_init_conf(ngx_cycle_t *cycle, v return NGX_CONF_OK; } -#if (NGX_OLD_THREADS) - - ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, - "poll() is not supported in the threaded mode"); - return NGX_CONF_ERROR; - -#else - return NGX_CONF_OK; - -#endif } diff -r 537259db5af4 -r 8c79c506ea20 src/event/modules/ngx_select_module.c --- a/src/event/modules/ngx_select_module.c Thu Mar 26 14:15:17 2015 +0300 +++ b/src/event/modules/ngx_select_module.c Thu Mar 26 14:20:07 2015 +0300 @@ -419,15 +419,5 @@ ngx_select_init_conf(ngx_cycle_t *cycle, return NGX_CONF_ERROR; } -#if (NGX_OLD_THREADS) - - ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, - "select() is not supported in the threaded mode"); - return NGX_CONF_ERROR; - -#else - return NGX_CONF_OK; - -#endif } From ru at nginx.com Thu Apr 16 20:02:19 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 16 Apr 2015 20:02:19 +0000 Subject: [nginx] Replaced the remaining NGX_OLD_THREADS check with NGX_WI... Message-ID: details: http://hg.nginx.org/nginx/rev/36d99c042652 branches: changeset: 6113:36d99c042652 user: Ruslan Ermilov date: Thu Mar 26 14:20:51 2015 +0300 description: Replaced the remaining NGX_OLD_THREADS check with NGX_WIN32. diffstat: src/event/ngx_event.c | 4 +++- src/os/win32/ngx_win32_config.h | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (26 lines): diff -r 8c79c506ea20 -r 36d99c042652 src/event/ngx_event.c --- a/src/event/ngx_event.c Thu Mar 26 14:20:07 2015 +0300 +++ b/src/event/ngx_event.c Thu Mar 26 14:20:51 2015 +0300 @@ -212,7 +212,9 @@ ngx_process_events_and_timers(ngx_cycle_ timer = ngx_event_find_timer(); flags = NGX_UPDATE_TIME; -#if (NGX_OLD_THREADS) +#if (NGX_WIN32) + + /* handle signals from master in case of network inactivity */ if (timer == NGX_TIMER_INFINITE || timer > 500) { timer = 500; diff -r 8c79c506ea20 -r 36d99c042652 src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h Thu Mar 26 14:20:07 2015 +0300 +++ b/src/os/win32/ngx_win32_config.h Thu Mar 26 14:20:51 2015 +0300 @@ -218,8 +218,6 @@ typedef int sig_atomic_t #define NGX_HAVE_LITTLE_ENDIAN 1 #define NGX_HAVE_NONALIGNED 1 -#define NGX_OLD_THREADS 1 - #define NGX_WIN_NT 200000 From ru at nginx.com Sun Apr 19 19:41:35 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Sun, 19 Apr 2015 19:41:35 +0000 Subject: [nginx] Upstream: fixed unlocked access to peer->conns. Message-ID: details: http://hg.nginx.org/nginx/rev/4a640716f4e2 branches: changeset: 6114:4a640716f4e2 user: Ruslan Ermilov date: Sun Apr 19 22:41:09 2015 +0300 description: Upstream: fixed unlocked access to peer->conns. diffstat: src/http/ngx_http_upstream_round_robin.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diffs (27 lines): diff -r 36d99c042652 -r 4a640716f4e2 src/http/ngx_http_upstream_round_robin.c --- a/src/http/ngx_http_upstream_round_robin.c Thu Mar 26 14:20:51 2015 +0300 +++ b/src/http/ngx_http_upstream_round_robin.c Sun Apr 19 22:41:09 2015 +0300 @@ -599,17 +599,20 @@ ngx_http_upstream_free_round_robin_peer( peer = rrp->current; + ngx_http_upstream_rr_peers_rlock(rrp->peers); + ngx_http_upstream_rr_peer_lock(rrp->peers, peer); + if (rrp->peers->single) { peer->conns--; + ngx_http_upstream_rr_peer_unlock(rrp->peers, peer); + ngx_http_upstream_rr_peers_unlock(rrp->peers); + pc->tries = 0; return; } - ngx_http_upstream_rr_peers_rlock(rrp->peers); - ngx_http_upstream_rr_peer_lock(rrp->peers, peer); - if (state & NGX_PEER_FAILED) { now = ngx_time(); From ru at nginx.com Mon Apr 20 12:16:29 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 20 Apr 2015 12:16:29 +0000 Subject: [nginx] Stream: port from NGINX+. Message-ID: details: http://hg.nginx.org/nginx/rev/61d7ae76647d branches: changeset: 6115:61d7ae76647d user: Ruslan Ermilov date: Mon Apr 20 13:05:11 2015 +0300 description: Stream: port from NGINX+. diffstat: auto/make | 57 + auto/modules | 36 + auto/options | 24 + auto/sources | 34 + src/core/ngx_log.c | 2 +- src/core/ngx_log.h | 3 +- src/stream/ngx_stream.c | 557 ++++++++ src/stream/ngx_stream.h | 215 +++ src/stream/ngx_stream_core_module.c | 495 +++++++ src/stream/ngx_stream_handler.c | 296 ++++ src/stream/ngx_stream_proxy_module.c | 1288 ++++++++++++++++++++ src/stream/ngx_stream_ssl_module.c | 456 +++++++ src/stream/ngx_stream_ssl_module.h | 49 + src/stream/ngx_stream_upstream.c | 462 +++++++ src/stream/ngx_stream_upstream.h | 103 + src/stream/ngx_stream_upstream_hash_module.c | 657 ++++++++++ src/stream/ngx_stream_upstream_least_conn_module.c | 305 ++++ src/stream/ngx_stream_upstream_round_robin.c | 697 ++++++++++ src/stream/ngx_stream_upstream_round_robin.h | 138 ++ src/stream/ngx_stream_upstream_zone_module.c | 207 +++ 20 files changed, 6079 insertions(+), 2 deletions(-) diffs (truncated from 6239 to 300 lines): diff -r 4a640716f4e2 -r 61d7ae76647d auto/make --- a/auto/make Sun Apr 19 22:41:09 2015 +0300 +++ b/auto/make Mon Apr 20 13:05:11 2015 +0300 @@ -10,6 +10,7 @@ mkdir -p $NGX_OBJS/src/core $NGX_OBJS/sr $NGX_OBJS/src/http $NGX_OBJS/src/http/modules \ $NGX_OBJS/src/http/modules/perl \ $NGX_OBJS/src/mail \ + $NGX_OBJS/src/stream \ $NGX_OBJS/src/misc @@ -121,6 +122,32 @@ END fi +# the stream dependences and include paths + +if [ $STREAM = YES ]; then + + ngx_all_srcs="$ngx_all_srcs $STREAM_SRCS" + + ngx_deps=`echo $STREAM_DEPS \ + | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \ + -e "s/\//$ngx_regex_dirsep/g"` + + ngx_incs=`echo $STREAM_INCS \ + | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \ + -e "s/\//$ngx_regex_dirsep/g"` + + cat << END >> $NGX_MAKEFILE + +STREAM_DEPS = $ngx_deps + + +STREAM_INCS = $ngx_include_opt$ngx_incs + +END + +fi + + ngx_all_srcs="$ngx_all_srcs $NGX_MISC_SRCS" @@ -306,6 +333,36 @@ END fi +# the stream sources + +if [ $STREAM = YES ]; then + + if test -n "$NGX_PCH"; then + ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)" + else + ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(STREAM_INCS)" + fi + + for ngx_src in $STREAM_SRCS + do + ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"` + ngx_obj=`echo $ngx_src \ + | sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \ + -e "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \ + -e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \ + -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"` + + cat << END >> $NGX_MAKEFILE + +$ngx_obj: \$(CORE_DEPS) \$(STREAM_DEPS)$ngx_cont$ngx_src + $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX + +END + done + +fi + + # the misc sources if test -n "$NGX_MISC_SRCS"; then diff -r 4a640716f4e2 -r 61d7ae76647d auto/modules --- a/auto/modules Sun Apr 19 22:41:09 2015 +0300 +++ b/auto/modules Mon Apr 20 13:05:11 2015 +0300 @@ -435,6 +435,12 @@ if [ $MAIL_SSL = YES ]; then fi +if [ $STREAM_SSL = YES ]; then + have=NGX_STREAM_SSL . auto/have + USE_OPENSSL=YES +fi + + modules="$CORE_MODULES $EVENT_MODULES" @@ -505,6 +511,36 @@ if [ $MAIL = YES ]; then fi +if [ $STREAM = YES ]; then + have=NGX_STREAM . auto/have + modules="$modules $STREAM_MODULES" + + if [ $STREAM_SSL = YES ]; then + modules="$modules $STREAM_SSL_MODULE" + STREAM_DEPS="$STREAM_DEPS $STREAM_SSL_DEPS" + STREAM_SRCS="$STREAM_SRCS $STREAM_SSL_SRCS" + fi + + if [ $STREAM_UPSTREAM_HASH = YES ]; then + modules="$modules $STREAM_UPSTREAM_HASH_MODULE" + STREAM_SRCS="$STREAM_SRCS $STREAM_UPSTREAM_HASH_SRCS" + fi + + if [ $STREAM_UPSTREAM_LEAST_CONN = YES ]; then + modules="$modules $STREAM_UPSTREAM_LEAST_CONN_MODULE" + STREAM_SRCS="$STREAM_SRCS $STREAM_UPSTREAM_LEAST_CONN_SRCS" + fi + + if [ $STREAM_UPSTREAM_ZONE = YES ]; then + have=NGX_STREAM_UPSTREAM_ZONE . auto/have + modules="$modules $STREAM_UPSTREAM_ZONE_MODULE" + STREAM_SRCS="$STREAM_SRCS $STREAM_UPSTREAM_ZONE_SRCS" + fi + + NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(STREAM_DEPS)" +fi + + if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then modules="$modules $NGX_GOOGLE_PERFTOOLS_MODULE" NGX_MISC_SRCS="$NGX_MISC_SRCS $NGX_GOOGLE_PERFTOOLS_SRCS" diff -r 4a640716f4e2 -r 61d7ae76647d auto/options --- a/auto/options Sun Apr 19 22:41:09 2015 +0300 +++ b/auto/options Mon Apr 20 13:05:11 2015 +0300 @@ -114,6 +114,12 @@ MAIL_POP3=YES MAIL_IMAP=YES MAIL_SMTP=YES +STREAM=NO +STREAM_SSL=NO +STREAM_UPSTREAM_HASH=YES +STREAM_UPSTREAM_LEAST_CONN=YES +STREAM_UPSTREAM_ZONE=YES + NGX_ADDONS= USE_PCRE=NO @@ -275,6 +281,15 @@ use the \"--without-http_limit_conn_modu --without-mail_imap_module) MAIL_IMAP=NO ;; --without-mail_smtp_module) MAIL_SMTP=NO ;; + --with-stream) STREAM=YES ;; + --with-stream_ssl_module) STREAM_SSL=YES ;; + --without-stream_upstream_hash_module) + STREAM_UPSTREAM_HASH=NO ;; + --without-stream_upstream_least_conn_module) + STREAM_UPSTREAM_LEAST_CONN=NO ;; + --without-stream_upstream_zone_module) + STREAM_UPSTREAM_ZONE=NO ;; + --with-google_perftools_module) NGX_GOOGLE_PERFTOOLS=YES ;; --with-cpp_test_module) NGX_CPP_TEST=YES ;; @@ -436,6 +451,15 @@ cat << END --without-mail_imap_module disable ngx_mail_imap_module --without-mail_smtp_module disable ngx_mail_smtp_module + --with-stream enable TCP proxy module + --with-stream_ssl_module enable ngx_stream_ssl_module + --without-stream_upstream_hash_module + disable ngx_stream_upstream_hash_module + --without-stream_upstream_least_conn_module + disable ngx_stream_upstream_least_conn_module + --without-stream_upstream_zone_module + disable ngx_stream_upstream_zone_module + --with-google_perftools_module enable ngx_google_perftools_module --with-cpp_test_module enable ngx_cpp_test_module diff -r 4a640716f4e2 -r 61d7ae76647d auto/sources --- a/auto/sources Sun Apr 19 22:41:09 2015 +0300 +++ b/auto/sources Mon Apr 20 13:05:11 2015 +0300 @@ -554,6 +554,40 @@ MAIL_AUTH_HTTP_SRCS="src/mail/ngx_mail_a MAIL_PROXY_MODULE="ngx_mail_proxy_module" MAIL_PROXY_SRCS="src/mail/ngx_mail_proxy_module.c" + +STREAM_INCS="src/stream" + +STREAM_DEPS="src/stream/ngx_stream.h \ + src/stream/ngx_stream_upstream.h \ + src/stream/ngx_stream_upstream_round_robin.h" + +STREAM_MODULES="ngx_stream_module \ + ngx_stream_core_module \ + ngx_stream_proxy_module \ + ngx_stream_upstream_module" + +STREAM_SRCS="src/stream/ngx_stream.c \ + src/stream/ngx_stream_handler.c \ + src/stream/ngx_stream_core_module.c \ + src/stream/ngx_stream_proxy_module.c \ + src/stream/ngx_stream_upstream.c \ + src/stream/ngx_stream_upstream_round_robin.c" + +STREAM_SSL_MODULE="ngx_stream_ssl_module" +STREAM_SSL_DEPS="src/stream/ngx_stream_ssl_module.h" +STREAM_SSL_SRCS="src/stream/ngx_stream_ssl_module.c" + +STREAM_UPSTREAM_HASH_MODULE=ngx_stream_upstream_hash_module +STREAM_UPSTREAM_HASH_SRCS=src/stream/ngx_stream_upstream_hash_module.c + +STREAM_UPSTREAM_LEAST_CONN_MODULE=ngx_stream_upstream_least_conn_module +STREAM_UPSTREAM_LEAST_CONN_SRCS=" \ + src/stream/ngx_stream_upstream_least_conn_module.c" + +STREAM_UPSTREAM_ZONE_MODULE=ngx_stream_upstream_zone_module +STREAM_UPSTREAM_ZONE_SRCS=src/stream/ngx_stream_upstream_zone_module.c + + NGX_GOOGLE_PERFTOOLS_MODULE=ngx_google_perftools_module NGX_GOOGLE_PERFTOOLS_SRCS=src/misc/ngx_google_perftools_module.c diff -r 4a640716f4e2 -r 61d7ae76647d src/core/ngx_log.c --- a/src/core/ngx_log.c Sun Apr 19 22:41:09 2015 +0300 +++ b/src/core/ngx_log.c Mon Apr 20 13:05:11 2015 +0300 @@ -86,7 +86,7 @@ static ngx_str_t err_levels[] = { static const char *debug_levels[] = { "debug_core", "debug_alloc", "debug_mutex", "debug_event", - "debug_http", "debug_mail", "debug_mysql" + "debug_http", "debug_mail", "debug_mysql", "debug_stream" }; diff -r 4a640716f4e2 -r 61d7ae76647d src/core/ngx_log.h --- a/src/core/ngx_log.h Sun Apr 19 22:41:09 2015 +0300 +++ b/src/core/ngx_log.h Mon Apr 20 13:05:11 2015 +0300 @@ -30,6 +30,7 @@ #define NGX_LOG_DEBUG_HTTP 0x100 #define NGX_LOG_DEBUG_MAIL 0x200 #define NGX_LOG_DEBUG_MYSQL 0x400 +#define NGX_LOG_DEBUG_STREAM 0x800 /* * do not forget to update debug_levels[] in src/core/ngx_log.c @@ -37,7 +38,7 @@ */ #define NGX_LOG_DEBUG_FIRST NGX_LOG_DEBUG_CORE -#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_MYSQL +#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_STREAM #define NGX_LOG_DEBUG_CONNECTION 0x80000000 #define NGX_LOG_DEBUG_ALL 0x7ffffff0 diff -r 4a640716f4e2 -r 61d7ae76647d src/stream/ngx_stream.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/stream/ngx_stream.c Mon Apr 20 13:05:11 2015 +0300 @@ -0,0 +1,557 @@ + +/* + * Copyright (C) Roman Arutyunyan + * Copyright (C) Nginx, Inc. + */ + + +#include +#include +#include +#include + + +static char *ngx_stream_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static ngx_int_t ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports, + ngx_stream_listen_t *listen); +static char *ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports); +static ngx_int_t ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport, + ngx_stream_conf_addr_t *addr); +#if (NGX_HAVE_INET6) +static ngx_int_t ngx_stream_add_addrs6(ngx_conf_t *cf, + ngx_stream_port_t *stport, ngx_stream_conf_addr_t *addr); +#endif +static ngx_int_t ngx_stream_cmp_conf_addrs(const void *one, const void *two); + + +ngx_uint_t ngx_stream_max_module; + + +static ngx_command_t ngx_stream_commands[] = { + + { ngx_string("stream"), + NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, + ngx_stream_block, + 0, + 0, + NULL }, + From pluknet at nginx.com Mon Apr 20 13:59:41 2015 From: pluknet at nginx.com (Sergey Kandaurov) Date: Mon, 20 Apr 2015 13:59:41 +0000 Subject: [nginx] Core: allow shared memory size to be declared after a re... Message-ID: details: http://hg.nginx.org/nginx/rev/48b3d5ddfb03 branches: changeset: 6116:48b3d5ddfb03 user: Sergey Kandaurov date: Mon Apr 20 16:53:04 2015 +0300 description: Core: allow shared memory size to be declared after a reference. For example, this fixes the case when "proxy_cache_path" is specified after "proxy_cache" that references it. diffstat: src/core/ngx_cycle.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r 61d7ae76647d -r 48b3d5ddfb03 src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Mon Apr 20 13:05:11 2015 +0300 +++ b/src/core/ngx_cycle.c Mon Apr 20 16:53:04 2015 +0300 @@ -1207,6 +1207,10 @@ ngx_shared_memory_add(ngx_conf_t *cf, ng return NULL; } + if (shm_zone[i].shm.size == 0) { + shm_zone[i].shm.size = size; + } + if (size && size != shm_zone[i].shm.size) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the size %uz of shared memory zone \"%V\" " From pluknet at nginx.com Mon Apr 20 13:59:44 2015 From: pluknet at nginx.com (Sergey Kandaurov) Date: Mon, 20 Apr 2015 13:59:44 +0000 Subject: [nginx] Limit req: removed check for unknown limit_req_zone. Message-ID: details: http://hg.nginx.org/nginx/rev/3b7a60371a9a branches: changeset: 6117:3b7a60371a9a user: Sergey Kandaurov date: Mon Apr 20 16:54:41 2015 +0300 description: Limit req: removed check for unknown limit_req_zone. With 48b3d5ddfb03, it's possible to specify limit_req_zone after limit_req. diffstat: src/http/modules/ngx_http_limit_req_module.c | 7 ------- 1 files changed, 0 insertions(+), 7 deletions(-) diffs (17 lines): diff -r 48b3d5ddfb03 -r 3b7a60371a9a src/http/modules/ngx_http_limit_req_module.c --- a/src/http/modules/ngx_http_limit_req_module.c Mon Apr 20 16:53:04 2015 +0300 +++ b/src/http/modules/ngx_http_limit_req_module.c Mon Apr 20 16:54:41 2015 +0300 @@ -919,13 +919,6 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c return NGX_CONF_ERROR; } - if (shm_zone->data == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "unknown limit_req_zone \"%V\"", - &shm_zone->shm.name); - return NGX_CONF_ERROR; - } - limits = lrcf->limits.elts; if (limits == NULL) { From pluknet at nginx.com Tue Apr 21 07:14:54 2015 From: pluknet at nginx.com (Sergey Kandaurov) Date: Tue, 21 Apr 2015 07:14:54 +0000 Subject: [nginx] Fixed building --with-stream when precompiled headers ar... Message-ID: details: http://hg.nginx.org/nginx/rev/1bdfceda86a9 branches: changeset: 6118:1bdfceda86a9 user: Sergey Kandaurov date: Mon Apr 20 17:36:51 2015 +0300 description: Fixed building --with-stream when precompiled headers are used. diffstat: auto/make | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 3b7a60371a9a -r 1bdfceda86a9 auto/make --- a/auto/make Mon Apr 20 16:54:41 2015 +0300 +++ b/auto/make Mon Apr 20 17:36:51 2015 +0300 @@ -36,7 +36,7 @@ fi # ALL_INCS, required by the addons and by OpenWatcom C precompiled headers -ngx_incs=`echo $CORE_INCS $NGX_OBJS $HTTP_INCS $MAIL_INCS\ +ngx_incs=`echo $CORE_INCS $NGX_OBJS $HTTP_INCS $MAIL_INCS $STREAM_INCS\ | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \ -e "s/\//$ngx_regex_dirsep/g"` From nexus at smoula.net Tue Apr 21 11:37:52 2015 From: nexus at smoula.net (=?utf-8?b?TWFydGluIE1seW7DocWZ?=) Date: Tue, 21 Apr 2015 13:37:52 +0200 Subject: [PATCH] memcached_force_ranges for memcached upstream Message-ID: <4cb149154501fc638596.1429616272@interceptor.in.smoula.net> # HG changeset patch # User Martin Mlyn?? # Date 1429613281 -7200 # Tue Apr 21 12:48:01 2015 +0200 # Node ID 4cb149154501fc638596ab51031f8b3b64da2a7f # Parent 1bdfceda86a99a4dc99934181d2f9e2632003ca8 memcached_force_ranges for memcached upstream Allow option force_ranges for memcached upstream diff -r 1bdfceda86a9 -r 4cb149154501 src/http/modules/ngx_http_memcached_module.c --- a/src/http/modules/ngx_http_memcached_module.c Mon Apr 20 17:36:51 2015 +0300 +++ b/src/http/modules/ngx_http_memcached_module.c Tue Apr 21 12:48:01 2015 +0200 @@ -95,6 +95,13 @@ offsetof(ngx_http_memcached_loc_conf_t, upstream.read_timeout), NULL }, + { ngx_string("memcached_force_ranges"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_memcached_loc_conf_t, upstream.force_ranges), + NULL }, + { ngx_string("memcached_next_upstream"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_conf_set_bitmask_slot, @@ -604,6 +611,7 @@ conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; + conf->upstream.force_ranges = NGX_CONF_UNSET; /* the hardcoded values */ conf->upstream.cyclic_temp_file = 0; @@ -647,6 +655,9 @@ ngx_conf_merge_msec_value(conf->upstream.read_timeout, prev->upstream.read_timeout, 60000); + ngx_conf_merge_value(conf->upstream.force_ranges, + prev->upstream.force_ranges, 0); + ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout, prev->upstream.next_upstream_timeout, 0); From nexus at smoula.net Tue Apr 21 11:45:18 2015 From: nexus at smoula.net (=?UTF-8?Q?Martin_Mlyn=C3=A1=C5=99?=) Date: Tue, 21 Apr 2015 13:45:18 +0200 Subject: [PATCH] memcached_force_ranges for memcached upstream In-Reply-To: <4cb149154501fc638596.1429616272@interceptor.in.smoula.net> References: <4cb149154501fc638596.1429616272@interceptor.in.smoula.net> Message-ID: Hello, It would be very nice to have ability to use force_ranges for memcached cache upstrems. I'm serving about 5MB files from it and resume is a nice feature which is available on other upstreams and could be beneficial also here. Thank you! Dne 2015-04-21 13:37, Martin Mlyn?? napsal: > # HG changeset patch > # User Martin Mlyn?? > # Date 1429613281 -7200 > # Tue Apr 21 12:48:01 2015 +0200 > # Node ID 4cb149154501fc638596ab51031f8b3b64da2a7f > # Parent 1bdfceda86a99a4dc99934181d2f9e2632003ca8 > memcached_force_ranges for memcached upstream > > Allow option force_ranges for memcached upstream > > diff -r 1bdfceda86a9 -r 4cb149154501 > src/http/modules/ngx_http_memcached_module.c > --- a/src/http/modules/ngx_http_memcached_module.c Mon Apr 20 17:36:51 > 2015 +0300 > +++ b/src/http/modules/ngx_http_memcached_module.c Tue Apr 21 12:48:01 > 2015 +0200 > @@ -95,6 +95,13 @@ > offsetof(ngx_http_memcached_loc_conf_t, upstream.read_timeout), > NULL }, > > + { ngx_string("memcached_force_ranges"), > + > NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, > + ngx_conf_set_flag_slot, > + NGX_HTTP_LOC_CONF_OFFSET, > + offsetof(ngx_http_memcached_loc_conf_t, upstream.force_ranges), > + NULL }, > + > { ngx_string("memcached_next_upstream"), > > NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, > ngx_conf_set_bitmask_slot, > @@ -604,6 +611,7 @@ > conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC; > > conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; > + conf->upstream.force_ranges = NGX_CONF_UNSET; > > /* the hardcoded values */ > conf->upstream.cyclic_temp_file = 0; > @@ -647,6 +655,9 @@ > ngx_conf_merge_msec_value(conf->upstream.read_timeout, > prev->upstream.read_timeout, 60000); > > + ngx_conf_merge_value(conf->upstream.force_ranges, > + prev->upstream.force_ranges, 0); > + > ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout, > prev->upstream.next_upstream_timeout, > 0); > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -- Martin Mlyn?? From arut at nginx.com Tue Apr 21 13:39:32 2015 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 21 Apr 2015 16:39:32 +0300 Subject: [PATCH] memcached_force_ranges for memcached upstream In-Reply-To: <4cb149154501fc638596.1429616272@interceptor.in.smoula.net> References: <4cb149154501fc638596.1429616272@interceptor.in.smoula.net> Message-ID: <20150421133932.GB54924@Romans-MacBook-Air.local> Hello! On Tue, Apr 21, 2015 at 01:37:52PM +0200, Martin Mlyn?? wrote: > # HG changeset patch > # User Martin Mlyn?? > # Date 1429613281 -7200 > # Tue Apr 21 12:48:01 2015 +0200 > # Node ID 4cb149154501fc638596ab51031f8b3b64da2a7f > # Parent 1bdfceda86a99a4dc99934181d2f9e2632003ca8 > memcached_force_ranges for memcached upstream > > Allow option force_ranges for memcached upstream > > diff -r 1bdfceda86a9 -r 4cb149154501 src/http/modules/ngx_http_memcached_module.c > --- a/src/http/modules/ngx_http_memcached_module.c Mon Apr 20 17:36:51 2015 +0300 > +++ b/src/http/modules/ngx_http_memcached_module.c Tue Apr 21 12:48:01 2015 +0200 > @@ -95,6 +95,13 @@ > offsetof(ngx_http_memcached_loc_conf_t, upstream.read_timeout), > NULL }, > > + { ngx_string("memcached_force_ranges"), > + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, > + ngx_conf_set_flag_slot, > + NGX_HTTP_LOC_CONF_OFFSET, > + offsetof(ngx_http_memcached_loc_conf_t, upstream.force_ranges), > + NULL }, > + > { ngx_string("memcached_next_upstream"), > NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, > ngx_conf_set_bitmask_slot, > @@ -604,6 +611,7 @@ > conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC; > > conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; > + conf->upstream.force_ranges = NGX_CONF_UNSET; > > /* the hardcoded values */ > conf->upstream.cyclic_temp_file = 0; > @@ -647,6 +655,9 @@ > ngx_conf_merge_msec_value(conf->upstream.read_timeout, > prev->upstream.read_timeout, 60000); > > + ngx_conf_merge_value(conf->upstream.force_ranges, > + prev->upstream.force_ranges, 0); > + > ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout, > prev->upstream.next_upstream_timeout, 0); It's better to enable ranges in the memcached module without any directives. You can find such "hardcoded values" in ngx_http_memcached_create_loc_conf(). -- Arutyunyan Roman From nexus at smoula.net Tue Apr 21 13:45:12 2015 From: nexus at smoula.net (=?UTF-8?Q?Martin_Mlyn=C3=A1=C5=99?=) Date: Tue, 21 Apr 2015 15:45:12 +0200 Subject: [PATCH] memcached_force_ranges for memcached upstream In-Reply-To: <20150421133932.GB54924@Romans-MacBook-Air.local> References: <4cb149154501fc638596.1429616272@interceptor.in.smoula.net> <20150421133932.GB54924@Romans-MacBook-Air.local> Message-ID: Hello, Dne 2015-04-21 15:39, Roman Arutyunyan napsal: > Hello! > > On Tue, Apr 21, 2015 at 01:37:52PM +0200, Martin Mlyn?? wrote: >> # HG changeset patch >> # User Martin Mlyn?? >> # Date 1429613281 -7200 >> # Tue Apr 21 12:48:01 2015 +0200 >> # Node ID 4cb149154501fc638596ab51031f8b3b64da2a7f >> # Parent 1bdfceda86a99a4dc99934181d2f9e2632003ca8 >> memcached_force_ranges for memcached upstream >> >> Allow option force_ranges for memcached upstream >> >> diff -r 1bdfceda86a9 -r 4cb149154501 >> src/http/modules/ngx_http_memcached_module.c >> --- a/src/http/modules/ngx_http_memcached_module.c Mon Apr 20 17:36:51 >> 2015 +0300 >> +++ b/src/http/modules/ngx_http_memcached_module.c Tue Apr 21 12:48:01 >> 2015 +0200 >> @@ -95,6 +95,13 @@ >> offsetof(ngx_http_memcached_loc_conf_t, upstream.read_timeout), >> NULL }, >> >> + { ngx_string("memcached_force_ranges"), >> + >> NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, >> + ngx_conf_set_flag_slot, >> + NGX_HTTP_LOC_CONF_OFFSET, >> + offsetof(ngx_http_memcached_loc_conf_t, upstream.force_ranges), >> + NULL }, >> + >> { ngx_string("memcached_next_upstream"), >> >> NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, >> ngx_conf_set_bitmask_slot, >> @@ -604,6 +611,7 @@ >> conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC; >> >> conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; >> + conf->upstream.force_ranges = NGX_CONF_UNSET; >> >> /* the hardcoded values */ >> conf->upstream.cyclic_temp_file = 0; >> @@ -647,6 +655,9 @@ >> ngx_conf_merge_msec_value(conf->upstream.read_timeout, >> prev->upstream.read_timeout, 60000); >> >> + ngx_conf_merge_value(conf->upstream.force_ranges, >> + prev->upstream.force_ranges, 0); >> + >> ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout, >> prev->upstream.next_upstream_timeout, >> 0); > > It's better to enable ranges in the memcached module without any > directives. > You can find such "hardcoded values" in > ngx_http_memcached_create_loc_conf(). I've tried to be consistent with other modules which does it this way like: ngx_http_proxy_module.c ngx_http_scgi_module.c ngx_http_uwsgi_module.c ngx_http_fastcgi_module.c Is there any reason why memcached should be an exception? Or am I getting something wrong? Thank you for your reply. -- Martin > > -- > Arutyunyan Roman > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From arut at nginx.com Tue Apr 21 13:53:30 2015 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 21 Apr 2015 16:53:30 +0300 Subject: [PATCH] memcached_force_ranges for memcached upstream In-Reply-To: References: <4cb149154501fc638596.1429616272@interceptor.in.smoula.net> <20150421133932.GB54924@Romans-MacBook-Air.local> Message-ID: <20150421135330.GC54924@Romans-MacBook-Air.local> Hello, On Tue, Apr 21, 2015 at 03:45:12PM +0200, Martin Mlyn?? wrote: > Hello, > > Dne 2015-04-21 15:39, Roman Arutyunyan napsal: > >Hello! > > > >On Tue, Apr 21, 2015 at 01:37:52PM +0200, Martin Mlyn?? wrote: > >># HG changeset patch > >># User Martin Mlyn?? > >># Date 1429613281 -7200 > >># Tue Apr 21 12:48:01 2015 +0200 > >># Node ID 4cb149154501fc638596ab51031f8b3b64da2a7f > >># Parent 1bdfceda86a99a4dc99934181d2f9e2632003ca8 > >>memcached_force_ranges for memcached upstream > >> > >>Allow option force_ranges for memcached upstream > >> > >>diff -r 1bdfceda86a9 -r 4cb149154501 > >>src/http/modules/ngx_http_memcached_module.c > >>--- a/src/http/modules/ngx_http_memcached_module.c Mon Apr 20 17:36:51 > >>2015 +0300 > >>+++ b/src/http/modules/ngx_http_memcached_module.c Tue Apr 21 12:48:01 > >>2015 +0200 > >>@@ -95,6 +95,13 @@ > >> offsetof(ngx_http_memcached_loc_conf_t, upstream.read_timeout), > >> NULL }, > >> > >>+ { ngx_string("memcached_force_ranges"), > >>+ > >>NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, > >>+ ngx_conf_set_flag_slot, > >>+ NGX_HTTP_LOC_CONF_OFFSET, > >>+ offsetof(ngx_http_memcached_loc_conf_t, upstream.force_ranges), > >>+ NULL }, > >>+ > >> { ngx_string("memcached_next_upstream"), > >>NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, > >> ngx_conf_set_bitmask_slot, > >>@@ -604,6 +611,7 @@ > >> conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC; > >> > >> conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; > >>+ conf->upstream.force_ranges = NGX_CONF_UNSET; > >> > >> /* the hardcoded values */ > >> conf->upstream.cyclic_temp_file = 0; > >>@@ -647,6 +655,9 @@ > >> ngx_conf_merge_msec_value(conf->upstream.read_timeout, > >> prev->upstream.read_timeout, 60000); > >> > >>+ ngx_conf_merge_value(conf->upstream.force_ranges, > >>+ prev->upstream.force_ranges, 0); > >>+ > >> ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout, > >> prev->upstream.next_upstream_timeout, 0); > > > >It's better to enable ranges in the memcached module without any > >directives. > >You can find such "hardcoded values" in > >ngx_http_memcached_create_loc_conf(). > > I've tried to be consistent with other modules which does it this way like: > > ngx_http_proxy_module.c > ngx_http_scgi_module.c > ngx_http_uwsgi_module.c > ngx_http_fastcgi_module.c > > Is there any reason why memcached should be an exception? Or am I getting > something wrong? As you can see, the memcached module is an exception for many settings. As for ranges, memcache backend cannot apply ranges, so nginx is the only option. With other upstream modules nginx tries to be consistent with the origin server behavior. -- Roman Arutyunyan From nexus at smoula.net Tue Apr 21 14:29:32 2015 From: nexus at smoula.net (=?UTF-8?Q?Martin_Mlyn=C3=A1=C5=99?=) Date: Tue, 21 Apr 2015 16:29:32 +0200 Subject: [PATCH] memcached_force_ranges for memcached upstream In-Reply-To: <20150421135330.GC54924@Romans-MacBook-Air.local> References: <4cb149154501fc638596.1429616272@interceptor.in.smoula.net> <20150421133932.GB54924@Romans-MacBook-Air.local> <20150421135330.GC54924@Romans-MacBook-Air.local> Message-ID: <582721111082eab7b11ee2fc50ef2a54@smoula.net> Hello, Dne 2015-04-21 15:53, Roman Arutyunyan napsal: > Hello, > > On Tue, Apr 21, 2015 at 03:45:12PM +0200, Martin Mlyn?? wrote: >> Hello, >> >> Dne 2015-04-21 15:39, Roman Arutyunyan napsal: >> >Hello! >> > >> >On Tue, Apr 21, 2015 at 01:37:52PM +0200, Martin Mlyn?? wrote: >> >># HG changeset patch >> >># User Martin Mlyn?? >> >># Date 1429613281 -7200 >> >># Tue Apr 21 12:48:01 2015 +0200 >> >># Node ID 4cb149154501fc638596ab51031f8b3b64da2a7f >> >># Parent 1bdfceda86a99a4dc99934181d2f9e2632003ca8 >> >>memcached_force_ranges for memcached upstream >> >> >> >>Allow option force_ranges for memcached upstream >> >> >> >>diff -r 1bdfceda86a9 -r 4cb149154501 >> >>src/http/modules/ngx_http_memcached_module.c >> >>--- a/src/http/modules/ngx_http_memcached_module.c Mon Apr 20 17:36:51 >> >>2015 +0300 >> >>+++ b/src/http/modules/ngx_http_memcached_module.c Tue Apr 21 12:48:01 >> >>2015 +0200 >> >>@@ -95,6 +95,13 @@ >> >> offsetof(ngx_http_memcached_loc_conf_t, upstream.read_timeout), >> >> NULL }, >> >> >> >>+ { ngx_string("memcached_force_ranges"), >> >>+ >> >>NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, >> >>+ ngx_conf_set_flag_slot, >> >>+ NGX_HTTP_LOC_CONF_OFFSET, >> >>+ offsetof(ngx_http_memcached_loc_conf_t, upstream.force_ranges), >> >>+ NULL }, >> >>+ >> >> { ngx_string("memcached_next_upstream"), >> >>NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, >> >> ngx_conf_set_bitmask_slot, >> >>@@ -604,6 +611,7 @@ >> >> conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC; >> >> >> >> conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; >> >>+ conf->upstream.force_ranges = NGX_CONF_UNSET; >> >> >> >> /* the hardcoded values */ >> >> conf->upstream.cyclic_temp_file = 0; >> >>@@ -647,6 +655,9 @@ >> >> ngx_conf_merge_msec_value(conf->upstream.read_timeout, >> >> prev->upstream.read_timeout, 60000); >> >> >> >>+ ngx_conf_merge_value(conf->upstream.force_ranges, >> >>+ prev->upstream.force_ranges, 0); >> >>+ >> >> ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout, >> >> prev->upstream.next_upstream_timeout, 0); >> > >> >It's better to enable ranges in the memcached module without any >> >directives. >> >You can find such "hardcoded values" in >> >ngx_http_memcached_create_loc_conf(). >> >> I've tried to be consistent with other modules which does it this way >> like: >> >> ngx_http_proxy_module.c >> ngx_http_scgi_module.c >> ngx_http_uwsgi_module.c >> ngx_http_fastcgi_module.c >> >> Is there any reason why memcached should be an exception? Or am I >> getting >> something wrong? > > As you can see, the memcached module is an exception for many settings. > > As for ranges, memcache backend cannot apply ranges, so nginx is the > only > option. With other upstream modules nginx tries to be consistent with > the > origin server behavior. Thank you for your explanation. I expect according to the policy you've mentioned change like this can not be accepted to upstream. Am I right? -- Best regards, Martin From arut at nginx.com Tue Apr 21 14:37:42 2015 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 21 Apr 2015 17:37:42 +0300 Subject: [PATCH] memcached_force_ranges for memcached upstream In-Reply-To: <582721111082eab7b11ee2fc50ef2a54@smoula.net> References: <4cb149154501fc638596.1429616272@interceptor.in.smoula.net> <20150421133932.GB54924@Romans-MacBook-Air.local> <20150421135330.GC54924@Romans-MacBook-Air.local> <582721111082eab7b11ee2fc50ef2a54@smoula.net> Message-ID: <20150421143742.GA65646@Romans-MacBook-Air.local> On Tue, Apr 21, 2015 at 04:29:32PM +0200, Martin Mlyn?? wrote: > Hello, > > Dne 2015-04-21 15:53, Roman Arutyunyan napsal: > >Hello, > > > >On Tue, Apr 21, 2015 at 03:45:12PM +0200, Martin Mlyn?? wrote: > >>Hello, > >> > >>Dne 2015-04-21 15:39, Roman Arutyunyan napsal: > >>>Hello! > >>> > >>>On Tue, Apr 21, 2015 at 01:37:52PM +0200, Martin Mlyn?? wrote: > >>>># HG changeset patch > >>>># User Martin Mlyn?? > >>>># Date 1429613281 -7200 > >>>># Tue Apr 21 12:48:01 2015 +0200 > >>>># Node ID 4cb149154501fc638596ab51031f8b3b64da2a7f > >>>># Parent 1bdfceda86a99a4dc99934181d2f9e2632003ca8 > >>>>memcached_force_ranges for memcached upstream > >>>> > >>>>Allow option force_ranges for memcached upstream > >>>> > >>>>diff -r 1bdfceda86a9 -r 4cb149154501 > >>>>src/http/modules/ngx_http_memcached_module.c > >>>>--- a/src/http/modules/ngx_http_memcached_module.c Mon Apr 20 17:36:51 > >>>>2015 +0300 > >>>>+++ b/src/http/modules/ngx_http_memcached_module.c Tue Apr 21 12:48:01 > >>>>2015 +0200 > >>>>@@ -95,6 +95,13 @@ > >>>> offsetof(ngx_http_memcached_loc_conf_t, upstream.read_timeout), > >>>> NULL }, > >>>> > >>>>+ { ngx_string("memcached_force_ranges"), > >>>>+ > >>>>NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, > >>>>+ ngx_conf_set_flag_slot, > >>>>+ NGX_HTTP_LOC_CONF_OFFSET, > >>>>+ offsetof(ngx_http_memcached_loc_conf_t, upstream.force_ranges), > >>>>+ NULL }, > >>>>+ > >>>> { ngx_string("memcached_next_upstream"), > >>>>NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, > >>>> ngx_conf_set_bitmask_slot, > >>>>@@ -604,6 +611,7 @@ > >>>> conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC; > >>>> > >>>> conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; > >>>>+ conf->upstream.force_ranges = NGX_CONF_UNSET; > >>>> > >>>> /* the hardcoded values */ > >>>> conf->upstream.cyclic_temp_file = 0; > >>>>@@ -647,6 +655,9 @@ > >>>> ngx_conf_merge_msec_value(conf->upstream.read_timeout, > >>>> prev->upstream.read_timeout, 60000); > >>>> > >>>>+ ngx_conf_merge_value(conf->upstream.force_ranges, > >>>>+ prev->upstream.force_ranges, 0); > >>>>+ > >>>> ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout, > >>>> prev->upstream.next_upstream_timeout, 0); > >>> > >>>It's better to enable ranges in the memcached module without any > >>>directives. > >>>You can find such "hardcoded values" in > >>>ngx_http_memcached_create_loc_conf(). > >> > >>I've tried to be consistent with other modules which does it this way > >>like: > >> > >>ngx_http_proxy_module.c > >>ngx_http_scgi_module.c > >>ngx_http_uwsgi_module.c > >>ngx_http_fastcgi_module.c > >> > >>Is there any reason why memcached should be an exception? Or am I > >>getting > >>something wrong? > > > >As you can see, the memcached module is an exception for many settings. > > > >As for ranges, memcache backend cannot apply ranges, so nginx is the only > >option. With other upstream modules nginx tries to be consistent with the > >origin server behavior. > > Thank you for your explanation. I expect according to the policy you've > mentioned > change like this can not be accepted to upstream. Am I right? Yes. We'll accept a simpler patch with the hardcoded setting. -- Roman Arutyunyan From mdounin at mdounin.ru Tue Apr 21 14:42:20 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 21 Apr 2015 14:42:20 +0000 Subject: [nginx] nginx-1.8.0-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/01d52c2b460d branches: stable-1.8 changeset: 6119:01d52c2b460d user: Maxim Dounin date: Tue Apr 21 17:11:58 2015 +0300 description: nginx-1.8.0-RELEASE diffstat: docs/xml/nginx/changes.xml | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diffs (24 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,20 @@ + + + + +?????????? ????? 1.8.x. + + +1.8.x stable branch. + + + + + + From mdounin at mdounin.ru Tue Apr 21 14:42:22 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 21 Apr 2015 14:42:22 +0000 Subject: [nginx] release-1.8.0 tag Message-ID: details: http://hg.nginx.org/nginx/rev/cebc9a2c2144 branches: stable-1.8 changeset: 6120:cebc9a2c2144 user: Maxim Dounin date: Tue Apr 21 17:11:58 2015 +0300 description: release-1.8.0 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -382,3 +382,4 @@ 34b201c1abd1e2d4faeae4650a21574771a03c0e 860cfbcc4606ee36d898a9cd0c5ae8858db984d6 release-1.7.10 2b3b737b5456c05cd63d3d834f4fb4d3776953d0 release-1.7.11 3ef00a71f56420a9c3e9cec311c9a2109a015d67 release-1.7.12 +01d52c2b460da263fd1557ab5f8d0af5e404b47a release-1.8.0 From nexus at smoula.net Tue Apr 21 19:14:06 2015 From: nexus at smoula.net (=?utf-8?b?TWFydGluIE1seW7DocWZ?=) Date: Tue, 21 Apr 2015 21:14:06 +0200 Subject: [PATCH] Enable ranges for memcached upstream module Message-ID: <11553f9d9ef331d16476.1429643646@interceptor.in.smoula.net> # HG changeset patch # User Martin Mlyn?? # Date 1429643076 -7200 # Tue Apr 21 21:04:36 2015 +0200 # Node ID 11553f9d9ef331d16476f17de47b33d93b05a467 # Parent 1bdfceda86a99a4dc99934181d2f9e2632003ca8 Enable ranges for memcached upstream module diff -r 1bdfceda86a9 -r 11553f9d9ef3 src/http/modules/ngx_http_memcached_module.c --- a/src/http/modules/ngx_http_memcached_module.c Mon Apr 20 17:36:51 2015 +0300 +++ b/src/http/modules/ngx_http_memcached_module.c Tue Apr 21 21:04:36 2015 +0200 @@ -618,6 +618,7 @@ conf->upstream.intercept_404 = 1; conf->upstream.pass_request_headers = 0; conf->upstream.pass_request_body = 0; + conf->upstream.force_ranges = 1; conf->index = NGX_CONF_UNSET; conf->gzip_flag = NGX_CONF_UNSET_UINT; From ru at nginx.com Tue Apr 21 20:04:14 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 21 Apr 2015 20:04:14 +0000 Subject: [nginx] Upstream: simplified ip_hash and hash peer selection code. Message-ID: details: http://hg.nginx.org/nginx/rev/b6047abf5f30 branches: changeset: 6121:b6047abf5f30 user: Ruslan Ermilov date: Tue Apr 21 19:09:04 2015 +0300 description: Upstream: simplified ip_hash and hash peer selection code. Now that peers are stored as a list, the weighted and unweighted cases became nearly identical. diffstat: src/http/modules/ngx_http_upstream_hash_module.c | 30 +++++--------------- src/http/modules/ngx_http_upstream_ip_hash_module.c | 28 ++++-------------- src/stream/ngx_stream_upstream_hash_module.c | 30 +++++--------------- 3 files changed, 23 insertions(+), 65 deletions(-) diffs (135 lines): diff -r 1bdfceda86a9 -r b6047abf5f30 src/http/modules/ngx_http_upstream_hash_module.c --- a/src/http/modules/ngx_http_upstream_hash_module.c Mon Apr 20 17:36:51 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_hash_module.c Tue Apr 21 19:09:04 2015 +0300 @@ -170,7 +170,7 @@ ngx_http_upstream_get_hash_peer(ngx_peer uint32_t hash; ngx_int_t w; uintptr_t m; - ngx_uint_t i, n, p; + ngx_uint_t n, p; ngx_http_upstream_rr_peer_t *peer; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, @@ -211,28 +211,14 @@ ngx_http_upstream_get_hash_peer(ngx_peer hp->hash += hash; hp->rehash++; - if (!hp->rrp.peers->weighted) { - p = hp->hash % hp->rrp.peers->number; + w = hp->hash % hp->rrp.peers->total_weight; + peer = hp->rrp.peers->peer; + p = 0; - peer = hp->rrp.peers->peer; - for (i = 0; i < p; i++) { - peer = peer->next; - } - - } else { - w = hp->hash % hp->rrp.peers->total_weight; - - for (peer = hp->rrp.peers->peer, i = 0; - peer; - peer = peer->next, i++) - { - w -= peer->weight; - if (w < 0) { - break; - } - } - - p = i; + while (w >= peer->weight) { + w -= peer->weight; + peer = peer->next; + p++; } n = p / (8 * sizeof(uintptr_t)); diff -r 1bdfceda86a9 -r b6047abf5f30 src/http/modules/ngx_http_upstream_ip_hash_module.c --- a/src/http/modules/ngx_http_upstream_ip_hash_module.c Mon Apr 20 17:36:51 2015 +0300 +++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c Tue Apr 21 19:09:04 2015 +0300 @@ -181,28 +181,14 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p hash = (hash * 113 + iphp->addr[i]) % 6271; } - if (!iphp->rrp.peers->weighted) { - p = hash % iphp->rrp.peers->number; + w = hash % iphp->rrp.peers->total_weight; + peer = iphp->rrp.peers->peer; + p = 0; - peer = iphp->rrp.peers->peer; - for (i = 0; i < p; i++) { - peer = peer->next; - } - - } else { - w = hash % iphp->rrp.peers->total_weight; - - for (peer = iphp->rrp.peers->peer, i = 0; - peer; - peer = peer->next, i++) - { - w -= peer->weight; - if (w < 0) { - break; - } - } - - p = i; + while (w >= peer->weight) { + w -= peer->weight; + peer = peer->next; + p++; } n = p / (8 * sizeof(uintptr_t)); diff -r 1bdfceda86a9 -r b6047abf5f30 src/stream/ngx_stream_upstream_hash_module.c --- a/src/stream/ngx_stream_upstream_hash_module.c Mon Apr 20 17:36:51 2015 +0300 +++ b/src/stream/ngx_stream_upstream_hash_module.c Tue Apr 21 19:09:04 2015 +0300 @@ -164,7 +164,7 @@ ngx_stream_upstream_get_hash_peer(ngx_pe uint32_t hash; ngx_int_t w; uintptr_t m; - ngx_uint_t i, n, p; + ngx_uint_t n, p; ngx_stream_upstream_rr_peer_t *peer; ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, @@ -204,28 +204,14 @@ ngx_stream_upstream_get_hash_peer(ngx_pe hp->hash += hash; hp->rehash++; - if (!hp->rrp.peers->weighted) { - p = hp->hash % hp->rrp.peers->number; + w = hp->hash % hp->rrp.peers->total_weight; + peer = hp->rrp.peers->peer; + p = 0; - peer = hp->rrp.peers->peer; - for (i = 0; i < p; i++) { - peer = peer->next; - } - - } else { - w = hp->hash % hp->rrp.peers->total_weight; - - for (peer = hp->rrp.peers->peer, i = 0; - peer; - peer = peer->next, i++) - { - w -= peer->weight; - if (w < 0) { - break; - } - } - - p = i; + while (w >= peer->weight) { + w -= peer->weight; + peer = peer->next; + p++; } n = p / (8 * sizeof(uintptr_t)); From serg.brester at sebres.de Wed Apr 22 07:45:45 2015 From: serg.brester at sebres.de (Sergey Brester) Date: Wed, 22 Apr 2015 09:45:45 +0200 Subject: Fwd: Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) Message-ID: <706ca3a5ec658ea41fb9975f90ab9ab4@sebres.de> Hi, enclosed you will find an attached changeset, that fixes a ASLR/DEP problem on windows platforms (example Win 7/2008 x64). To find shared addr offset with ASLR, we have successful used the same resp. similar solution on various open source projects (ex.: postgresql etc.). Also nginx with suggested patch works fine over 5 months in production on several machines (Win-2k8-R2). BTW(1): I have interest to fix a problem with multiple workers under windows (ex.: http://forum.nginx.org/read.php?2,188714,188714#msg-188714 [1]). @Maxim Dounin: can you possibly give me more information, what you mean here, resp. what it currently depends on (see http://forum.nginx.org/read.php?2,188714,212568#msg-212568 [2]). BTW(2): I would like to fix iocp under windows also. Thanks in advance for any information about. P.S. speak fluently russian and german... Regards, Serg G. Brester (sebres) ------------------------- Links: ------ [1] http://forum.nginx.org/read.php?2,188714,188714#msg-188714 [2] http://forum.nginx.org/read.php?2,188714,212568#msg-212568 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: update.patch Type: text/x-diff Size: 5901 bytes Desc: not available URL: From fdasilva at ingima.com Wed Apr 22 08:53:04 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Wed, 22 Apr 2015 08:53:04 +0000 Subject: Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) In-Reply-To: <706ca3a5ec658ea41fb9975f90ab9ab4@sebres.de> References: <706ca3a5ec658ea41fb9975f90ab9ab4@sebres.de> Message-ID: Hi, A few style remarks about your patch?: - LF Line ending only - Only C style comments, so no // ? - Indentation is 4 spaces. - Add this setting to your .hgrc /mercurial.ini [diff] showfunc = True - Do not remove existing blank lines . Additional information here : http://nginx.org/en/docs/contributing_changes.html Regards, Filipe --- De?: nginx-devel-bounces at nginx.org [mailto:nginx-devel-bounces at nginx.org] De la part de Sergey Brester Envoy??: mercredi 22 avril 2015 09:46 ??: nginx-devel at nginx.org Objet?: Fwd: Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) Hi, enclosed you will find an attached changeset, that fixes a ASLR/DEP problem on windows platforms (example Win 7/2008 x64). To find shared addr offset with ASLR, we have successful used the same resp. similar solution on various open source projects (ex.: postgresql etc.). Also nginx with suggested patch works fine over 5 months in production on several machines (Win-2k8-R2). BTW(1): I have interest to fix a problem with multiple workers under windows (ex.: http://forum.nginx.org/read.php?2,188714,188714#msg-188714). @Maxim Dounin: can you possibly give me more information, what you mean here, resp. what it currently depends on (see http://forum.nginx.org/read.php?2,188714,212568#msg-212568). BTW(2): I would like to fix iocp under windows also. Thanks in advance for any information about. P.S. speak fluently russian and german... Regards, Serg G. Brester (sebres) ________________________________________ From serg.brester at sebres.de Wed Apr 22 11:38:02 2015 From: serg.brester at sebres.de (Sergey Brester) Date: Wed, 22 Apr 2015 13:38:02 +0200 Subject: Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) In-Reply-To: References: <706ca3a5ec658ea41fb9975f90ab9ab4@sebres.de> Message-ID: <5f9db56b6819f9cefeadf4394a3c4aab@sebres.de> Thx, and sorry for your effort. I speak "git" (stumble over "hg" sometimes:) Your patch was a little bit broken: * dual ``` return NGX_OK; ``` in line 135 after debug; * line 157: ``` if (UnmapViewOfFile(shm->addr) == 0) { ``` should be removed. New changeset attached. BTW: pure C comments are imho rudiments, because these prevent a (temporary) commenting of larger code blocks. That's why I try to avoid these - just pure habit. And really 80 cols (and CRLF-problem) in 21st century? But, once again sorry and thanks. Regargs, sebres. Am 22.04.2015 10:57, schrieb Filipe DA SILVA: > Hi, > > Please find attach a quickly reworked version of your patch . > > I forget to speak about th 80 cols limits. > > Regards, > > Filipe DA SILVA > > DE : nginx-devel-bounces at nginx.org [mailto:nginx-devel-bounces at nginx.org] DE LA PART DE Sergey Brester > ENVOY? : mercredi 22 avril 2015 09:46 > ? : nginx-devel at nginx.org > OBJET : Fwd: Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) > > Hi, > > enclosed you will find an attached changeset, that fixes a ASLR/DEP problem on windows platforms (example Win 7/2008 x64). > > To find shared addr offset with ASLR, we have successful used the same resp. similar solution on various open source projects (ex.: postgresql etc.). Also nginx with suggested patch works fine over 5 months in production on several machines (Win-2k8-R2). > > BTW(1): I have interest to fix a problem with multiple workers under windows (ex.: http://forum.nginx.org/read.php?2,188714,188714#msg-188714 [1]). > @Maxim Dounin: can you possibly give me more information, what you mean here, resp. what it currently depends on (see http://forum.nginx.org/read.php?2,188714,212568#msg-212568 [2]). > > BTW(2): I would like to fix iocp under windows also. Thanks in advance for any information about. > > P.S. speak fluently russian and german... > > Regards, > > Serg G. Brester (sebres) > > ------------------------- Links: ------ [1] http://forum.nginx.org/read.php?2,188714,188714#msg-188714 [2] http://forum.nginx.org/read.php?2,188714,212568#msg-212568 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: shmem fix2.patch Type: text/x-diff Size: 6128 bytes Desc: not available URL: From arut at nginx.com Wed Apr 22 14:55:08 2015 From: arut at nginx.com (Roman Arutyunyan) Date: Wed, 22 Apr 2015 14:55:08 +0000 Subject: [nginx] Memcached: enabled ranges. Message-ID: details: http://hg.nginx.org/nginx/rev/85f00678e54a branches: changeset: 6122:85f00678e54a user: Martin Mlyn?? date: Tue Apr 21 21:04:36 2015 +0200 description: Memcached: enabled ranges. diffstat: src/http/modules/ngx_http_memcached_module.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r b6047abf5f30 -r 85f00678e54a src/http/modules/ngx_http_memcached_module.c --- a/src/http/modules/ngx_http_memcached_module.c Tue Apr 21 19:09:04 2015 +0300 +++ b/src/http/modules/ngx_http_memcached_module.c Tue Apr 21 21:04:36 2015 +0200 @@ -618,6 +618,7 @@ ngx_http_memcached_create_loc_conf(ngx_c conf->upstream.intercept_404 = 1; conf->upstream.pass_request_headers = 0; conf->upstream.pass_request_body = 0; + conf->upstream.force_ranges = 1; conf->index = NGX_CONF_UNSET; conf->gzip_flag = NGX_CONF_UNSET_UINT; From arut at nginx.com Wed Apr 22 14:58:22 2015 From: arut at nginx.com (Roman Arutyunyan) Date: Wed, 22 Apr 2015 17:58:22 +0300 Subject: [PATCH] Enable ranges for memcached upstream module In-Reply-To: <11553f9d9ef331d16476.1429643646@interceptor.in.smoula.net> References: <11553f9d9ef331d16476.1429643646@interceptor.in.smoula.net> Message-ID: <20150422145822.GC65646@Romans-MacBook-Air.local> On Tue, Apr 21, 2015 at 09:14:06PM +0200, Martin Mlyn?? wrote: > # HG changeset patch > # User Martin Mlyn?? > # Date 1429643076 -7200 > # Tue Apr 21 21:04:36 2015 +0200 > # Node ID 11553f9d9ef331d16476f17de47b33d93b05a467 > # Parent 1bdfceda86a99a4dc99934181d2f9e2632003ca8 > Enable ranges for memcached upstream module > > diff -r 1bdfceda86a9 -r 11553f9d9ef3 src/http/modules/ngx_http_memcached_module.c > --- a/src/http/modules/ngx_http_memcached_module.c Mon Apr 20 17:36:51 2015 +0300 > +++ b/src/http/modules/ngx_http_memcached_module.c Tue Apr 21 21:04:36 2015 +0200 > @@ -618,6 +618,7 @@ > conf->upstream.intercept_404 = 1; > conf->upstream.pass_request_headers = 0; > conf->upstream.pass_request_body = 0; > + conf->upstream.force_ranges = 1; > > conf->index = NGX_CONF_UNSET; > conf->gzip_flag = NGX_CONF_UNSET_UINT; > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel Committed, thanks. -- Roman Arutyunyan From ru at nginx.com Wed Apr 22 15:49:38 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 22 Apr 2015 15:49:38 +0000 Subject: [nginx] Upstream: allow multiple upstreams to use the same share... Message-ID: details: http://hg.nginx.org/nginx/rev/caa103acf180 branches: changeset: 6123:caa103acf180 user: Ruslan Ermilov date: Wed Apr 22 18:37:34 2015 +0300 description: Upstream: allow multiple upstreams to use the same shared zone. diffstat: src/http/modules/ngx_http_upstream_zone_module.c | 98 +++++++++++++---------- src/stream/ngx_stream_upstream_zone_module.c | 98 +++++++++++++---------- 2 files changed, 112 insertions(+), 84 deletions(-) diffs (truncated from 324 to 300 lines): diff -r 85f00678e54a -r caa103acf180 src/http/modules/ngx_http_upstream_zone_module.c --- a/src/http/modules/ngx_http_upstream_zone_module.c Tue Apr 21 21:04:36 2015 +0200 +++ b/src/http/modules/ngx_http_upstream_zone_module.c Wed Apr 22 18:37:34 2015 +0300 @@ -14,12 +14,14 @@ static char *ngx_http_upstream_zone(ngx_ void *conf); static ngx_int_t ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data); +static ngx_int_t ngx_http_upstream_zone_copy_peers(ngx_slab_pool_t *shpool, + ngx_http_upstream_srv_conf_t *uscf); static ngx_command_t ngx_http_upstream_zone_commands[] = { { ngx_string("zone"), - NGX_HTTP_UPS_CONF|NGX_CONF_TAKE2, + NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12, ngx_http_upstream_zone, 0, 0, @@ -63,11 +65,13 @@ ngx_module_t ngx_http_upstream_zone_mod static char * ngx_http_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_http_upstream_srv_conf_t *uscf; - ssize_t size; - ngx_str_t *value; + ssize_t size; + ngx_str_t *value; + ngx_http_upstream_srv_conf_t *uscf; + ngx_http_upstream_main_conf_t *umcf; uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); + umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module); value = cf->args->elts; @@ -77,18 +81,23 @@ ngx_http_upstream_zone(ngx_conf_t *cf, n return NGX_CONF_ERROR; } - size = ngx_parse_size(&value[2]); + if (cf->args->nelts == 3) { + size = ngx_parse_size(&value[2]); - if (size == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid zone size \"%V\"", &value[2]); - return NGX_CONF_ERROR; - } + if (size == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid zone size \"%V\"", &value[2]); + return NGX_CONF_ERROR; + } - if (size < (ssize_t) (8 * ngx_pagesize)) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "zone \"%V\" is too small", &value[1]); - return NGX_CONF_ERROR; + if (size < (ssize_t) (8 * ngx_pagesize)) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "zone \"%V\" is too small", &value[1]); + return NGX_CONF_ERROR; + } + + } else { + size = 0; } uscf->shm_zone = ngx_shared_memory_add(cf, &value[1], size, @@ -97,19 +106,8 @@ ngx_http_upstream_zone(ngx_conf_t *cf, n return NGX_CONF_ERROR; } - if (uscf->shm_zone->data) { - uscf = uscf->shm_zone->data; - - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "upstream \"%V\" in %s:%ui " - "is already bound to zone \"%V\"", - &uscf->host, uscf->file_name, uscf->line, - &value[1]); - return NGX_CONF_ERROR; - } - uscf->shm_zone->init = ngx_http_upstream_init_zone; - uscf->shm_zone->data = uscf; + uscf->shm_zone->data = umcf; uscf->shm_zone->noreuse = 1; @@ -120,21 +118,11 @@ ngx_http_upstream_zone(ngx_conf_t *cf, n static ngx_int_t ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data) { - ngx_http_upstream_srv_conf_t *ouscf = data; - size_t len; + ngx_uint_t i; ngx_slab_pool_t *shpool; - ngx_http_upstream_rr_peer_t *peer, **peerp; - ngx_http_upstream_rr_peers_t *peers, *backup; - ngx_http_upstream_srv_conf_t *uscf; - - uscf = shm_zone->data; - - if (ouscf) { - ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, - "zone \"%V\" cannot be reused", &shm_zone->shm.name); - return NGX_ERROR; - } + ngx_http_upstream_srv_conf_t *uscf, **uscfp; + ngx_http_upstream_main_conf_t *umcf; shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; @@ -142,9 +130,6 @@ ngx_http_upstream_init_zone(ngx_shm_zone return NGX_ERROR; } - - /* copy peers to shared memory */ - len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len; shpool->log_ctx = ngx_slab_alloc(shpool, len); @@ -155,6 +140,35 @@ ngx_http_upstream_init_zone(ngx_shm_zone ngx_sprintf(shpool->log_ctx, " in upstream zone \"%V\"%Z", &shm_zone->shm.name); + + /* copy peers to shared memory */ + + umcf = shm_zone->data; + uscfp = umcf->upstreams.elts; + + for (i = 0; i < umcf->upstreams.nelts; i++) { + uscf = uscfp[i]; + + if (uscf->shm_zone != shm_zone) { + continue; + } + + if (ngx_http_upstream_zone_copy_peers(shpool, uscf) != NGX_OK) { + return NGX_ERROR; + } + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_upstream_zone_copy_peers(ngx_slab_pool_t *shpool, + ngx_http_upstream_srv_conf_t *uscf) +{ + ngx_http_upstream_rr_peer_t *peer, **peerp; + ngx_http_upstream_rr_peers_t *peers, *backup; + peers = ngx_slab_alloc(shpool, sizeof(ngx_http_upstream_rr_peers_t)); if (peers == NULL) { return NGX_ERROR; diff -r 85f00678e54a -r caa103acf180 src/stream/ngx_stream_upstream_zone_module.c --- a/src/stream/ngx_stream_upstream_zone_module.c Tue Apr 21 21:04:36 2015 +0200 +++ b/src/stream/ngx_stream_upstream_zone_module.c Wed Apr 22 18:37:34 2015 +0300 @@ -14,12 +14,14 @@ static char *ngx_stream_upstream_zone(ng void *conf); static ngx_int_t ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data); +static ngx_int_t ngx_stream_upstream_zone_copy_peers(ngx_slab_pool_t *shpool, + ngx_stream_upstream_srv_conf_t *uscf); static ngx_command_t ngx_stream_upstream_zone_commands[] = { { ngx_string("zone"), - NGX_STREAM_UPS_CONF|NGX_CONF_TAKE2, + NGX_STREAM_UPS_CONF|NGX_CONF_TAKE12, ngx_stream_upstream_zone, 0, 0, @@ -57,11 +59,13 @@ ngx_module_t ngx_stream_upstream_zone_m static char * ngx_stream_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ssize_t size; - ngx_str_t *value; - ngx_stream_upstream_srv_conf_t *uscf; + ssize_t size; + ngx_str_t *value; + ngx_stream_upstream_srv_conf_t *uscf; + ngx_stream_upstream_main_conf_t *umcf; uscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_upstream_module); + umcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_upstream_module); value = cf->args->elts; @@ -71,18 +75,23 @@ ngx_stream_upstream_zone(ngx_conf_t *cf, return NGX_CONF_ERROR; } - size = ngx_parse_size(&value[2]); + if (cf->args->nelts == 3) { + size = ngx_parse_size(&value[2]); - if (size == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid zone size \"%V\"", &value[2]); - return NGX_CONF_ERROR; - } + if (size == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid zone size \"%V\"", &value[2]); + return NGX_CONF_ERROR; + } - if (size < (ssize_t) (8 * ngx_pagesize)) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "zone \"%V\" is too small", &value[1]); - return NGX_CONF_ERROR; + if (size < (ssize_t) (8 * ngx_pagesize)) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "zone \"%V\" is too small", &value[1]); + return NGX_CONF_ERROR; + } + + } else { + size = 0; } uscf->shm_zone = ngx_shared_memory_add(cf, &value[1], size, @@ -91,19 +100,8 @@ ngx_stream_upstream_zone(ngx_conf_t *cf, return NGX_CONF_ERROR; } - if (uscf->shm_zone->data) { - uscf = uscf->shm_zone->data; - - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "upstream \"%V\" in %s:%ui " - "is already bound to zone \"%V\"", - &uscf->host, uscf->file_name, uscf->line, - &value[1]); - return NGX_CONF_ERROR; - } - uscf->shm_zone->init = ngx_stream_upstream_init_zone; - uscf->shm_zone->data = uscf; + uscf->shm_zone->data = umcf; uscf->shm_zone->noreuse = 1; @@ -114,21 +112,11 @@ ngx_stream_upstream_zone(ngx_conf_t *cf, static ngx_int_t ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data) { - ngx_stream_upstream_srv_conf_t *ouscf = data; - size_t len; + ngx_uint_t i; ngx_slab_pool_t *shpool; - ngx_stream_upstream_rr_peer_t *peer, **peerp; - ngx_stream_upstream_rr_peers_t *peers, *backup; - ngx_stream_upstream_srv_conf_t *uscf; - - uscf = shm_zone->data; - - if (ouscf) { - ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, - "zone \"%V\" cannot be reused", &shm_zone->shm.name); - return NGX_ERROR; - } + ngx_stream_upstream_srv_conf_t *uscf, **uscfp; + ngx_stream_upstream_main_conf_t *umcf; shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; @@ -136,9 +124,6 @@ ngx_stream_upstream_init_zone(ngx_shm_zo return NGX_ERROR; } - - /* copy peers to shared memory */ - len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len; shpool->log_ctx = ngx_slab_alloc(shpool, len); @@ -149,6 +134,35 @@ ngx_stream_upstream_init_zone(ngx_shm_zo ngx_sprintf(shpool->log_ctx, " in upstream zone \"%V\"%Z", &shm_zone->shm.name); + + /* copy peers to shared memory */ + + umcf = shm_zone->data; + uscfp = umcf->upstreams.elts; + + for (i = 0; i < umcf->upstreams.nelts; i++) { + uscf = uscfp[i]; From mdounin at mdounin.ru Wed Apr 22 16:29:29 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 22 Apr 2015 19:29:29 +0300 Subject: Fwd: Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) In-Reply-To: <706ca3a5ec658ea41fb9975f90ab9ab4@sebres.de> References: <706ca3a5ec658ea41fb9975f90ab9ab4@sebres.de> Message-ID: <20150422162929.GD32429@mdounin.ru> Hello! On Wed, Apr 22, 2015 at 09:45:45AM +0200, Sergey Brester wrote: > enclosed you will find an attached changeset, that fixes a ASLR/DEP > problem on windows platforms (example Win 7/2008 x64). > > To find shared addr offset with ASLR, we have successful used the same > resp. similar solution on various open source projects (ex.: postgresql > etc.). Also nginx with suggested patch works fine over 5 months in > production on several machines (Win-2k8-R2). Interesting, thanks, though the patch certainly needs some cleanup. See below for some comments. > BTW(1): I have interest to fix a problem with multiple workers under > windows (ex.: http://forum.nginx.org/read.php?2,188714,188714#msg-188714 > [1]). > @Maxim Dounin: can you possibly give me more information, what you mean > here, resp. what it currently depends on (see > http://forum.nginx.org/read.php?2,188714,212568#msg-212568 [2]). The most obvious problem with multiple workers on Windows is listening sockets. As of now, if you start multiple workers on windows, nginx will open multiple listening sockets - one in each worker process. These are independant sockets, each opened with SO_REUSEADDR, and only one of these sockets will be able to accept connections. Possible solution to the problem would be to pass listening sockets from a master process to worker processes via handle inheritance as available in Windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683463(v=vs.85).aspx [...] > # HG changeset patch > # User Serg G. Brester (sebres) > # Date 1429643760 -7200 > # Tue Apr 21 21:16:00 2015 +0200 > # Branch sb-mod > # Node ID f759f7084204bb1f3c2b0a8023a8f03a81da9a0b > # Parent 1bdfceda86a99a4dc99934181d2f9e2632003ca8 > Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) > > diff -r 1bdfceda86a9 -r f759f7084204 src/os/win32/ngx_shmem.c > --- a/src/os/win32/ngx_shmem.c Mon Apr 20 17:36:51 2015 +0300 > +++ b/src/os/win32/ngx_shmem.c Tue Apr 21 21:16:00 2015 +0200 > @@ -9,11 +9,30 @@ > #include > > > +static volatile size_t g_addrbaseoffs = 0; > + > +static volatile int g_SystemInfo_init = 0; > +SYSTEM_INFO g_SystemInfo; > + > +int ngx_shm_init_once() { > + if (g_SystemInfo_init) > + return 1; > + g_SystemInfo_init = 1; > + GetSystemInfo(&g_SystemInfo); > + return 1; > +} Such things belong to ngx_win32_init.c. It may be also good enough to use ngx_pagesize, which is already set there. > + > +/* ------------------- */ > + There are lots of style problems which need cleanup. > ngx_int_t > ngx_shm_alloc(ngx_shm_t *shm) > { > u_char *name; > uint64_t size; > + u_char *addr; > + u_char *addrbase; > + > + ngx_shm_init_once(); > > name = ngx_alloc(shm->name.len + 2 + NGX_INT32_LEN, shm->log); > if (name == NULL) { > @@ -26,6 +45,9 @@ > > size = shm->size; > > + // increase for base address, will be saved inside shared mem : > + size += sizeof(addr); > + As of now, uses of ngx_shm_alloc() already contain address in the shared memory region where addresses are important. It may worth to try to use it, if possible (may be with some additional call to redo the mapping with the address specified). > shm->handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, > (u_long) (size >> 32), > (u_long) (size & 0xffffffff), > @@ -34,7 +56,7 @@ > if (shm->handle == NULL) { > ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, > "CreateFileMapping(%uz, %s) failed", > - shm->size, name); > + size, name); > ngx_free(name); > > return NGX_ERROR; > @@ -42,14 +64,79 @@ > > ngx_free(name); > > + shm->exists = 0; This looks like an unneeded change. The exists flag is set to 0 in ngx_shared_memory_add(), when ngx_shm_t is allocated and initialized. > if (ngx_errno == ERROR_ALREADY_EXISTS) { > shm->exists = 1; > } > > - shm->addr = MapViewOfFile(shm->handle, FILE_MAP_WRITE, 0, 0, 0); > + /* > + // Because of Win x64 since Vista/Win7 (always ASLR in kernel32), and nginx uses pointer > + // inside this shared areas, we should use the same address for shared memory (Windows IPC) > + > + // Now we set preferred base to a hardcoded address that newborn processes never seem to be using (in available versions of Windows). > + // The addresses was selected somewhat randomly in order to minimize the probability that some other library doing something similar > + // conflicts with us. That is, using conspicuous addresses like 0x20000000 might not be good if someone else does it. > + */ > + #ifdef _WIN64 > + /* > + * There is typically a giant hole (almost 8TB): > + * 00000000 7fff0000 > + * ... > + * 000007f6 8e8b0000 > + */ > + addrbase = (u_char*)0x0000047047e00000ULL; > + #else > + /* > + * This is more dicey. However, even with ASLR there still > + * seems to be a big hole: > + * 10000000 > + * ... > + * 70000000 > + */ > + addrbase = (u_char*)0x2efe0000; > + #endif This probably should be somewhere at ngx_win32_config.h. > > - if (shm->addr != NULL) { > + // add offset (corresponding all used shared) to preferred base: > + addrbase += g_addrbaseoffs; > + > + addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, addrbase); Have you tried using an arbitrary addresses (with subsequent remap using proper base address for already existing mappings)? Does is work noticeably worse? > + > + ngx_log_debug4(NGX_LOG_DEBUG_CORE, shm->log, 0, "map shared \"%V\" -> %p (base %p), size: %uz", &shm->name, addr, addrbase, size); > + > + if (addr != NULL) { > + > + // get allocated address if already exists: > + if (shm->exists) { > + // get base and realoc using it if different: > + addrbase = *(u_char **)addr; > + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, 0, "shared \"%V\" -> %p -> %p", &shm->name, addr, addrbase); > + if (addrbase != addr) { > + // free: > + if (UnmapViewOfFile(addr) == 0) { > + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, > + "UnmapViewOfFile(%p) of file mapping \"%V\" failed", > + addr, &shm->name); > + } > + // allocate again using base address: > + addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, > + addrbase // lpBaseAddress > + ); > + } > + } else { > + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, 0, "shared \"%V\" -> %p (base %p)", &shm->name, addr, addrbase); > + // save first allocated address as base for next caller : > + *(u_char **)addr = addr; It might be better idea to save the address at the end of the memory block allocated, this will at least allow to avoid address manipulation here and in ngx_shm_free(). Or use the address stored in the memory block itself, see above. > + } > + > + if (addr != NULL) { > + // increase base offset (use proper alignment, obtain it from dwAllocationGranularity): > + g_addrbaseoffs += (size + g_SystemInfo.dwAllocationGranularity) & (0xffffffff & ~(g_SystemInfo.dwAllocationGranularity-1)); > + //ngx_log_debug2(NGX_LOG_DEBUG_CORE, shm->log, 0, "offset %ui, granularity %ui", g_addrbaseoffs, g_SystemInfo.dwAllocationGranularity); > + shm->addr = addr + sizeof(addr); > + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, 0, "shared alloc \"%V\" -> %p = %p", &shm->name, addr, shm->addr); > return NGX_OK; > + } > + > } > > ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, > @@ -65,14 +152,17 @@ > return NGX_ERROR; > } > > - > void Unrelated change (and a style bug). > ngx_shm_free(ngx_shm_t *shm) > { > - if (UnmapViewOfFile(shm->addr) == 0) { > + u_char *addr; > + > + addr = shm->addr - sizeof(addr); > + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, 0, "shared free \"%V\" -> %p = %p", &shm->name, addr, shm->addr); > + if (UnmapViewOfFile(addr) == 0) { > ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, > "UnmapViewOfFile(%p) of file mapping \"%V\" failed", > - shm->addr, &shm->name); > + addr, &shm->name); > } > > if (CloseHandle(shm->handle) == 0) { See above, this change shouldn't be needed. -- Maxim Dounin http://nginx.org/ From arut at nginx.com Wed Apr 22 16:56:32 2015 From: arut at nginx.com (Roman Arutyunyan) Date: Wed, 22 Apr 2015 16:56:32 +0000 Subject: [nginx] Stream: prevent repeated event notifications after eof. Message-ID: details: http://hg.nginx.org/nginx/rev/f1f222db290b branches: changeset: 6124:f1f222db290b user: Roman Arutyunyan date: Wed Apr 22 19:55:04 2015 +0300 description: Stream: prevent repeated event notifications after eof. When client or upstream connection is closed, level-triggered read event remained active until the end of the session leading to cpu hog. Now the flag NGX_CLOSE_EVENT is used to unschedule the event. diffstat: src/stream/ngx_stream_proxy_module.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (22 lines): diff -r caa103acf180 -r f1f222db290b src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Wed Apr 22 18:37:34 2015 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Wed Apr 22 19:55:04 2015 +0300 @@ -814,6 +814,7 @@ ngx_stream_proxy_process(ngx_stream_sess size_t size; ssize_t n; ngx_buf_t *b; + ngx_uint_t flags; ngx_connection_t *c, *pc, *src, *dst; ngx_log_handler_pt handler; ngx_stream_upstream_t *u; @@ -911,7 +912,9 @@ ngx_stream_proxy_process(ngx_stream_sess return NGX_DONE; } - if (ngx_handle_read_event(src->read, 0) != NGX_OK) { + flags = src->read->eof ? NGX_CLOSE_EVENT : 0; + + if (ngx_handle_read_event(src->read, flags) != NGX_OK) { ngx_stream_proxy_finalize(s, NGX_ERROR); return NGX_ERROR; } From ru at nginx.com Thu Apr 23 11:18:16 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 23 Apr 2015 11:18:16 +0000 Subject: [nginx] Removed the obsolete aio module. Message-ID: details: http://hg.nginx.org/nginx/rev/4dc8e7b62216 branches: changeset: 6125:4dc8e7b62216 user: Ruslan Ermilov date: Wed Apr 22 18:57:32 2015 +0300 description: Removed the obsolete aio module. diffstat: auto/options | 2 - auto/os/freebsd | 20 ---- auto/os/win32 | 1 - auto/sources | 7 - src/core/ngx_connection.c | 2 +- src/core/ngx_resolver.c | 2 +- src/event/modules/ngx_aio_module.c | 171 ------------------------------------ src/event/modules/ngx_iocp_module.c | 2 +- src/event/ngx_event.c | 4 +- src/event/ngx_event.h | 10 +- src/event/ngx_event_accept.c | 9 +- src/event/ngx_event_connect.c | 4 +- src/http/ngx_http_request.c | 2 +- src/http/ngx_http_upstream.c | 2 +- src/os/unix/ngx_aio_read.c | 109 ---------------------- src/os/unix/ngx_aio_read_chain.c | 78 ---------------- src/os/unix/ngx_aio_write.c | 109 ---------------------- src/os/unix/ngx_aio_write_chain.c | 100 --------------------- src/os/unix/ngx_freebsd_config.h | 2 +- src/os/unix/ngx_os.h | 8 - 20 files changed, 14 insertions(+), 630 deletions(-) diffs (truncated from 860 to 300 lines): diff -r f1f222db290b -r 4dc8e7b62216 auto/options --- a/auto/options Wed Apr 22 19:55:04 2015 +0300 +++ b/auto/options Wed Apr 22 18:57:32 2015 +0300 @@ -41,7 +41,6 @@ EVENT_FOUND=NO EVENT_RTSIG=NO EVENT_SELECT=NO EVENT_POLL=NO -EVENT_AIO=NO USE_THREADS=NO @@ -195,7 +194,6 @@ do --without-select_module) EVENT_SELECT=NONE ;; --with-poll_module) EVENT_POLL=YES ;; --without-poll_module) EVENT_POLL=NONE ;; - --with-aio_module) EVENT_AIO=YES ;; --with-threads) USE_THREADS=YES ;; diff -r f1f222db290b -r 4dc8e7b62216 auto/os/freebsd --- a/auto/os/freebsd Wed Apr 22 19:55:04 2015 +0300 +++ b/auto/os/freebsd Wed Apr 22 18:57:32 2015 +0300 @@ -99,26 +99,6 @@ then fi -if [ $EVENT_AIO = YES ]; then - if [ \( $version -lt 500000 -a $version -ge 430000 \) \ - -o $version -ge 500014 ] - then - have=NGX_HAVE_AIO . auto/have - EVENT_MODULES="$EVENT_MODULES $AIO_MODULE" - CORE_SRCS="$CORE_SRCS $AIO_SRCS" - else - -cat << END - -$0: error: the kqueue does not support AIO on this FreeBSD version - -END - - exit 1 - fi -fi - - # cpuset_setaffinity() if [ $version -ge 701000 ]; then diff -r f1f222db290b -r 4dc8e7b62216 auto/os/win32 --- a/auto/os/win32 Wed Apr 22 19:55:04 2015 +0300 +++ b/auto/os/win32 Wed Apr 22 18:57:32 2015 +0300 @@ -36,5 +36,4 @@ if [ $NGX_IPV6 = YES ]; then have=NGX_HAVE_INET6 . auto/have fi -have=NGX_HAVE_AIO . auto/have have=NGX_HAVE_IOCP . auto/have diff -r f1f222db290b -r 4dc8e7b62216 auto/sources --- a/auto/sources Wed Apr 22 19:55:04 2015 +0300 +++ b/auto/sources Wed Apr 22 18:57:32 2015 +0300 @@ -130,13 +130,6 @@ RTSIG_SRCS=src/event/modules/ngx_rtsig_m IOCP_MODULE=ngx_iocp_module IOCP_SRCS=src/event/modules/ngx_iocp_module.c -AIO_MODULE=ngx_aio_module -AIO_SRCS="src/event/modules/ngx_aio_module.c \ - src/os/unix/ngx_aio_read.c \ - src/os/unix/ngx_aio_write.c \ - src/os/unix/ngx_aio_read_chain.c \ - src/os/unix/ngx_aio_write_chain.c" - FILE_AIO_SRCS="src/os/unix/ngx_file_aio_read.c" LINUX_AIO_SRCS="src/os/unix/ngx_linux_aio_read.c" diff -r f1f222db290b -r 4dc8e7b62216 src/core/ngx_connection.c --- a/src/core/ngx_connection.c Wed Apr 22 19:55:04 2015 +0300 +++ b/src/core/ngx_connection.c Wed Apr 22 18:57:32 2015 +0300 @@ -389,7 +389,7 @@ ngx_open_listening_sockets(ngx_cycle_t * #endif /* TODO: close on exit */ - if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) { + if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) { if (ngx_nonblocking(s) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, ngx_nonblocking_n " %V failed", diff -r f1f222db290b -r 4dc8e7b62216 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Wed Apr 22 19:55:04 2015 +0300 +++ b/src/core/ngx_resolver.c Wed Apr 22 18:57:32 2015 +0300 @@ -3092,7 +3092,7 @@ ngx_udp_connect(ngx_udp_connection_t *uc rc = connect(s, uc->sockaddr, uc->socklen); - /* TODO: aio, iocp */ + /* TODO: iocp */ if (rc == -1) { ngx_log_error(NGX_LOG_CRIT, &uc->log, ngx_socket_errno, diff -r f1f222db290b -r 4dc8e7b62216 src/event/modules/ngx_aio_module.c --- a/src/event/modules/ngx_aio_module.c Wed Apr 22 19:55:04 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,171 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include -#include -#include - - -extern ngx_event_module_t ngx_kqueue_module_ctx; - - -static ngx_int_t ngx_aio_init(ngx_cycle_t *cycle, ngx_msec_t timer); -static void ngx_aio_done(ngx_cycle_t *cycle); -static ngx_int_t ngx_aio_add_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_aio_del_event(ngx_event_t *ev, ngx_int_t event, - ngx_uint_t flags); -static ngx_int_t ngx_aio_del_connection(ngx_connection_t *c, ngx_uint_t flags); -static ngx_int_t ngx_aio_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags); - - -ngx_os_io_t ngx_os_aio = { - ngx_aio_read, - ngx_aio_read_chain, - NULL, - ngx_aio_write, - ngx_aio_write_chain, - 0 -}; - - -static ngx_str_t aio_name = ngx_string("aio"); - -ngx_event_module_t ngx_aio_module_ctx = { - &aio_name, - NULL, /* create configuration */ - NULL, /* init configuration */ - - { - ngx_aio_add_event, /* add an event */ - ngx_aio_del_event, /* delete an event */ - NULL, /* enable an event */ - NULL, /* disable an event */ - NULL, /* add an connection */ - ngx_aio_del_connection, /* delete an connection */ - NULL, /* trigger a notify */ - ngx_aio_process_events, /* process the events */ - ngx_aio_init, /* init the events */ - ngx_aio_done /* done the events */ - } - -}; - -ngx_module_t ngx_aio_module = { - NGX_MODULE_V1, - &ngx_aio_module_ctx, /* module context */ - NULL, /* module directives */ - NGX_EVENT_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ - NGX_MODULE_V1_PADDING -}; - - -#if (NGX_HAVE_KQUEUE) - -static ngx_int_t -ngx_aio_init(ngx_cycle_t *cycle, ngx_msec_t timer) -{ - if (ngx_kqueue_module_ctx.actions.init(cycle, timer) == NGX_ERROR) { - return NGX_ERROR; - } - - ngx_io = ngx_os_aio; - - ngx_event_flags = NGX_USE_AIO_EVENT; - ngx_event_actions = ngx_aio_module_ctx.actions; - - - return NGX_OK; -} - - -static void -ngx_aio_done(ngx_cycle_t *cycle) -{ - ngx_kqueue_module_ctx.actions.done(cycle); -} - - -/* the event adding and deleting are needed for the listening sockets */ - -static ngx_int_t -ngx_aio_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - return ngx_kqueue_module_ctx.actions.add(ev, event, flags); -} - - -static ngx_int_t -ngx_aio_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) -{ - return ngx_kqueue_module_ctx.actions.del(ev, event, flags); -} - - -static ngx_int_t -ngx_aio_del_connection(ngx_connection_t *c, ngx_uint_t flags) -{ - int rc; - - if (c->read->active == 0 && c->write->active == 0) { - return NGX_OK; - } - - if (flags & NGX_CLOSE_EVENT) { - return NGX_OK; - } - - rc = aio_cancel(c->fd, NULL); - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "aio_cancel: %d", rc); - - if (rc == AIO_CANCELED) { - c->read->active = 0; - c->write->active = 0; - return NGX_OK; - } - - if (rc == AIO_ALLDONE) { - c->read->active = 0; - c->write->active = 0; - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "aio_cancel() returned AIO_ALLDONE"); - return NGX_OK; - } - - if (rc == -1) { - ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, - "aio_cancel() failed"); - return NGX_ERROR; - } - - if (rc == AIO_NOTCANCELED) { - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "aio_cancel() returned AIO_NOTCANCELED"); - - return NGX_ERROR; - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_aio_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags) -{ - return ngx_kqueue_module_ctx.actions.process_events(cycle, timer, flags); -} - -#endif /* NGX_HAVE_KQUEUE */ diff -r f1f222db290b -r 4dc8e7b62216 src/event/modules/ngx_iocp_module.c --- a/src/event/modules/ngx_iocp_module.c Wed Apr 22 19:55:04 2015 +0300 +++ b/src/event/modules/ngx_iocp_module.c Wed Apr 22 18:57:32 2015 +0300 @@ -125,7 +125,7 @@ ngx_iocp_init(ngx_cycle_t *cycle, ngx_ms ngx_event_actions = ngx_iocp_module_ctx.actions; - ngx_event_flags = NGX_USE_AIO_EVENT|NGX_USE_IOCP_EVENT; + ngx_event_flags = NGX_USE_IOCP_EVENT; if (timer == 0) { return NGX_OK; diff -r f1f222db290b -r 4dc8e7b62216 src/event/ngx_event.c --- a/src/event/ngx_event.c Wed Apr 22 19:55:04 2015 +0300 +++ b/src/event/ngx_event.c Wed Apr 22 18:57:32 2015 +0300 @@ -330,7 +330,7 @@ ngx_handle_read_event(ngx_event_t *rev, } } - /* aio, iocp, rtsig */ + /* iocp, rtsig */ return NGX_OK; } @@ -409,7 +409,7 @@ ngx_handle_write_event(ngx_event_t *wev, } From ru at nginx.com Thu Apr 23 11:18:18 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 23 Apr 2015 11:18:18 +0000 Subject: [nginx] Removed the obsolete rtsig module. Message-ID: details: http://hg.nginx.org/nginx/rev/adba26ff70b5 branches: changeset: 6126:adba26ff70b5 user: Ruslan Ermilov date: Thu Apr 23 14:17:40 2015 +0300 description: Removed the obsolete rtsig module. diffstat: auto/modules | 7 - auto/options | 5 - auto/os/linux | 12 - auto/sources | 3 - src/core/ngx_connection.c | 5 +- src/core/ngx_resolver.c | 24 +- src/event/modules/ngx_rtsig_module.c | 735 ----------------------------------- src/event/ngx_event.c | 58 +-- src/event/ngx_event.h | 10 +- src/event/ngx_event_accept.c | 41 +- src/http/ngx_http_request.c | 2 +- src/os/unix/ngx_linux.h | 2 - src/os/unix/ngx_linux_config.h | 6 - src/os/unix/ngx_linux_init.c | 33 - 14 files changed, 28 insertions(+), 915 deletions(-) diffs (truncated from 1220 to 300 lines): diff -r 4dc8e7b62216 -r adba26ff70b5 auto/modules --- a/auto/modules Wed Apr 22 18:57:32 2015 +0300 +++ b/auto/modules Thu Apr 23 14:17:40 2015 +0300 @@ -49,13 +49,6 @@ if [ $NGX_TEST_BUILD_EPOLL = YES ]; then CORE_SRCS="$CORE_SRCS $EPOLL_SRCS" fi -if [ $NGX_TEST_BUILD_RTSIG = YES ]; then - have=NGX_HAVE_RTSIG . auto/have - have=NGX_TEST_BUILD_RTSIG . auto/have - EVENT_MODULES="$EVENT_MODULES $RTSIG_MODULE" - CORE_SRCS="$CORE_SRCS $RTSIG_SRCS" -fi - if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = YES ]; then have=NGX_TEST_BUILD_SOLARIS_SENDFILEV . auto/have CORE_SRCS="$CORE_SRCS $SOLARIS_SENDFILEV_SRCS" diff -r 4dc8e7b62216 -r adba26ff70b5 auto/options --- a/auto/options Wed Apr 22 18:57:32 2015 +0300 +++ b/auto/options Thu Apr 23 14:17:40 2015 +0300 @@ -30,7 +30,6 @@ NGX_RPATH=NO NGX_TEST_BUILD_DEVPOLL=NO NGX_TEST_BUILD_EVENTPORT=NO NGX_TEST_BUILD_EPOLL=NO -NGX_TEST_BUILD_RTSIG=NO NGX_TEST_BUILD_SOLARIS_SENDFILEV=NO NGX_PLATFORM= @@ -38,7 +37,6 @@ NGX_WINE= EVENT_FOUND=NO -EVENT_RTSIG=NO EVENT_SELECT=NO EVENT_POLL=NO @@ -189,7 +187,6 @@ do --build=*) NGX_BUILD="$value" ;; --builddir=*) NGX_OBJS="$value" ;; - --with-rtsig_module) EVENT_RTSIG=YES ;; --with-select_module) EVENT_SELECT=YES ;; --without-select_module) EVENT_SELECT=NONE ;; --with-poll_module) EVENT_POLL=YES ;; @@ -327,7 +324,6 @@ use the \"--without-http_limit_conn_modu --test-build-devpoll) NGX_TEST_BUILD_DEVPOLL=YES ;; --test-build-eventport) NGX_TEST_BUILD_EVENTPORT=YES ;; --test-build-epoll) NGX_TEST_BUILD_EPOLL=YES ;; - --test-build-rtsig) NGX_TEST_BUILD_RTSIG=YES ;; --test-build-solaris-sendfilev) NGX_TEST_BUILD_SOLARIS_SENDFILEV=YES ;; *) @@ -362,7 +358,6 @@ cat << END --build=NAME set build name --builddir=DIR set build directory - --with-rtsig_module enable rtsig module --with-select_module enable select module --without-select_module disable select module --with-poll_module enable poll module diff -r 4dc8e7b62216 -r adba26ff70b5 auto/os/linux --- a/auto/os/linux Wed Apr 22 18:57:32 2015 +0300 +++ b/auto/os/linux Thu Apr 23 14:17:40 2015 +0300 @@ -26,18 +26,6 @@ version=$((`uname -r \ version=${version:-0} -# enable the rt signals on Linux between 2.2.19 and 2.6.17 - -if [ \( $version -ge 131603 -a $version -lt 132626 \) -o $EVENT_RTSIG = YES ] -then - echo " + rt signals found" - have=NGX_HAVE_RTSIG . auto/have - EVENT_MODULES="$EVENT_MODULES $RTSIG_MODULE" - CORE_SRCS="$CORE_SRCS $RTSIG_SRCS" - EVENT_FOUND=YES -fi - - # posix_fadvise64() had been implemented in 2.5.60 if [ $version -lt 132412 ]; then diff -r 4dc8e7b62216 -r adba26ff70b5 auto/sources --- a/auto/sources Wed Apr 22 18:57:32 2015 +0300 +++ b/auto/sources Thu Apr 23 14:17:40 2015 +0300 @@ -124,9 +124,6 @@ EVENTPORT_SRCS=src/event/modules/ngx_eve EPOLL_MODULE=ngx_epoll_module EPOLL_SRCS=src/event/modules/ngx_epoll_module.c -RTSIG_MODULE=ngx_rtsig_module -RTSIG_SRCS=src/event/modules/ngx_rtsig_module.c - IOCP_MODULE=ngx_iocp_module IOCP_SRCS=src/event/modules/ngx_iocp_module.c diff -r 4dc8e7b62216 -r adba26ff70b5 src/core/ngx_connection.c --- a/src/core/ngx_connection.c Wed Apr 22 18:57:32 2015 +0300 +++ b/src/core/ngx_connection.c Thu Apr 23 14:17:40 2015 +0300 @@ -764,10 +764,7 @@ ngx_close_listening_sockets(ngx_cycle_t if (c) { if (c->read->active) { - if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { - ngx_del_conn(c, NGX_CLOSE_EVENT); - - } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) { + if (ngx_event_flags & NGX_USE_EPOLL_EVENT) { /* * it seems that Linux-2.6.x OpenVZ sends events diff -r 4dc8e7b62216 -r adba26ff70b5 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Wed Apr 22 18:57:32 2015 +0300 +++ b/src/core/ngx_resolver.c Thu Apr 23 14:17:40 2015 +0300 @@ -3104,23 +3104,13 @@ ngx_udp_connect(ngx_udp_connection_t *uc /* UDP sockets are always ready to write */ wev->ready = 1; - if (ngx_add_event) { - - event = (ngx_event_flags & NGX_USE_CLEAR_EVENT) ? - /* kqueue, epoll */ NGX_CLEAR_EVENT: - /* select, poll, /dev/poll */ NGX_LEVEL_EVENT; - /* eventport event type has no meaning: oneshot only */ - - if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) { - goto failed; - } - - } else { - /* rtsig */ - - if (ngx_add_conn(c) == NGX_ERROR) { - goto failed; - } + event = (ngx_event_flags & NGX_USE_CLEAR_EVENT) ? + /* kqueue, epoll */ NGX_CLEAR_EVENT: + /* select, poll, /dev/poll */ NGX_LEVEL_EVENT; + /* eventport event type has no meaning: oneshot only */ + + if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) { + goto failed; } return NGX_OK; diff -r 4dc8e7b62216 -r adba26ff70b5 src/event/modules/ngx_rtsig_module.c --- a/src/event/modules/ngx_rtsig_module.c Wed Apr 22 18:57:32 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,735 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include -#include -#include - - -#if (NGX_TEST_BUILD_RTSIG) - -#if (NGX_DARWIN) - -#define SIGRTMIN 33 -#define si_fd __pad[0] - -#else - -#ifdef SIGRTMIN -#define si_fd _reason.__spare__.__spare2__[0] -#else -#define SIGRTMIN 33 -#define si_fd __spare__[0] -#endif - -#endif - -#define F_SETSIG 10 -#define KERN_RTSIGNR 30 -#define KERN_RTSIGMAX 31 - -int sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec *timeout); - -int sigtimedwait(const sigset_t *set, siginfo_t *info, - const struct timespec *timeout) -{ - return -1; -} - -int ngx_linux_rtsig_max; - -#endif - - -typedef struct { - ngx_uint_t signo; - ngx_uint_t overflow_events; - ngx_uint_t overflow_test; - ngx_uint_t overflow_threshold; -} ngx_rtsig_conf_t; - - -extern ngx_event_module_t ngx_poll_module_ctx; - -static ngx_int_t ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer); -static void ngx_rtsig_done(ngx_cycle_t *cycle); -static ngx_int_t ngx_rtsig_add_connection(ngx_connection_t *c); -static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c, - ngx_uint_t flags); -static ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle, - ngx_msec_t timer, ngx_uint_t flags); -static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle, - ngx_msec_t timer, ngx_uint_t flags); - -static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle); -static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf); -static char *ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf, - void *post, void *data); - - -static sigset_t set; -static ngx_uint_t overflow, overflow_current; -static struct pollfd *overflow_list; - - -static ngx_str_t rtsig_name = ngx_string("rtsig"); - -static ngx_conf_num_bounds_t ngx_overflow_threshold_bounds = { - ngx_check_ngx_overflow_threshold_bounds, 2, 10 -}; - - -static ngx_command_t ngx_rtsig_commands[] = { - - { ngx_string("rtsig_signo"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_rtsig_conf_t, signo), - NULL }, - - { ngx_string("rtsig_overflow_events"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_rtsig_conf_t, overflow_events), - NULL }, - - { ngx_string("rtsig_overflow_test"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_rtsig_conf_t, overflow_test), - NULL }, - - { ngx_string("rtsig_overflow_threshold"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_rtsig_conf_t, overflow_threshold), - &ngx_overflow_threshold_bounds }, - - ngx_null_command -}; - - -ngx_event_module_t ngx_rtsig_module_ctx = { - &rtsig_name, - ngx_rtsig_create_conf, /* create configuration */ - ngx_rtsig_init_conf, /* init configuration */ - - { - NULL, /* add an event */ - NULL, /* delete an event */ - NULL, /* enable an event */ - NULL, /* disable an event */ - ngx_rtsig_add_connection, /* add an connection */ - ngx_rtsig_del_connection, /* delete an connection */ - NULL, /* trigger a notify */ - ngx_rtsig_process_events, /* process the events */ - ngx_rtsig_init, /* init the events */ - ngx_rtsig_done, /* done the events */ - } - -}; - -ngx_module_t ngx_rtsig_module = { - NGX_MODULE_V1, - &ngx_rtsig_module_ctx, /* module context */ - ngx_rtsig_commands, /* module directives */ - NGX_EVENT_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ From ru at nginx.com Thu Apr 23 11:51:19 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 23 Apr 2015 11:51:19 +0000 Subject: [nginx] Removed the "worker_rlimit_sigpending" directive. Message-ID: details: http://hg.nginx.org/nginx/rev/967594ba7571 branches: changeset: 6127:967594ba7571 user: Ruslan Ermilov date: Thu Apr 23 14:26:11 2015 +0300 description: Removed the "worker_rlimit_sigpending" directive. It was only needed by the just removed rtsig module. diffstat: src/core/nginx.c | 8 -------- src/core/ngx_cycle.h | 1 - src/os/unix/ngx_process_cycle.c | 13 ------------- 3 files changed, 0 insertions(+), 22 deletions(-) diffs (59 lines): diff -r adba26ff70b5 -r 967594ba7571 src/core/nginx.c --- a/src/core/nginx.c Thu Apr 23 14:17:40 2015 +0300 +++ b/src/core/nginx.c Thu Apr 23 14:26:11 2015 +0300 @@ -118,13 +118,6 @@ static ngx_command_t ngx_core_commands[ offsetof(ngx_core_conf_t, rlimit_core), NULL }, - { ngx_string("worker_rlimit_sigpending"), - NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_core_conf_t, rlimit_sigpending), - NULL }, - { ngx_string("working_directory"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -948,7 +941,6 @@ ngx_core_module_create_conf(ngx_cycle_t ccf->rlimit_nofile = NGX_CONF_UNSET; ccf->rlimit_core = NGX_CONF_UNSET; - ccf->rlimit_sigpending = NGX_CONF_UNSET; ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT; ccf->group = (ngx_gid_t) NGX_CONF_UNSET_UINT; diff -r adba26ff70b5 -r 967594ba7571 src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h Thu Apr 23 14:17:40 2015 +0300 +++ b/src/core/ngx_cycle.h Thu Apr 23 14:26:11 2015 +0300 @@ -83,7 +83,6 @@ typedef struct { ngx_int_t debug_points; ngx_int_t rlimit_nofile; - ngx_int_t rlimit_sigpending; off_t rlimit_core; int priority; diff -r adba26ff70b5 -r 967594ba7571 src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c Thu Apr 23 14:17:40 2015 +0300 +++ b/src/os/unix/ngx_process_cycle.c Thu Apr 23 14:26:11 2015 +0300 @@ -840,19 +840,6 @@ ngx_worker_process_init(ngx_cycle_t *cyc } } -#ifdef RLIMIT_SIGPENDING - if (ccf->rlimit_sigpending != NGX_CONF_UNSET) { - rlmt.rlim_cur = (rlim_t) ccf->rlimit_sigpending; - rlmt.rlim_max = (rlim_t) ccf->rlimit_sigpending; - - if (setrlimit(RLIMIT_SIGPENDING, &rlmt) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "setrlimit(RLIMIT_SIGPENDING, %i) failed", - ccf->rlimit_sigpending); - } - } -#endif - if (geteuid() == 0) { if (setgid(ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, From dani at telecom.pt Thu Apr 23 12:03:12 2015 From: dani at telecom.pt (Dani Bento) Date: Thu, 23 Apr 2015 13:03:12 +0100 Subject: nginx-log-zmq module Message-ID: <20150423130312.4979f361@alma> Hello, We recently wrote a nginx module (https://github.com/sapo/nginx-log-zmq) and it may be interesting to add it to the 3rd Party Modules page. It's possible? What we have to do to put our information there? Thanks, Dani -- Dani Bento Dire??o de Internet e Tecnologia DTS/DVS tlm: +351 91 429 72 81 dani at telecom.pt From grantksupport at operamail.com Thu Apr 23 23:15:40 2015 From: grantksupport at operamail.com (grantksupport at operamail.com) Date: Thu, 23 Apr 2015 16:15:40 -0700 Subject: Building nginx 1.8.0, linking to local-install of Openssl, 'nginx -V' still reports "built with" *system* openssl. why? Message-ID: <1429830940.1335157.257873777.22445FAD@webmail.messagingengine.com> I'm building nginx 1.8.0 on linux/64. I have openssl 1.0.2a built locally, and installed into /usr/local/ssl which openssl /usr/local/ssl/bin/openssl I've configured nginx build with ./configure \ ... --with-cc-opt='... -I/usr/local/ssl/include -I/usr/local/include' \ --with-ld-opt='-L/usr/local/ssl/lib64 -Wl,-rpath,/usr/local/ssl/lib64 -lssl -lcrypto -ldl -lz' \ --with-http_ssl_module \ ... checking after build/install, the intended ssl libs ARE correctly linked ldd objs/nginx | egrep -i "ssl|crypto" libssl.so.1.0.0 => /usr/local/ssl/lib64/libssl.so.1.0.0 (0x00007f9cedd2b000) libcrypto.so.1.0.0 => /usr/local/ssl/lib64/libcrypto.so.1.0.0 (0x00007f9ced8e8000) But 'nginx -V' references BOTH the system-installed OpenSSL 1.0.1k-fips, and 'my' OpenSSL 1.0.2a nginx -V nginx version: nginx/1.8.0 built with OpenSSL 1.0.1k-fips 8 Jan 2015 (running with OpenSSL 1.0.2a 19 Mar 2015) TLS SNI support enabled configure arguments: ... I want to ensure that the system-installed OpenSSL 1.0.1k-fips is completely UNinvolved. What needs to change in the build/config to make sure that it's not? grant From serg.brester at sebres.de Thu Apr 23 23:21:41 2015 From: serg.brester at sebres.de (Sergey Brester) Date: Fri, 24 Apr 2015 01:21:41 +0200 Subject: Fwd: Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) In-Reply-To: References: <706ca3a5ec658ea41fb9975f90ab9ab4@sebres.de> <20150422162929.GD32429@mdounin.ru> Message-ID: <54cf66a081e1767be9e630003485c4fa@sebres.de> Hello, > There are lots of style problems which need cleanup. The newer, "nginx-style" compliant version of changeset (shmem fix2.patch) was already posted to nginx-devel (Thx, Filipe DA SILVA). You will find it also on under https://github.com/sebres/nginx/commit/e7c149f1ad76b9d850fb59ecc479d4a658c13e04 [4]. > Such things belong to ngx_win32_init.c. It may be also good > enough to use ngx_pagesize, which is already set there. Agree, but some (little) things can reside in same module, where these are used (noted as todo). > This probably should be somewhere at ngx_win32_config.h. Imho, belong definitelly in shmem module. But don't want to fight about it :) > It might be better idea to save the address at the end of the > memory block allocated... And for example stop to work of other new worker (when unfortunately overwriting of it occurs). That brings at once many problem and restrictions later (for example more difficult implementing of shared area resizing, etc). And for what? To save 2 line code for decrement addr pointer in ngx_shm_free? > Have you tried using an arbitrary addresses (with subsequent > remap using proper base address for already existing mappings)? > Does is work noticeably worse? I've fought against ASLR since 2008 resp. x64 was released and it was essential. This specific solution is extensively tested and runs in production also without any problems (not only in nginx). Regards, sebres. Am 22.04.2015 18:29, schrieb Maxim Dounin: > Hello! > > On Wed, Apr 22, 2015 at 09:45:45AM +0200, Sergey Brester wrote: > >> enclosed you will find an attached changeset, that fixes a ASLR/DEP problem on windows platforms (example Win 7/2008 x64). To find shared addr offset with ASLR, we have successful used the same resp. similar solution on various open source projects (ex.: postgresql etc.). Also nginx with suggested patch works fine over 5 months in production on several machines (Win-2k8-R2). > > Interesting, thanks, though the patch certainly needs some > cleanup. See below for some comments. > >> BTW(1): I have interest to fix a problem with multiple workers under windows (ex.: http://forum.nginx.org/read.php?2,188714,188714#msg-188714 [1] [1]). @Maxim Dounin: can you possibly give me more information, what you mean here, resp. what it currently depends on (see http://forum.nginx.org/read.php?2,188714,212568#msg-212568 [2] [2]). > > The most obvious problem with multiple workers on Windows is > listening sockets. As of now, if you start multiple workers on > windows, nginx will open multiple listening sockets - one in each > worker process. These are independant sockets, each opened with > SO_REUSEADDR, and only one of these sockets will be able to accept > connections. > > Possible solution to the problem would be to pass listening sockets > from a master process to worker processes via handle inheritance > as available in Windows: > > http://msdn.microsoft.com/en-us/library/windows/desktop/ms683463(v=vs.85).aspx [3] > > [...] > >> # HG changeset patch # User Serg G. Brester (sebres) # Date 1429643760 -7200 # Tue Apr 21 21:16:00 2015 +0200 # Branch sb-mod # Node ID f759f7084204bb1f3c2b0a8023a8f03a81da9a0b # Parent 1bdfceda86a99a4dc99934181d2f9e2632003ca8 Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) diff -r 1bdfceda86a9 -r f759f7084204 src/os/win32/ngx_shmem.c --- a/src/os/win32/ngx_shmem.c Mon Apr 20 17:36:51 2015 +0300 +++ b/src/os/win32/ngx_shmem.c Tue Apr 21 21:16:00 2015 +0200 @@ -9,11 +9,30 @@ #include +static volatile size_t g_addrbaseoffs = 0; + +static volatile int g_SystemInfo_init = 0; +SYSTEM_INFO g_SystemInfo; + +int ngx_shm_init_once() { + if (g_SystemInfo_init) + return 1; + g_SystemInfo_init = 1; + GetSystemInfo(&g_SystemInfo); + return 1; +} > > Such things belong to ngx_win32_init.c. It may be also good > enough to use ngx_pagesize, which is already set there. > >> + +/* ------------------- */ + > > There are lots of style problems which need cleanup. > >> ngx_int_t ngx_shm_alloc(ngx_shm_t *shm) { u_char *name; uint64_t size; + u_char *addr; + u_char *addrbase; + + ngx_shm_init_once(); name = ngx_alloc(shm->name.len + 2 + NGX_INT32_LEN, shm->log); if (name == NULL) { @@ -26,6 +45,9 @@ size = shm->size; + // increase for base address, will be saved inside shared mem : + size += sizeof(addr); + > > As of now, uses of ngx_shm_alloc() already contain address in the > shared memory region where addresses are important. It may worth > to try to use it, if possible (may be with some additional call to > redo the mapping with the address specified). > >> shm->handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, (u_long) (size >> 32), (u_long) (size & 0xffffffff), @@ -34,7 +56,7 @@ if (shm->handle == NULL) { ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, "CreateFileMapping(%uz, %s) failed", - shm->size, name); + size, name); ngx_free(name); return NGX_ERROR; @@ -42,14 +64,79 @@ ngx_free(name); + shm->exists = 0; > > This looks like an unneeded change. The exists flag is set to 0 > in ngx_shared_memory_add(), when ngx_shm_t is allocated and > initialized. > >> if (ngx_errno == ERROR_ALREADY_EXISTS) { shm->exists = 1; } - shm->addr = MapViewOfFile(shm->handle, FILE_MAP_WRITE, 0, 0, 0); + /* + // Because of Win x64 since Vista/Win7 (always ASLR in kernel32), and nginx uses pointer + // inside this shared areas, we should use the same address for shared memory (Windows IPC) + + // Now we set preferred base to a hardcoded address that newborn processes never seem to be using (in available versions of Windows). + // The addresses was selected somewhat randomly in order to minimize the probability that some other library doing something similar + // conflicts with us. That is, using conspicuous addresses like 0x20000000 might not be good if someone else does it. + */ + #ifdef _WIN64 + /* + * There is typically a giant hole (almost 8TB): + * 00000000 7fff0000 + * ... + * 000007f6 8e8b0000 + */ + addrbase = (u_char*)0x0000047047e00000ULL; + #else + /* + * This is more dicey. However, even with ASLR there still + * seems to be a big hole: + * 10000000 + * ... + * 70000000 + */ + addrbase = (u_char*)0x2efe0000; + #endif > > This probably should be somewhere at ngx_win32_config.h. > >> - if (shm->addr != NULL) { + // add offset (corresponding all used shared) to preferred base: + addrbase += g_addrbaseoffs; + + addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, addrbase); > > Have you tried using an arbitrary addresses (with subsequent > remap using proper base address for already existing mappings)? > Does is work noticeably worse? > >> + + ngx_log_debug4(NGX_LOG_DEBUG_CORE, shm->log, 0, "map shared "%V" -> %p (base %p), size: %uz", &shm->name, addr, addrbase, size); + + if (addr != NULL) { + + // get allocated address if already exists: + if (shm->exists) { + // get base and realoc using it if different: + addrbase = *(u_char **)addr; + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, 0, "shared "%V" -> %p -> %p", &shm->name, addr, addrbase); + if (addrbase != addr) { + // free: + if (UnmapViewOfFile(addr) == 0) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "UnmapViewOfFile(%p) of file mapping "%V" failed", + addr, &shm->name); + } + // allocate again using base address: + addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, + addrbase // lpBaseAddress + ); + } + } else { + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, 0, "shared "%V" -> %p (base %p)", &shm->name, addr, addrbase); + // save first allocated address as base for next caller : + *(u_char **)addr = addr; > > It might be better idea to save the address at the end of the > memory block allocated, this will at least allow to avoid address > manipulation here and in ngx_shm_free(). Or use the address > stored in the memory block itself, see above. > >> + } + + if (addr != NULL) { + // increase base offset (use proper alignment, obtain it from dwAllocationGranularity): + g_addrbaseoffs += (size + g_SystemInfo.dwAllocationGranularity) & (0xffffffff & ~(g_SystemInfo.dwAllocationGranularity-1)); + //ngx_log_debug2(NGX_LOG_DEBUG_CORE, shm->log, 0, "offset %ui, granularity %ui", g_addrbaseoffs, g_SystemInfo.dwAllocationGranularity); + shm->addr = addr + sizeof(addr); + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, 0, "shared alloc "%V" -> %p = %p", &shm->name, addr, shm->addr); return NGX_OK; + } + } ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, @@ -65,14 +152,17 @@ return NGX_ERROR; } - void > > Unrelated change (and a style bug). > >> ngx_shm_free(ngx_shm_t *shm) { - if (UnmapViewOfFile(shm->addr) == 0) { + u_char *addr; + + addr = shm->addr - sizeof(addr); + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, 0, "shared free "%V" -> %p = %p", &shm->name, addr, shm->addr); + if (UnmapViewOfFile(addr) == 0) { ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, "UnmapViewOfFile(%p) of file mapping "%V" failed", - shm->addr, &shm->name); + addr, &shm->name); } if (CloseHandle(shm->handle) == 0) { > > See above, this change shouldn't be needed. Links: ------ [1] http://forum.nginx.org/read.php?2,188714,188714#msg-188714 [2] http://forum.nginx.org/read.php?2,188714,212568#msg-212568 [3] http://msdn.microsoft.com/en-us/library/windows/desktop/ms683463(v=vs.85).aspx [4] https://github.com/sebres/nginx/commit/e7c149f1ad76b9d850fb59ecc479d4a658c13e04 -------------- next part -------------- An HTML attachment was scrubbed... URL: From ru at nginx.com Fri Apr 24 06:02:47 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Fri, 24 Apr 2015 09:02:47 +0300 Subject: Building nginx 1.8.0, linking to local-install of Openssl, 'nginx -V' still reports "built with" *system* openssl. why? In-Reply-To: <1429830940.1335157.257873777.22445FAD@webmail.messagingengine.com> References: <1429830940.1335157.257873777.22445FAD@webmail.messagingengine.com> Message-ID: <20150424060247.GJ53884@lo0.su> On Thu, Apr 23, 2015 at 04:15:40PM -0700, grantksupport at operamail.com wrote: > I'm building nginx 1.8.0 on linux/64. > > I have openssl 1.0.2a built locally, and installed into /usr/local/ssl > > which openssl > /usr/local/ssl/bin/openssl > > I've configured nginx build with > > ./configure \ > ... > --with-cc-opt='... -I/usr/local/ssl/include -I/usr/local/include' \ > --with-ld-opt='-L/usr/local/ssl/lib64 -Wl,-rpath,/usr/local/ssl/lib64 -lssl -lcrypto -ldl -lz' \ > --with-http_ssl_module \ > ... Pass absolutely the same CFLAGS as you specified in --with-cc-opt, including those hidden by "...", to the following command: $ cpp -include openssl/opensslv.h -dM /dev/null | grep OPENSSL_VERSION_TEXT If it shows 1.0.1k, then probably something in the search path (verify with the same command plus -v) picks up the wrong include file. > checking after build/install, the intended ssl libs ARE correctly linked > > ldd objs/nginx | egrep -i "ssl|crypto" > libssl.so.1.0.0 => /usr/local/ssl/lib64/libssl.so.1.0.0 (0x00007f9cedd2b000) > libcrypto.so.1.0.0 => /usr/local/ssl/lib64/libcrypto.so.1.0.0 (0x00007f9ced8e8000) > > But 'nginx -V' references BOTH the system-installed OpenSSL 1.0.1k-fips, and 'my' OpenSSL 1.0.2a > > nginx -V > nginx version: nginx/1.8.0 > built with OpenSSL 1.0.1k-fips 8 Jan 2015 (running with OpenSSL 1.0.2a 19 Mar 2015) > TLS SNI support enabled > configure arguments: ... > > I want to ensure that the system-installed OpenSSL 1.0.1k-fips is completely UNinvolved. > > What needs to change in the build/config to make sure that it's not? > > grant > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Ruslan Ermilov From arut at nginx.com Fri Apr 24 07:55:16 2015 From: arut at nginx.com (Roman Arutyunyan) Date: Fri, 24 Apr 2015 07:55:16 +0000 Subject: [nginx] Merge proxy_protocol setting of listen directives. Message-ID: details: http://hg.nginx.org/nginx/rev/69ad3e77922b branches: changeset: 6128:69ad3e77922b user: Roman Arutyunyan date: Fri Apr 24 10:54:06 2015 +0300 description: Merge proxy_protocol setting of listen directives. It's now enough to specify proxy_protocol option in one listen directive to enable it in all servers listening on the same address/port. Previously, the setting from the first directive was always used. diffstat: src/http/ngx_http.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (29 lines): diff -r 967594ba7571 -r 69ad3e77922b src/http/ngx_http.c --- a/src/http/ngx_http.c Thu Apr 23 14:26:11 2015 +0300 +++ b/src/http/ngx_http.c Fri Apr 24 10:54:06 2015 +0300 @@ -1220,7 +1220,7 @@ ngx_http_add_addresses(ngx_conf_t *cf, n { u_char *p; size_t len, off; - ngx_uint_t i, default_server; + ngx_uint_t i, default_server, proxy_protocol; struct sockaddr *sa; ngx_http_conf_addr_t *addr; #if (NGX_HAVE_UNIX_DOMAIN) @@ -1281,6 +1281,8 @@ ngx_http_add_addresses(ngx_conf_t *cf, n /* preserve default_server bit during listen options overwriting */ default_server = addr[i].opt.default_server; + proxy_protocol = lsopt->proxy_protocol || addr[i].opt.proxy_protocol; + #if (NGX_HTTP_SSL) ssl = lsopt->ssl || addr[i].opt.ssl; #endif @@ -1314,6 +1316,7 @@ ngx_http_add_addresses(ngx_conf_t *cf, n } addr[i].opt.default_server = default_server; + addr[i].opt.proxy_protocol = proxy_protocol; #if (NGX_HTTP_SSL) addr[i].opt.ssl = ssl; #endif From yuva at codemancers.com Fri Apr 24 19:07:30 2015 From: yuva at codemancers.com (Yuva) Date: Sat, 25 Apr 2015 00:37:30 +0530 Subject: [Re-posting] http/2 support Message-ID: hi, (Im posting this mail as i feel devel mailing list is more appropriate than ideas and feature requests forum) I have read this post http://nginx.com/blog/how-nginx-plans-to-support-http2/ about http/2 support, and am pretty excited. Has the development already started? If yes, i would like to contribute. Please let me know. Thanks. -- Yuva (@iffyuva) Co-founder at Codemancers Tech Pvt Ltd http://codemancers.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Sat Apr 25 06:14:31 2015 From: vbart at nginx.com (Valentin V. Bartenev) Date: Sat, 25 Apr 2015 09:14:31 +0300 Subject: [Re-posting] http/2 support In-Reply-To: References: Message-ID: <8437251.cVXCZURXdE@vbart-laptop> On Saturday 25 April 2015 00:37:30 Yuva wrote: > hi, > (Im posting this mail as i feel devel mailing list is more appropriate > than ideas and feature requests forum) > > I have read this post > http://nginx.com/blog/how-nginx-plans-to-support-http2/ about http/2 > support, and am pretty excited. Has the development already started? If > yes, i would like to contribute. Please let me know. Thanks. > How would you like to contribute? wbr, Valentin V. Bartenev From yuva at codemancers.com Sat Apr 25 09:38:24 2015 From: yuva at codemancers.com (Yuva) Date: Sat, 25 Apr 2015 15:08:24 +0530 Subject: [Re-posting] http/2 support In-Reply-To: <8437251.cVXCZURXdE@vbart-laptop> References: <8437251.cVXCZURXdE@vbart-laptop> Message-ID: hi, I would like to contribute by coding. For a start, this is what im thinking: - get familiar with nginx spdy source code (since spdy is close to http/2) - understand source code written to support http/2, if any. - start with implementing small features, and fixing bugs. Thanks. On Sat, Apr 25, 2015 at 11:44 AM, Valentin V. Bartenev wrote: > On Saturday 25 April 2015 00:37:30 Yuva wrote: > > hi, > > (Im posting this mail as i feel devel mailing list is more appropriate > > than ideas and feature requests forum) > > > > I have read this post > > http://nginx.com/blog/how-nginx-plans-to-support-http2/ about http/2 > > support, and am pretty excited. Has the development already started? If > > yes, i would like to contribute. Please let me know. Thanks. > > > > How would you like to contribute? > > wbr, Valentin V. Bartenev > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Yuva (@iffyuva) Co-founder at Codemancers Tech Pvt Ltd http://codemancers.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From vl at nginx.com Sun Apr 26 07:28:49 2015 From: vl at nginx.com (Vladimir Homutov) Date: Sun, 26 Apr 2015 07:28:49 +0000 Subject: [nginx] Core: the ngx_set_connection_log() macro. Message-ID: details: http://hg.nginx.org/nginx/rev/187aa751ad62 branches: changeset: 6129:187aa751ad62 user: Vladimir Homutov date: Sat Apr 25 22:44:02 2015 +0300 description: Core: the ngx_set_connection_log() macro. The http and stream versions of this macro were identical. diffstat: src/core/ngx_connection.h | 11 +++++++++++ src/http/ngx_http_core_module.c | 2 +- src/http/ngx_http_request.c | 6 +++--- src/http/ngx_http_request.h | 11 ----------- src/stream/ngx_stream.c | 2 +- src/stream/ngx_stream.h | 10 ---------- src/stream/ngx_stream_handler.c | 2 +- 7 files changed, 17 insertions(+), 27 deletions(-) diffs (129 lines): diff -r 69ad3e77922b -r 187aa751ad62 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Fri Apr 24 10:54:06 2015 +0300 +++ b/src/core/ngx_connection.h Sat Apr 25 22:44:02 2015 +0300 @@ -190,6 +190,17 @@ struct ngx_connection_s { }; +#define ngx_set_connection_log(c, l) \ + \ + c->log->file = l->file; \ + c->log->next = l->next; \ + c->log->writer = l->writer; \ + c->log->wdata = l->wdata; \ + if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { \ + c->log->log_level = l->log_level; \ + } + + ngx_listening_t *ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen); ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle); diff -r 69ad3e77922b -r 187aa751ad62 src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Fri Apr 24 10:54:06 2015 +0300 +++ b/src/http/ngx_http_core_module.c Sat Apr 25 22:44:02 2015 +0300 @@ -1445,7 +1445,7 @@ ngx_http_update_location_config(ngx_http } if (r == r->main) { - ngx_http_set_connection_log(r->connection, clcf->error_log); + ngx_set_connection_log(r->connection, clcf->error_log); } if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) { diff -r 69ad3e77922b -r 187aa751ad62 src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Fri Apr 24 10:54:06 2015 +0300 +++ b/src/http/ngx_http_request.c Sat Apr 25 22:44:02 2015 +0300 @@ -543,7 +543,7 @@ ngx_http_create_request(ngx_connection_t clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - ngx_http_set_connection_log(r->connection, clcf->error_log); + ngx_set_connection_log(r->connection, clcf->error_log); r->header_in = hc->nbusy ? hc->busy[0] : c->buffer; @@ -867,7 +867,7 @@ ngx_http_ssl_servername(ngx_ssl_conn_t * clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module); - ngx_http_set_connection_log(c, clcf->error_log); + ngx_set_connection_log(c, clcf->error_log); sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); @@ -2073,7 +2073,7 @@ ngx_http_set_virtual_server(ngx_http_req clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - ngx_http_set_connection_log(r->connection, clcf->error_log); + ngx_set_connection_log(r->connection, clcf->error_log); return NGX_OK; } diff -r 69ad3e77922b -r 187aa751ad62 src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h Fri Apr 24 10:54:06 2015 +0300 +++ b/src/http/ngx_http_request.h Sat Apr 25 22:44:02 2015 +0300 @@ -586,17 +586,6 @@ extern ngx_http_header_t ngx_http_ extern ngx_http_header_out_t ngx_http_headers_out[]; -#define ngx_http_set_connection_log(c, l) \ - \ - c->log->file = l->file; \ - c->log->next = l->next; \ - c->log->writer = l->writer; \ - c->log->wdata = l->wdata; \ - if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { \ - c->log->log_level = l->log_level; \ - } - - #define ngx_http_set_log_request(log, r) \ ((ngx_http_log_ctx_t *) log->data)->current_request = r diff -r 69ad3e77922b -r 187aa751ad62 src/stream/ngx_stream.c --- a/src/stream/ngx_stream.c Fri Apr 24 10:54:06 2015 +0300 +++ b/src/stream/ngx_stream.c Sat Apr 25 22:44:02 2015 +0300 @@ -370,8 +370,8 @@ ngx_stream_optimize_servers(ngx_conf_t * ls->pool_size = 256; cscf = addr->ctx->srv_conf[ngx_stream_core_module.ctx_index]; + ls->logp = cscf->error_log; - ls->log.data = &ls->addr_text; ls->log.handler = ngx_accept_log_error; diff -r 69ad3e77922b -r 187aa751ad62 src/stream/ngx_stream.h --- a/src/stream/ngx_stream.h Fri Apr 24 10:54:06 2015 +0300 +++ b/src/stream/ngx_stream.h Sat Apr 25 22:44:02 2015 +0300 @@ -192,16 +192,6 @@ typedef struct { ->main_conf[module.ctx_index]: \ NULL) -#define ngx_stream_set_connection_log(c, l) \ - \ - c->log->file = l->file; \ - c->log->next = l->next; \ - c->log->writer = l->writer; \ - c->log->wdata = l->wdata; \ - if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { \ - c->log->log_level = l->log_level; \ - } - void ngx_stream_init_connection(ngx_connection_t *c); void ngx_stream_close_connection(ngx_connection_t *c); diff -r 69ad3e77922b -r 187aa751ad62 src/stream/ngx_stream_handler.c --- a/src/stream/ngx_stream_handler.c Fri Apr 24 10:54:06 2015 +0300 +++ b/src/stream/ngx_stream_handler.c Sat Apr 25 22:44:02 2015 +0300 @@ -130,7 +130,7 @@ ngx_stream_init_connection(ngx_connectio cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); - ngx_stream_set_connection_log(c, cscf->error_log); + ngx_set_connection_log(c, cscf->error_log); len = ngx_sock_ntop(c->sockaddr, c->socklen, text, NGX_SOCKADDR_STRLEN, 1); From vl at nginx.com Sun Apr 26 07:28:52 2015 From: vl at nginx.com (Vladimir Homutov) Date: Sun, 26 Apr 2015 07:28:52 +0000 Subject: [nginx] Mail: error_log support. Message-ID: details: http://hg.nginx.org/nginx/rev/fc99323a3d79 branches: changeset: 6130:fc99323a3d79 user: Vladimir Homutov date: Fri Feb 20 15:31:37 2015 +0300 description: Mail: error_log support. diffstat: src/mail/ngx_mail.c | 16 +++++++++------- src/mail/ngx_mail.h | 1 + src/mail/ngx_mail_core_module.c | 27 +++++++++++++++++++++++++++ src/mail/ngx_mail_handler.c | 29 +++++++++++++++++------------ 4 files changed, 54 insertions(+), 19 deletions(-) diffs (156 lines): diff -r 187aa751ad62 -r fc99323a3d79 src/mail/ngx_mail.c --- a/src/mail/ngx_mail.c Sat Apr 25 22:44:02 2015 +0300 +++ b/src/mail/ngx_mail.c Fri Feb 20 15:31:37 2015 +0300 @@ -334,11 +334,12 @@ found: static char * ngx_mail_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) { - ngx_uint_t i, p, last, bind_wildcard; - ngx_listening_t *ls; - ngx_mail_port_t *mport; - ngx_mail_conf_port_t *port; - ngx_mail_conf_addr_t *addr; + ngx_uint_t i, p, last, bind_wildcard; + ngx_listening_t *ls; + ngx_mail_port_t *mport; + ngx_mail_conf_port_t *port; + ngx_mail_conf_addr_t *addr; + ngx_mail_core_srv_conf_t *cscf; port = ports->elts; for (p = 0; p < ports->nelts; p++) { @@ -380,8 +381,9 @@ ngx_mail_optimize_servers(ngx_conf_t *cf ls->handler = ngx_mail_init_connection; ls->pool_size = 256; - /* TODO: error_log directive */ - ls->logp = &cf->cycle->new_log; + cscf = addr->ctx->srv_conf[ngx_mail_core_module.ctx_index]; + + ls->logp = cscf->error_log; ls->log.data = &ls->addr_text; ls->log.handler = ngx_accept_log_error; diff -r 187aa751ad62 -r fc99323a3d79 src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h Sat Apr 25 22:44:02 2015 +0300 +++ b/src/mail/ngx_mail.h Fri Feb 20 15:31:37 2015 +0300 @@ -139,6 +139,7 @@ typedef struct { ngx_int_t line; ngx_resolver_t *resolver; + ngx_log_t *error_log; /* server ctx */ ngx_mail_conf_ctx_t *ctx; diff -r 187aa751ad62 -r fc99323a3d79 src/mail/ngx_mail_core_module.c --- a/src/mail/ngx_mail_core_module.c Sat Apr 25 22:44:02 2015 +0300 +++ b/src/mail/ngx_mail_core_module.c Fri Feb 20 15:31:37 2015 +0300 @@ -21,6 +21,8 @@ static char *ngx_mail_core_listen(ngx_co void *conf); static char *ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_mail_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); static char *ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -75,6 +77,13 @@ static ngx_command_t ngx_mail_core_comm offsetof(ngx_mail_core_srv_conf_t, server_name), NULL }, + { ngx_string("error_log"), + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, + ngx_mail_core_error_log, + NGX_MAIL_SRV_CONF_OFFSET, + 0, + NULL }, + { ngx_string("resolver"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, ngx_mail_core_resolver, @@ -161,6 +170,7 @@ ngx_mail_core_create_srv_conf(ngx_conf_t * set by ngx_pcalloc(): * * cscf->protocol = NULL; + * cscf->error_log = NULL; */ cscf->timeout = NGX_CONF_UNSET_MSEC; @@ -202,6 +212,14 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t return NGX_CONF_ERROR; } + if (conf->error_log == NULL) { + if (prev->error_log) { + conf->error_log = prev->error_log; + } else { + conf->error_log = &cf->cycle->new_log; + } + } + ngx_conf_merge_ptr_value(conf->resolver, prev->resolver, NULL); return NGX_CONF_OK; @@ -601,6 +619,15 @@ ngx_mail_core_protocol(ngx_conf_t *cf, n static char * +ngx_mail_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_mail_core_srv_conf_t *cscf = conf; + + return ngx_log_set_log(cf, &cscf->error_log); +} + + +static char * ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_mail_core_srv_conf_t *cscf = conf; diff -r 187aa751ad62 -r fc99323a3d79 src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c Sat Apr 25 22:44:02 2015 +0300 +++ b/src/mail/ngx_mail_handler.c Fri Feb 20 15:31:37 2015 +0300 @@ -24,19 +24,20 @@ static ngx_int_t ngx_mail_verify_cert(ng void ngx_mail_init_connection(ngx_connection_t *c) { - size_t len; - ngx_uint_t i; - ngx_mail_port_t *port; - struct sockaddr *sa; - struct sockaddr_in *sin; - ngx_mail_log_ctx_t *ctx; - ngx_mail_in_addr_t *addr; - ngx_mail_session_t *s; - ngx_mail_addr_conf_t *addr_conf; - u_char text[NGX_SOCKADDR_STRLEN]; + size_t len; + ngx_uint_t i; + ngx_mail_port_t *port; + struct sockaddr *sa; + struct sockaddr_in *sin; + ngx_mail_log_ctx_t *ctx; + ngx_mail_in_addr_t *addr; + ngx_mail_session_t *s; + ngx_mail_addr_conf_t *addr_conf; + ngx_mail_core_srv_conf_t *cscf; + u_char text[NGX_SOCKADDR_STRLEN]; #if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; - ngx_mail_in6_addr_t *addr6; + struct sockaddr_in6 *sin6; + ngx_mail_in6_addr_t *addr6; #endif @@ -133,6 +134,10 @@ ngx_mail_init_connection(ngx_connection_ c->data = s; s->connection = c; + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + + ngx_set_connection_log(c, cscf->error_log); + len = ngx_sock_ntop(c->sockaddr, c->socklen, text, NGX_SOCKADDR_STRLEN, 1); ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA client %*s connected to %V", From mdounin at mdounin.ru Mon Apr 27 01:25:30 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 27 Apr 2015 04:25:30 +0300 Subject: Fwd: Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) In-Reply-To: <54cf66a081e1767be9e630003485c4fa@sebres.de> References: <706ca3a5ec658ea41fb9975f90ab9ab4@sebres.de> <20150422162929.GD32429@mdounin.ru> <54cf66a081e1767be9e630003485c4fa@sebres.de> Message-ID: <20150427012530.GS32429@mdounin.ru> Hello! On Fri, Apr 24, 2015 at 01:21:41AM +0200, Sergey Brester wrote: > Hello, > > > There are lots of style problems which need cleanup. > > The newer, "nginx-style" compliant version of changeset (shmem > fix2.patch) was already posted to nginx-devel (Thx, Filipe DA SILVA). > You will find it also on under > https://github.com/sebres/nginx/commit/e7c149f1ad76b9d850fb59ecc479d4a658c13e04 > [4]. It still needs cleanup, but I don't think it worth detailed comments as there are more important things to be addressed. > > Such things belong to ngx_win32_init.c. It may be also good > > enough to use ngx_pagesize, which is already set there. > > Agree, but some (little) things can reside in same module, where these > are used (noted as todo). > > > This probably should be somewhere at ngx_win32_config.h. > > Imho, belong definitelly in shmem module. But don't want to fight about > it :) The question here is a balance between code locality and visibility of platform-dependent constants for modifications. E.g., we've recently added 64-bit constants into ngx_win32_config.h to allow compilation of 64-bit windows binaries - and I'm perfectly sure shmem code would have been forgotten assuming it used just magic addresses as in your patch. May be some constants with appropriate comments at the top of the ngx_shmem.c file will be a good compromise solution. > > It might be better idea to save the address at the end of the > > memory block allocated... > > And for example stop to work of other new worker (when unfortunately > overwriting of it occurs). That brings at once many problem and > restrictions later (for example more difficult implementing of shared > area resizing, etc). And for what? To save 2 line code for decrement > addr pointer in ngx_shm_free? It won't be overwritten as long as you allocate additional bytes for it (as of now) and shm->size is not incremented. And yes, saving 2 lines of code is important - especially if it happens because the whole approach becomes simplier. Anyway, I think that we should try to use the address which is already present, see other comments. This will also avoid unneeded restrictions on mappings where pointers are not stored. > > Have you tried using an arbitrary addresses (with subsequent > > remap using proper base address for already existing mappings)? > > Does is work noticeably worse? > > I've fought against ASLR since 2008 resp. x64 was released and it was > essential. This specific solution is extensively tested and runs in > production also without any problems (not only in nginx). So the answer is "no", right? Either way, I tried it myself, and it seems to be noticeably worse - in my tests in most cases it can't use the address from the master process in workers due to conflicts with other allocations. When combined with base address selection, it seems to be much more stable. Below is a patch which takes into account above comments, and also fixes a problem observed with your patch on configuration reloads, e.g., when something like: proxy_cache_path cache1 keys_zone=cache1:10m; is changed to proxy_cache_path cache0 keys_zone=cache0:10m; proxy_cache_path cache1 keys_zone=cache1:10m; (i.e., when mappings are created in master and worker processes in a different order, resulting in conflicts between a mapping we are trying to create at some base address with a mapping already remapped to this address). Review, comments and testing appreciated. # HG changeset patch # User Maxim Dounin # Date 1430097438 -10800 # Mon Apr 27 04:17:18 2015 +0300 # Node ID 89cd9c63c58e5d7c474d317f83584779e2342ee3 # Parent 859ce1c41f642c39d2db9741bdd305f3ee6507f5 Win32: shared memory base addresses and remapping. Two mechanisms are implemented to make it possible to store pointers in shared memory on Windows, in particular on Windows Vista and later versions with ASLR: - The ngx_shm_remap() function added to allow remapping of a shared memory zone to the address originally used for it in the master process. While important, it doesn't solve the problem by itself as in many cases it's not possible to use the address because of conflicts with other allocations. - We now create mappings at the same address in all processes by starting mappings at predefined addresses normally unused by newborn processes. These two mechanisms combined allow to use shared memory on Windows almost without problems, including reloads. Based on the patch by Sergey Brester: http://mailman.nginx.org/pipermail/nginx-devel/2015-April/006836.html diff -r 859ce1c41f64 -r 89cd9c63c58e src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Mon Apr 27 03:44:30 2015 +0300 +++ b/src/core/ngx_cycle.c Mon Apr 27 04:17:18 2015 +0300 @@ -863,6 +863,22 @@ ngx_init_zone_pool(ngx_cycle_t *cycle, n return NGX_OK; } +#if (NGX_WIN32) + + /* remap at the required address */ + + if (ngx_shm_remap(&zn->shm, sp->addr) != NGX_OK) { + return NGX_ERROR; + } + + sp = (ngx_slab_pool_t *) zn->shm.addr; + + if (sp == sp->addr) { + return NGX_OK; + } + +#endif + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "shared zone \"%V\" has no equal addresses: %p vs %p", &zn->shm.name, sp->addr, sp); diff -r 859ce1c41f64 -r 89cd9c63c58e src/os/win32/ngx_shmem.c --- a/src/os/win32/ngx_shmem.c Mon Apr 27 03:44:30 2015 +0300 +++ b/src/os/win32/ngx_shmem.c Mon Apr 27 04:17:18 2015 +0300 @@ -9,11 +9,44 @@ #include +/* + * Base addresses selected by system for shared memory mappings are likely + * to be different on Windows Vista and later versions due to address space + * layout randomization. This is however incompatible with storing absolute + * addresses within the shared memory. + * + * To make it possible to store absolute addresses we create mappings + * at the same address in all processes by starting mappings at predefined + * addresses. The addresses was selected somewhat randomly in order to + * minimize the probability that some other library doing something similar + * conflicts with us. The addresses are from the following typically free + * blocks: + * + * - 0x10000000 .. 0x70000000 (about 1.8 GB in total) on 32-bit platforms + * - 0x000000007fff0000 .. 0x000007f68e8b0000 (about 8 TB) on 64-bit platforms + * + * Additionally, we allow to change the mapping address once it was detected + * to be different from one originally used. This is needed to support + * reconfiguration. + */ + + +#ifdef _WIN64 +#define NGX_SHMEM_BASE 0x0000047047e00000 +#else +#define NGX_SHMEM_BASE 0x2efe0000 +#endif + + +ngx_uint_t ngx_allocation_granularity; + + ngx_int_t ngx_shm_alloc(ngx_shm_t *shm) { - u_char *name; - uint64_t size; + u_char *name; + uint64_t size; + static u_char *base = (u_char *) NGX_SHMEM_BASE; name = ngx_alloc(shm->name.len + 2 + NGX_INT32_LEN, shm->log); if (name == NULL) { @@ -46,6 +79,27 @@ ngx_shm_alloc(ngx_shm_t *shm) shm->exists = 1; } + shm->addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, base); + + if (shm->addr != NULL) { + base += ngx_align(size, ngx_allocation_granularity); + return NGX_OK; + } + + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, ngx_errno, + "MapViewOfFileEx(%uz, %p) of file mapping \"%V\" failed, " + "retry without a base address", + shm->size, base, &shm->name); + + /* + * Order of shared memory zones may be different in the master process + * and worker processes after reconfiguration. As a result, the above + * may fail due to a conflict with a previously created mapping remapped + * to a different address. Additionally, there may be a conflict with + * some other uses of the memory. In this case we retry without a base + * address to let the system assign the address itself. + */ + shm->addr = MapViewOfFile(shm->handle, FILE_MAP_WRITE, 0, 0, 0); if (shm->addr != NULL) { @@ -66,6 +120,30 @@ ngx_shm_alloc(ngx_shm_t *shm) } +ngx_int_t +ngx_shm_remap(ngx_shm_t *shm, u_char *addr) +{ + if (UnmapViewOfFile(shm->addr) == 0) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "UnmapViewOfFile(%p) of file mapping \"%V\" failed", + shm->addr, &shm->name); + return NGX_ERROR; + } + + shm->addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, addr); + + if (shm->addr != NULL) { + return NGX_OK; + } + + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "MapViewOfFileEx(%uz, %p) of file mapping \"%V\" failed", + shm->size, addr, &shm->name); + + return NGX_ERROR; +} + + void ngx_shm_free(ngx_shm_t *shm) { diff -r 859ce1c41f64 -r 89cd9c63c58e src/os/win32/ngx_shmem.h --- a/src/os/win32/ngx_shmem.h Mon Apr 27 03:44:30 2015 +0300 +++ b/src/os/win32/ngx_shmem.h Mon Apr 27 04:17:18 2015 +0300 @@ -24,7 +24,10 @@ typedef struct { ngx_int_t ngx_shm_alloc(ngx_shm_t *shm); +ngx_int_t ngx_shm_remap(ngx_shm_t *shm, u_char *addr); void ngx_shm_free(ngx_shm_t *shm); +extern ngx_uint_t ngx_allocation_granularity; + #endif /* _NGX_SHMEM_H_INCLUDED_ */ diff -r 859ce1c41f64 -r 89cd9c63c58e src/os/win32/ngx_win32_init.c --- a/src/os/win32/ngx_win32_init.c Mon Apr 27 03:44:30 2015 +0300 +++ b/src/os/win32/ngx_win32_init.c Mon Apr 27 04:17:18 2015 +0300 @@ -118,6 +118,7 @@ ngx_os_init(ngx_log_t *log) GetSystemInfo(&si); ngx_pagesize = si.dwPageSize; + ngx_allocation_granularity = si.dwAllocationGranularity; ngx_ncpu = si.dwNumberOfProcessors; ngx_cacheline_size = NGX_CPU_CACHE_LINE; -- Maxim Dounin http://nginx.org/ From fdasilva at ingima.com Mon Apr 27 08:55:00 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Mon, 27 Apr 2015 08:55:00 +0000 Subject: [PATCH 1 of 2] Mail: add SSL Stapling support. Message-ID: Hi, everybody. I've noticed that this feature was not available in the SSL mail module. I was thinking it's easy to have until I have to deal with module post-configuration?;) Patch is also compatible with previous 1.6 and 1.8 nginx version. Regards, Filipe --- # HG changeset patch # User Filipe da Silva # Date 1430124785 -7200 # Mon Apr 27 10:53:05 2015 +0200 # Branch stable-1.6 # Node ID bc8fc02d70953b3e55a10312130f4c22c5adf1b7 # Parent c94bc8f034ff0a2201a19b9581aa4d8bf15188ec Mail: add SSL Stapling support. Same functionality as in http_ssl_module. Same configuration directives as in http_ssl_module. Compatible with nginx 1.6 and 1.8 diff -r c94bc8f034ff -r bc8fc02d7095 src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c Tue Apr 07 18:57:56 2015 +0300 +++ b/src/mail/ngx_mail_ssl_module.c Mon Apr 27 10:53:05 2015 +0200 @@ -137,6 +137,34 @@ static ngx_command_t ngx_mail_ssl_comma offsetof(ngx_mail_ssl_conf_t, session_timeout), NULL }, + { ngx_string("ssl_stapling"), + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_MAIL_SRV_CONF_OFFSET, + offsetof(ngx_mail_ssl_conf_t, stapling), + NULL }, + + { ngx_string("ssl_stapling_file"), + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_MAIL_SRV_CONF_OFFSET, + offsetof(ngx_mail_ssl_conf_t, stapling_file), + NULL }, + + { ngx_string("ssl_stapling_responder"), + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_MAIL_SRV_CONF_OFFSET, + offsetof(ngx_mail_ssl_conf_t, stapling_responder), + NULL }, + + { ngx_string("ssl_stapling_verify"), + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_MAIL_SRV_CONF_OFFSET, + offsetof(ngx_mail_ssl_conf_t, stapling_verify), + NULL }, + ngx_null_command }; @@ -191,6 +219,8 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf) * scf->ecdh_curve = { 0, NULL }; * scf->ciphers = { 0, NULL }; * scf->shm_zone = NULL; + * scf->stapling_file = { 0, NULL }; + * scf->stapling_responder = { 0, NULL }; */ scf->enable = NGX_CONF_UNSET; @@ -200,6 +230,8 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf) scf->session_timeout = NGX_CONF_UNSET; scf->session_tickets = NGX_CONF_UNSET; scf->session_ticket_keys = NGX_CONF_UNSET_PTR; + scf->stapling = NGX_CONF_UNSET; + scf->stapling_verify = NGX_CONF_UNSET; return scf; } @@ -236,6 +268,12 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve, NGX_DEFAULT_ECDH_CURVE); + ngx_conf_merge_value(conf->stapling, prev->stapling, 0); + ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0); + ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, ""); + ngx_conf_merge_str_value(conf->stapling_responder, + prev->stapling_responder, ""); + ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS); @@ -365,6 +403,17 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } + if (conf->stapling) { + + if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file, + &conf->stapling_responder, conf->stapling_verify) + != NGX_OK) + { + return NGX_CONF_ERROR; + } + + } + return NGX_CONF_OK; } diff -r c94bc8f034ff -r bc8fc02d7095 src/mail/ngx_mail_ssl_module.h --- a/src/mail/ngx_mail_ssl_module.h Tue Apr 07 18:57:56 2015 +0300 +++ b/src/mail/ngx_mail_ssl_module.h Mon Apr 27 10:53:05 2015 +0200 @@ -44,6 +44,11 @@ typedef struct { ngx_flag_t session_tickets; ngx_array_t *session_ticket_keys; + ngx_flag_t stapling; + ngx_flag_t stapling_verify; + ngx_str_t stapling_file; + ngx_str_t stapling_responder; + u_char *file; ngx_uint_t line; } ngx_mail_ssl_conf_t; From fdasilva at ingima.com Mon Apr 27 08:55:15 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Mon, 27 Apr 2015 08:55:15 +0000 Subject: [PATCH 2 of 2] Mail: add SSL stapling resolver and timeout. Message-ID: # HG changeset patch # User Filipe da Silva # Date 1430124786 -7200 # Mon Apr 27 10:53:06 2015 +0200 # Branch stable-1.6 # Node ID 55cca5107f72f4ed950a20265e2627296acfa4a5 # Parent bc8fc02d70953b3e55a10312130f4c22c5adf1b7 Mail: propagate resolver and resolver_timeout settings to SSL stapling Propagate resolver and resolver_timeout settings from mail core module to mail ssl module. Same functionality as in http_ssl_module. Compatible with nginx 1.6 and 1.8 diff -r bc8fc02d7095 -r 55cca5107f72 src/mail/ngx_mail.c --- a/src/mail/ngx_mail.c Mon Apr 27 10:53:05 2015 +0200 +++ b/src/mail/ngx_mail.c Mon Apr 27 10:53:06 2015 +0200 @@ -217,6 +217,21 @@ ngx_mail_block(ngx_conf_t *cf, ngx_comma } } + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_MAIL_MODULE) { + continue; + } + + module = ngx_modules[m]->ctx; + + if (module->postconfiguration) { + if (module->postconfiguration(cf) != NGX_OK) { + return NGX_CONF_ERROR; + } + } + } + + *cf = pcf; diff -r bc8fc02d7095 -r 55cca5107f72 src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h Mon Apr 27 10:53:05 2015 +0200 +++ b/src/mail/ngx_mail.h Mon Apr 27 10:53:06 2015 +0200 @@ -342,6 +342,8 @@ struct ngx_mail_protocol_s { typedef struct { ngx_mail_protocol_t *protocol; + ngx_int_t (*postconfiguration)(ngx_conf_t *cf); + void *(*create_main_conf)(ngx_conf_t *cf); char *(*init_main_conf)(ngx_conf_t *cf, void *conf); diff -r bc8fc02d7095 -r 55cca5107f72 src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c Mon Apr 27 10:53:05 2015 +0200 +++ b/src/mail/ngx_mail_auth_http_module.c Mon Apr 27 10:53:06 2015 +0200 @@ -113,6 +113,8 @@ static ngx_command_t ngx_mail_auth_http static ngx_mail_module_t ngx_mail_auth_http_module_ctx = { NULL, /* protocol */ + NULL, /* post configuration */ + NULL, /* create main configuration */ NULL, /* init main configuration */ diff -r bc8fc02d7095 -r 55cca5107f72 src/mail/ngx_mail_core_module.c --- a/src/mail/ngx_mail_core_module.c Mon Apr 27 10:53:05 2015 +0200 +++ b/src/mail/ngx_mail_core_module.c Mon Apr 27 10:53:06 2015 +0200 @@ -96,6 +96,8 @@ static ngx_command_t ngx_mail_core_comm static ngx_mail_module_t ngx_mail_core_module_ctx = { NULL, /* protocol */ + NULL, /* post configuration */ + ngx_mail_core_create_main_conf, /* create main configuration */ NULL, /* init main configuration */ diff -r bc8fc02d7095 -r 55cca5107f72 src/mail/ngx_mail_imap_module.c --- a/src/mail/ngx_mail_imap_module.c Mon Apr 27 10:53:05 2015 +0200 +++ b/src/mail/ngx_mail_imap_module.c Mon Apr 27 10:53:06 2015 +0200 @@ -86,6 +86,8 @@ static ngx_command_t ngx_mail_imap_comm static ngx_mail_module_t ngx_mail_imap_module_ctx = { &ngx_mail_imap_protocol, /* protocol */ + NULL, /* post configuration */ + NULL, /* create main configuration */ NULL, /* init main configuration */ diff -r bc8fc02d7095 -r 55cca5107f72 src/mail/ngx_mail_pop3_module.c --- a/src/mail/ngx_mail_pop3_module.c Mon Apr 27 10:53:05 2015 +0200 +++ b/src/mail/ngx_mail_pop3_module.c Mon Apr 27 10:53:06 2015 +0200 @@ -85,6 +85,8 @@ static ngx_command_t ngx_mail_pop3_comm static ngx_mail_module_t ngx_mail_pop3_module_ctx = { &ngx_mail_pop3_protocol, /* protocol */ + NULL, /* post configuration */ + NULL, /* create main configuration */ NULL, /* init main configuration */ diff -r bc8fc02d7095 -r 55cca5107f72 src/mail/ngx_mail_proxy_module.c --- a/src/mail/ngx_mail_proxy_module.c Mon Apr 27 10:53:05 2015 +0200 +++ b/src/mail/ngx_mail_proxy_module.c Mon Apr 27 10:53:06 2015 +0200 @@ -81,6 +81,8 @@ static ngx_command_t ngx_mail_proxy_com static ngx_mail_module_t ngx_mail_proxy_module_ctx = { NULL, /* protocol */ + NULL, /* post configuration */ + NULL, /* create main configuration */ NULL, /* init main configuration */ diff -r bc8fc02d7095 -r 55cca5107f72 src/mail/ngx_mail_smtp_module.c --- a/src/mail/ngx_mail_smtp_module.c Mon Apr 27 10:53:05 2015 +0200 +++ b/src/mail/ngx_mail_smtp_module.c Mon Apr 27 10:53:06 2015 +0200 @@ -86,6 +86,8 @@ static ngx_command_t ngx_mail_smtp_comm static ngx_mail_module_t ngx_mail_smtp_module_ctx = { &ngx_mail_smtp_protocol, /* protocol */ + NULL, /* post configuration */ + NULL, /* create main configuration */ NULL, /* init main configuration */ diff -r bc8fc02d7095 -r 55cca5107f72 src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c Mon Apr 27 10:53:05 2015 +0200 +++ b/src/mail/ngx_mail_ssl_module.c Mon Apr 27 10:53:06 2015 +0200 @@ -23,6 +23,7 @@ static char *ngx_mail_ssl_starttls(ngx_c void *conf); static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static ngx_int_t ngx_mail_ssl_init(ngx_conf_t *cf); static ngx_conf_enum_t ngx_mail_starttls_state[] = { @@ -172,6 +173,8 @@ static ngx_command_t ngx_mail_ssl_comma static ngx_mail_module_t ngx_mail_ssl_module_ctx = { NULL, /* protocol */ + ngx_mail_ssl_init, /* post configuration */ + NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -580,3 +583,37 @@ invalid: return NGX_CONF_ERROR; } + + +static ngx_int_t +ngx_mail_ssl_init(ngx_conf_t *cf) +{ + ngx_uint_t s; + ngx_mail_ssl_conf_t *scf; + ngx_mail_core_srv_conf_t *cscf; + ngx_mail_core_srv_conf_t **cscfp; + ngx_mail_core_main_conf_t *cmcf; + + cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); + cscfp = cmcf->servers.elts; + + for (s = 0; s < cmcf->servers.nelts; s++) { + + scf = cscfp[s]->ctx->srv_conf[ngx_mail_ssl_module.ctx_index]; + + if (scf->ssl.ctx == NULL || !scf->stapling) { + continue; + } + + cscf = cscfp[s]->ctx->srv_conf[ngx_mail_core_module.ctx_index]; + + if (ngx_ssl_stapling_resolver(cf, &scf->ssl, cscf->resolver, + cscf->resolver_timeout) + != NGX_OK) + { + return NGX_ERROR; + } + } + + return NGX_OK; +} From serg.brester at sebres.de Mon Apr 27 08:57:39 2015 From: serg.brester at sebres.de (Sergey Brester) Date: Mon, 27 Apr 2015 10:57:39 +0200 Subject: Fwd: Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) In-Reply-To: <20150427012530.GS32429@mdounin.ru> References: <706ca3a5ec658ea41fb9975f90ab9ab4@sebres.de> <20150422162929.GD32429@mdounin.ru> <54cf66a081e1767be9e630003485c4fa@sebres.de> <20150427012530.GS32429@mdounin.ru> Message-ID: Hi, Your patch looks very interesting. But small comment by the way: > So the answer is "no", right? ... I had no problem with reaload at all... What I do so differently? The last test was repeated 2000 times: added and removed up to 10 zones and reload with '-s reload'. I see no problem. ??? Am 27.04.2015 03:25, schrieb Maxim Dounin: > Hello! > > On Fri, Apr 24, 2015 at 01:21:41AM +0200, Sergey Brester wrote: > Hello, There are lots of style problems which need cleanup. The newer, "nginx-style" compliant version of changeset (shmem fix2.patch) was already posted to nginx-devel (Thx, Filipe DA SILVA). You will find it also on under https://github.com/sebres/nginx/commit/e7c149f1ad76b9d850fb59ecc479d4a658c13e04 [1] [4]. It still needs cleanup, but I don't think it worth detailed comments as there are more important things to be addressed. >> Such things belong to ngx_win32_init.c. It may be also good enough to use ngx_pagesize, which is already set there. > Agree, but some (little) things can reside in same module, where these are used (noted as todo). > >> This probably should be somewhere at ngx_win32_config.h. > Imho, belong definitelly in shmem module. But don't want to fight about it :) The question here is a balance between code locality and visibility of platform-dependent constants for modifications. E.g., we've recently added 64-bit constants into ngx_win32_config.h to allow compilation of 64-bit windows binaries - and I'm perfectly sure shmem code would have been forgotten assuming it used just magic addresses as in your patch. May be some constants with appropriate comments at the top of the ngx_shmem.c file will be a good compromise solution. >> It might be better idea to save the address at the end of the memory block allocated... > And for example stop to work of other new worker (when unfortunately overwriting of it occurs). That brings at once many problem and restrictions later (for example more difficult implementing of shared area resizing, etc). And for what? To save 2 line code for decrement addr pointer in ngx_shm_free? It won't be overwritten as long as you allocate additional bytes for it (as of now) and shm->size is not incremented. And yes, saving 2 lines of code is important - especially if it happens because the whole approach becomes simplier. Anyway, I think that we should try to use the address which is already present, see other comments. This will also avoid unneeded restrictions on mappings where pointers are not stored. >> Have you tried using an arbitrary addresses (with subsequent remap using proper base address for already existing mappings)? Does is work noticeably worse? > I've fought against ASLR since 2008 resp. x64 was released and it was essential. This specific solution is extensively tested and runs in production also without any problems (not only in nginx). So the answer is "no", right? Either way, I tried it myself, and it seems to be noticeably worse - in my tests in most cases it can't use the address from the master process in workers due to conflicts with other allocations. When combined with base address selection, it seems to be much more stable. Below is a patch which takes into account above comments, and also fixes a problem observed with your patch on configuration reloads, e.g., when something like: proxy_cache_path cache1 keys_zone=cache1:10m; is changed to proxy_cache_path cache0 keys_zone=cache0:10m; proxy_cache_path cache1 keys_zone=cache1:10m; (i.e., when mappings are created in master and worker processes in a different order, resulting in conflicts between a mapping we are trying to create at some base address with a mapping already remapped to this address). Review, comments and testing appreciated. # HG changeset patch # User Maxim Dounin # Date 1430097438 -10800 # Mon Apr 27 04:17:18 2015 +0300 # Node ID 89cd9c63c58e5d7c474d317f83584779e2342ee3 # Parent 859ce1c41f642c39d2db9741bdd305f3ee6507f5 Win32: shared memory base addresses and remapping. Two mechanisms are implemented to make it possible to store pointers in shared memory on Windows, in particular on Windows Vista and later versions with ASLR: - The ngx_shm_remap() function added to allow remapping of a shared memory zone to the address originally used for it in the master process. While important, it doesn't solve the problem by itself as in many cases it's not possible to use the address because of conflicts with other allocations. - We now create mappings at the same address in all processes by starting mappings at predefined addresses normally unused by newborn processes. These two mechanisms combined allow to use shared memory on Windows almost without problems, including reloads. Based on the patch by Sergey Brester: http://mailman.nginx.org/pipermail/nginx-devel/2015-April/006836.html [2] diff -r 859ce1c41f64 -r 89cd9c63c58e src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Mon Apr 27 03:44:30 2015 +0300 +++ b/src/core/ngx_cycle.c Mon Apr 27 04:17:18 2015 +0300 @@ -863,6 +863,22 @@ ngx_init_zone_pool(ngx_cycle_t *cycle, n return NGX_OK; } +#if (NGX_WIN32) + + /* remap at the required address */ + + if (ngx_shm_remap(&zn->shm, sp->addr) != NGX_OK) { + return NGX_ERROR; + } + + sp = (ngx_slab_pool_t *) zn->shm.addr; + + if (sp == sp->addr) { + return NGX_OK; + } + +#endif + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "shared zone "%V" has no equal addresses: %p vs %p", &zn->shm.name, sp->addr, sp); diff -r 859ce1c41f64 -r 89cd9c63c58e src/os/win32/ngx_shmem.c --- a/src/os/win32/ngx_shmem.c Mon Apr 27 03:44:30 2015 +0300 +++ b/src/os/win32/ngx_shmem.c Mon Apr 27 04:17:18 2015 +0300 @@ -9,11 +9,44 @@ #include +/* + * Base addresses selected by system for shared memory mappings are likely + * to be different on Windows Vista and later versions due to address space + * layout randomization. This is however incompatible with storing absolute + * addresses within the shared memory. + * + * To make it possible to store absolute addresses we create mappings + * at the same address in all processes by starting mappings at predefined + * addresses. The addresses was selected somewhat randomly in order to + * minimize the probability that some other library doing something similar + * conflicts with us. The addresses are from the following typically free + * blocks: + * + * - 0x10000000 .. 0x70000000 (about 1.8 GB in total) on 32-bit platforms + * - 0x000000007fff0000 .. 0x000007f68e8b0000 (about 8 TB) on 64-bit platforms + * + * Additionally, we allow to change the mapping address once it was detected + * to be different from one originally used. This is needed to support + * reconfiguration. + */ + + +#ifdef _WIN64 +#define NGX_SHMEM_BASE 0x0000047047e00000 +#else +#define NGX_SHMEM_BASE 0x2efe0000 +#endif + + +ngx_uint_t ngx_allocation_granularity; + + ngx_int_t ngx_shm_alloc(ngx_shm_t *shm) { - u_char *name; - uint64_t size; + u_char *name; + uint64_t size; + static u_char *base = (u_char *) NGX_SHMEM_BASE; name = ngx_alloc(shm->name.len + 2 + NGX_INT32_LEN, shm->log); if (name == NULL) { @@ -46,6 +79,27 @@ ngx_shm_alloc(ngx_shm_t *shm) shm->exists = 1; } + shm->addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, base); + + if (shm->addr != NULL) { + base += ngx_align(size, ngx_allocation_granularity); + return NGX_OK; + } + + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, ngx_errno, + "MapViewOfFileEx(%uz, %p) of file mapping "%V" failed, " + "retry without a base address", + shm->size, base, &shm->name); + + /* + * Order of shared memory zones may be different in the master process + * and worker processes after reconfiguration. As a result, the above + * may fail due to a conflict with a previously created mapping remapped + * to a different address. Additionally, there may be a conflict with + * some other uses of the memory. In this case we retry without a base + * address to let the system assign the address itself. + */ + shm->addr = MapViewOfFile(shm->handle, FILE_MAP_WRITE, 0, 0, 0); if (shm->addr != NULL) { @@ -66,6 +120,30 @@ ngx_shm_alloc(ngx_shm_t *shm) } +ngx_int_t +ngx_shm_remap(ngx_shm_t *shm, u_char *addr) +{ + if (UnmapViewOfFile(shm->addr) == 0) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "UnmapViewOfFile(%p) of file mapping "%V" failed", + shm->addr, &shm->name); + return NGX_ERROR; + } + + shm->addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, addr); + + if (shm->addr != NULL) { + return NGX_OK; + } + + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "MapViewOfFileEx(%uz, %p) of file mapping "%V" failed", + shm->size, addr, &shm->name); + + return NGX_ERROR; +} + + void ngx_shm_free(ngx_shm_t *shm) { diff -r 859ce1c41f64 -r 89cd9c63c58e src/os/win32/ngx_shmem.h --- a/src/os/win32/ngx_shmem.h Mon Apr 27 03:44:30 2015 +0300 +++ b/src/os/win32/ngx_shmem.h Mon Apr 27 04:17:18 2015 +0300 @@ -24,7 +24,10 @@ typedef struct { ngx_int_t ngx_shm_alloc(ngx_shm_t *shm); +ngx_int_t ngx_shm_remap(ngx_shm_t *shm, u_char *addr); void ngx_shm_free(ngx_shm_t *shm); +extern ngx_uint_t ngx_allocation_granularity; + #endif /* _NGX_SHMEM_H_INCLUDED_ */ diff -r 859ce1c41f64 -r 89cd9c63c58e src/os/win32/ngx_win32_init.c --- a/src/os/win32/ngx_win32_init.c Mon Apr 27 03:44:30 2015 +0300 +++ b/src/os/win32/ngx_win32_init.c Mon Apr 27 04:17:18 2015 +0300 @@ -118,6 +118,7 @@ ngx_os_init(ngx_log_t *log) GetSystemInfo(&si); ngx_pagesize = si.dwPageSize; + ngx_allocation_granularity = si.dwAllocationGranularity; ngx_ncpu = si.dwNumberOfProcessors; ngx_cacheline_size = NGX_CPU_CACHE_LINE; Links: ------ [1] https://github.com/sebres/nginx/commit/e7c149f1ad76b9d850fb59ecc479d4a658c13e04 [2] http://mailman.nginx.org/pipermail/nginx-devel/2015-April/006836.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Mon Apr 27 13:17:16 2015 From: vbart at nginx.com (Valentin V. Bartenev) Date: Mon, 27 Apr 2015 16:17:16 +0300 Subject: [Re-posting] http/2 support In-Reply-To: References: <8437251.cVXCZURXdE@vbart-laptop> Message-ID: <1860164.nPqXeOqyJn@vbart-workstation> On Saturday 25 April 2015 15:08:24 Yuva wrote: > hi, > I would like to contribute by coding. For a start, this is what im > thinking: > - get familiar with nginx spdy source code (since spdy is close to http/2) Well, this may take all your time and effort, especially if you're not familiar with nginx internals. > - understand source code written to support http/2, if any. > - start with implementing small features, and fixing bugs. There's a couple of open tickets about SPDY: http://trac.nginx.org You can start by trying to fix them. wbr, Valentin V. Bartenev From serg.brester at sebres.de Mon Apr 27 14:38:15 2015 From: serg.brester at sebres.de (Sergey Brester) Date: Mon, 27 Apr 2015 16:38:15 +0200 Subject: Fwd: Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) In-Reply-To: <20150427012530.GS32429@mdounin.ru> References: <706ca3a5ec658ea41fb9975f90ab9ab4@sebres.de> <20150422162929.GD32429@mdounin.ru> <54cf66a081e1767be9e630003485c4fa@sebres.de> <20150427012530.GS32429@mdounin.ru> Message-ID: Hi, I have little bit tested your changeset. Looks good: 10000 successful reloads with randomly adding/removing zones up to 1GB (Win7 x64 and 2K8-R2 x64). Thx and regards, sebres. P.S. If someone needs a git version of it: https://github.com/sebres/nginx/commit/2d549c958cf4fa53eeacec13b410946bbe053544 [3] -- Am 27.04.2015 03:25, schrieb Maxim Dounin: > Hello! > > On Fri, Apr 24, 2015 at 01:21:41AM +0200, Sergey Brester wrote: > Hello, There are lots of style problems which need cleanup. The newer, "nginx-style" compliant version of changeset (shmem fix2.patch) was already posted to nginx-devel (Thx, Filipe DA SILVA). You will find it also on under https://github.com/sebres/nginx/commit/e7c149f1ad76b9d850fb59ecc479d4a658c13e04 [1] [4]. It still needs cleanup, but I don't think it worth detailed comments as there are more important things to be addressed. >> Such things belong to ngx_win32_init.c. It may be also good enough to use ngx_pagesize, which is already set there. > Agree, but some (little) things can reside in same module, where these are used (noted as todo). > >> This probably should be somewhere at ngx_win32_config.h. > Imho, belong definitelly in shmem module. But don't want to fight about it :) The question here is a balance between code locality and visibility of platform-dependent constants for modifications. E.g., we've recently added 64-bit constants into ngx_win32_config.h to allow compilation of 64-bit windows binaries - and I'm perfectly sure shmem code would have been forgotten assuming it used just magic addresses as in your patch. May be some constants with appropriate comments at the top of the ngx_shmem.c file will be a good compromise solution. >> It might be better idea to save the address at the end of the memory block allocated... > And for example stop to work of other new worker (when unfortunately overwriting of it occurs). That brings at once many problem and restrictions later (for example more difficult implementing of shared area resizing, etc). And for what? To save 2 line code for decrement addr pointer in ngx_shm_free? It won't be overwritten as long as you allocate additional bytes for it (as of now) and shm->size is not incremented. And yes, saving 2 lines of code is important - especially if it happens because the whole approach becomes simplier. Anyway, I think that we should try to use the address which is already present, see other comments. This will also avoid unneeded restrictions on mappings where pointers are not stored. >> Have you tried using an arbitrary addresses (with subsequent remap using proper base address for already existing mappings)? Does is work noticeably worse? > I've fought against ASLR since 2008 resp. x64 was released and it was essential. This specific solution is extensively tested and runs in production also without any problems (not only in nginx). So the answer is "no", right? Either way, I tried it myself, and it seems to be noticeably worse - in my tests in most cases it can't use the address from the master process in workers due to conflicts with other allocations. When combined with base address selection, it seems to be much more stable. Below is a patch which takes into account above comments, and also fixes a problem observed with your patch on configuration reloads, e.g., when something like: proxy_cache_path cache1 keys_zone=cache1:10m; is changed to proxy_cache_path cache0 keys_zone=cache0:10m; proxy_cache_path cache1 keys_zone=cache1:10m; (i.e., when mappings are created in master and worker processes in a different order, resulting in conflicts between a mapping we are trying to create at some base address with a mapping already remapped to this address). Review, comments and testing appreciated. # HG changeset patch # User Maxim Dounin # Date 1430097438 -10800 # Mon Apr 27 04:17:18 2015 +0300 # Node ID 89cd9c63c58e5d7c474d317f83584779e2342ee3 # Parent 859ce1c41f642c39d2db9741bdd305f3ee6507f5 Win32: shared memory base addresses and remapping. Two mechanisms are implemented to make it possible to store pointers in shared memory on Windows, in particular on Windows Vista and later versions with ASLR: - The ngx_shm_remap() function added to allow remapping of a shared memory zone to the address originally used for it in the master process. While important, it doesn't solve the problem by itself as in many cases it's not possible to use the address because of conflicts with other allocations. - We now create mappings at the same address in all processes by starting mappings at predefined addresses normally unused by newborn processes. These two mechanisms combined allow to use shared memory on Windows almost without problems, including reloads. Based on the patch by Sergey Brester: http://mailman.nginx.org/pipermail/nginx-devel/2015-April/006836.html [2] diff -r 859ce1c41f64 -r 89cd9c63c58e src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Mon Apr 27 03:44:30 2015 +0300 +++ b/src/core/ngx_cycle.c Mon Apr 27 04:17:18 2015 +0300 @@ -863,6 +863,22 @@ ngx_init_zone_pool(ngx_cycle_t *cycle, n return NGX_OK; } +#if (NGX_WIN32) + + /* remap at the required address */ + + if (ngx_shm_remap(&zn->shm, sp->addr) != NGX_OK) { + return NGX_ERROR; + } + + sp = (ngx_slab_pool_t *) zn->shm.addr; + + if (sp == sp->addr) { + return NGX_OK; + } + +#endif + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "shared zone "%V" has no equal addresses: %p vs %p", &zn->shm.name, sp->addr, sp); diff -r 859ce1c41f64 -r 89cd9c63c58e src/os/win32/ngx_shmem.c --- a/src/os/win32/ngx_shmem.c Mon Apr 27 03:44:30 2015 +0300 +++ b/src/os/win32/ngx_shmem.c Mon Apr 27 04:17:18 2015 +0300 @@ -9,11 +9,44 @@ #include +/* + * Base addresses selected by system for shared memory mappings are likely + * to be different on Windows Vista and later versions due to address space + * layout randomization. This is however incompatible with storing absolute + * addresses within the shared memory. + * + * To make it possible to store absolute addresses we create mappings + * at the same address in all processes by starting mappings at predefined + * addresses. The addresses was selected somewhat randomly in order to + * minimize the probability that some other library doing something similar + * conflicts with us. The addresses are from the following typically free + * blocks: + * + * - 0x10000000 .. 0x70000000 (about 1.8 GB in total) on 32-bit platforms + * - 0x000000007fff0000 .. 0x000007f68e8b0000 (about 8 TB) on 64-bit platforms + * + * Additionally, we allow to change the mapping address once it was detected + * to be different from one originally used. This is needed to support + * reconfiguration. + */ + + +#ifdef _WIN64 +#define NGX_SHMEM_BASE 0x0000047047e00000 +#else +#define NGX_SHMEM_BASE 0x2efe0000 +#endif + + +ngx_uint_t ngx_allocation_granularity; + + ngx_int_t ngx_shm_alloc(ngx_shm_t *shm) { - u_char *name; - uint64_t size; + u_char *name; + uint64_t size; + static u_char *base = (u_char *) NGX_SHMEM_BASE; name = ngx_alloc(shm->name.len + 2 + NGX_INT32_LEN, shm->log); if (name == NULL) { @@ -46,6 +79,27 @@ ngx_shm_alloc(ngx_shm_t *shm) shm->exists = 1; } + shm->addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, base); + + if (shm->addr != NULL) { + base += ngx_align(size, ngx_allocation_granularity); + return NGX_OK; + } + + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, ngx_errno, + "MapViewOfFileEx(%uz, %p) of file mapping "%V" failed, " + "retry without a base address", + shm->size, base, &shm->name); + + /* + * Order of shared memory zones may be different in the master process + * and worker processes after reconfiguration. As a result, the above + * may fail due to a conflict with a previously created mapping remapped + * to a different address. Additionally, there may be a conflict with + * some other uses of the memory. In this case we retry without a base + * address to let the system assign the address itself. + */ + shm->addr = MapViewOfFile(shm->handle, FILE_MAP_WRITE, 0, 0, 0); if (shm->addr != NULL) { @@ -66,6 +120,30 @@ ngx_shm_alloc(ngx_shm_t *shm) } +ngx_int_t +ngx_shm_remap(ngx_shm_t *shm, u_char *addr) +{ + if (UnmapViewOfFile(shm->addr) == 0) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "UnmapViewOfFile(%p) of file mapping "%V" failed", + shm->addr, &shm->name); + return NGX_ERROR; + } + + shm->addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, addr); + + if (shm->addr != NULL) { + return NGX_OK; + } + + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "MapViewOfFileEx(%uz, %p) of file mapping "%V" failed", + shm->size, addr, &shm->name); + + return NGX_ERROR; +} + + void ngx_shm_free(ngx_shm_t *shm) { diff -r 859ce1c41f64 -r 89cd9c63c58e src/os/win32/ngx_shmem.h --- a/src/os/win32/ngx_shmem.h Mon Apr 27 03:44:30 2015 +0300 +++ b/src/os/win32/ngx_shmem.h Mon Apr 27 04:17:18 2015 +0300 @@ -24,7 +24,10 @@ typedef struct { ngx_int_t ngx_shm_alloc(ngx_shm_t *shm); +ngx_int_t ngx_shm_remap(ngx_shm_t *shm, u_char *addr); void ngx_shm_free(ngx_shm_t *shm); +extern ngx_uint_t ngx_allocation_granularity; + #endif /* _NGX_SHMEM_H_INCLUDED_ */ diff -r 859ce1c41f64 -r 89cd9c63c58e src/os/win32/ngx_win32_init.c --- a/src/os/win32/ngx_win32_init.c Mon Apr 27 03:44:30 2015 +0300 +++ b/src/os/win32/ngx_win32_init.c Mon Apr 27 04:17:18 2015 +0300 @@ -118,6 +118,7 @@ ngx_os_init(ngx_log_t *log) GetSystemInfo(&si); ngx_pagesize = si.dwPageSize; + ngx_allocation_granularity = si.dwAllocationGranularity; ngx_ncpu = si.dwNumberOfProcessors; ngx_cacheline_size = NGX_CPU_CACHE_LINE; Links: ------ [1] https://github.com/sebres/nginx/commit/e7c149f1ad76b9d850fb59ecc479d4a658c13e04 [2] http://mailman.nginx.org/pipermail/nginx-devel/2015-April/006836.html [3] https://github.com/sebres/nginx/commit/2d549c958cf4fa53eeacec13b410946bbe053544 -------------- next part -------------- An HTML attachment was scrubbed... URL: From fdasilva at ingima.com Mon Apr 27 15:38:57 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Mon, 27 Apr 2015 15:38:57 +0000 Subject: [PATCH 1 of 5] SSL: introduce support of last openssl 1.0.2 features. Message-ID: Hi, This is my last version of 'Multiple server certificates support ' patches. I restaged the changes in a more smart way. It is more respectful of 'contributing' requirements. It relies on OpenSSL to maintain a list of server certificates. It now stores a stapling context within/for each server certificate. Reviews and comments are welcome. Regards, Filipe da Silva Ingima --- # HG changeset patch # User Filipe da Silva # Date 1430147821 -7200 # Mon Apr 27 17:17:01 2015 +0200 # Node ID 0ac2a8668f852b604d46ff858199650bd3003fdb # Parent fc99323a3d790dcc7b87121261b4236d098336de SSL: introduce support of last openssl 1.0.2 features. Rely on openSSL 1.0.2 internals to manage the server certificate list and replace the previous SSL_CTX_ex_data(ngx_ssl_certificate_index, ...) storage. Add two new server certificate accessor methods to encapsulate this change: ngx_ssl_get_server_certificate & ngx_ssl_get_next_server_certificate. Add guards around ngx_ssl_stapling_index init when OCSP stapling is unsupported. Compatible with 'stable-1.8'. diff -r fc99323a3d79 -r 0ac2a8668f85 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Fri Feb 20 15:31:37 2015 +0300 +++ b/src/event/ngx_event_openssl.c Mon Apr 27 17:17:01 2015 +0200 @@ -168,6 +168,7 @@ ngx_ssl_init(ngx_log_t *log) return NGX_ERROR; } +#if OPENSSL_VERSION_NUMBER < 0x10002000L ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); if (ngx_ssl_certificate_index == -1) { @@ -175,7 +176,9 @@ ngx_ssl_init(ngx_log_t *log) "SSL_CTX_get_ex_new_index() failed"); return NGX_ERROR; } - +#endif + +#if (!defined OPENSSL_NO_OCSP && defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB) ngx_ssl_stapling_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); if (ngx_ssl_stapling_index == -1) { @@ -183,6 +186,7 @@ ngx_ssl_init(ngx_log_t *log) "SSL_CTX_get_ex_new_index() failed"); return NGX_ERROR; } +#endif return NGX_OK; } @@ -297,6 +301,33 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_ } +X509* +ngx_ssl_get_server_certificate(ngx_ssl_t *ssl) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + if (SSL_CTX_set_current_cert(ssl->ctx, SSL_CERT_SET_FIRST)) { + return (SSL_CTX_get0_certificate(ssl->ctx)); + } + return NULL; +#else + + return (SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index)); +#endif +} + + +X509* +ngx_ssl_get_next_server_certificate(ngx_ssl_t *ssl) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + if (SSL_CTX_set_current_cert(ssl->ctx, SSL_CERT_SET_NEXT)) { + return (SSL_CTX_get0_certificate(ssl->ctx)); + } +#endif + return NULL; +} + + ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords) @@ -340,6 +371,7 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ return NGX_ERROR; } +#if OPENSSL_VERSION_NUMBER < 0x10002000L if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509) == 0) { @@ -349,6 +381,7 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ BIO_free(bio); return NGX_ERROR; } +#endif X509_free(x509); @@ -376,10 +409,21 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ return NGX_ERROR; } +#ifdef SSL_CTX_add0_chain_cert + /* + * OpenSSL >=1.0.2 allows multiple server certificates in a single + * SSL_CTX to each have a different chain + */ + if (SSL_CTX_add0_chain_cert(ssl->ctx, x509) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_add0_chain_cert(\"%s\") failed", + cert->data); +#else if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_add_extra_chain_cert(\"%s\") failed", cert->data); +#endif X509_free(x509); BIO_free(bio); return NGX_ERROR; @@ -2150,7 +2194,7 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss goto failed; } - cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); + cert = ngx_ssl_get_server_certificate(ssl); if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, diff -r fc99323a3d79 -r 0ac2a8668f85 src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Fri Feb 20 15:31:37 2015 +0300 +++ b/src/event/ngx_event_openssl.h Mon Apr 27 17:17:01 2015 +0200 @@ -189,6 +189,8 @@ ngx_int_t ngx_ssl_get_fingerprint(ngx_co ngx_str_t *s); ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +X509* ngx_ssl_get_server_certificate(ngx_ssl_t *ssl); +X509* ngx_ssl_get_next_server_certificate(ngx_ssl_t *ssl); ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); @@ -208,7 +210,6 @@ extern int ngx_ssl_connection_index; extern int ngx_ssl_server_conf_index; extern int ngx_ssl_session_cache_index; extern int ngx_ssl_session_ticket_keys_index; -extern int ngx_ssl_certificate_index; extern int ngx_ssl_stapling_index; diff -r fc99323a3d79 -r 0ac2a8668f85 src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Fri Feb 20 15:31:37 2015 +0300 +++ b/src/event/ngx_event_openssl_stapling.c Mon Apr 27 17:17:01 2015 +0200 @@ -265,9 +265,11 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_stapling_t *staple; staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); - cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); + cert = ngx_ssl_get_server_certificate(ssl->ctx); -#if OPENSSL_VERSION_NUMBER >= 0x10001000L +#ifdef SSL_CTX_get0_chain_certs + SSL_CTX_get0_chain_certs(ssl->ctx, &chain); +#elif OPENSSL_VERSION_NUMBER >= 0x10001000L SSL_CTX_get_extra_chain_certs(ssl->ctx, &chain); #else chain = ssl->ctx->extra_certs; @@ -532,6 +534,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc u_char *p; int n; size_t len; + unsigned long flags; ngx_str_t response; X509_STORE *store; STACK_OF(X509) *chain; @@ -585,15 +588,28 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc goto error; } -#if OPENSSL_VERSION_NUMBER >= 0x10001000L +#ifdef SSL_CTX_get0_chain_certs + SSL_CTX_get0_chain_certs(staple->ssl_ctx, &chain); +#elif OPENSSL_VERSION_NUMBER >= 0x10001000L SSL_CTX_get_extra_chain_certs(staple->ssl_ctx, &chain); #else chain = staple->ssl_ctx->extra_certs; #endif - if (OCSP_basic_verify(basic, chain, store, - staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY) - != 1) + flags = staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY; + +#if OPENSSL_VERSION_NUMBER < 0x10000000L + /* + * ECDSA/SHA-2 signature verification not supported. + * Released with OpenSSL 1.0.0 [29 Mar 2010] + * *) Add support for dsa-with-SHA224 and dsa-with-SHA256. + * See openssl commit 06e2dd037e29f82b92e1d1b9454f1595e602fb94 + */ + flags = flags | OCSP_NOSIGS; + /* TODO: improve case handling */ +#endif + + if (OCSP_basic_verify(basic, chain, store, flags) != 1) { ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0, "OCSP_basic_verify() failed"); From fdasilva at ingima.com Mon Apr 27 15:39:01 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Mon, 27 Apr 2015 15:39:01 +0000 Subject: [PATCH 2 of 5] OCSP Stapling: attach one stapling_t context per server certificate. Message-ID: # HG changeset patch # User Filipe da Silva # Date 1430147821 -7200 # Mon Apr 27 17:17:01 2015 +0200 # Node ID caabe5c77b51274237d7c49fffb864a27ca0a25f # Parent 0ac2a8668f852b604d46ff858199650bd3003fdb OCSP Stapling: attach one stapling_t context per server certificate. Prepare for multiple server certificate support. Split common stapling settings from per-certificate settings. Keep common stapling settings attached to initial SSL server context, as before. Know limit: the staple file must contain a response with as much CERTID as server certificate. This means that one OCSP request must be made about all the certificates at once. Compatible with 'stable-1.8' diff -r 0ac2a8668f85 -r caabe5c77b51 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Mon Apr 27 17:17:01 2015 +0200 +++ b/src/event/ngx_event_openssl.c Mon Apr 27 17:17:01 2015 +0200 @@ -103,6 +103,7 @@ int ngx_ssl_session_cache_index; int ngx_ssl_session_ticket_keys_index; int ngx_ssl_certificate_index; int ngx_ssl_stapling_index; +int ngx_ssl_cert_stapling_index; ngx_int_t @@ -186,6 +187,14 @@ ngx_ssl_init(ngx_log_t *log) "SSL_CTX_get_ex_new_index() failed"); return NGX_ERROR; } + + ngx_ssl_cert_stapling_index = X509_get_ex_new_index(0, NULL, NULL, NULL, + NULL); + if (ngx_ssl_cert_stapling_index == -1) { + ngx_ssl_error(NGX_LOG_ALERT, log, 0, + "X509_get_ex_new_index() failed"); + return NGX_ERROR; + } #endif return NGX_OK; diff -r 0ac2a8668f85 -r caabe5c77b51 src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Mon Apr 27 17:17:01 2015 +0200 +++ b/src/event/ngx_event_openssl.h Mon Apr 27 17:17:01 2015 +0200 @@ -211,6 +211,7 @@ extern int ngx_ssl_server_conf_index; extern int ngx_ssl_session_cache_index; extern int ngx_ssl_session_ticket_keys_index; extern int ngx_ssl_stapling_index; +extern int ngx_ssl_cert_stapling_index; #endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */ diff -r 0ac2a8668f85 -r caabe5c77b51 src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Mon Apr 27 17:17:01 2015 +0200 +++ b/src/event/ngx_event_openssl_stapling.c Mon Apr 27 17:17:01 2015 +0200 @@ -14,13 +14,22 @@ #if (!defined OPENSSL_NO_OCSP && defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB) +/* OCSP stapling configuration per server */ typedef struct { - ngx_str_t staple; + ngx_str_t staple_file; ngx_msec_t timeout; ngx_resolver_t *resolver; ngx_msec_t resolver_timeout; + unsigned verify:1; +} ngx_ssl_staple_conf_t; + + +/* OCSP stapling context per certificate */ +typedef struct { + ngx_str_t staple; /* OCSP response from responder */ + ngx_addr_t *addrs; ngx_str_t host; ngx_str_t uri; @@ -33,7 +42,6 @@ typedef struct { time_t valid; - unsigned verify:1; unsigned loading:1; } ngx_ssl_stapling_t; @@ -53,6 +61,7 @@ struct ngx_ssl_ocsp_ctx_s { ngx_resolver_t *resolver; ngx_msec_t resolver_timeout; + unsigned verify:1; ngx_msec_t timeout; @@ -83,14 +92,15 @@ struct ngx_ssl_ocsp_ctx_s { static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_str_t *file); + ngx_str_t *file, ngx_ssl_staple_conf_t *conf); static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl); static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder); static int ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn, void *data); -static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple); +static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple, + ngx_ssl_staple_conf_t *conf); static void ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx); static void ngx_ssl_stapling_cleanup(void *data); @@ -119,23 +129,14 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl ngx_str_t *responder, ngx_uint_t verify) { ngx_int_t rc; - ngx_pool_cleanup_t *cln; - ngx_ssl_stapling_t *staple; + ngx_ssl_staple_conf_t *conf; - staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t)); - if (staple == NULL) { + conf = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_staple_conf_t)); + if (conf == NULL) { return NGX_ERROR; } - cln = ngx_pool_cleanup_add(cf->pool, 0); - if (cln == NULL) { - return NGX_ERROR; - } - - cln->handler = ngx_ssl_stapling_cleanup; - cln->data = staple; - - if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_stapling_index, staple) + if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_stapling_index, conf) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, @@ -143,14 +144,13 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl return NGX_ERROR; } - staple->ssl_ctx = ssl->ctx; - staple->timeout = 60000; - staple->verify = verify; + conf->timeout = 60000; + conf->verify = verify; if (file->len) { /* use OCSP response from the file */ - if (ngx_ssl_stapling_file(cf, ssl, file) != NGX_OK) { + if (ngx_ssl_stapling_file(cf, ssl, file, conf) != NGX_OK) { return NGX_ERROR; } @@ -180,22 +180,20 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl done: SSL_CTX_set_tlsext_status_cb(ssl->ctx, ngx_ssl_certificate_status_callback); - SSL_CTX_set_tlsext_status_arg(ssl->ctx, staple); + SSL_CTX_set_tlsext_status_arg(ssl->ctx, conf); return NGX_OK; } static ngx_int_t -ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file) +ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, + ngx_ssl_staple_conf_t *conf) { BIO *bio; int len; u_char *p, *buf; OCSP_RESPONSE *response; - ngx_ssl_stapling_t *staple; - - staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) { return NGX_ERROR; @@ -223,7 +221,8 @@ ngx_ssl_stapling_file(ngx_conf_t *cf, ng goto failed; } - buf = ngx_alloc(len, ssl->log); + /* File content buffer allocated from pool to avoid additional cleanup */ + buf = ngx_palloc(cf->pool, len); if (buf == NULL) { goto failed; } @@ -240,8 +239,8 @@ ngx_ssl_stapling_file(ngx_conf_t *cf, ng OCSP_RESPONSE_free(response); BIO_free(bio); - staple->staple.data = buf; - staple->staple.len = len; + conf->staple_file.data = buf; + conf->staple_file.len = len; return NGX_OK; @@ -263,10 +262,33 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, X509_STORE_CTX *store_ctx; STACK_OF(X509) *chain; ngx_ssl_stapling_t *staple; + ngx_pool_cleanup_t *cln; - staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); cert = ngx_ssl_get_server_certificate(ssl->ctx); + staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t)); + if (staple == NULL) { + return NGX_ERROR; + } + + cln = ngx_pool_cleanup_add(cf->pool, 0); + if (cln == NULL) { + return NGX_ERROR; + } + + cln->handler = ngx_ssl_stapling_cleanup; + cln->data = staple; + + if (X509_set_ex_data(cert, ngx_ssl_cert_stapling_index, staple) + == 0) + { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "X509_set_ex_data() failed"); + return NGX_ERROR; + } + + staple->ssl_ctx = ssl->ctx; + #ifdef SSL_CTX_get0_chain_certs SSL_CTX_get0_chain_certs(ssl->ctx, &chain); #elif OPENSSL_VERSION_NUMBER >= 0x10001000L @@ -350,9 +372,11 @@ ngx_ssl_stapling_responder(ngx_conf_t *c ngx_url_t u; char *s; ngx_ssl_stapling_t *staple; + X509 *cert; STACK_OF(OPENSSL_STRING) *aia; - staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); + cert = ngx_ssl_get_server_certificate(ssl); + staple = X509_get_ex_data(cert, ngx_ssl_cert_stapling_index); if (responder->len == 0) { @@ -437,7 +461,7 @@ ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_resolver_t *resolver, ngx_msec_t resolver_timeout) { - ngx_ssl_stapling_t *staple; + ngx_ssl_staple_conf_t *staple; staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); @@ -451,43 +475,57 @@ ngx_ssl_stapling_resolver(ngx_conf_t *cf static int ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn, void *data) { - int rc; - u_char *p; - ngx_connection_t *c; - ngx_ssl_stapling_t *staple; + int rc; + u_char *p; + ngx_str_t resp; + ngx_connection_t *c; + ngx_ssl_staple_conf_t *conf; + ngx_ssl_stapling_t *staple; + X509 *cert; c = ngx_ssl_get_connection(ssl_conn); + cert = SSL_get_certificate(ssl_conn); ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL certificate status callback"); - staple = data; + staple = X509_get_ex_data(cert, ngx_ssl_cert_stapling_index); + conf = data; rc = SSL_TLSEXT_ERR_NOACK; + resp.len = 0; - if (staple->staple.len) { - /* we have to copy ocsp response as OpenSSL will free it by itself */ + if (conf->staple_file.len) { + resp = conf->staple_file; + } + else if (staple && staple->staple.len) { + resp = staple->staple; + } - p = OPENSSL_malloc(staple->staple.len); + if (resp.len) { + /* We have to copy ocsp response as OpenSSL will free it by itself */ + p = OPENSSL_malloc(resp.len); if (p == NULL) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "OPENSSL_malloc() failed"); return SSL_TLSEXT_ERR_NOACK; } - ngx_memcpy(p, staple->staple.data, staple->staple.len); + ngx_memcpy(p, resp.data, resp.len); - SSL_set_tlsext_status_ocsp_resp(ssl_conn, p, staple->staple.len); + SSL_set_tlsext_status_ocsp_resp(ssl_conn, p, resp.len); rc = SSL_TLSEXT_ERR_OK; } - ngx_ssl_stapling_update(staple); + if (staple) { + ngx_ssl_stapling_update(staple, conf); + } return rc; } static void -ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple) +ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple, ngx_ssl_staple_conf_t *conf) { ngx_ssl_ocsp_ctx_t *ctx; @@ -511,10 +549,10 @@ ngx_ssl_stapling_update(ngx_ssl_stapling ctx->host = staple->host; ctx->uri = staple->uri; ctx->port = staple->port; - ctx->timeout = staple->timeout; + ctx->timeout = conf->timeout; - ctx->resolver = staple->resolver; - ctx->resolver_timeout = staple->resolver_timeout; + ctx->resolver = conf->resolver; + ctx->resolver_timeout = conf->resolver_timeout; ctx->handler = ngx_ssl_stapling_ocsp_handler; ctx->data = staple; @@ -596,7 +634,7 @@ ngx_ssl_stapling_ocsp_handler(ngx_ssl_oc chain = staple->ssl_ctx->extra_certs; #endif - flags = staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY; + flags = ctx->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY; #if OPENSSL_VERSION_NUMBER < 0x10000000L /* From fdasilva at ingima.com Mon Apr 27 15:39:48 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Mon, 27 Apr 2015 15:39:48 +0000 Subject: [PATCH 3 of 5] OCSP Stapling: introduce multiple cert support. Message-ID: # HG changeset patch # User Filipe da Silva # Date 1430147821 -7200 # Mon Apr 27 17:17:01 2015 +0200 # Node ID 1b79826c93a4822fa3c11bc4139ca76e5189b14c # Parent caabe5c77b51274237d7c49fffb864a27ca0a25f OCSP Stapling: introduce multiple cert support. Loop on each certificate to init his respective stapling context. Compatible with 'stable-1.8' diff -r caabe5c77b51 -r 1b79826c93a4 src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Mon Apr 27 17:17:01 2015 +0200 +++ b/src/event/ngx_event_openssl_stapling.c Mon Apr 27 17:17:01 2015 +0200 @@ -93,9 +93,10 @@ struct ngx_ssl_ocsp_ctx_s { static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, ngx_ssl_staple_conf_t *conf); -static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl); +static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl, + X509 *cert); static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_str_t *responder); + ngx_str_t *responder, X509 *cert); static int ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn, void *data); @@ -128,8 +129,9 @@ ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify) { - ngx_int_t rc; + ngx_int_t rc, res; ngx_ssl_staple_conf_t *conf; + X509 *cert; conf = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_staple_conf_t)); if (conf == NULL) { @@ -157,26 +159,32 @@ ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl goto done; } - rc = ngx_ssl_stapling_issuer(cf, ssl); + res = NGX_DECLINED; + cert = ngx_ssl_get_server_certificate(ssl); - if (rc == NGX_DECLINED) { - return NGX_OK; + while (cert) { + rc = ngx_ssl_stapling_issuer(cf, ssl, cert); + + if (rc == NGX_OK) { + rc = ngx_ssl_stapling_responder(cf, ssl, responder, cert); + } + + if (rc == NGX_OK) { + /* result becomes OK when at least one cert is OK */ + res = NGX_OK; + } else if (rc == NGX_DECLINED) { + rc = NGX_OK; + } else { + return NGX_ERROR; + } + + cert = ngx_ssl_get_next_server_certificate(ssl); } - if (rc != NGX_OK) { - return NGX_ERROR; - } - - rc = ngx_ssl_stapling_responder(cf, ssl, responder); - - if (rc == NGX_DECLINED) { + if (res == NGX_DECLINED) { return NGX_OK; } - if (rc != NGX_OK) { - return NGX_ERROR; - } - done: SSL_CTX_set_tlsext_status_cb(ssl->ctx, ngx_ssl_certificate_status_callback); @@ -254,18 +262,16 @@ failed: static ngx_int_t -ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl) +ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl, X509 *cert) { int i, n, rc; - X509 *cert, *issuer; + X509 *issuer; X509_STORE *store; X509_STORE_CTX *store_ctx; STACK_OF(X509) *chain; ngx_ssl_stapling_t *staple; ngx_pool_cleanup_t *cln; - cert = ngx_ssl_get_server_certificate(ssl->ctx); - staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t)); if (staple == NULL) { return NGX_ERROR; @@ -367,22 +373,21 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, static ngx_int_t -ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder) +ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder, + X509 *cert) { ngx_url_t u; char *s; ngx_ssl_stapling_t *staple; - X509 *cert; STACK_OF(OPENSSL_STRING) *aia; - cert = ngx_ssl_get_server_certificate(ssl); staple = X509_get_ex_data(cert, ngx_ssl_cert_stapling_index); if (responder->len == 0) { /* extract OCSP responder URL from certificate */ - aia = X509_get1_ocsp(staple->cert); + aia = X509_get1_ocsp(cert); if (aia == NULL) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, " From fdasilva at ingima.com Mon Apr 27 15:39:52 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Mon, 27 Apr 2015 15:39:52 +0000 Subject: [PATCH 4 of 5] SSL: introduce certificate list support. Message-ID: # HG changeset patch # User Filipe da Silva # Date 1430147821 -7200 # Mon Apr 27 17:17:01 2015 +0200 # Node ID e465a170ec3889eef1ab2d5d9f59cf8b12e97055 # Parent 1b79826c93a4822fa3c11bc4139ca76e5189b14c SSL: introduce certificate list support. Arguments are now a list of certificates and list of keys. Split ngx_ssl_certificate to loop separately on cert and keys. SSL session_id_context value is build with every configured certificate. Compatible with 'stable-1.8' diff -r 1b79826c93a4 -r e465a170ec38 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Mon Apr 27 17:17:01 2015 +0200 +++ b/src/event/ngx_event_openssl.c Mon Apr 27 17:17:01 2015 +0200 @@ -33,6 +33,10 @@ static void ngx_ssl_connection_error(ngx ngx_err_t err, char *text); static void ngx_ssl_clear_error(ngx_log_t *log); +static ngx_int_t ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_str_t *cert); +static ngx_int_t ngx_ssl_private_key(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_str_t *key, ngx_array_t *passwords); static ngx_int_t ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx); ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data); @@ -338,14 +342,39 @@ ngx_ssl_get_next_server_certificate(ngx_ ngx_int_t -ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, - ngx_str_t *key, ngx_array_t *passwords) +ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, + ngx_array_t *keys, ngx_array_t *passwords) +{ + ngx_uint_t i, j; + ngx_str_t *cert; + ngx_str_t *key; + + /* Load server certificates */ + cert = certs->elts; + for (i = 0; i < certs->nelts; i++, cert++) { + if (ngx_ssl_server_certificate(cf, ssl, cert) != NGX_OK) { + return NGX_ERROR; + } + } + + /* Load private keys */ + key = keys->elts; + for (j = 0; j < keys->nelts; j++, key++) { + if (ngx_ssl_private_key(cf, ssl, key, passwords) != NGX_OK) { + return NGX_ERROR; + } + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_ssl_server_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert) { BIO *bio; X509 *x509; u_long n; - ngx_str_t *pwd; - ngx_uint_t tries; if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { return NGX_ERROR; @@ -441,6 +470,17 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ BIO_free(bio); + return NGX_OK; +} + + +static ngx_int_t +ngx_ssl_private_key(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *key, + ngx_array_t *passwords) +{ + ngx_str_t *pwd; + ngx_uint_t tries; + if (ngx_strncmp(key->data, "engine:", sizeof("engine:") - 1) == 0) { #ifndef OPENSSL_NO_ENGINE @@ -2205,17 +2245,23 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss cert = ngx_ssl_get_server_certificate(ssl); - if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "X509_digest() failed"); - goto failed; + while (cert) { + + if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "X509_digest() failed"); + goto failed; + } + + if (EVP_DigestUpdate(&md, buf, len) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "EVP_DigestUpdate() failed"); + goto failed; + } + + cert = ngx_ssl_get_next_server_certificate(ssl); } - if (EVP_DigestUpdate(&md, buf, len) == 0) { - ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, - "EVP_DigestUpdate() failed"); - goto failed; - } list = SSL_CTX_get_client_CA_list(ssl->ctx); diff -r 1b79826c93a4 -r e465a170ec38 src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Mon Apr 27 17:17:01 2015 +0200 +++ b/src/event/ngx_event_openssl.h Mon Apr 27 17:17:01 2015 +0200 @@ -122,8 +122,8 @@ typedef struct { ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); -ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, - ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); +ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, From fdasilva at ingima.com Mon Apr 27 15:39:55 2015 From: fdasilva at ingima.com (Filipe DA SILVA) Date: Mon, 27 Apr 2015 15:39:55 +0000 Subject: [PATCH 5 of 5] SSL: add Multiple SSL certificate support to various modules. Message-ID: # HG changeset patch # User Filipe da Silva # Date 1430148930 -7200 # Mon Apr 27 17:35:30 2015 +0200 # Node ID 64aad233af2e71b17d6ef8c7c021b701c83d578d # Parent f4975130e1101c4003a0ce4e5422990b780d50fe SSL: add Multiple SSL certificate support to other modules. Multiple entries are now possible for ssl_certificate and ssl_certificate_key settings. Fix compilation of previous patch changes. Compatible with 'stable-1.8' diff -r f4975130e110 -r 64aad233af2e src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Mon Apr 27 17:34:19 2015 +0200 +++ b/src/http/modules/ngx_http_proxy_module.c Mon Apr 27 17:35:30 2015 +0200 @@ -97,8 +97,8 @@ typedef struct { ngx_uint_t ssl_verify_depth; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; - ngx_str_t ssl_certificate; - ngx_str_t ssl_certificate_key; + ngx_array_t *ssl_certificates; + ngx_array_t *ssl_certificate_keys; ngx_array_t *ssl_passwords; #endif } ngx_http_proxy_loc_conf_t; @@ -672,16 +672,16 @@ static ngx_command_t ngx_http_proxy_com { ngx_string("proxy_ssl_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate), + offsetof(ngx_http_proxy_loc_conf_t, ssl_certificates), NULL }, { ngx_string("proxy_ssl_certificate_key"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate_key), + offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate_keys), NULL }, { ngx_string("proxy_ssl_password_file"), @@ -2858,6 +2858,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ conf->upstream.ssl_verify = NGX_CONF_UNSET; conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; conf->ssl_passwords = NGX_CONF_UNSET_PTR; + conf->ssl_certificates = NGX_CONF_UNSET_PTR; + conf->ssl_certificate_keys = NGX_CONF_UNSET_PTR; #endif /* "proxy_cyclic_temp_file" is disabled */ @@ -3189,10 +3191,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t prev->ssl_trusted_certificate, ""); ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); - ngx_conf_merge_str_value(conf->ssl_certificate, - prev->ssl_certificate, ""); - ngx_conf_merge_str_value(conf->ssl_certificate_key, - prev->ssl_certificate_key, ""); + ngx_conf_merge_ptr_value(conf->ssl_certificates, + prev->ssl_certificates, NULL); + ngx_conf_merge_ptr_value(conf->ssl_certificate_keys, + prev->ssl_certificate_keys, NULL); + ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL); if (conf->ssl && ngx_http_proxy_set_ssl(cf, conf) != NGX_OK) { @@ -4279,6 +4282,7 @@ static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf) { ngx_pool_cleanup_t *cln; + ngx_str_t *oddkey; plcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t)); if (plcf->upstream.ssl == NULL) { @@ -4301,18 +4305,43 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n cln->handler = ngx_ssl_cleanup_ctx; cln->data = plcf->upstream.ssl; - if (plcf->ssl_certificate.len) { - - if (plcf->ssl_certificate_key.len == 0) { + if (plcf->ssl_certificates && plcf->ssl_certificates->nelts > 0) { + + if (!plcf->ssl_certificate_keys + || plcf->ssl_certificate_keys->nelts + < plcf->ssl_certificates->nelts) + { + + oddkey = plcf->ssl_certificates->elts; + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"proxy_ssl_certificate_key\" is defined " - "for certificate \"%V\"", &plcf->ssl_certificate); + "for ssl certificate \"%V\"", + oddkey[(plcf->ssl_certificate_keys) + ? plcf->ssl_certificate_keys->nelts + : 0]); + return NGX_ERROR; } - if (ngx_ssl_certificate(cf, plcf->upstream.ssl, &plcf->ssl_certificate, - &plcf->ssl_certificate_key, plcf->ssl_passwords) - != NGX_OK) +#ifndef SSL_CTX_add0_chain_cert + if (plcf->ssl_certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured " + "in \"proxy_ssl_certificate\", " + "but OpenSSL version < 1.0.2 used"); + return NGX_ERROR; + } +#endif + + if (ngx_ssl_certificates(cf, plcf->upstream.ssl, plcf->ssl_certificates, + plcf->ssl_certificate_keys, + plcf->ssl_passwords) + != NGX_OK) { return NGX_ERROR; } diff -r f4975130e110 -r 64aad233af2e src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c Mon Apr 27 17:34:19 2015 +0200 +++ b/src/http/modules/ngx_http_ssl_module.c Mon Apr 27 17:35:30 2015 +0200 @@ -81,16 +81,16 @@ static ngx_command_t ngx_http_ssl_comma { ngx_string("ssl_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_SRV_CONF_OFFSET, - offsetof(ngx_http_ssl_srv_conf_t, certificate), + offsetof(ngx_http_ssl_srv_conf_t, certificates), NULL }, { ngx_string("ssl_certificate_key"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_SRV_CONF_OFFSET, - offsetof(ngx_http_ssl_srv_conf_t, certificate_key), + offsetof(ngx_http_ssl_srv_conf_t, certificate_keys), NULL }, { ngx_string("ssl_password_file"), @@ -505,8 +505,6 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t * set by ngx_pcalloc(): * * sscf->protocols = 0; - * sscf->certificate = { 0, NULL }; - * sscf->certificate_key = { 0, NULL }; * sscf->dhparam = { 0, NULL }; * sscf->ecdh_curve = { 0, NULL }; * sscf->client_certificate = { 0, NULL }; @@ -523,6 +521,8 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t sscf->buffer_size = NGX_CONF_UNSET_SIZE; sscf->verify = NGX_CONF_UNSET_UINT; sscf->verify_depth = NGX_CONF_UNSET_UINT; + sscf->certificates = NGX_CONF_UNSET_PTR; + sscf->certificate_keys = NGX_CONF_UNSET_PTR; sscf->passwords = NGX_CONF_UNSET_PTR; sscf->builtin_session_cache = NGX_CONF_UNSET; sscf->session_timeout = NGX_CONF_UNSET; @@ -570,8 +570,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); - ngx_conf_merge_str_value(conf->certificate, prev->certificate, ""); - ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, ""); + ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); + ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, + NULL); ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); @@ -598,7 +599,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * if (conf->enable) { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate\" is defined for " "the \"ssl\" directive in %s:%ui", @@ -606,7 +607,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * return NGX_CONF_ERROR; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined for " "the \"ssl\" directive in %s:%ui", @@ -616,18 +617,38 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * } else { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { return NGX_CONF_OK; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined " - "for certificate \"%V\"", &conf->certificate); + "for certificate \"%V\"", &conf->certificates[0]); + return NGX_CONF_ERROR; + } + if (conf->certificate_keys->nelts < conf->certificates->nelts) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "no \"ssl_certificate_key\" is defined " + "for certificate \"%V\"", + &conf->certificates[conf->certificate_keys->nelts]); return NGX_CONF_ERROR; } } +#ifndef SSL_CTX_add0_chain_cert + if (conf->certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured in " + "\"ssl_certificate\", but OpenSSL < 1.0.2 used"); + return NGX_CONF_ERROR; + } +#endif + if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) { return NGX_CONF_ERROR; } @@ -663,8 +684,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * cln->handler = ngx_ssl_cleanup_ctx; cln->data = &conf->ssl; - if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate, - &conf->certificate_key, conf->passwords) + if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, + conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; diff -r f4975130e110 -r 64aad233af2e src/http/modules/ngx_http_ssl_module.h --- a/src/http/modules/ngx_http_ssl_module.h Mon Apr 27 17:34:19 2015 +0200 +++ b/src/http/modules/ngx_http_ssl_module.h Mon Apr 27 17:35:30 2015 +0200 @@ -32,8 +32,8 @@ typedef struct { time_t session_timeout; - ngx_str_t certificate; - ngx_str_t certificate_key; + ngx_array_t *certificates; + ngx_array_t *certificate_keys; ngx_str_t dhparam; ngx_str_t ecdh_curve; ngx_str_t client_certificate; diff -r f4975130e110 -r 64aad233af2e src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c Mon Apr 27 17:34:19 2015 +0200 +++ b/src/http/modules/ngx_http_uwsgi_module.c Mon Apr 27 17:35:30 2015 +0200 @@ -54,8 +54,8 @@ typedef struct { ngx_uint_t ssl_verify_depth; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; - ngx_str_t ssl_certificate; - ngx_str_t ssl_certificate_key; + ngx_array_t *ssl_certificates; + ngx_array_t *ssl_certificate_keys; ngx_array_t *ssl_passwords; #endif } ngx_http_uwsgi_loc_conf_t; @@ -517,16 +517,16 @@ static ngx_command_t ngx_http_uwsgi_comm { ngx_string("uwsgi_ssl_certificate"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate), + offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificates), NULL }, { ngx_string("uwsgi_ssl_certificate_key"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate_key), + offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate_keys), NULL }, { ngx_string("uwsgi_ssl_password_file"), @@ -1430,6 +1430,8 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_ conf->upstream.ssl_verify = NGX_CONF_UNSET; conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; conf->ssl_passwords = NGX_CONF_UNSET_PTR; + conf->ssl_certificates = NGX_CONF_UNSET_PTR; + conf->ssl_certificate_keys = NGX_CONF_UNSET_PTR; #endif /* "uwsgi_cyclic_temp_file" is disabled */ @@ -1744,11 +1746,10 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t ngx_conf_merge_str_value(conf->ssl_trusted_certificate, prev->ssl_trusted_certificate, ""); ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); - - ngx_conf_merge_str_value(conf->ssl_certificate, - prev->ssl_certificate, ""); - ngx_conf_merge_str_value(conf->ssl_certificate_key, - prev->ssl_certificate_key, ""); + ngx_conf_merge_ptr_value(conf->ssl_certificates, + prev->ssl_certificates, NULL); + ngx_conf_merge_ptr_value(conf->ssl_certificate_keys, + prev->ssl_certificate_keys, NULL); ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL); if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) { @@ -2285,6 +2286,7 @@ static ngx_int_t ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf) { ngx_pool_cleanup_t *cln; + ngx_str_t *oddkey; uwcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t)); if (uwcf->upstream.ssl == NULL) { @@ -2307,17 +2309,42 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, n cln->handler = ngx_ssl_cleanup_ctx; cln->data = uwcf->upstream.ssl; - if (uwcf->ssl_certificate.len) { - - if (uwcf->ssl_certificate_key.len == 0) { + if (uwcf->ssl_certificates && uwcf->ssl_certificates->nelts > 0) { + + if (!uwcf->ssl_certificate_keys + || uwcf->ssl_certificate_keys->nelts + < uwcf->ssl_certificates->nelts) + { + + oddkey = uwcf->ssl_certificates->elts; + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"uwsgi_ssl_certificate_key\" is defined " - "for certificate \"%V\"", &uwcf->ssl_certificate); + "for ssl certificate \"%V\"", + oddkey[(uwcf->ssl_certificate_keys) + ? uwcf->ssl_certificate_keys->nelts + : 0]); + return NGX_ERROR; } - if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, &uwcf->ssl_certificate, - &uwcf->ssl_certificate_key, uwcf->ssl_passwords) +#ifndef SSL_CTX_add0_chain_cert + if (uwcf->ssl_certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured " + "in \"uwsgi_ssl_certificate\", but " + "OpenSSL < 1.0.2 used"); + return NGX_ERROR; + } +#endif + + if (ngx_ssl_certificates(cf, uwcf->upstream.ssl, uwcf->ssl_certificates, + uwcf->ssl_certificate_keys, + uwcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; diff -r f4975130e110 -r 64aad233af2e src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c Mon Apr 27 17:34:19 2015 +0200 +++ b/src/mail/ngx_mail_ssl_module.c Mon Apr 27 17:35:30 2015 +0200 @@ -73,16 +73,16 @@ static ngx_command_t ngx_mail_ssl_comma { ngx_string("ssl_certificate"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_ssl_conf_t, certificate), + offsetof(ngx_mail_ssl_conf_t, certificates), NULL }, { ngx_string("ssl_certificate_key"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_conf_set_str_array_slot, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_ssl_conf_t, certificate_key), + offsetof(ngx_mail_ssl_conf_t, certificate_keys), NULL }, { ngx_string("ssl_password_file"), @@ -238,8 +238,6 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf) * set by ngx_pcalloc(): * * scf->protocols = 0; - * scf->certificate = { 0, NULL }; - * scf->certificate_key = { 0, NULL }; * scf->dhparam = { 0, NULL }; * scf->ecdh_curve = { 0, NULL }; * scf->client_certificate = { 0, NULL }; @@ -250,6 +248,8 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf) */ scf->enable = NGX_CONF_UNSET; + scf->certificates = NGX_CONF_UNSET_PTR; + scf->certificate_keys = NGX_CONF_UNSET_PTR; scf->starttls = NGX_CONF_UNSET_UINT; scf->passwords = NGX_CONF_UNSET_PTR; scf->prefer_server_ciphers = NGX_CONF_UNSET; @@ -290,8 +290,9 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); - ngx_conf_merge_str_value(conf->certificate, prev->certificate, ""); - ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, ""); + ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); + ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, + NULL); ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); @@ -328,7 +329,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, if (*mode) { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate\" is defined for " "the \"%s\" directive in %s:%ui", @@ -336,7 +337,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined for " "the \"%s\" directive in %s:%ui", @@ -344,17 +345,24 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } + if (conf->certificate_keys->nelts < conf->certificates->nelts) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "no \"ssl_certificate_key\" is defined " + "for certificate \"%V\"", + &conf->certificates[conf->certificate_keys->nelts]); + return NGX_CONF_ERROR; + } + } else { - if (conf->certificate.len == 0) { + if (!conf->certificates || conf->certificates->nelts == 0) { return NGX_CONF_OK; } - if (conf->certificate_key.len == 0) { + if (!conf->certificate_keys || conf->certificate_keys->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined " - "for certificate \"%V\"", - &conf->certificate); + "for certificate \"%V\"", &conf->certificates[0]); return NGX_CONF_ERROR; } } @@ -371,8 +379,21 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, cln->handler = ngx_ssl_cleanup_ctx; cln->data = &conf->ssl; - if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate, - &conf->certificate_key, conf->passwords) +#ifndef SSL_CTX_add0_chain_cert + if (conf->certificates->nelts > 1) { + /* + * no multiple certificates support for OpenSSL < 1.0.2, + * so we need to alarm user + */ + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "Multiple certificate configured in " + "\"ssl_certificate\", but OpenSSL < 1.0.2 used"); + return NGX_CONF_ERROR; + } +#endif + + if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, + conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; diff -r f4975130e110 -r 64aad233af2e src/mail/ngx_mail_ssl_module.h --- a/src/mail/ngx_mail_ssl_module.h Mon Apr 27 17:34:19 2015 +0200 +++ b/src/mail/ngx_mail_ssl_module.h Mon Apr 27 17:35:30 2015 +0200 @@ -35,8 +35,8 @@ typedef struct { time_t session_timeout; - ngx_str_t certificate; - ngx_str_t certificate_key; + ngx_array_t *certificates; + ngx_array_t *certificate_keys; ngx_str_t dhparam; ngx_str_t ecdh_curve; ngx_str_t client_certificate; From mdounin at mdounin.ru Mon Apr 27 17:04:49 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 27 Apr 2015 17:04:49 +0000 Subject: [nginx] Core: fixed nginx_shared_zone name. Message-ID: details: http://hg.nginx.org/nginx/rev/be3aaf9f0005 branches: changeset: 6131:be3aaf9f0005 user: Maxim Dounin date: Mon Apr 27 03:44:03 2015 +0300 description: Core: fixed nginx_shared_zone name. diffstat: src/event/ngx_event.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -507,7 +507,7 @@ ngx_event_module_init(ngx_cycle_t *cycle #endif shm.size = size; - shm.name.len = sizeof("nginx_shared_zone"); + shm.name.len = sizeof("nginx_shared_zone") - 1; shm.name.data = (u_char *) "nginx_shared_zone"; shm.log = cycle->log; From mdounin at mdounin.ru Mon Apr 27 17:04:51 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 27 Apr 2015 17:04:51 +0000 Subject: [nginx] Win32: fixed shm.handle loss on reload. Message-ID: details: http://hg.nginx.org/nginx/rev/859ce1c41f64 branches: changeset: 6132:859ce1c41f64 user: Maxim Dounin date: Mon Apr 27 03:44:30 2015 +0300 description: Win32: fixed shm.handle loss on reload. diffstat: src/core/ngx_cycle.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -441,6 +441,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) && !shm_zone[i].noreuse) { shm_zone[i].shm.addr = oshm_zone[n].shm.addr; +#if (NGX_WIN32) + shm_zone[i].shm.handle = oshm_zone[n].shm.handle; +#endif if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data) != NGX_OK) From mdounin at mdounin.ru Mon Apr 27 17:04:56 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 27 Apr 2015 17:04:56 +0000 Subject: [nginx] Added stream module to win32 builds. Message-ID: details: http://hg.nginx.org/nginx/rev/96e22e4f1b03 branches: changeset: 6134:96e22e4f1b03 user: Maxim Dounin date: Mon Apr 27 18:51:18 2015 +0300 description: Added stream module to win32 builds. diffstat: misc/GNUmakefile | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (16 lines): diff --git a/misc/GNUmakefile b/misc/GNUmakefile --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -80,10 +80,12 @@ win32: --with-http_random_index_module \ --with-http_secure_link_module \ --with-mail \ + --with-stream \ --with-openssl=$(OBJS)/lib/$(OPENSSL) \ --with-openssl-opt=enable-tlsext \ --with-http_ssl_module \ --with-mail_ssl_module \ + --with-stream_ssl_module \ --with-ipv6 From mdounin at mdounin.ru Mon Apr 27 17:04:54 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 27 Apr 2015 17:04:54 +0000 Subject: [nginx] Win32: shared memory base addresses and remapping. Message-ID: details: http://hg.nginx.org/nginx/rev/af7eba90645d branches: changeset: 6133:af7eba90645d user: Maxim Dounin date: Mon Apr 27 18:25:42 2015 +0300 description: Win32: shared memory base addresses and remapping. Two mechanisms are implemented to make it possible to store pointers in shared memory on Windows, in particular on Windows Vista and later versions with ASLR: - The ngx_shm_remap() function added to allow remapping of a shared memory zone to the address originally used for it in the master process. While important, it doesn't solve the problem by itself as in many cases it's not possible to use the address because of conflicts with other allocations. - We now create mappings at the same address in all processes by starting mappings at predefined addresses normally unused by newborn processes. These two mechanisms combined allow to use shared memory on Windows almost without problems, including reloads. Based on the patch by Sergey Brester: http://mailman.nginx.org/pipermail/nginx-devel/2015-April/006836.html diffstat: src/core/ngx_cycle.c | 16 ++++++++ src/os/win32/ngx_shmem.c | 82 +++++++++++++++++++++++++++++++++++++++++- src/os/win32/ngx_shmem.h | 3 + src/os/win32/ngx_win32_init.c | 1 + 4 files changed, 100 insertions(+), 2 deletions(-) diffs (160 lines): diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -863,6 +863,22 @@ ngx_init_zone_pool(ngx_cycle_t *cycle, n return NGX_OK; } +#if (NGX_WIN32) + + /* remap at the required address */ + + if (ngx_shm_remap(&zn->shm, sp->addr) != NGX_OK) { + return NGX_ERROR; + } + + sp = (ngx_slab_pool_t *) zn->shm.addr; + + if (sp == sp->addr) { + return NGX_OK; + } + +#endif + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "shared zone \"%V\" has no equal addresses: %p vs %p", &zn->shm.name, sp->addr, sp); diff --git a/src/os/win32/ngx_shmem.c b/src/os/win32/ngx_shmem.c --- a/src/os/win32/ngx_shmem.c +++ b/src/os/win32/ngx_shmem.c @@ -9,11 +9,44 @@ #include +/* + * Base addresses selected by system for shared memory mappings are likely + * to be different on Windows Vista and later versions due to address space + * layout randomization. This is however incompatible with storing absolute + * addresses within the shared memory. + * + * To make it possible to store absolute addresses we create mappings + * at the same address in all processes by starting mappings at predefined + * addresses. The addresses were selected somewhat randomly in order to + * minimize the probability that some other library doing something similar + * conflicts with us. The addresses are from the following typically free + * blocks: + * + * - 0x10000000 .. 0x70000000 (about 1.5 GB in total) on 32-bit platforms + * - 0x000000007fff0000 .. 0x000007f68e8b0000 (about 8 TB) on 64-bit platforms + * + * Additionally, we allow to change the mapping address once it was detected + * to be different from one originally used. This is needed to support + * reconfiguration. + */ + + +#ifdef _WIN64 +#define NGX_SHMEM_BASE 0x0000047047e00000 +#else +#define NGX_SHMEM_BASE 0x2efe0000 +#endif + + +ngx_uint_t ngx_allocation_granularity; + + ngx_int_t ngx_shm_alloc(ngx_shm_t *shm) { - u_char *name; - uint64_t size; + u_char *name; + uint64_t size; + static u_char *base = (u_char *) NGX_SHMEM_BASE; name = ngx_alloc(shm->name.len + 2 + NGX_INT32_LEN, shm->log); if (name == NULL) { @@ -46,6 +79,27 @@ ngx_shm_alloc(ngx_shm_t *shm) shm->exists = 1; } + shm->addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, base); + + if (shm->addr != NULL) { + base += ngx_align(size, ngx_allocation_granularity); + return NGX_OK; + } + + ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, ngx_errno, + "MapViewOfFileEx(%uz, %p) of file mapping \"%V\" failed, " + "retry without a base address", + shm->size, base, &shm->name); + + /* + * Order of shared memory zones may be different in the master process + * and worker processes after reconfiguration. As a result, the above + * may fail due to a conflict with a previously created mapping remapped + * to a different address. Additionally, there may be a conflict with + * some other uses of the memory. In this case we retry without a base + * address to let the system assign the address itself. + */ + shm->addr = MapViewOfFile(shm->handle, FILE_MAP_WRITE, 0, 0, 0); if (shm->addr != NULL) { @@ -66,6 +120,30 @@ ngx_shm_alloc(ngx_shm_t *shm) } +ngx_int_t +ngx_shm_remap(ngx_shm_t *shm, u_char *addr) +{ + if (UnmapViewOfFile(shm->addr) == 0) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "UnmapViewOfFile(%p) of file mapping \"%V\" failed", + shm->addr, &shm->name); + return NGX_ERROR; + } + + shm->addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, addr); + + if (shm->addr != NULL) { + return NGX_OK; + } + + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "MapViewOfFileEx(%uz, %p) of file mapping \"%V\" failed", + shm->size, addr, &shm->name); + + return NGX_ERROR; +} + + void ngx_shm_free(ngx_shm_t *shm) { diff --git a/src/os/win32/ngx_shmem.h b/src/os/win32/ngx_shmem.h --- a/src/os/win32/ngx_shmem.h +++ b/src/os/win32/ngx_shmem.h @@ -24,7 +24,10 @@ typedef struct { ngx_int_t ngx_shm_alloc(ngx_shm_t *shm); +ngx_int_t ngx_shm_remap(ngx_shm_t *shm, u_char *addr); void ngx_shm_free(ngx_shm_t *shm); +extern ngx_uint_t ngx_allocation_granularity; + #endif /* _NGX_SHMEM_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_win32_init.c b/src/os/win32/ngx_win32_init.c --- a/src/os/win32/ngx_win32_init.c +++ b/src/os/win32/ngx_win32_init.c @@ -118,6 +118,7 @@ ngx_os_init(ngx_log_t *log) GetSystemInfo(&si); ngx_pagesize = si.dwPageSize; + ngx_allocation_granularity = si.dwAllocationGranularity; ngx_ncpu = si.dwNumberOfProcessors; ngx_cacheline_size = NGX_CPU_CACHE_LINE; From mdounin at mdounin.ru Mon Apr 27 17:16:22 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 27 Apr 2015 20:16:22 +0300 Subject: Fwd: Windows shmem fix: makes shared memory fully ASLR and DEP compliant (ea. cache zone, limit zone, etc.) In-Reply-To: References: <706ca3a5ec658ea41fb9975f90ab9ab4@sebres.de> <20150422162929.GD32429@mdounin.ru> <54cf66a081e1767be9e630003485c4fa@sebres.de> <20150427012530.GS32429@mdounin.ru> Message-ID: <20150427171622.GA32429@mdounin.ru> Hello! On Mon, Apr 27, 2015 at 04:38:15PM +0200, Sergey Brester wrote: > I have little bit tested your changeset. > Looks good: 10000 successful reloads with randomly adding/removing zones > up to 1GB (Win7 x64 and 2K8-R2 x64). Committed, thanks. -- Maxim Dounin http://nginx.org/ From shawgoff at amazon.com Mon Apr 27 19:19:09 2015 From: shawgoff at amazon.com (Shawn J. Goff) Date: Mon, 27 Apr 2015 12:19:09 -0700 Subject: Adding asynchronous logging Message-ID: <553E8BAD.1090007@amazon.com> I have been doing some load tests against Nginx and have found significant client-side latency outliers at the 99.9th percentile. During the load test, I'm looking at iostat and it's showing me mostly zero utilization. When I log to a tmpfs instead, the outliers go away. When I use buffer=32M, the outliers come much less frequently. This leads me to believe that the synchronous write in the ngx_http_log_module is contributing to the latency as the worker threads can't accept until they're done writing. I'm considering adding asynchronous logging to the module and wanted input. So far, I planning on using aio and would like to know if this is a bad idea or not. I saw recently that the aio module was deprecated, but I'm not sure why. Thanks, Shawn J. Goff From mdounin at mdounin.ru Mon Apr 27 19:40:05 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 27 Apr 2015 22:40:05 +0300 Subject: Adding asynchronous logging In-Reply-To: <553E8BAD.1090007@amazon.com> References: <553E8BAD.1090007@amazon.com> Message-ID: <20150427193946.GB32429@mdounin.ru> Hello! On Mon, Apr 27, 2015 at 12:19:09PM -0700, Shawn J. Goff wrote: > I have been doing some load tests against Nginx and have found significant > client-side latency outliers at the 99.9th percentile. During the load test, > I'm looking at iostat and it's showing me mostly zero utilization. When I > log to a tmpfs instead, the outliers go away. When I use buffer=32M, the > outliers come much less frequently. This leads me to believe that the > synchronous write in the ngx_http_log_module is contributing to the latency > as the worker threads can't accept until they're done writing. Just a side note: as nginx does nothing to make writes synchronous, it's up to OS to optimize writes as long as it is able to do it. You may want to look into what your OS can do here and how to tune it. > I'm considering adding asynchronous logging to the module and wanted input. > So far, I planning on using aio and would like to know if this is a bad idea > or not. I saw recently that the aio module was deprecated, but I'm not sure > why. The module that was deprecated (and removed) is the aio event module, an experimental module to work with sockets with AIO operations as available on FreeBSD. Not to be confused with file AIO functions available if nginx is compiled with --with-file-aio configure option. -- Maxim Dounin http://nginx.org/ From piotr at cloudflare.com Mon Apr 27 23:38:47 2015 From: piotr at cloudflare.com (Piotr Sikora) Date: Mon, 27 Apr 2015 16:38:47 -0700 Subject: [PATCH] Cache: provide naive feedback loop for uncacheable URLs Message-ID: <1e7878138228e3decb86.1430177927@piotrs-macbook-pro.local> # HG changeset patch # User Piotr Sikora # Date 1430177825 25200 # Mon Apr 27 16:37:05 2015 -0700 # Node ID 1e7878138228e3decb868f38eddc38937d55f403 # Parent 96e22e4f1b03ff15a774c6ed34d74b897af32c55 Cache: provide naive feedback loop for uncacheable URLs. The cache lock provides a mechanism that allows only one request for the same URL to be sent upstream at the same time. All other requests must wait until the lock is released and/or not needed. While this works as designed and protects upstream from requests stampede in case the response is cacheable, it results in a huge performance degradation for popular and uncacheable URLs, thanks to the artificial delay added to the upstream requests. To make things even worse, the lock acquisition is retried every 500ms and prone to lock starvation - there is no queue, so newly accepted requests can jump ahead and acquire the lock before any of the already pending requests have a chance to retry it, which can lead to huge spikes in the response times and even timeouts. This feedback loop provides a mechanism that allows requests for uncacheable URLs to immediately skip the cache lock. Signed-off-by: Piotr Sikora diff -r 96e22e4f1b03 -r 1e7878138228 src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h Mon Apr 27 18:51:18 2015 +0300 +++ b/src/http/ngx_http_cache.h Mon Apr 27 16:37:05 2015 -0700 @@ -50,7 +50,8 @@ typedef struct { unsigned exists:1; unsigned updating:1; unsigned deleting:1; - /* 11 unused bits */ + unsigned cacheable:1; + /* 10 unused bits */ ngx_file_uniq_t uniq; time_t expire; @@ -171,7 +172,8 @@ ngx_int_t ngx_http_file_cache_set_header void ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf); void ngx_http_file_cache_update_header(ngx_http_request_t *r); ngx_int_t ngx_http_cache_send(ngx_http_request_t *); -void ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf); +void ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf, + ngx_uint_t cacheable); time_t ngx_http_file_cache_valid(ngx_array_t *cache_valid, ngx_uint_t status); char *ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, diff -r 96e22e4f1b03 -r 1e7878138228 src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c Mon Apr 27 18:51:18 2015 +0300 +++ b/src/http/ngx_http_file_cache.c Mon Apr 27 16:37:05 2015 -0700 @@ -399,6 +399,7 @@ static ngx_int_t ngx_http_file_cache_lock(ngx_http_request_t *r, ngx_http_cache_t *c) { ngx_msec_t now, timer; + ngx_uint_t cacheable; ngx_http_file_cache_t *cache; if (!c->lock) { @@ -412,6 +413,7 @@ ngx_http_file_cache_lock(ngx_http_reques ngx_shmtx_lock(&cache->shpool->mutex); timer = c->node->lock_time - now; + cacheable = c->node->cacheable; if (!c->node->updating || (ngx_msec_int_t) timer <= 0) { c->node->updating = 1; @@ -422,11 +424,11 @@ ngx_http_file_cache_lock(ngx_http_reques ngx_shmtx_unlock(&cache->shpool->mutex); - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http file cache lock u:%d wt:%M", - c->updating, c->wait_time); - - if (c->updating) { + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http file cache lock u:%d c:%d wt:%M", + c->updating, cacheable, c->wait_time); + + if (c->updating || !cacheable) { return NGX_DECLINED; } @@ -880,6 +882,7 @@ renew: fcn->uniq = 0; fcn->body_start = 0; fcn->fs_size = 0; + fcn->cacheable = 1; done: @@ -1300,6 +1303,7 @@ ngx_http_file_cache_update_variant(ngx_h c->node->count--; c->node->updating = 0; + c->node->cacheable = 1; c->node = NULL; ngx_shmtx_unlock(&cache->shpool->mutex); @@ -1389,6 +1393,7 @@ ngx_http_file_cache_update(ngx_http_requ } c->node->updating = 0; + c->node->cacheable = 1; ngx_shmtx_unlock(&cache->shpool->mutex); } @@ -1578,7 +1583,8 @@ ngx_http_cache_send(ngx_http_request_t * void -ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf) +ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf, + ngx_uint_t cacheable) { ngx_http_file_cache_t *cache; ngx_http_file_cache_node_t *fcn; @@ -1599,6 +1605,7 @@ ngx_http_file_cache_free(ngx_http_cache_ if (c->updating && fcn->lock_time == c->lock_time) { fcn->updating = 0; + fcn->cacheable = cacheable; } if (c->error) { @@ -1609,7 +1616,9 @@ ngx_http_file_cache_free(ngx_http_cache_ fcn->valid_msec = c->valid_msec; } - } else if (!fcn->exists && fcn->count == 0 && c->min_uses == 1) { + } else if (!fcn->exists && fcn->count == 0 && c->min_uses == 1 + && (!c->lock || fcn->cacheable)) + { ngx_queue_remove(&fcn->queue); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_slab_free_locked(cache->shpool, fcn); @@ -1658,7 +1667,7 @@ ngx_http_file_cache_cleanup(void *data) "stalled cache updating, error:%ui", c->error); } - ngx_http_file_cache_free(c, NULL); + ngx_http_file_cache_free(c, NULL, 1); } diff -r 96e22e4f1b03 -r 1e7878138228 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Mon Apr 27 18:51:18 2015 +0300 +++ b/src/http/ngx_http_upstream.c Mon Apr 27 16:37:05 2015 -0700 @@ -2353,7 +2353,8 @@ ngx_http_upstream_intercept_errors(ngx_h r->cache->error = status; } - ngx_http_file_cache_free(r->cache, u->pipe->temp_file); + ngx_http_file_cache_free(r->cache, u->pipe->temp_file, + u->cacheable); } #endif ngx_http_upstream_finalize_request(r, u, status); @@ -2835,7 +2836,7 @@ ngx_http_upstream_send_response(ngx_http "http cacheable: %d", u->cacheable); if (u->cacheable == 0 && r->cache) { - ngx_http_file_cache_free(r->cache, u->pipe->temp_file); + ngx_http_file_cache_free(r->cache, u->pipe->temp_file, 0); } #endif @@ -3643,11 +3644,11 @@ ngx_http_upstream_process_request(ngx_ht ngx_http_file_cache_update(r, tf); } else { - ngx_http_file_cache_free(r->cache, tf); + ngx_http_file_cache_free(r->cache, tf, 1); } } else if (p->upstream_error) { - ngx_http_file_cache_free(r->cache, p->temp_file); + ngx_http_file_cache_free(r->cache, p->temp_file, 1); } } @@ -4029,7 +4030,7 @@ ngx_http_upstream_finalize_request(ngx_h } } - ngx_http_file_cache_free(r->cache, u->pipe->temp_file); + ngx_http_file_cache_free(r->cache, u->pipe->temp_file, u->cacheable); } #endif From pdan at esync.org Tue Apr 28 09:56:54 2015 From: pdan at esync.org (Dan Podeanu) Date: Tue, 28 Apr 2015 16:56:54 +0700 Subject: Client disconnect in ngx_http_image_filter_module Message-ID: I have encountered a bug in ngx_http_image_filter_module when used in conjunction with ngx_http_proxy_module ; the configuration is as following: location /img/ { proxy_pass http://mybucket.s3.amazonaws.com ; image_filter resize 150 100; } The steps to reproduce are rather complicated as they depend on how TCP fragments the response coming from the proxy: - If http://mybucket.s3.amazonaws.com returns, in the first TCP packet, a sizable amount of data (1-2k), the image is resized correctly. - If http://mybucket.s3.amazonaws.com returns, in the first TCP packet, a small amount of data (HTTP header, or HTTP header + a few bytes), the content is marked as not an image and NGX_HTTP_UNSUPPORTED_MEDIA_TYPE is returned (disconnecting the client), irrespective on whether or not subsequent data would complete the response to a valid image. Nginx appears to give up right away on waiting for data if the contents of the first TCP packet received from the proxy does not contain a valid image header- i.e. ngx_http_image_test() will return NGX_HTTP_IMAGE_SIZE, etc. In my experience this was triggered by a subtle change in AWS S3 that fragments the TCP header more. Versions affected: 1.6.2, 1.6.3, 1.7.2, 1.8.0, etc. Attaching a patch which fixes it for my use case (1.6.2) below; the other versions can be fixed similarly: ???????????????????????? diff -ruN nginx-1.6.2.orig/src/http/modules/ngx_http_image_filter_module.c nginx-1.6.2/src/http/modules/ngx_http_image_filter_module.c --- nginx-1.6.2.orig/src/http/modules/ngx_http_image_filter_module.c 2014-09-16 19:23:19.000000000 +0700 +++ nginx-1.6.2/src/http/modules/ngx_http_image_filter_module.c 2015-04-28 16:25:47.000000000 +0700 @@ -317,9 +317,8 @@ } } - return ngx_http_filter_finalize_request(r, - &ngx_http_image_filter_module, - NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); + /* wait to consume more data, do not give up on the request right away */ + return NGX_OK; } /* override content type */ ???????????????????????? Thoughts ? Is this the right fix ? Should I also post on the nginx Trac ? Thank you, Dan -------------- next part -------------- An HTML attachment was scrubbed... URL: From aviram at adallom.com Tue Apr 28 14:00:07 2015 From: aviram at adallom.com (Aviram Cohen) Date: Tue, 28 Apr 2015 14:00:07 +0000 Subject: Different SSL protocols for different server blocks on the same port Message-ID: Hello! The Nginx configuration allows you to define different server blocks that have different server names but listen on the same port in SSL. For an incoming connection, Nginx uses SNI in order to know under which server block the connection should be handled. However, the 'ssl_protocols' directive doesn't work as expected in this scenario. Let's say that we have two servers blocks - the first allows TLSv1, TLSv1.1 and TLSv1.2, and the second allows only TLSv1 connections ('ssl_protocols TLSv1;' directive). From what I've seen, in this case, the second server will still accept incoming TLSv1.1 and TLSv1.2 connections. I've debugged it a bit, and wrote some independent code that uses OpenSSL, and it seems that OpenSSL doesn't allow you to change the supported TLS versions of a connection during the SNI callback. The following may occur - an incoming connection to the second server starts, and it gets the default SSL CTX object (in Nginx, that would be the context of the first server block). When the SNI callback (ngx_http_ssl_servername) is called, the context is replaced for the connection (with the context of the second server block), along with the SSL options of the connections (SSL_set_options is called with the new CTX's options). These options contain the second server's allowed protocols. Even though the correct options are set, when the handshake continues, it would succeed even for TLSv1.1 and TLSv1.2 (which are enabled for the first server, but not for the second one). A similar problem can occur as well; for example, if the first server allows only for TLSv1 connections and the second one allows for TLSv1.1, then TLSv1.1 connections will be rejected by OpenSSL, even if their SNI name is the name of the second server. This seems like an OpenSSL issue (I've reproduced it on both v1.0.1 and v1.0.2), but I think that this should at least be documented in Nginx's SSL documentation, as the 'ssl_protocols' directive doesn't behave as expected for different server blocks with the same port - you'd expect that one server block would not affect the other, but it does. Nginx development team (e.g. Maxim, Igor), I'd love to hear your thoughts about this. Below is an example of this scenario. Best regards, Aviram The following is an example configuration: server { listen 443 ssl; server_name server1; ssl_protocols TLSv1 TLSv1.1; ... } server { listen 443 ssl; server_name server2; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ... } The following would occur when trying to connect (should succeed as server2 allows for TLSv1.2, but fails): $ openssl s_client -connect localhost:443 -servername server2 -tls1_2 CONNECTED(00000003) 140495355434656:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:339: --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 5 bytes and written 7 bytes --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1.2 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1430229239 Timeout : 7200 (sec) Verify return code: 0 (ok) --- And Nginx would show the error: SSL_do_handshake() failed (SSL: error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:SSL alert number 70) while SSL handshaking -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Tue Apr 28 14:24:30 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 28 Apr 2015 17:24:30 +0300 Subject: Different SSL protocols for different server blocks on the same port In-Reply-To: References: Message-ID: <20150428142430.GD32429@mdounin.ru> Hello! On Tue, Apr 28, 2015 at 02:00:07PM +0000, Aviram Cohen wrote: > Hello! > > The Nginx configuration allows you to define different server > blocks that have different server names but listen on the same > port in SSL. For an incoming connection, Nginx uses SNI in order > to know under which server block the connection should be > handled. > However, the 'ssl_protocols' directive doesn't work as expected > in this scenario. > Let's say that we have two servers blocks - the first allows > TLSv1, TLSv1.1 and TLSv1.2, and the second allows only TLSv1 > connections ('ssl_protocols TLSv1;' directive). From what I've > seen, in this case, the second server will still accept incoming > TLSv1.1 and TLSv1.2 connections. > > I've debugged it a bit, and wrote some independent code that > uses OpenSSL, and it seems that OpenSSL doesn't allow you to > change the supported TLS versions of a connection during the SNI > callback. > The following may occur - an incoming connection to the second > server starts, and it gets the default SSL CTX object (in Nginx, > that would be the context of the first server block). When the > SNI callback (ngx_http_ssl_servername) is called, the context is > replaced for the connection (with the context of the second > server block), along with the SSL options of the connections > (SSL_set_options is called with the new CTX's options). These > options contain the second server's allowed protocols. Even > though the correct options are set, when the handshake > continues, it would succeed even for TLSv1.1 and TLSv1.2 (which > are enabled for the first server, but not for the second one). > > A similar problem can occur as well; for example, if the first > server allows only for TLSv1 connections and the second one > allows for TLSv1.1, then TLSv1.1 connections will be rejected by > OpenSSL, even if their SNI name is the name of the second > server. > > This seems like an OpenSSL issue (I've reproduced it on both > v1.0.1 and v1.0.2), but I think that this should at least be > documented in Nginx's SSL documentation, as the 'ssl_protocols' > directive doesn't behave as expected for different server blocks > with the same port - you'd expect that one server block would > not affect the other, but it does. > > Nginx development team (e.g. Maxim, Igor), I'd love to hear your > thoughts about this. > Below is an example of this scenario. This was discussed a while ago, see here and previous messages: http://mailman.nginx.org/pipermail/nginx/2014-November/045738.html In short: there are some cases which should work IMHO, but don't due to OpenSSL behaviour. There are other cases which aren't expected to work at all, even theorethically. I don't think that OpenSSL behaviour here is a bug - the SNI callback can only happen once OpenSSL started processing of a ClientHello message, and it basically means that it already chosen a protocol to use. While in theory it can be possible to choose another protocol - it will seriously complicate things. I also think that people trying to do such things with SNI are utterly wrong. -- Maxim Dounin http://nginx.org/ From jamel at yandex-team.ru Tue Apr 28 15:12:01 2015 From: jamel at yandex-team.ru (Sergey Polovko) Date: Tue, 28 Apr 2015 18:12:01 +0300 Subject: [PATCH] check that last IPv4 octet has valid value Message-ID: <14EF63D3-3DB8-4112-ACE2-2561F104D488@yandex-team.ru> # HG changeset patch # User Sergey Polovko # Date 1430232559 -10800 # Tue Apr 28 17:49:19 2015 +0300 # Node ID e98e249441adc75c525556ca32e9f3e65e87f653 # Parent 96e22e4f1b03ff15a774c6ed34d74b897af32c55 check that last IPv4 octet has valid value diff -r 96e22e4f1b03 -r e98e249441ad src/core/ngx_inet.c --- a/src/core/ngx_inet.c Mon Apr 27 18:51:18 2015 +0300 +++ b/src/core/ngx_inet.c Tue Apr 28 17:49:19 2015 +0300 @@ -48,7 +48,7 @@ return INADDR_NONE; } - if (n == 3) { + if (n == 3 && octet <= 255) { addr = (addr << 8) + octet; return htonl(addr); } -------------- next part -------------- An HTML attachment was scrubbed... URL: From ru at nginx.com Tue Apr 28 15:31:06 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 28 Apr 2015 18:31:06 +0300 Subject: [PATCH] check that last IPv4 octet has valid value In-Reply-To: <14EF63D3-3DB8-4112-ACE2-2561F104D488@yandex-team.ru> References: <14EF63D3-3DB8-4112-ACE2-2561F104D488@yandex-team.ru> Message-ID: <20150428153106.GB40075@lo0.su> On Tue, Apr 28, 2015 at 06:12:01PM +0300, Sergey Polovko wrote: > # HG changeset patch > # User Sergey Polovko > # Date 1430232559 -10800 > # Tue Apr 28 17:49:19 2015 +0300 > # Node ID e98e249441adc75c525556ca32e9f3e65e87f653 > # Parent 96e22e4f1b03ff15a774c6ed34d74b897af32c55 > check that last IPv4 octet has valid value > > diff -r 96e22e4f1b03 -r e98e249441ad src/core/ngx_inet.c > --- a/src/core/ngx_inet.c Mon Apr 27 18:51:18 2015 +0300 > +++ b/src/core/ngx_inet.c Tue Apr 28 17:49:19 2015 +0300 > @@ -48,7 +48,7 @@ > return INADDR_NONE; > } > > - if (n == 3) { > + if (n == 3 && octet <= 255) { > addr = (addr << 8) + octet; > return htonl(addr); > } http://hg.nginx.org/nginx/rev/550212836c8f From mdounin at mdounin.ru Tue Apr 28 15:37:21 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 28 Apr 2015 15:37:21 +0000 Subject: [nginx] nginx-1.9.0-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/53d850fe292f branches: changeset: 6135:53d850fe292f user: Maxim Dounin date: Tue Apr 28 18:31:17 2015 +0300 description: nginx-1.9.0-RELEASE diffstat: docs/xml/nginx/changes.xml | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 78 insertions(+), 0 deletions(-) diffs (88 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,84 @@ + + + + +?????????? ?????? ????????? ?????????? aio ? rtsig ?????? ?? ??????????????. + + +obsolete aio and rtsig event methods have been removed. + + + + + +????????? zone ? ????? upstream. + + +the "zone" directive inside the "upstream" block. + + + + + +?????? stream. + + +the stream module. + + + + + +????????? byte ranges ??? ??????? ?????? ngx_http_memcached_module.
+??????? Martin Mlyn??. +
+ +byte ranges support in the ngx_http_memcached_module.
+Thanks to Martin Mlyn??. +
+
+ + + +??????????? ?????? ?????? ????? ???????????? ?? ??????? Windows +? ????????????? ????????? ????????????.
+??????? ?????? ????????. +
+ +shared memory can now be used on Windows versions +with address space layout randomization.
+Thanks to Sergey Brester. +
+
+ + + +????????? error_log ?????? ????? ???????????? +?? ??????? mail ? server ? ???????? ??????-???????. + + +the "error_log" directive can now be used +on mail and server levels in mail proxy. + + + + + +???????? proxy_protocol ????????? listen ?? ???????, +???? ?? ??? ?????? ? ?????? ????????? listen ??? ??????? listen-??????. + + +the "proxy_protocol" parameter of the "listen" directive did not work +if not specified in the first "listen" directive for a listen socket. + + + +
+ + From mdounin at mdounin.ru Tue Apr 28 15:37:24 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 28 Apr 2015 15:37:24 +0000 Subject: [nginx] release-1.9.0 tag Message-ID: details: http://hg.nginx.org/nginx/rev/f53f5b00859d branches: changeset: 6136:f53f5b00859d user: Maxim Dounin date: Tue Apr 28 18:31:18 2015 +0300 description: release-1.9.0 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -382,3 +382,4 @@ 34b201c1abd1e2d4faeae4650a21574771a03c0e 860cfbcc4606ee36d898a9cd0c5ae8858db984d6 release-1.7.10 2b3b737b5456c05cd63d3d834f4fb4d3776953d0 release-1.7.11 3ef00a71f56420a9c3e9cec311c9a2109a015d67 release-1.7.12 +53d850fe292f157d2fb999c52788ec1dc53c91ed release-1.9.0 From mdounin at mdounin.ru Tue Apr 28 15:50:07 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 28 Apr 2015 18:50:07 +0300 Subject: [PATCH] check that last IPv4 octet has valid value In-Reply-To: <20150428153106.GB40075@lo0.su> References: <14EF63D3-3DB8-4112-ACE2-2561F104D488@yandex-team.ru> <20150428153106.GB40075@lo0.su> Message-ID: <20150428155006.GK32429@mdounin.ru> Hello! On Tue, Apr 28, 2015 at 06:31:06PM +0300, Ruslan Ermilov wrote: > On Tue, Apr 28, 2015 at 06:12:01PM +0300, Sergey Polovko wrote: > > # HG changeset patch > > # User Sergey Polovko > > # Date 1430232559 -10800 > > # Tue Apr 28 17:49:19 2015 +0300 > > # Node ID e98e249441adc75c525556ca32e9f3e65e87f653 > > # Parent 96e22e4f1b03ff15a774c6ed34d74b897af32c55 > > check that last IPv4 octet has valid value > > > > diff -r 96e22e4f1b03 -r e98e249441ad src/core/ngx_inet.c > > --- a/src/core/ngx_inet.c Mon Apr 27 18:51:18 2015 +0300 > > +++ b/src/core/ngx_inet.c Tue Apr 28 17:49:19 2015 +0300 > > @@ -48,7 +48,7 @@ > > return INADDR_NONE; > > } > > > > - if (n == 3) { > > + if (n == 3 && octet <= 255) { > > addr = (addr << 8) + octet; > > return htonl(addr); > > } > > http://hg.nginx.org/nginx/rev/550212836c8f So, the commit is actually wrong: the "octet < 256" check is needed. -- Maxim Dounin http://nginx.org/ From vbart at nginx.com Tue Apr 28 15:55:28 2015 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 28 Apr 2015 15:55:28 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/5d0c9405af71 branches: changeset: 6137:5d0c9405af71 user: Valentin Bartenev date: Tue Apr 28 18:54:48 2015 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r f53f5b00859d -r 5d0c9405af71 src/core/nginx.h --- a/src/core/nginx.h Tue Apr 28 18:31:18 2015 +0300 +++ b/src/core/nginx.h Tue Apr 28 18:54:48 2015 +0300 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1009000 -#define NGINX_VERSION "1.9.0" +#define nginx_version 1009001 +#define NGINX_VERSION "1.9.1" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From vbart at nginx.com Tue Apr 28 15:55:31 2015 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 28 Apr 2015 15:55:31 +0000 Subject: [nginx] Fixed overflow detection in ngx_inet_addr(). Message-ID: details: http://hg.nginx.org/nginx/rev/bc47a7a8159c branches: changeset: 6138:bc47a7a8159c user: Valentin Bartenev date: Tue Apr 28 18:55:03 2015 +0300 description: Fixed overflow detection in ngx_inet_addr(). Overflow detection of the last octet might not work. Reported by Sergey Polovko. diffstat: src/core/ngx_inet.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diffs (24 lines): diff -r 5d0c9405af71 -r bc47a7a8159c src/core/ngx_inet.c --- a/src/core/ngx_inet.c Tue Apr 28 18:54:48 2015 +0300 +++ b/src/core/ngx_inet.c Tue Apr 28 18:55:03 2015 +0300 @@ -26,15 +26,15 @@ ngx_inet_addr(u_char *text, size_t len) n = 0; for (p = text; p < text + len; p++) { - - if (octet > 255) { - return INADDR_NONE; - } - c = *p; if (c >= '0' && c <= '9') { octet = octet * 10 + (c - '0'); + + if (octet > 255) { + return INADDR_NONE; + } + continue; } From ru at nginx.com Tue Apr 28 15:56:23 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 28 Apr 2015 18:56:23 +0300 Subject: [PATCH] check that last IPv4 octet has valid value In-Reply-To: <20150428153106.GB40075@lo0.su> References: <14EF63D3-3DB8-4112-ACE2-2561F104D488@yandex-team.ru> <20150428153106.GB40075@lo0.su> Message-ID: <20150428155623.GD40075@lo0.su> On Tue, Apr 28, 2015 at 06:31:06PM +0300, Ruslan Ermilov wrote: > On Tue, Apr 28, 2015 at 06:12:01PM +0300, Sergey Polovko wrote: > > # HG changeset patch > > # User Sergey Polovko > > # Date 1430232559 -10800 > > # Tue Apr 28 17:49:19 2015 +0300 > > # Node ID e98e249441adc75c525556ca32e9f3e65e87f653 > > # Parent 96e22e4f1b03ff15a774c6ed34d74b897af32c55 > > check that last IPv4 octet has valid value > > > > diff -r 96e22e4f1b03 -r e98e249441ad src/core/ngx_inet.c > > --- a/src/core/ngx_inet.c Mon Apr 27 18:51:18 2015 +0300 > > +++ b/src/core/ngx_inet.c Tue Apr 28 17:49:19 2015 +0300 > > @@ -48,7 +48,7 @@ > > return INADDR_NONE; > > } > > > > - if (n == 3) { > > + if (n == 3 && octet <= 255) { > > addr = (addr << 8) + octet; > > return htonl(addr); > > } > > http://hg.nginx.org/nginx/rev/550212836c8f Sorry :) here's the correct link? http://hg.nginx.org/nginx/rev/bc47a7a8159c From mdounin at mdounin.ru Tue Apr 28 19:23:28 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 28 Apr 2015 22:23:28 +0300 Subject: [PATCH] Cache: provide naive feedback loop for uncacheable URLs In-Reply-To: <1e7878138228e3decb86.1430177927@piotrs-macbook-pro.local> References: <1e7878138228e3decb86.1430177927@piotrs-macbook-pro.local> Message-ID: <20150428192328.GO32429@mdounin.ru> Hello! On Mon, Apr 27, 2015 at 04:38:47PM -0700, Piotr Sikora wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1430177825 25200 > # Mon Apr 27 16:37:05 2015 -0700 > # Node ID 1e7878138228e3decb868f38eddc38937d55f403 > # Parent 96e22e4f1b03ff15a774c6ed34d74b897af32c55 > Cache: provide naive feedback loop for uncacheable URLs. > > The cache lock provides a mechanism that allows only one request > for the same URL to be sent upstream at the same time. All other > requests must wait until the lock is released and/or not needed. > > While this works as designed and protects upstream from requests > stampede in case the response is cacheable, it results in a huge > performance degradation for popular and uncacheable URLs, thanks > to the artificial delay added to the upstream requests. > > To make things even worse, the lock acquisition is retried every > 500ms and prone to lock starvation - there is no queue, so newly > accepted requests can jump ahead and acquire the lock before any > of the already pending requests have a chance to retry it, which > can lead to huge spikes in the response times and even timeouts. > > This feedback loop provides a mechanism that allows requests for > uncacheable URLs to immediately skip the cache lock. I'm not really sure this is a right change. In particular, because "uncacheable" is a property of a response, not URLs. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Tue Apr 28 19:32:34 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 28 Apr 2015 22:32:34 +0300 Subject: Client disconnect in ngx_http_image_filter_module In-Reply-To: References: Message-ID: <20150428193234.GP32429@mdounin.ru> Hello! On Tue, Apr 28, 2015 at 04:56:54PM +0700, Dan Podeanu wrote: > > I have encountered a bug in ngx_http_image_filter_module when used in conjunction with ngx_http_proxy_module ; the configuration is as following: > > location /img/ { > proxy_pass http://mybucket.s3.amazonaws.com ; > image_filter resize 150 100; > } > > The steps to reproduce are rather complicated as they depend on how TCP fragments the response coming from the proxy: > > - If http://mybucket.s3.amazonaws.com returns, in the first TCP packet, a sizable amount of data (1-2k), the image is resized correctly. > > - If http://mybucket.s3.amazonaws.com returns, in the first TCP packet, a small amount of data (HTTP header, or HTTP header + a few bytes), the content is marked as not an image and NGX_HTTP_UNSUPPORTED_MEDIA_TYPE is returned (disconnecting the client), irrespective on whether or not subsequent data would complete the response to a valid image. > > Nginx appears to give up right away on waiting for data if the contents of the first TCP packet received from the proxy does not contain a valid image header- i.e. ngx_http_image_test() will return NGX_HTTP_IMAGE_SIZE, etc. > > In my experience this was triggered by a subtle change in AWS S3 that fragments the TCP header more. > > Versions affected: 1.6.2, 1.6.3, 1.7.2, 1.8.0, etc. > > > > Attaching a patch which fixes it for my use case (1.6.2) below; the other versions can be fixed similarly: > > ???????????????????????? > diff -ruN nginx-1.6.2.orig/src/http/modules/ngx_http_image_filter_module.c nginx-1.6.2/src/http/modules/ngx_http_image_filter_module.c > --- nginx-1.6.2.orig/src/http/modules/ngx_http_image_filter_module.c 2014-09-16 19:23:19.000000000 +0700 > +++ nginx-1.6.2/src/http/modules/ngx_http_image_filter_module.c 2015-04-28 16:25:47.000000000 +0700 > @@ -317,9 +317,8 @@ > } > } > > - return ngx_http_filter_finalize_request(r, > - &ngx_http_image_filter_module, > - NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); > + /* wait to consume more data, do not give up on the request right away */ > + return NGX_OK; > } > > /* override content type */ > ???????????????????????? > > > Thoughts ? Is this the right fix ? Should I also post on the nginx Trac ? Thanks, looks like a valid problem - and yes, please file a ticket on trac. The fix doesn't looks correct for me though - with such a change nginx will silently skip first bytes of a response. -- Maxim Dounin http://nginx.org/ From piotr at cloudflare.com Tue Apr 28 22:03:10 2015 From: piotr at cloudflare.com (Piotr Sikora) Date: Tue, 28 Apr 2015 15:03:10 -0700 Subject: [PATCH] Cache: provide naive feedback loop for uncacheable URLs In-Reply-To: <20150428192328.GO32429@mdounin.ru> References: <1e7878138228e3decb86.1430177927@piotrs-macbook-pro.local> <20150428192328.GO32429@mdounin.ru> Message-ID: Hey Maxim, > I'm not really sure this is a right change. It is, without this change proxy_cache_lock basically serializes access to the upstream. > In particular, because "uncacheable" is a property of a response, not URLs. That's nitpicking, but you're right, I should have used "cache key", not "URL", but that only applies to the commit message and not the code. Regarding the code, the "uncacheable" flag is only set for a particular cache key after nginx receives uncacheable response for it and it's only used to skip the cache lock on subsequent requests for the same cache key, not to determine cacheability of the response. Nothing changes when proxy_cache_lock isn't configured, nothing changes for a cache key that didn't receive any response yet and nothing changes for a cache key that received cacheable response. What exactly isn't right? Best regards, Piotr Sikora From pdan at esync.org Wed Apr 29 05:30:35 2015 From: pdan at esync.org (Dan Podeanu) Date: Wed, 29 Apr 2015 12:30:35 +0700 Subject: Client disconnect in ngx_http_image_filter_module In-Reply-To: <20150428193234.GP32429@mdounin.ru> References: <20150428193234.GP32429@mdounin.ru> Message-ID: Thank you for the feedback- http://trac.nginx.org/nginx/ticket/756 Regarding the fix, I do not believe bytes are silently skipped- if you look further below in src/http/modules/ngx_http_image_filter_module.c: switch (ctx->phase) { case NGX_HTTP_IMAGE_START: ctx->type = ngx_http_image_test(r, in); ?. if (ctx->type == NGX_HTTP_IMAGE_NONE) { ?. /* wait to consume more data, do not give up on the request right away */ return NGX_OK; /* as in the patch */ } ?. /* fall-through */ case NGX_HTTP_IMAGE_READ: ? /* fall-through */ case NGX_HTTP_IMAGE_PROCESS: ? } i.e. that section of code is, correctly, designed to maintain state and be called repeatedly for the same image. In any case, we are no longer able to replicate the bug once we have applied the patch. I think a better fix would be to "return NGX_OK" if we do not have enough data in ?case NGX_HTTP_IMAGE_START", and "return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE" (as per the original code) if enough data has been read, but it?s really not an image- but this exceeds the scope of the fix and my use case. Thoughts ? Thank you, Dan > On Apr 29, 2015, at 2:32 AM, Maxim Dounin wrote: > > Hello! > > On Tue, Apr 28, 2015 at 04:56:54PM +0700, Dan Podeanu wrote: > >> >> I have encountered a bug in ngx_http_image_filter_module when used in conjunction with ngx_http_proxy_module ; the configuration is as following: >> >> location /img/ { >> proxy_pass http://mybucket.s3.amazonaws.com ; >> image_filter resize 150 100; >> } >> >> The steps to reproduce are rather complicated as they depend on how TCP fragments the response coming from the proxy: >> >> - If http://mybucket.s3.amazonaws.com returns, in the first TCP packet, a sizable amount of data (1-2k), the image is resized correctly. >> >> - If http://mybucket.s3.amazonaws.com returns, in the first TCP packet, a small amount of data (HTTP header, or HTTP header + a few bytes), the content is marked as not an image and NGX_HTTP_UNSUPPORTED_MEDIA_TYPE is returned (disconnecting the client), irrespective on whether or not subsequent data would complete the response to a valid image. >> >> Nginx appears to give up right away on waiting for data if the contents of the first TCP packet received from the proxy does not contain a valid image header- i.e. ngx_http_image_test() will return NGX_HTTP_IMAGE_SIZE, etc. >> >> In my experience this was triggered by a subtle change in AWS S3 that fragments the TCP header more. >> >> Versions affected: 1.6.2, 1.6.3, 1.7.2, 1.8.0, etc. >> >> >> >> Attaching a patch which fixes it for my use case (1.6.2) below; the other versions can be fixed similarly: >> >> ???????????????????????? >> diff -ruN nginx-1.6.2.orig/src/http/modules/ngx_http_image_filter_module.c nginx-1.6.2/src/http/modules/ngx_http_image_filter_module.c >> --- nginx-1.6.2.orig/src/http/modules/ngx_http_image_filter_module.c 2014-09-16 19:23:19.000000000 +0700 >> +++ nginx-1.6.2/src/http/modules/ngx_http_image_filter_module.c 2015-04-28 16:25:47.000000000 +0700 >> @@ -317,9 +317,8 @@ >> } >> } >> >> - return ngx_http_filter_finalize_request(r, >> - &ngx_http_image_filter_module, >> - NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); >> + /* wait to consume more data, do not give up on the request right away */ >> + return NGX_OK; >> } >> >> /* override content type */ >> ???????????????????????? >> >> >> Thoughts ? Is this the right fix ? Should I also post on the nginx Trac ? > > Thanks, looks like a valid problem - and yes, please file a ticket > on trac. The fix doesn't looks correct for me though - with such > a change nginx will silently skip first bytes of a response. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From yuva at codemancers.com Wed Apr 29 06:05:11 2015 From: yuva at codemancers.com (Yuva) Date: Wed, 29 Apr 2015 11:35:11 +0530 Subject: [Re-posting] http/2 support In-Reply-To: <1860164.nPqXeOqyJn@vbart-workstation> References: <8437251.cVXCZURXdE@vbart-laptop> <1860164.nPqXeOqyJn@vbart-workstation> Message-ID: hi, On Mon, Apr 27, 2015 at 6:47 PM, Valentin V. Bartenev wrote: > On Saturday 25 April 2015 15:08:24 Yuva wrote: > > hi, > > I would like to contribute by coding. For a start, this is what im > > thinking: > > - get familiar with nginx spdy source code (since spdy is close to > http/2) > > Well, this may take all your time and effort, especially if you're not > familiar > with nginx internals. > > > > - understand source code written to support http/2, if any. > > - start with implementing small features, and fixing bugs. > > There's a couple of open tickets about SPDY: http://trac.nginx.org > You can start by trying to fix them. > actually there are no outstanding tickets abouty SPDY, or atleast i couldn't find them. thanks for letting me know that understanding nginx internals is time consuming. > wbr, Valentin V. Bartenev > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Yuva (@iffyuva) Co-founder at Codemancers Tech Pvt Ltd http://codemancers.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From serg.brester at sebres.de Wed Apr 29 07:18:11 2015 From: serg.brester at sebres.de (Sergey Brester) Date: Wed, 29 Apr 2015 09:18:11 +0200 Subject: nginx http-core enhancement: named location in subrequests + directive use_location Message-ID: <5196ab90dc32b09880371ff3d29c2826@sebres.de> Hi, enclosed you will find an attached changeset, that: - allows to fast use of named location in sub requests, such as auth_request, etc. Currently no named location was possible in any sub requests, real (or internal) locations only. # now you can use named location in sub requests: # auth_request /auth_loc/; auth_request @auth_loc; - in addition, a second mini-commit (37d7786e7015) with new directive "use_location" as alias or replacement for "try_files" with no file argument and without checking the existence of file(s): # try_files "" @loc use_location @loc It was allready more times discussed (goto location, etc.). PS. If someone needs a git version of it: https://github.com/sebres/nginx/commits/hg-sb-mod [1] Regards, sebres. Links: ------ [1] https://github.com/sebres/nginx/commits/hg-sb-mod -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: http-core-enhancement.patch Type: text/x-diff Size: 6327 bytes Desc: not available URL: From serg.brester at sebres.de Wed Apr 29 10:00:01 2015 From: serg.brester at sebres.de (Sergey Brester) Date: Wed, 29 Apr 2015 12:00:01 +0200 Subject: Allow more than one challenge - multiple authenticate response-header [rfc2616 sec14.47] Message-ID: <0656f1d059c504298adcf0f46b72b55a@sebres.de> Hi, enclosed you will find an attached changeset, that allows more than one authentication challenge - multiple authenticate response-header [rfc2616 sec14.47]. Implemented for auth_request and http upstream (ex. backends). If you want to support it in your own authentication module, just call `ngx_http_upstream_transmit_headers` after setting `headers_out.www_authenticate` of request, like in both implemented modules (see changeset attached). For upstreams simply add a multiple header entries with www-authentificate challenges, supported from your module. PS. If someone needs a git version of it: https://github.com/sebres/nginx/commits/hg-sb-mod [1] Regards, sebres. Links: ------ [1] https://github.com/sebres/nginx/commits/hg-sb-mod -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: auth-multiple-challenges.patch Type: text/x-diff Size: 4542 bytes Desc: not available URL: From vbart at nginx.com Wed Apr 29 10:01:24 2015 From: vbart at nginx.com (Valentin V. Bartenev) Date: Wed, 29 Apr 2015 13:01:24 +0300 Subject: [Re-posting] http/2 support In-Reply-To: References: <1860164.nPqXeOqyJn@vbart-workstation> Message-ID: <2166664.oF3KKYR7vU@vbart-workstation> On Wednesday 29 April 2015 11:35:11 Yuva wrote: [..] > > > - understand source code written to support http/2, if any. > > > - start with implementing small features, and fixing bugs. > > > > There's a couple of open tickets about SPDY: http://trac.nginx.org > > You can start by trying to fix them. > > > > actually there are no outstanding tickets abouty SPDY, or atleast i > couldn't find them. http://trac.nginx.org/nginx/ticket/714 http://trac.nginx.org/nginx/ticket/626 wbr, Valentin V. Bartenev From ru at nginx.com Wed Apr 29 12:28:05 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 29 Apr 2015 12:28:05 +0000 Subject: [nginx] Removed the deprecated "connections" directive. Message-ID: details: http://hg.nginx.org/nginx/rev/b19350b896bb branches: changeset: 6139:b19350b896bb user: Ruslan Ermilov date: Wed Apr 29 13:52:37 2015 +0300 description: Removed the deprecated "connections" directive. diffstat: src/event/ngx_event.c | 13 ------------- 1 files changed, 0 insertions(+), 13 deletions(-) diffs (30 lines): diff -r bc47a7a8159c -r b19350b896bb src/event/ngx_event.c --- a/src/event/ngx_event.c Tue Apr 28 18:55:03 2015 +0300 +++ b/src/event/ngx_event.c Wed Apr 29 13:52:37 2015 +0300 @@ -126,13 +126,6 @@ static ngx_command_t ngx_event_core_com 0, NULL }, - { ngx_string("connections"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_event_connections, - 0, - 0, - NULL }, - { ngx_string("use"), NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_event_use, @@ -956,12 +949,6 @@ ngx_event_connections(ngx_conf_t *cf, ng return "is duplicate"; } - if (ngx_strcmp(cmd->name.data, "connections") == 0) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "the \"connections\" directive is deprecated, " - "use the \"worker_connections\" directive instead"); - } - value = cf->args->elts; ecf->connections = ngx_atoi(value[1].data, value[1].len); if (ecf->connections == (ngx_uint_t) NGX_ERROR) { From ru at nginx.com Wed Apr 29 12:28:08 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 29 Apr 2015 12:28:08 +0000 Subject: [nginx] Removed deprecated HTTP directives. Message-ID: details: http://hg.nginx.org/nginx/rev/2911b7e5491b branches: changeset: 6140:2911b7e5491b user: Ruslan Ermilov date: Wed Apr 29 13:52:49 2015 +0300 description: Removed deprecated HTTP directives. diffstat: src/http/ngx_http_core_module.c | 33 --------------------------------- 1 files changed, 0 insertions(+), 33 deletions(-) diffs (64 lines): diff -r b19350b896bb -r 2911b7e5491b src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Wed Apr 29 13:52:37 2015 +0300 +++ b/src/http/ngx_http_core_module.c Wed Apr 29 13:52:49 2015 +0300 @@ -96,18 +96,6 @@ static ngx_conf_post_t ngx_http_core_lo static ngx_conf_post_handler_pt ngx_http_core_pool_size_p = ngx_http_core_pool_size; -static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_server_names = { - ngx_conf_deprecated, "optimize_server_names", "server_name_in_redirect" -}; - -static ngx_conf_deprecated_t ngx_conf_deprecated_open_file_cache_retest = { - ngx_conf_deprecated, "open_file_cache_retest", "open_file_cache_valid" -}; - -static ngx_conf_deprecated_t ngx_conf_deprecated_satisfy_any = { - ngx_conf_deprecated, "satisfy_any", "satisfy" -}; - static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = { { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF }, @@ -255,13 +243,6 @@ static ngx_command_t ngx_http_core_comm offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers), NULL }, - { ngx_string("optimize_server_names"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect), - &ngx_conf_deprecated_optimize_server_names }, - { ngx_string("ignore_invalid_headers"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -519,13 +500,6 @@ static ngx_command_t ngx_http_core_comm offsetof(ngx_http_core_loc_conf_t, satisfy), &ngx_http_core_satisfy }, - { ngx_string("satisfy_any"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, satisfy), - &ngx_conf_deprecated_satisfy_any }, - { ngx_string("internal"), NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, ngx_http_core_internal, @@ -689,13 +663,6 @@ static ngx_command_t ngx_http_core_comm offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid), NULL }, - { ngx_string("open_file_cache_retest"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_sec_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid), - &ngx_conf_deprecated_open_file_cache_retest }, - { ngx_string("open_file_cache_min_uses"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, From ru at nginx.com Wed Apr 29 12:28:10 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 29 Apr 2015 12:28:10 +0000 Subject: [nginx] Removed the deprecated "so_keepalive" directive. Message-ID: details: http://hg.nginx.org/nginx/rev/bf1655ae9a1c branches: changeset: 6141:bf1655ae9a1c user: Ruslan Ermilov date: Wed Apr 29 13:53:08 2015 +0300 description: Removed the deprecated "so_keepalive" directive. diffstat: src/mail/ngx_mail.h | 2 -- src/mail/ngx_mail_core_module.c | 16 ---------------- src/mail/ngx_mail_proxy_module.c | 13 ------------- 3 files changed, 0 insertions(+), 31 deletions(-) diffs (89 lines): diff -r 2911b7e5491b -r bf1655ae9a1c src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h Wed Apr 29 13:52:49 2015 +0300 +++ b/src/mail/ngx_mail.h Wed Apr 29 13:53:08 2015 +0300 @@ -131,8 +131,6 @@ typedef struct { ngx_msec_t timeout; ngx_msec_t resolver_timeout; - ngx_flag_t so_keepalive; - ngx_str_t server_name; u_char *file_name; diff -r 2911b7e5491b -r bf1655ae9a1c src/mail/ngx_mail_core_module.c --- a/src/mail/ngx_mail_core_module.c Wed Apr 29 13:52:49 2015 +0300 +++ b/src/mail/ngx_mail_core_module.c Wed Apr 29 13:53:08 2015 +0300 @@ -27,12 +27,6 @@ static char *ngx_mail_core_resolver(ngx_ void *conf); -static ngx_conf_deprecated_t ngx_conf_deprecated_so_keepalive = { - ngx_conf_deprecated, "so_keepalive", - "so_keepalive\" parameter of the \"listen" -}; - - static ngx_command_t ngx_mail_core_commands[] = { { ngx_string("server"), @@ -56,13 +50,6 @@ static ngx_command_t ngx_mail_core_comm 0, NULL }, - { ngx_string("so_keepalive"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, so_keepalive), - &ngx_conf_deprecated_so_keepalive }, - { ngx_string("timeout"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, @@ -175,7 +162,6 @@ ngx_mail_core_create_srv_conf(ngx_conf_t cscf->timeout = NGX_CONF_UNSET_MSEC; cscf->resolver_timeout = NGX_CONF_UNSET_MSEC; - cscf->so_keepalive = NGX_CONF_UNSET; cscf->resolver = NGX_CONF_UNSET_PTR; @@ -196,8 +182,6 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t ngx_conf_merge_msec_value(conf->resolver_timeout, prev->resolver_timeout, 30000); - ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0); - ngx_conf_merge_str_value(conf->server_name, prev->server_name, ""); diff -r 2911b7e5491b -r bf1655ae9a1c src/mail/ngx_mail_proxy_module.c --- a/src/mail/ngx_mail_proxy_module.c Wed Apr 29 13:52:49 2015 +0300 +++ b/src/mail/ngx_mail_proxy_module.c Wed Apr 29 13:53:08 2015 +0300 @@ -111,7 +111,6 @@ static u_char smtp_auth_ok[] = "235 2.0 void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer) { - int keepalive; ngx_int_t rc; ngx_mail_proxy_ctx_t *p; ngx_mail_proxy_conf_t *pcf; @@ -121,18 +120,6 @@ ngx_mail_proxy_init(ngx_mail_session_t * cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); - if (cscf->so_keepalive) { - keepalive = 1; - - if (setsockopt(s->connection->fd, SOL_SOCKET, SO_KEEPALIVE, - (const void *) &keepalive, sizeof(int)) - == -1) - { - ngx_log_error(NGX_LOG_ALERT, s->connection->log, ngx_socket_errno, - "setsockopt(SO_KEEPALIVE) failed"); - } - } - p = ngx_pcalloc(s->connection->pool, sizeof(ngx_mail_proxy_ctx_t)); if (p == NULL) { ngx_mail_session_internal_server_error(s); From ru at nginx.com Wed Apr 29 12:28:23 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 29 Apr 2015 12:28:23 +0000 Subject: [nginx] Removed the deprecated "imap" directive. Message-ID: details: http://hg.nginx.org/nginx/rev/53bccdc4923a branches: changeset: 6142:53bccdc4923a user: Ruslan Ermilov date: Wed Apr 29 13:53:24 2015 +0300 description: Removed the deprecated "imap" directive. diffstat: src/mail/ngx_mail.c | 13 ------------- 1 files changed, 0 insertions(+), 13 deletions(-) diffs (30 lines): diff -r bf1655ae9a1c -r 53bccdc4923a src/mail/ngx_mail.c --- a/src/mail/ngx_mail.c Wed Apr 29 13:53:08 2015 +0300 +++ b/src/mail/ngx_mail.c Wed Apr 29 13:53:24 2015 +0300 @@ -36,13 +36,6 @@ static ngx_command_t ngx_mail_commands[ 0, NULL }, - { ngx_string("imap"), - NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_mail_block, - 0, - 0, - NULL }, - ngx_null_command }; @@ -83,12 +76,6 @@ ngx_mail_block(ngx_conf_t *cf, ngx_comma ngx_mail_core_srv_conf_t **cscfp; ngx_mail_core_main_conf_t *cmcf; - if (cmd->name.data[0] == 'i') { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "the \"imap\" directive is deprecated, " - "use the \"mail\" directive instead"); - } - /* the main mail context */ ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t)); From ru at nginx.com Wed Apr 29 12:28:25 2015 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 29 Apr 2015 12:28:25 +0000 Subject: [nginx] Configure: handle deprecated options. Message-ID: details: http://hg.nginx.org/nginx/rev/162b2d27d4e1 branches: changeset: 6143:162b2d27d4e1 user: Ruslan Ermilov date: Wed Apr 29 14:59:02 2015 +0300 description: Configure: handle deprecated options. Removed the deprecated --without-http_limit_zone_module option. Deprecated the --with-imap and --with-imap_ssl_module options. diffstat: auto/options | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) diffs (37 lines): diff -r 53bccdc4923a -r 162b2d27d4e1 auto/options --- a/auto/options Wed Apr 29 13:53:24 2015 +0300 +++ b/auto/options Wed Apr 29 14:59:02 2015 +0300 @@ -243,12 +243,6 @@ do --without-http_uwsgi_module) HTTP_UWSGI=NO ;; --without-http_scgi_module) HTTP_SCGI=NO ;; --without-http_memcached_module) HTTP_MEMCACHED=NO ;; - --without-http_limit_zone_module) - HTTP_LIMIT_CONN=NO - NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG -$0: warning: the \"--without-http_limit_zone_module\" option is deprecated, \ -use the \"--without-http_limit_conn_module\" option instead" - ;; --without-http_limit_conn_module) HTTP_LIMIT_CONN=NO ;; --without-http_limit_req_module) HTTP_LIMIT_REQ=NO ;; --without-http_empty_gif_module) HTTP_EMPTY_GIF=NO ;; @@ -270,8 +264,18 @@ use the \"--without-http_limit_conn_modu --with-mail) MAIL=YES ;; --with-mail_ssl_module) MAIL_SSL=YES ;; # STUB - --with-imap) MAIL=YES ;; - --with-imap_ssl_module) MAIL_SSL=YES ;; + --with-imap) + MAIL=YES + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-imap\" option is deprecated, \ +use the \"--with-mail\" option instead" + ;; + --with-imap_ssl_module) + MAIL_SSL=YES + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-imap_ssl_module\" option is deprecated, \ +use the \"--with-mail_ssl_module\" option instead" + ;; --without-mail_pop3_module) MAIL_POP3=NO ;; --without-mail_imap_module) MAIL_IMAP=NO ;; --without-mail_smtp_module) MAIL_SMTP=NO ;; From mdounin at mdounin.ru Wed Apr 29 12:30:02 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 29 Apr 2015 15:30:02 +0300 Subject: Client disconnect in ngx_http_image_filter_module In-Reply-To: References: <20150428193234.GP32429@mdounin.ru> Message-ID: <20150429123001.GX32429@mdounin.ru> Hello! On Wed, Apr 29, 2015 at 12:30:35PM +0700, Dan Podeanu wrote: > Thank you for the feedback- > http://trac.nginx.org/nginx/ticket/756 > Thanks. > Regarding the fix, I do not believe bytes are silently skipped- > if you look further below in > src/http/modules/ngx_http_image_filter_module.c: > > switch (ctx->phase) { > case NGX_HTTP_IMAGE_START: > ctx->type = ngx_http_image_test(r, in); > ?. > if (ctx->type == NGX_HTTP_IMAGE_NONE) { > ?. > /* wait to consume more data, do not give > up on the request right away */ > return NGX_OK; /* as in the patch */ > } > ?. > /* fall-through */ > case NGX_HTTP_IMAGE_READ: > ? > /* fall-through */ > case NGX_HTTP_IMAGE_PROCESS: > ? > } > > i.e. that section of code is, correctly, designed to maintain > state and be called repeatedly for the same image. In any case, > we are no longer able to replicate the bug once we have applied > the patch. The problem is that you return NGX_OK, and all the code designed to store the response bits from the "in" chain will be skipped. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Apr 29 12:56:20 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 29 Apr 2015 15:56:20 +0300 Subject: [PATCH] Cache: provide naive feedback loop for uncacheable URLs In-Reply-To: References: <1e7878138228e3decb86.1430177927@piotrs-macbook-pro.local> <20150428192328.GO32429@mdounin.ru> Message-ID: <20150429125620.GY32429@mdounin.ru> Hello! On Tue, Apr 28, 2015 at 03:03:10PM -0700, Piotr Sikora wrote: > Hey Maxim, > > > I'm not really sure this is a right change. > > It is, without this change proxy_cache_lock basically serializes > access to the upstream. It is designed to do so, and does exactly what it's expected to do. I'm perfectly understand what you are trying to do an why. That is, you are trying to teach proxy_cache_lock to be smart and to switch itself off automatically once it sees an uncacheable response - because it's not practical to configure proxy_cache_lock on a per-resource basis when proxying arbitrary client sites. But as I said, I'm not sure it's a right change. May be it is, or may be it should be an optional behaviour, or may be we need some other way to address this problem. > > In particular, because "uncacheable" is a property of a response, not URLs. > > That's nitpicking, but you're right, I should have used "cache key", > not "URL", but that only applies to the commit message and not the > code. > > Regarding the code, the "uncacheable" flag is only set for a > particular cache key after nginx receives uncacheable response for it > and it's only used to skip the cache lock on subsequent requests for > the same cache key, not to determine cacheability of the response. You can't set "uncacheable" flag for a cache key, as you never know if a particular response will be cacheable or not. E.g., for some client a backend may return an uncacheable response because this client is somewhat special - e.g., have some debug cookie set or uses some form of conditional requests. And another client will get a cacheable response for the same key. So an obvious edge case with your code is: - a special client gets an uncacheable response (e.g., something like "we don't like you, here is a captcha"), the "unceacheable" flag is set; - N (or, rather, M, as N isn't big enough) normal clients are passed to an upstream server, and all load cacheable responses. Of course this is an edge case, but it is to be considered. -- Maxim Dounin http://nginx.org/ From pdan at esync.org Wed Apr 29 13:03:46 2015 From: pdan at esync.org (Dan Podeanu) Date: Wed, 29 Apr 2015 20:03:46 +0700 Subject: Client disconnect in ngx_http_image_filter_module In-Reply-To: <20150429123001.GX32429@mdounin.ru> References: <20150428193234.GP32429@mdounin.ru> <20150429123001.GX32429@mdounin.ru> Message-ID: <1B4CAE70-59E3-40F9-9E12-A7E783087E1B@esync.org> Ok fair enough- I am new to the nginx source code. What would be a better fix ? > On Apr 29, 2015, at 7:30 PM, Maxim Dounin wrote: > > Hello! > > On Wed, Apr 29, 2015 at 12:30:35PM +0700, Dan Podeanu wrote: > >> Thank you for the feedback- >> http://trac.nginx.org/nginx/ticket/756 >> > > Thanks. > >> Regarding the fix, I do not believe bytes are silently skipped- >> if you look further below in >> src/http/modules/ngx_http_image_filter_module.c: >> >> switch (ctx->phase) { >> case NGX_HTTP_IMAGE_START: >> ctx->type = ngx_http_image_test(r, in); >> ?. >> if (ctx->type == NGX_HTTP_IMAGE_NONE) { >> ?. >> /* wait to consume more data, do not give >> up on the request right away */ >> return NGX_OK; /* as in the patch */ >> } >> ?. >> /* fall-through */ >> case NGX_HTTP_IMAGE_READ: >> ? >> /* fall-through */ >> case NGX_HTTP_IMAGE_PROCESS: >> ? >> } >> >> i.e. that section of code is, correctly, designed to maintain >> state and be called repeatedly for the same image. In any case, >> we are no longer able to replicate the bug once we have applied >> the patch. > > The problem is that you return NGX_OK, and all the code designed to > store the response bits from the "in" chain will be skipped. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From mdounin at mdounin.ru Wed Apr 29 13:48:28 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 29 Apr 2015 16:48:28 +0300 Subject: nginx http-core enhancement: named location in subrequests + directive use_location In-Reply-To: <5196ab90dc32b09880371ff3d29c2826@sebres.de> References: <5196ab90dc32b09880371ff3d29c2826@sebres.de> Message-ID: <20150429134828.GZ32429@mdounin.ru> Hello! On Wed, Apr 29, 2015 at 09:18:11AM +0200, Sergey Brester wrote: > > > Hi, > > enclosed you will find an attached changeset, that: > > - allows to fast use of named location in sub requests, such as > auth_request, etc. Currently no named location was possible in any sub > requests, real (or internal) locations only. > > # now you can use named location in sub requests: > # auth_request /auth_loc/; > auth_request @auth_loc; > > - in addition, a second mini-commit (37d7786e7015) with new directive > "use_location" as alias or replacement for "try_files" with no file > argument and without checking the existence of file(s): > > # try_files "" @loc > use_location @loc > > It was allready more times discussed (goto location, etc.). > > PS. If someone needs a git version of it: > https://github.com/sebres/nginx/commits/hg-sb-mod [1] > > Regards, > > sebres. > > Links: > ------ > [1] https://github.com/sebres/nginx/commits/hg-sb-mod > # HG changeset patch > # User Serg G. Brester (sebres) > # Date 1430227790 -7200 > # Tue Apr 28 15:29:50 2015 +0200 > # Node ID 37d7786e7015f8a784e6a4dc3f88f8a7573a4c08 > # Parent 96e22e4f1b03ff15a774c6ed34d74b897af32c55 > http-core: new directive "use_location" as replacement or alias for "try_files" with no file > argument and without checking the existence of file(s): > > `use_location @loc` replaces `try_files "" @loc` Something like this was previously discussed more than once, and the short answer is "no". > # HG changeset patch > # User Serg G. Brester (sebres) > # Date 1430228073 -7200 > # Tue Apr 28 15:34:33 2015 +0200 > # Node ID 43135346275c76add5bf953024a3d244f04184ba > # Parent 37d7786e7015f8a784e6a4dc3f88f8a7573a4c08 > http-core: allow to fast use of named location in (internal) sub requests, ex.: auth_request, etc.; > > diff -r 37d7786e7015 -r 43135346275c src/http/ngx_http_core_module.c > --- a/src/http/ngx_http_core_module.c Tue Apr 28 15:29:50 2015 +0200 > +++ b/src/http/ngx_http_core_module.c Tue Apr 28 15:34:33 2015 +0200 > @@ -22,6 +22,7 @@ typedef struct { > > > static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r); > +static ngx_int_t ngx_http_core_find_named_location(ngx_http_request_t *r, ngx_str_t *name); > static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r, > ngx_http_location_tree_node_t *node); > > @@ -1542,6 +1543,16 @@ ngx_http_core_find_location(ngx_http_req > noregex = 0; > #endif > > + /* already internal - check is resp. can be named location - search it */ > + > + if (r->internal && r->uri.len >= 1 && r->uri.data[0] == '@') { > + > + if (ngx_http_core_find_named_location(r, &r->uri) == NGX_OK) { > + > + return NGX_OK; > + } > + } > + And how it's expected to be processed in a named location if r->uri is "@..."? Note that named locations are ones where requests are handled with their original URIs unmodified. This, in particular, allows to use the original URI to select a file, or in a request to the upstream server, etc. With what you are trying to do it doesn't look different from a static location. -- Maxim Dounin http://nginx.org/ From billappleton at dreamfactory.com Wed Apr 29 16:30:23 2015 From: billappleton at dreamfactory.com (Bill Appleton) Date: Wed, 29 Apr 2015 09:30:23 -0700 Subject: Trying to understand benchmarking results Message-ID: Hi All, I ran some benchmarks on our DreamFactory product running on NGINX using Apache Benchmark DreamFactory is a REST API platform, but from a server point of view it should look more or less like a simple WordPress website see the graphical results here: www*.dreamfactory.com/publications/comparison.png * the red lines show the average and maximum response time for 500 requests at different levels of concurrency running on a "medium" aws server with 1 CPU the blue lines show the average and maximum response time for 500 requests at different levels of concurrency running on a "large" aws server with 2 CPUs Does anyone know why at about 100 concurrent requests we start to see some requests taking much longer to finish? Is this too much work for the processor? The database is overloaded? There is some server setting that limits concurrency? I have also included one of the benchmark reports below, as you can see most of the requests are handled promptly but about 5% are deferred and take a much longer time.... Any help would be appreciated! Thanks, Bill Appleton www.dreamfactory.com Server Software: nginx Server Hostname: next.cloud.dreamfactory.com Server Port: 80 Document Length: 126 bytes Concurrency Level: 200 Time taken for tests: 16.147 seconds Complete requests: 500 Failed requests: 0 Non-2xx responses: 500 Total transferred: 298000 bytes HTML transferred: 63000 bytes Requests per second: 30.97 [#/sec] (mean) Time per request: 6458.755 [ms] (mean) Time per request: 32.294 [ms] (mean, across all concurrent requests) Transfer rate: 18.02 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 85 209 208.7 91 725 Processing: 146 3605 2629.2 3096 15633 Waiting: 145 3604 2629.2 3095 15633 Total: 243 3814 2725.4 3189 16143 Percentage of the requests served within a certain time (ms) 50% 3189 66% 3264 75% 3831 80% 4175 90% 6766 95% 10568 98% 11114 99% 16069 100% 16143 (longest request) -------------- next part -------------- An HTML attachment was scrubbed... URL: From serg.brester at sebres.de Wed Apr 29 17:08:39 2015 From: serg.brester at sebres.de (Sergey Brester) Date: Wed, 29 Apr 2015 19:08:39 +0200 Subject: Trying to understand benchmarking results In-Reply-To: References: Message-ID: <6f2c54368ce199f601ecffdb61a60fab@sebres.de> Hi, Dynamic content? You can measure static also (exapmle URL to any image), to see difference to your another test. So if it is fast enough, your post does not apply to nginx (so check your backend / upstream and please contact manufacturer of it). In addition to database, hdd, cpu etc, it can be "ab" self: - "ab" does not support http 1.1 (so it can be for example not keep-alive - too many connections); - sometimes "ab" can not correctly measure non 200 requests (I don't remember what it was) - and all your requests are non 200 (not OK); Can you test it again with something else, for example wrk [5] or siege benchmark [6]? Regards, sebres. Am 29.04.2015 18:30, schrieb Bill Appleton: > Hi All, > > I ran some benchmarks on our DreamFactory product running on NGINX using Apache Benchmark > > DreamFactory is a REST API platform, but from a server point of view it should look more or less like a simple WordPress website > > see the graphical results here: www.DREAMFACTORY.COM/PUBLICATIONS/COMPARISON.PNG [2] the red lines show the average and maximum response time for 500 requests at different levels of concurrency running on a "medium" aws server with 1 CPU > > the blue lines show the average and maximum response time for 500 requests at different levels of concurrency running on a "large" aws server with 2 CPUs > > Does anyone know why at about 100 concurrent requests we start to see some requests taking much longer to finish? > > Is this too much work for the processor? The database is overloaded? There is some server setting that limits concurrency? > > I have also included one of the benchmark reports below, as you can see most of the requests are handled promptly but about 5% are deferred and take a much longer time.... > > Any help would be appreciated! > > Thanks, > > Bill Appleton > > www.dreamfactory.com [3] > > Server Software: nginx > Server Hostname: next.cloud.dreamfactory.com [4] > Server Port: 80 > Document Length: 126 bytes > > Concurrency Level: 200 > Time taken for tests: 16.147 seconds > Complete requests: 500 > Failed requests: 0 > Non-2xx responses: 500 > Total transferred: 298000 bytes > HTML transferred: 63000 bytes > Requests per second: 30.97 [#/sec] (mean) > Time per request: 6458.755 [ms] (mean) > Time per request: 32.294 [ms] (mean, across all concurrent requests) > Transfer rate: 18.02 [Kbytes/sec] received > > Connection Times (ms) > min mean[+/-sd] median max > Connect: 85 209 208.7 91 725 > Processing: 146 3605 2629.2 3096 15633 > Waiting: 145 3604 2629.2 3095 15633 > Total: 243 3814 2725.4 3189 16143 > > Percentage of the requests served within a certain time (ms) > 50% 3189 > 66% 3264 > 75% 3831 > 80% 4175 > 90% 6766 > 95% 10568 > 98% 11114 > 99% 16069 > 100% 16143 (longest request) > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel [1] Links: ------ [1] http://mailman.nginx.org/mailman/listinfo/nginx-devel [2] http://dreamfactory.com/publications/comparison.png [3] http://dreamfactory.com [4] http://next.cloud.dreamfactory.com [5] https://github.com/wg/wrk [6] https://www.joedog.org/siege-home/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From serg.brester at sebres.de Wed Apr 29 17:22:51 2015 From: serg.brester at sebres.de (Sergey Brester) Date: Wed, 29 Apr 2015 19:22:51 +0200 Subject: nginx http-core enhancement: named location in subrequests + directive use_location In-Reply-To: <20150429134828.GZ32429@mdounin.ru> References: <5196ab90dc32b09880371ff3d29c2826@sebres.de> <20150429134828.GZ32429@mdounin.ru> Message-ID: Am 29.04.2015 15:48, schrieb Maxim Dounin: > Hello! > > On Wed, Apr 29, 2015 at 09:18:11AM +0200, Sergey Brester wrote: > >> Hi, enclosed you will find an attached changeset, that: - allows to fast use of named location in sub requests, such as auth_request, etc. Currently no named location was possible in any sub requests, real (or internal) locations only. # now you can use named location in sub requests: # auth_request /auth_loc/; auth_request @auth_loc; - in addition, a second mini-commit (37d7786e7015) with new directive "use_location" as alias or replacement for "try_files" with no file argument and without checking the existence of file(s): # try_files "" @loc use_location @loc It was allready more times discussed (goto location, etc.). PS. If someone needs a git version of it: https://github.com/sebres/nginx/commits/hg-sb-mod [1] [1 [1]] Regards, sebres. Links: ------ [1] https://github.com/sebres/nginx/commits/hg-sb-mod [1] > >> # HG changeset patch # User Serg G. Brester (sebres) # Date 1430227790 -7200 # Tue Apr 28 15:29:50 2015 +0200 # Node ID 37d7786e7015f8a784e6a4dc3f88f8a7573a4c08 # Parent 96e22e4f1b03ff15a774c6ed34d74b897af32c55 http-core: new directive "use_location" as replacement or alias for "try_files" with no file argument and without checking the existence of file(s): `use_location @loc` replaces `try_files "" @loc` > > Something like this was previously discussed more than once, and > the short answer is "no". > >> # HG changeset patch # User Serg G. Brester (sebres) # Date 1430228073 -7200 # Tue Apr 28 15:34:33 2015 +0200 # Node ID 43135346275c76add5bf953024a3d244f04184ba # Parent 37d7786e7015f8a784e6a4dc3f88f8a7573a4c08 http-core: allow to fast use of named location in (internal) sub requests, ex.: auth_request, etc.; diff -r 37d7786e7015 -r 43135346275c src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Tue Apr 28 15:29:50 2015 +0200 +++ b/src/http/ngx_http_core_module.c Tue Apr 28 15:34:33 2015 +0200 @@ -22,6 +22,7 @@ typedef struct { static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r); +static ngx_int_t ngx_http_core_find_named_location(ngx_http_request_t *r, ngx_str_t *name); static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r, ngx_http_location_tree_node_t *node); @@ -1542,6 +1543,16 @@ ngx_http_core_find_location(ngx_http_req noregex = 0; #endif + /* already internal - check is resp. can be named location - search it */ + + if (r->internal && r->uri.len >= 1 && r->uri.data[0] == '@') { + + if (ngx_http_core_find_named_location(r, &r->uri) == NGX_OK) { + + return NGX_OK; + } + } + > > And how it's expected to be processed in a named location if > r->uri is "@..."? Function "ngx_http_core_find_named_location" if location was found set "r->loc_conf = (*clcfp)->loc_conf" and returns NGX_OK. > Note that named locations are ones where requests are handled with their original URIs unmodified. This, in particular, allows to use the original URI to select a file, or in a request to the upstream server, etc. With what you are trying to do it doesn't look different from a static location As I wrote it already (of course it is not a static location): Example, instead of : # auth_request /auth_loc/; You can use named location @auth_loc and write now: auth_request @auth_loc; Regards, sebres. Links: ------ [1] https://github.com/sebres/nginx/commits/hg-sb-mod -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at tomthorogood.co.uk Thu Apr 30 11:39:09 2015 From: me at tomthorogood.co.uk (Tom Thorogood) Date: Thu, 30 Apr 2015 21:09:09 +0930 Subject: [PATCH] HTTP: gzip resources upstream has flagged as sdch encoded. Message-ID: <5542145D.30308@tomthorogood.co.uk> Hi, This is ultimately a pretty simply change. When an proxied resource has been sdch encoded, currently the gzip module refuses to run. This change causes gzip to run on sdch resources and ensures that gzip is appended to the Content-Encoding header, keeping the sdch flag. For a working sdch server implementation, see . Regards, Tom Thorogood. -------------- next part -------------- A non-text attachment was scrubbed... Name: nginx-sdch-gzip.patch Type: text/x-patch Size: 2417 bytes Desc: not available URL: From mdounin at mdounin.ru Thu Apr 30 13:55:41 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 30 Apr 2015 16:55:41 +0300 Subject: nginx http-core enhancement: named location in subrequests + directive use_location In-Reply-To: References: <5196ab90dc32b09880371ff3d29c2826@sebres.de> <20150429134828.GZ32429@mdounin.ru> Message-ID: <20150430135541.GD32429@mdounin.ru> Hello! On Wed, Apr 29, 2015 at 07:22:51PM +0200, Sergey Brester wrote: [...] > > And how it's expected to be processed in a named location if > > r->uri is "@..."? > > Function "ngx_http_core_find_named_location" if location was found set > "r->loc_conf = (*clcfp)->loc_conf" and returns NGX_OK. The problem is that the r->uri will be illegal. > > Note that named locations are ones where requests are handled > > with their original URIs unmodified. This, in particular, > > allows to use the original URI to select a file, or in a > > request to the upstream server, etc. With what you are trying > > to do it doesn't look different from a static location > > As I wrote it already (of course it is not a static location): > > Example, instead of : > > # auth_request /auth_loc/; > > You can use named location @auth_loc and write now: > > auth_request @auth_loc; So what will happen if the location is: location @auth_loc { proxy_pass http://auth.backend; } Which URI will be used in a HTTP request to auth.backend? As far as I see, with your code it will result in a GET @auth_loc HTTP/1.0 request to the upstream server, and immediate 400 response is what will happen. -- Maxim Dounin http://nginx.org/ From serg.brester at sebres.de Thu Apr 30 17:13:01 2015 From: serg.brester at sebres.de (Sergey Brester) Date: Thu, 30 Apr 2015 19:13:01 +0200 Subject: nginx http-core enhancement: named location in subrequests + directive use_location In-Reply-To: <20150430135541.GD32429@mdounin.ru> References: <5196ab90dc32b09880371ff3d29c2826@sebres.de> <20150429134828.GZ32429@mdounin.ru> <20150430135541.GD32429@mdounin.ru> Message-ID: Am 30.04.2015 15:55, schrieb Maxim Dounin: > Hello! > > On Wed, Apr 29, 2015 at 07:22:51PM +0200, Sergey Brester wrote: > > [...] > And how it's expected to be processed in a named location if r->uri is "@..."? Function "ngx_http_core_find_named_location" if location was found set "r->loc_conf = (*clcfp)->loc_conf" and returns NGX_OK. The problem is that the r->uri will be illegal. I think not for internal request?! if (r->internal && r->uri... > Note that named locations are ones where requests are handled with their original URIs unmodified. This, in particular, allows to use the original URI to select a file, or in a request to the upstream server, etc. With what you are trying to do it doesn't look different from a static location As I wrote it already (of course it is not a static location): Example, instead of : # auth_request /auth_loc/; You can use named location @auth_loc and write now: auth_request @auth_loc; So what will happen if the location is: location @auth_loc { proxy_pass http://auth.backend [1]; } Which URI will be used in a HTTP request to auth.backend? As far as I see, with your code it will result in a GET @auth_loc HTTP/1.0 request to the upstream server, and immediate 400 response is what will happen. Yes, in this case the backend upstream should support such uri's or more likely in named location it should be overwritten... But for subrequests (example for auth_request) is anyway original "document_uri" resp. "script_name" more interesting... Anyway if proxy_pass should use real uri with "/" you can still use "normal" named convention for nonnamed internal location. Here is my config for example: location @cgisvc_auth1 { fastcgi_keep_conn on; include fastcgi_params; fastcgi_pass_request_body off; fastcgi_pass http_cgi_backend; } location @cgisvc_auth2 { proxy_pass http://localhost:8088/ [1]; } location /test1 { auth_request @cgisvc_auth1; } location /test2 { auth_request @cgisvc_auth2; } Links: ------ [1] http://auth.backend -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Thu Apr 30 18:56:55 2015 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 30 Apr 2015 21:56:55 +0300 Subject: nginx http-core enhancement: named location in subrequests + directive use_location In-Reply-To: References: <5196ab90dc32b09880371ff3d29c2826@sebres.de> <20150429134828.GZ32429@mdounin.ru> <20150430135541.GD32429@mdounin.ru> Message-ID: <20150430185655.GG32429@mdounin.ru> Hello! On Thu, Apr 30, 2015 at 07:13:01PM +0200, Sergey Brester wrote: > Am 30.04.2015 15:55, schrieb Maxim Dounin: > > > On Wed, Apr 29, 2015 at 07:22:51PM +0200, Sergey Brester > > wrote: > > > > > And how it's expected to be processed in a named location if > > > r->uri is "@..."? Function > > > "ngx_http_core_find_named_location" if location was found > > > set "r->loc_conf = (*clcfp)->loc_conf" and returns NGX_OK. > > > > The problem is that the r->uri will be illegal. > > I think not for internal request?! > > if (r->internal && r->uri... You think it's not a problem, or you think it won't be illegal? While it's not generally a problem for nginx if an URI in an internal request becomes illegal, it's certainly not a case we are going to promote by applying patches. If illegal URIs are ok for you, you may just use something like auth_request @foo; location = @foo { ... } And it will work right now out of the box. What you are trying to do is to misuse named locations as static locations with some invalid URIs. This is wrong, named locations are different. They preserve URI of a request untouched. That's their main property and main advantage. (BTW, please use plain text for further messages, I'm a bit bored to fix quoting in what your mail client produces as a plain text version. Thank you.) -- Maxim Dounin http://nginx.org/