Hello community,

here is the log from the commit of package nginx for openSUSE:Factory checked 
in at 2018-12-19 13:50:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nginx (Old)
 and      /work/SRC/openSUSE:Factory/.nginx.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nginx"

Wed Dec 19 13:50:53 2018 rev:32 rq:659039 version:1.15.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/nginx/nginx.changes      2018-11-12 
09:44:13.888936754 +0100
+++ /work/SRC/openSUSE:Factory/.nginx.new.28833/nginx.changes   2018-12-19 
13:51:07.399142812 +0100
@@ -1,0 +2,15 @@
+Fri Dec  7 14:53:14 UTC 2018 - ch...@computersalat.de
+
+- update to 1.15.7
+  * Feature: the "proxy_requests" directive in the stream module.
+  * Feature: the "delay" parameter of the "limit_req" directive.
+    Thanks to Vladislav Shabanov and Peter Shchuchkin.
+  * Bugfix: memory leak on errors during reconfiguration.
+  * Bugfix: in the $upstream_response_time, $upstream_connect_time, and
+    $upstream_header_time variables.
+  * Bugfix: a segmentation fault might occur in a worker process if the
+    ngx_http_mp4_module was used on 32-bit platforms.
+- fix changes file for submit to Backports
+  * see https://build.opensuse.org/request/show/653792
+
+-------------------------------------------------------------------
@@ -5 +20,2 @@
-  - Security: when using HTTP/2 a client might cause excessive memory
+  * fix for boo#1115022, boo#1115025
+    Security: when using HTTP/2 a client might cause excessive memory
@@ -7 +23,2 @@
-  - Security: processing of a specially crafted mp4 file with the
+  * fix for boo#1115015
+    Security: processing of a specially crafted mp4 file with the

Old:
----
  nginx-1.15.6.tar.gz
  nginx-1.15.6.tar.gz.asc

New:
----
  nginx-1.15.7.tar.gz
  nginx-1.15.7.tar.gz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nginx.spec ++++++
--- /var/tmp/diff_new_pack.8vUldx/_old  2018-12-19 13:51:08.079141870 +0100
+++ /var/tmp/diff_new_pack.8vUldx/_new  2018-12-19 13:51:08.083141865 +0100
@@ -70,7 +70,7 @@
 %define ngx_doc_dir    %{_datadir}/doc/packages/%{name}
 #
 Name:           nginx
-Version:        1.15.6
+Version:        1.15.7
 Release:        0
 %define ngx_fancyindex_version 0.4.2
 %define ngx_fancyindex_module_path ngx-fancyindex-%{ngx_fancyindex_version}

++++++ nginx-1.15.6.tar.gz -> nginx-1.15.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/CHANGES new/nginx-1.15.7/CHANGES
--- old/nginx-1.15.6/CHANGES    2018-11-06 14:32:17.000000000 +0100
+++ new/nginx-1.15.7/CHANGES    2018-11-27 15:40:40.000000000 +0100
@@ -1,4 +1,20 @@
 
+Changes with nginx 1.15.7                                        27 Nov 2018
+
+    *) Feature: the "proxy_requests" directive in the stream module.
+
+    *) Feature: the "delay" parameter of the "limit_req" directive.
+       Thanks to Vladislav Shabanov and Peter Shchuchkin.
+
+    *) Bugfix: memory leak on errors during reconfiguration.
+
+    *) Bugfix: in the $upstream_response_time, $upstream_connect_time, and
+       $upstream_header_time variables.
+
+    *) Bugfix: a segmentation fault might occur in a worker process if the
+       ngx_http_mp4_module was used on 32-bit platforms.
+
+
 Changes with nginx 1.15.6                                        06 Nov 2018
 
     *) Security: when using HTTP/2 a client might cause excessive memory
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/CHANGES.ru new/nginx-1.15.7/CHANGES.ru
--- old/nginx-1.15.6/CHANGES.ru 2018-11-06 14:32:14.000000000 +0100
+++ new/nginx-1.15.7/CHANGES.ru 2018-11-27 15:40:35.000000000 +0100
@@ -1,4 +1,21 @@
 
+Изменения в nginx 1.15.7                                          27.11.2018
+
+    *) Добавление: директива proxy_requests в модуле stream.
+
+    *) Добавление: параметр "delay" директивы "limit_req".
+       Спасибо Владиславу Шабанову и Петру Щучкину.
+
+    *) Исправление: утечки памяти в случае ошибок при переконфигурации.
+
+    *) Исправление: в переменных $upstream_response_time,
+       $upstream_connect_time и $upstream_header_time.
+
+    *) Исправление: в рабочем процессе мог произойти segmentation fault,
+       если использовался модуль ngx_http_mp4_module на 32-битных
+       платформах.
+
+
 Изменения в nginx 1.15.6                                          06.11.2018
 
     *) Безопасность: при использовании HTTP/2 клиент мог вызвать чрезмерное
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/core/nginx.h 
new/nginx-1.15.7/src/core/nginx.h
--- old/nginx-1.15.6/src/core/nginx.h   2018-11-06 14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/core/nginx.h   2018-11-27 15:40:21.000000000 +0100
@@ -9,8 +9,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version      1015006
-#define NGINX_VERSION      "1.15.6"
+#define nginx_version      1015007
+#define NGINX_VERSION      "1.15.7"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #ifdef NGX_BUILD
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/core/ngx_cycle.c 
new/nginx-1.15.7/src/core/ngx_cycle.c
--- old/nginx-1.15.6/src/core/ngx_cycle.c       2018-11-06 14:32:09.000000000 
+0100
+++ new/nginx-1.15.7/src/core/ngx_cycle.c       2018-11-27 15:40:21.000000000 
+0100
@@ -843,6 +843,69 @@
         }
     }
 
+    /* free the newly created shared memory */
+
+    part = &cycle->shared_memory.part;
+    shm_zone = part->elts;
+
+    for (i = 0; /* void */ ; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+            part = part->next;
+            shm_zone = part->elts;
+            i = 0;
+        }
+
+        if (shm_zone[i].shm.addr == NULL) {
+            continue;
+        }
+
+        opart = &old_cycle->shared_memory.part;
+        oshm_zone = opart->elts;
+
+        for (n = 0; /* void */ ; n++) {
+
+            if (n >= opart->nelts) {
+                if (opart->next == NULL) {
+                    break;
+                }
+                opart = opart->next;
+                oshm_zone = opart->elts;
+                n = 0;
+            }
+
+            if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) {
+                continue;
+            }
+
+            if (ngx_strncmp(shm_zone[i].shm.name.data,
+                            oshm_zone[n].shm.name.data,
+                            shm_zone[i].shm.name.len)
+                != 0)
+            {
+                continue;
+            }
+
+            if (shm_zone[i].tag == oshm_zone[n].tag
+                && shm_zone[i].shm.size == oshm_zone[n].shm.size
+                && !shm_zone[i].noreuse)
+            {
+                goto old_shm_zone_found;
+            }
+
+            break;
+        }
+
+        ngx_shm_free(&shm_zone[i].shm);
+
+    old_shm_zone_found:
+
+        continue;
+    }
+
     if (ngx_test_config) {
         ngx_destroy_cycle_pools(&conf);
         return NULL;
@@ -1274,6 +1337,7 @@
 
     shm_zone->data = NULL;
     shm_zone->shm.log = cf->cycle->log;
+    shm_zone->shm.addr = NULL;
     shm_zone->shm.size = size;
     shm_zone->shm.name = *name;
     shm_zone->shm.exists = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/core/ngx_output_chain.c 
new/nginx-1.15.7/src/core/ngx_output_chain.c
--- old/nginx-1.15.6/src/core/ngx_output_chain.c        2018-11-06 
14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/core/ngx_output_chain.c        2018-11-27 
15:40:21.000000000 +0100
@@ -126,6 +126,26 @@
                 continue;
             }
 
+            if (bsize < 0) {
+
+                ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
+                              "negative size buf in output "
+                              "t:%d r:%d f:%d %p %p-%p %p %O-%O",
+                              ctx->in->buf->temporary,
+                              ctx->in->buf->recycled,
+                              ctx->in->buf->in_file,
+                              ctx->in->buf->start,
+                              ctx->in->buf->pos,
+                              ctx->in->buf->last,
+                              ctx->in->buf->file,
+                              ctx->in->buf->file_pos,
+                              ctx->in->buf->file_last);
+
+                ngx_debug_point();
+
+                return NGX_ERROR;
+            }
+
             if (ngx_output_chain_as_is(ctx, ctx->in->buf)) {
 
                 /* move the chain link to the output chain */
@@ -665,7 +685,6 @@
 
     for (size = 0; in; in = in->next) {
 
-#if 1
         if (ngx_buf_size(in->buf) == 0 && !ngx_buf_special(in->buf)) {
 
             ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
@@ -685,7 +704,26 @@
 
             continue;
         }
-#endif
+
+        if (ngx_buf_size(in->buf) < 0) {
+
+            ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
+                          "negative size buf in chain writer "
+                          "t:%d r:%d f:%d %p %p-%p %p %O-%O",
+                          in->buf->temporary,
+                          in->buf->recycled,
+                          in->buf->in_file,
+                          in->buf->start,
+                          in->buf->pos,
+                          in->buf->last,
+                          in->buf->file,
+                          in->buf->file_pos,
+                          in->buf->file_last);
+
+            ngx_debug_point();
+
+            return NGX_ERROR;
+        }
 
         size += ngx_buf_size(in->buf);
 
@@ -709,7 +747,6 @@
 
     for (cl = ctx->out; cl; cl = cl->next) {
 
-#if 1
         if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) {
 
             ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
@@ -729,7 +766,26 @@
 
             continue;
         }
-#endif
+
+        if (ngx_buf_size(cl->buf) < 0) {
+
+            ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
+                          "negative size buf in chain writer "
+                          "t:%d r:%d f:%d %p %p-%p %p %O-%O",
+                          cl->buf->temporary,
+                          cl->buf->recycled,
+                          cl->buf->in_file,
+                          cl->buf->start,
+                          cl->buf->pos,
+                          cl->buf->last,
+                          cl->buf->file,
+                          cl->buf->file_pos,
+                          cl->buf->file_last);
+
+            ngx_debug_point();
+
+            return NGX_ERROR;
+        }
 
         size += ngx_buf_size(cl->buf);
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/core/ngx_string.c 
new/nginx-1.15.7/src/core/ngx_string.c
--- old/nginx-1.15.6/src/core/ngx_string.c      2018-11-06 14:32:09.000000000 
+0100
+++ new/nginx-1.15.7/src/core/ngx_string.c      2018-11-27 15:40:21.000000000 
+0100
@@ -2013,6 +2013,14 @@
 }
 
 
+void
+ngx_explicit_memzero(void *buf, size_t n)
+{
+    ngx_memzero(buf, n);
+    ngx_memory_barrier();
+}
+
+
 #if (NGX_MEMCPY_LIMIT)
 
 void *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/core/ngx_string.h 
new/nginx-1.15.7/src/core/ngx_string.h
--- old/nginx-1.15.6/src/core/ngx_string.h      2018-11-06 14:32:09.000000000 
+0100
+++ new/nginx-1.15.7/src/core/ngx_string.h      2018-11-27 15:40:21.000000000 
+0100
@@ -88,6 +88,8 @@
 #define ngx_memzero(buf, n)       (void) memset(buf, 0, n)
 #define ngx_memset(buf, c, n)     (void) memset(buf, c, n)
 
+void ngx_explicit_memzero(void *buf, size_t n);
+
 
 #if (NGX_MEMCPY_LIMIT)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/event/ngx_event.h 
new/nginx-1.15.7/src/event/ngx_event.h
--- old/nginx-1.15.6/src/event/ngx_event.h      2018-11-06 14:32:09.000000000 
+0100
+++ new/nginx-1.15.7/src/event/ngx_event.h      2018-11-27 15:40:21.000000000 
+0100
@@ -509,6 +509,7 @@
 void ngx_udp_rbtree_insert_value(ngx_rbtree_node_t *temp,
     ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
 #endif
+void ngx_delete_udp_connection(void *data);
 ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle);
 ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
 u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/event/ngx_event_openssl.c 
new/nginx-1.15.7/src/event/ngx_event_openssl.c
--- old/nginx-1.15.6/src/event/ngx_event_openssl.c      2018-11-06 
14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/event/ngx_event_openssl.c      2018-11-27 
15:40:21.000000000 +0100
@@ -1051,7 +1051,7 @@
                            ngx_close_file_n " \"%s\" failed", file->data);
     }
 
-    ngx_memzero(buf, NGX_SSL_PASSWORD_BUFFER_SIZE);
+    ngx_explicit_memzero(buf, NGX_SSL_PASSWORD_BUFFER_SIZE);
 
     return passwords;
 }
@@ -1068,7 +1068,7 @@
     pwd = passwords->elts;
 
     for (i = 0; i < passwords->nelts; i++) {
-        ngx_memzero(pwd[i].data, pwd[i].len);
+        ngx_explicit_memzero(pwd[i].data, pwd[i].len);
     }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/event/ngx_event_udp.c 
new/nginx-1.15.7/src/event/ngx_event_udp.c
--- old/nginx-1.15.6/src/event/ngx_event_udp.c  2018-11-06 14:32:09.000000000 
+0100
+++ new/nginx-1.15.7/src/event/ngx_event_udp.c  2018-11-27 15:40:21.000000000 
+0100
@@ -23,7 +23,6 @@
 static ssize_t ngx_udp_shared_recv(ngx_connection_t *c, u_char *buf,
     size_t size);
 static ngx_int_t ngx_insert_udp_connection(ngx_connection_t *c);
-static void ngx_delete_udp_connection(void *data);
 static ngx_connection_t *ngx_lookup_udp_connection(ngx_listening_t *ls,
     struct sockaddr *sockaddr, socklen_t socklen,
     struct sockaddr *local_sockaddr, socklen_t local_socklen);
@@ -261,7 +260,10 @@
 
             rev->handler(rev);
 
-            c->udp->buffer = NULL;
+            if (c->udp) {
+                c->udp->buffer = NULL;
+            }
+
             rev->ready = 0;
 
             goto next;
@@ -555,12 +557,18 @@
 }
 
 
-static void
+void
 ngx_delete_udp_connection(void *data)
 {
     ngx_connection_t  *c = data;
 
+    if (c->udp == NULL) {
+        return;
+    }
+
     ngx_rbtree_delete(&c->listening->rbtree, &c->udp->node);
+
+    c->udp = NULL;
 }
 
 
@@ -638,4 +646,12 @@
     return NULL;
 }
 
+#else
+
+void
+ngx_delete_udp_connection(void *data)
+{
+    return;
+}
+
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.15.6/src/http/modules/ngx_http_limit_req_module.c 
new/nginx-1.15.7/src/http/modules/ngx_http_limit_req_module.c
--- old/nginx-1.15.6/src/http/modules/ngx_http_limit_req_module.c       
2018-11-06 14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/http/modules/ngx_http_limit_req_module.c       
2018-11-27 15:40:21.000000000 +0100
@@ -44,7 +44,7 @@
     ngx_shm_zone_t              *shm_zone;
     /* integer value, 1 corresponds to 0.001 r/s */
     ngx_uint_t                   burst;
-    ngx_uint_t                   nodelay; /* unsigned  nodelay:1 */
+    ngx_uint_t                   delay;
 } ngx_http_limit_req_limit_t;
 
 
@@ -499,12 +499,12 @@
 
     excess = *ep;
 
-    if (excess == 0 || (*limit)->nodelay) {
+    if ((ngx_uint_t) excess <= (*limit)->delay) {
         max_delay = 0;
 
     } else {
         ctx = (*limit)->shm_zone->data;
-        max_delay = excess * 1000 / ctx->rate;
+        max_delay = (excess - (*limit)->delay) * 1000 / ctx->rate;
     }
 
     while (n--) {
@@ -544,11 +544,11 @@
 
         ctx->node = NULL;
 
-        if (limits[n].nodelay) {
+        if ((ngx_uint_t) excess <= limits[n].delay) {
             continue;
         }
 
-        delay = excess * 1000 / ctx->rate;
+        delay = (excess - limits[n].delay) * 1000 / ctx->rate;
 
         if (delay > max_delay) {
             max_delay = delay;
@@ -875,9 +875,9 @@
 {
     ngx_http_limit_req_conf_t  *lrcf = conf;
 
-    ngx_int_t                    burst;
+    ngx_int_t                    burst, delay;
     ngx_str_t                   *value, s;
-    ngx_uint_t                   i, nodelay;
+    ngx_uint_t                   i;
     ngx_shm_zone_t              *shm_zone;
     ngx_http_limit_req_limit_t  *limit, *limits;
 
@@ -885,7 +885,7 @@
 
     shm_zone = NULL;
     burst = 0;
-    nodelay = 0;
+    delay = 0;
 
     for (i = 1; i < cf->args->nelts; i++) {
 
@@ -908,7 +908,19 @@
             burst = ngx_atoi(value[i].data + 6, value[i].len - 6);
             if (burst <= 0) {
                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                                   "invalid burst rate \"%V\"", &value[i]);
+                                   "invalid burst value \"%V\"", &value[i]);
+                return NGX_CONF_ERROR;
+            }
+
+            continue;
+        }
+
+        if (ngx_strncmp(value[i].data, "delay=", 6) == 0) {
+
+            delay = ngx_atoi(value[i].data + 6, value[i].len - 6);
+            if (delay <= 0) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "invalid delay value \"%V\"", &value[i]);
                 return NGX_CONF_ERROR;
             }
 
@@ -916,7 +928,7 @@
         }
 
         if (ngx_strcmp(value[i].data, "nodelay") == 0) {
-            nodelay = 1;
+            delay = NGX_MAX_INT_T_VALUE / 1000;
             continue;
         }
 
@@ -956,7 +968,7 @@
 
     limit->shm_zone = shm_zone;
     limit->burst = burst * 1000;
-    limit->nodelay = nodelay;
+    limit->delay = delay * 1000;
 
     return NGX_CONF_OK;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/http/modules/ngx_http_mp4_module.c 
new/nginx-1.15.7/src/http/modules/ngx_http_mp4_module.c
--- old/nginx-1.15.6/src/http/modules/ngx_http_mp4_module.c     2018-11-06 
14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/http/modules/ngx_http_mp4_module.c     2018-11-27 
15:40:21.000000000 +0100
@@ -169,7 +169,14 @@
 
 
 #define ngx_mp4_atom_next(mp4, n)                                             \
-    mp4->buffer_pos += (size_t) n;                                            \
+                                                                              \
+    if (n > (size_t) (mp4->buffer_end - mp4->buffer_pos)) {                   \
+        mp4->buffer_pos = mp4->buffer_end;                                    \
+                                                                              \
+    } else {                                                                  \
+        mp4->buffer_pos += (size_t) n;                                        \
+    }                                                                         \
+                                                                              \
     mp4->offset += n
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/http/ngx_http_upstream.c 
new/nginx-1.15.7/src/http/ngx_http_upstream.c
--- old/nginx-1.15.6/src/http/ngx_http_upstream.c       2018-11-06 
14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/http/ngx_http_upstream.c       2018-11-27 
15:40:21.000000000 +0100
@@ -1505,8 +1505,8 @@
 
     r->connection->log->action = "connecting to upstream";
 
-    if (u->state && u->state->response_time) {
-        u->state->response_time = ngx_current_msec - u->state->response_time;
+    if (u->state && u->state->response_time == (ngx_msec_t) -1) {
+        u->state->response_time = ngx_current_msec - u->start_time;
     }
 
     u->state = ngx_array_push(r->upstream_states);
@@ -1518,7 +1518,9 @@
 
     ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t));
 
-    u->state->response_time = ngx_current_msec;
+    u->start_time = ngx_current_msec;
+
+    u->state->response_time = (ngx_msec_t) -1;
     u->state->connect_time = (ngx_msec_t) -1;
     u->state->header_time = (ngx_msec_t) -1;
 
@@ -2002,7 +2004,7 @@
                    "http upstream send request");
 
     if (u->state->connect_time == (ngx_msec_t) -1) {
-        u->state->connect_time = ngx_current_msec - u->state->response_time;
+        u->state->connect_time = ngx_current_msec - u->start_time;
     }
 
     if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {
@@ -2413,7 +2415,7 @@
 
     /* rc == NGX_OK */
 
-    u->state->header_time = ngx_current_msec - u->state->response_time;
+    u->state->header_time = ngx_current_msec - u->start_time;
 
     if (u->headers_in.status_n >= NGX_HTTP_SPECIAL_RESPONSE) {
 
@@ -4309,8 +4311,8 @@
         u->resolved->ctx = NULL;
     }
 
-    if (u->state && u->state->response_time) {
-        u->state->response_time = ngx_current_msec - u->state->response_time;
+    if (u->state && u->state->response_time == (ngx_msec_t) -1) {
+        u->state->response_time = ngx_current_msec - u->start_time;
 
         if (u->pipe && u->pipe->read_length) {
             u->state->bytes_received += u->pipe->read_length
@@ -5419,18 +5421,18 @@
     state = r->upstream_states->elts;
 
     for ( ;; ) {
-        if (state[i].status) {
 
-            if (data == 1 && state[i].header_time != (ngx_msec_t) -1) {
-                ms = state[i].header_time;
+        if (data == 1) {
+            ms = state[i].header_time;
 
-            } else if (data == 2 && state[i].connect_time != (ngx_msec_t) -1) {
-                ms = state[i].connect_time;
+        } else if (data == 2) {
+            ms = state[i].connect_time;
 
-            } else {
-                ms = state[i].response_time;
-            }
+        } else {
+            ms = state[i].response_time;
+        }
 
+        if (ms != -1) {
             ms = ngx_max(ms, 0);
             p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/http/ngx_http_upstream.h 
new/nginx-1.15.7/src/http/ngx_http_upstream.h
--- old/nginx-1.15.6/src/http/ngx_http_upstream.h       2018-11-06 
14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/http/ngx_http_upstream.h       2018-11-27 
15:40:21.000000000 +0100
@@ -365,7 +365,7 @@
     ngx_int_t                      (*rewrite_cookie)(ngx_http_request_t *r,
                                          ngx_table_elt_t *h);
 
-    ngx_msec_t                       timeout;
+    ngx_msec_t                       start_time;
 
     ngx_http_upstream_state_t       *state;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/http/ngx_http_write_filter_module.c 
new/nginx-1.15.7/src/http/ngx_http_write_filter_module.c
--- old/nginx-1.15.6/src/http/ngx_http_write_filter_module.c    2018-11-06 
14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/http/ngx_http_write_filter_module.c    2018-11-27 
15:40:21.000000000 +0100
@@ -80,7 +80,6 @@
                        cl->buf->file_pos,
                        cl->buf->file_last - cl->buf->file_pos);
 
-#if 1
         if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) {
             ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                           "zero size buf in writer "
@@ -98,7 +97,24 @@
             ngx_debug_point();
             return NGX_ERROR;
         }
-#endif
+
+        if (ngx_buf_size(cl->buf) < 0) {
+            ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                          "negative size buf in writer "
+                          "t:%d r:%d f:%d %p %p-%p %p %O-%O",
+                          cl->buf->temporary,
+                          cl->buf->recycled,
+                          cl->buf->in_file,
+                          cl->buf->start,
+                          cl->buf->pos,
+                          cl->buf->last,
+                          cl->buf->file,
+                          cl->buf->file_pos,
+                          cl->buf->file_last);
+
+            ngx_debug_point();
+            return NGX_ERROR;
+        }
 
         size += ngx_buf_size(cl->buf);
 
@@ -136,7 +152,6 @@
                        cl->buf->file_pos,
                        cl->buf->file_last - cl->buf->file_pos);
 
-#if 1
         if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) {
             ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                           "zero size buf in writer "
@@ -154,7 +169,24 @@
             ngx_debug_point();
             return NGX_ERROR;
         }
-#endif
+
+        if (ngx_buf_size(cl->buf) < 0) {
+            ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                          "negative size buf in writer "
+                          "t:%d r:%d f:%d %p %p-%p %p %O-%O",
+                          cl->buf->temporary,
+                          cl->buf->recycled,
+                          cl->buf->in_file,
+                          cl->buf->start,
+                          cl->buf->pos,
+                          cl->buf->last,
+                          cl->buf->file,
+                          cl->buf->file_pos,
+                          cl->buf->file_last);
+
+            ngx_debug_point();
+            return NGX_ERROR;
+        }
 
         size += ngx_buf_size(cl->buf);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/stream/ngx_stream_proxy_module.c 
new/nginx-1.15.7/src/stream/ngx_stream_proxy_module.c
--- old/nginx-1.15.6/src/stream/ngx_stream_proxy_module.c       2018-11-06 
14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/stream/ngx_stream_proxy_module.c       2018-11-27 
15:40:21.000000000 +0100
@@ -26,6 +26,7 @@
     size_t                           buffer_size;
     size_t                           upload_rate;
     size_t                           download_rate;
+    ngx_uint_t                       requests;
     ngx_uint_t                       responses;
     ngx_uint_t                       next_upstream_tries;
     ngx_flag_t                       next_upstream;
@@ -73,6 +74,8 @@
 static ngx_int_t ngx_stream_proxy_test_connect(ngx_connection_t *c);
 static void ngx_stream_proxy_process(ngx_stream_session_t *s,
     ngx_uint_t from_upstream, ngx_uint_t do_write);
+static ngx_int_t ngx_stream_proxy_test_finalize(ngx_stream_session_t *s,
+    ngx_uint_t from_upstream);
 static void ngx_stream_proxy_next_upstream(ngx_stream_session_t *s);
 static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc);
 static u_char *ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf,
@@ -193,6 +196,13 @@
       offsetof(ngx_stream_proxy_srv_conf_t, download_rate),
       NULL },
 
+    { ngx_string("proxy_requests"),
+      NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_STREAM_SRV_CONF_OFFSET,
+      offsetof(ngx_stream_proxy_srv_conf_t, requests),
+      NULL },
+
     { ngx_string("proxy_responses"),
       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_num_slot,
@@ -680,7 +690,7 @@
     u->proxy_protocol = pscf->proxy_protocol;
 
     if (u->state) {
-        u->state->response_time = ngx_current_msec - u->state->response_time;
+        u->state->response_time = ngx_current_msec - u->start_time;
     }
 
     u->state = ngx_array_push(s->upstream_states);
@@ -691,9 +701,11 @@
 
     ngx_memzero(u->state, sizeof(ngx_stream_upstream_state_t));
 
+    u->start_time = ngx_current_msec;
+
     u->state->connect_time = (ngx_msec_t) -1;
     u->state->first_byte_time = (ngx_msec_t) -1;
-    u->state->response_time = ngx_current_msec;
+    u->state->response_time = (ngx_msec_t) -1;
 
     rc = ngx_event_connect_peer(&u->peer);
 
@@ -807,7 +819,7 @@
         }
     }
 
-    u->state->connect_time = ngx_current_msec - u->state->response_time;
+    u->state->connect_time = ngx_current_msec - u->start_time;
 
     if (u->peer.notify) {
         u->peer.notify(&u->peer, u->peer.data,
@@ -1339,11 +1351,14 @@
 
         } else {
             if (s->connection->type == SOCK_DGRAM) {
-                if (pscf->responses == NGX_MAX_INT32_VALUE) {
+
+                if (pscf->responses == NGX_MAX_INT32_VALUE
+                    || (u->responses >= pscf->responses * u->requests))
+                {
 
                     /*
                      * successfully terminate timed out UDP session
-                     * with unspecified number of responses
+                     * if expected number of responses was received
                      */
 
                     handler = c->log->handler;
@@ -1609,7 +1624,7 @@
                 if (from_upstream) {
                     if (u->state->first_byte_time == (ngx_msec_t) -1) {
                         u->state->first_byte_time = ngx_current_msec
-                                                    - u->state->response_time;
+                                                    - u->start_time;
                     }
                 }
 
@@ -1646,44 +1661,7 @@
 
     c->log->action = "proxying connection";
 
-    if (c->type == SOCK_DGRAM
-        && pscf->responses != NGX_MAX_INT32_VALUE
-        && u->responses >= pscf->responses * u->requests
-        && !src->buffered && dst && !dst->buffered)
-    {
-        handler = c->log->handler;
-        c->log->handler = NULL;
-
-        ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                      "udp done"
-                      ", packets from/to client:%ui/%ui"
-                      ", bytes from/to client:%O/%O"
-                      ", bytes from/to upstream:%O/%O",
-                      u->requests, u->responses,
-                      s->received, c->sent, u->received, pc ? pc->sent : 0);
-
-        c->log->handler = handler;
-
-        ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
-        return;
-    }
-
-    if (c->type == SOCK_STREAM
-        && src->read->eof && dst && (dst->read->eof || !dst->buffered))
-    {
-        handler = c->log->handler;
-        c->log->handler = NULL;
-
-        ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                      "%s disconnected"
-                      ", bytes from/to client:%O/%O"
-                      ", bytes from/to upstream:%O/%O",
-                      from_upstream ? "upstream" : "client",
-                      s->received, c->sent, u->received, pc ? pc->sent : 0);
-
-        c->log->handler = handler;
-
-        ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
+    if (ngx_stream_proxy_test_finalize(s, from_upstream) == NGX_OK) {
         return;
     }
 
@@ -1710,6 +1688,87 @@
 }
 
 
+static ngx_int_t
+ngx_stream_proxy_test_finalize(ngx_stream_session_t *s,
+    ngx_uint_t from_upstream)
+{
+    ngx_connection_t             *c, *pc;
+    ngx_log_handler_pt            handler;
+    ngx_stream_upstream_t        *u;
+    ngx_stream_proxy_srv_conf_t  *pscf;
+
+    pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
+
+    c = s->connection;
+    u = s->upstream;
+    pc = u->connected ? u->peer.connection : NULL;
+
+    if (c->type == SOCK_DGRAM) {
+
+        if (pscf->requests && u->requests < pscf->requests) {
+            return NGX_DECLINED;
+        }
+
+        if (pscf->requests) {
+            ngx_delete_udp_connection(c);
+        }
+
+        if (pscf->responses == NGX_MAX_INT32_VALUE
+            || u->responses < pscf->responses * u->requests)
+        {
+            return NGX_DECLINED;
+        }
+
+        if (pc == NULL || c->buffered || pc->buffered) {
+            return NGX_DECLINED;
+        }
+
+        handler = c->log->handler;
+        c->log->handler = NULL;
+
+        ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                      "udp done"
+                      ", packets from/to client:%ui/%ui"
+                      ", bytes from/to client:%O/%O"
+                      ", bytes from/to upstream:%O/%O",
+                      u->requests, u->responses,
+                      s->received, c->sent, u->received, pc ? pc->sent : 0);
+
+        c->log->handler = handler;
+
+        ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
+
+        return NGX_OK;
+    }
+
+    /* c->type == SOCK_STREAM */
+
+    if (pc == NULL
+        || (!c->read->eof && !pc->read->eof)
+        || (!c->read->eof && c->buffered)
+        || (!pc->read->eof && pc->buffered))
+    {
+        return NGX_DECLINED;
+    }
+
+    handler = c->log->handler;
+    c->log->handler = NULL;
+
+    ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                  "%s disconnected"
+                  ", bytes from/to client:%O/%O"
+                  ", bytes from/to upstream:%O/%O",
+                  from_upstream ? "upstream" : "client",
+                  s->received, c->sent, u->received, pc ? pc->sent : 0);
+
+    c->log->handler = handler;
+
+    ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
+
+    return NGX_OK;
+}
+
+
 static void
 ngx_stream_proxy_next_upstream(ngx_stream_session_t *s)
 {
@@ -1800,7 +1859,9 @@
     pc = u->peer.connection;
 
     if (u->state) {
-        u->state->response_time = ngx_current_msec - u->state->response_time;
+        if (u->state->response_time == (ngx_msec_t) -1) {
+            u->state->response_time = ngx_current_msec - u->start_time;
+        }
 
         if (pc) {
             u->state->bytes_received = u->received;
@@ -1905,6 +1966,7 @@
     conf->buffer_size = NGX_CONF_UNSET_SIZE;
     conf->upload_rate = NGX_CONF_UNSET_SIZE;
     conf->download_rate = NGX_CONF_UNSET_SIZE;
+    conf->requests = NGX_CONF_UNSET_UINT;
     conf->responses = NGX_CONF_UNSET_UINT;
     conf->next_upstream_tries = NGX_CONF_UNSET_UINT;
     conf->next_upstream = NGX_CONF_UNSET;
@@ -1949,6 +2011,9 @@
     ngx_conf_merge_size_value(conf->download_rate,
                               prev->download_rate, 0);
 
+    ngx_conf_merge_uint_value(conf->requests,
+                              prev->requests, 0);
+
     ngx_conf_merge_uint_value(conf->responses,
                               prev->responses, NGX_MAX_INT32_VALUE);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/stream/ngx_stream_upstream.c 
new/nginx-1.15.7/src/stream/ngx_stream_upstream.c
--- old/nginx-1.15.6/src/stream/ngx_stream_upstream.c   2018-11-06 
14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/stream/ngx_stream_upstream.c   2018-11-27 
15:40:21.000000000 +0100
@@ -267,24 +267,22 @@
     for ( ;; ) {
 
         if (data == 1) {
-            if (state[i].first_byte_time == (ngx_msec_t) -1) {
-                *p++ = '-';
-                goto next;
-            }
-
             ms = state[i].first_byte_time;
 
-        } else if (data == 2 && state[i].connect_time != (ngx_msec_t) -1) {
+        } else if (data == 2) {
             ms = state[i].connect_time;
 
         } else {
             ms = state[i].response_time;
         }
 
-        ms = ngx_max(ms, 0);
-        p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000);
+        if (ms != -1) {
+            ms = ngx_max(ms, 0);
+            p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000);
 
-    next:
+        } else {
+            *p++ = '-';
+        }
 
         if (++i == s->upstream_states->nelts) {
             break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.15.6/src/stream/ngx_stream_upstream.h 
new/nginx-1.15.7/src/stream/ngx_stream_upstream.h
--- old/nginx-1.15.6/src/stream/ngx_stream_upstream.h   2018-11-06 
14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/stream/ngx_stream_upstream.h   2018-11-27 
15:40:21.000000000 +0100
@@ -130,6 +130,7 @@
     time_t                             start_sec;
     ngx_uint_t                         requests;
     ngx_uint_t                         responses;
+    ngx_msec_t                         start_time;
 
     ngx_str_t                          ssl_name;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.15.6/src/stream/ngx_stream_write_filter_module.c 
new/nginx-1.15.7/src/stream/ngx_stream_write_filter_module.c
--- old/nginx-1.15.6/src/stream/ngx_stream_write_filter_module.c        
2018-11-06 14:32:09.000000000 +0100
+++ new/nginx-1.15.7/src/stream/ngx_stream_write_filter_module.c        
2018-11-27 15:40:21.000000000 +0100
@@ -104,7 +104,6 @@
                        cl->buf->file_pos,
                        cl->buf->file_last - cl->buf->file_pos);
 
-#if 1
         if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) {
             ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                           "zero size buf in writer "
@@ -122,7 +121,24 @@
             ngx_debug_point();
             return NGX_ERROR;
         }
-#endif
+
+        if (ngx_buf_size(cl->buf) < 0) {
+            ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                          "negative size buf in writer "
+                          "t:%d r:%d f:%d %p %p-%p %p %O-%O",
+                          cl->buf->temporary,
+                          cl->buf->recycled,
+                          cl->buf->in_file,
+                          cl->buf->start,
+                          cl->buf->pos,
+                          cl->buf->last,
+                          cl->buf->file,
+                          cl->buf->file_pos,
+                          cl->buf->file_last);
+
+            ngx_debug_point();
+            return NGX_ERROR;
+        }
 
         size += ngx_buf_size(cl->buf);
 
@@ -160,7 +176,6 @@
                        cl->buf->file_pos,
                        cl->buf->file_last - cl->buf->file_pos);
 
-#if 1
         if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) {
             ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                           "zero size buf in writer "
@@ -178,7 +193,24 @@
             ngx_debug_point();
             return NGX_ERROR;
         }
-#endif
+
+        if (ngx_buf_size(cl->buf) < 0) {
+            ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                          "negative size buf in writer "
+                          "t:%d r:%d f:%d %p %p-%p %p %O-%O",
+                          cl->buf->temporary,
+                          cl->buf->recycled,
+                          cl->buf->in_file,
+                          cl->buf->start,
+                          cl->buf->pos,
+                          cl->buf->last,
+                          cl->buf->file,
+                          cl->buf->file_pos,
+                          cl->buf->file_last);
+
+            ngx_debug_point();
+            return NGX_ERROR;
+        }
 
         size += ngx_buf_size(cl->buf);
 



Reply via email to