]> git.kaiwu.me - nginx.git/commitdiff
Stream: fixed processing of zero length UDP packets (ticket #1982).
authorVladimir Homutov <vl@nginx.com>
Mon, 8 Jun 2020 08:40:34 +0000 (11:40 +0300)
committerVladimir Homutov <vl@nginx.com>
Mon, 8 Jun 2020 08:40:34 +0000 (11:40 +0300)
src/os/unix/ngx_udp_sendmsg_chain.c
src/stream/ngx_stream_proxy_module.c
src/stream/ngx_stream_write_filter_module.c

index 5399c7916a9e7806390659d7fca0ce7836cfd3cf..3d1d6dde4c8bc09dbb746a3671e2ed5d3a813d4a 100644 (file)
@@ -189,6 +189,13 @@ ngx_udp_output_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *in, ngx_log_t *log)
         return cl;
     }
 
+    /* zero-sized datagram; pretend to have at least 1 iov */
+    if (n == 0) {
+        iov = &vec->iovs[n++];
+        iov->iov_base = NULL;
+        iov->iov_len = 0;
+    }
+
     vec->count = n;
     vec->size = total;
 
index 7484a728ad759c3ba041ec849771e7c1b166094f..db11dd8651046563b879d728fa5278fc0bb74fd5 100644 (file)
@@ -839,7 +839,7 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
         u->upstream_buf.last = p;
     }
 
-    if (c->buffer && c->buffer->pos < c->buffer->last) {
+    if (c->buffer && c->buffer->pos <= c->buffer->last) {
         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
                        "stream proxy add preread buffer: %uz",
                        c->buffer->last - c->buffer->pos);
@@ -853,6 +853,7 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
         *cl->buf = *c->buffer;
 
         cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
+        cl->buf->temporary = (cl->buf->pos == cl->buf->last) ? 0 : 1;
         cl->buf->flush = 1;
 
         cl->next = u->upstream_out;
index 24326c60e16645bdd251b89d2b33059be25c1a07..156a61c3d5ac65f658b548e3c02e89eb4c27e4a2 100644 (file)
@@ -234,7 +234,8 @@ ngx_stream_write_filter(ngx_stream_session_t *s, ngx_chain_t *in,
 
     if (size == 0
         && !(c->buffered & NGX_LOWLEVEL_BUFFERED)
-        && !(last && c->need_last_buf))
+        && !(last && c->need_last_buf)
+        && !(c->type == SOCK_DGRAM && flush))
     {
         if (last || flush || sync) {
             for (cl = *out; cl; /* void */) {