changeset 8656:43f3574b3e6f quic

QUIC: fixed handling of clients connected to wildcard address. The patch replaces c->send() occurences with c->send_chain(), because the latter accounts for the local address, which may be different if the wildcard listener is used. Previously, server sent response to client using address different from one client connected to.
author Vladimir Homutov <vl@nginx.com>
date Mon, 07 Dec 2020 14:06:00 +0300
parents f596a4e5794b
children 2dfc5ef29973
files src/event/ngx_event_quic.c
diffstat 1 files changed, 32 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_quic.c
+++ b/src/event/ngx_event_quic.c
@@ -333,6 +333,7 @@ static ngx_int_t ngx_quic_output_frames(
 static void ngx_quic_free_frames(ngx_connection_t *c, ngx_queue_t *frames);
 static ngx_int_t ngx_quic_send_frames(ngx_connection_t *c,
     ngx_quic_send_ctx_t *ctx, ngx_queue_t *frames);
+static ssize_t ngx_quic_send(ngx_connection_t *c, u_char *buf, size_t len);
 
 static void ngx_quic_set_packet_number(ngx_quic_header_t *pkt,
     ngx_quic_send_ctx_t *ctx);
@@ -1171,7 +1172,7 @@ ngx_quic_send_stateless_reset(ngx_connec
         return NGX_ERROR;
     }
 
-    (void) c->send(c, buf, len);
+    (void) ngx_quic_send(c, buf, len);
 
     return NGX_DECLINED;
 }
@@ -1243,7 +1244,7 @@ ngx_quic_negotiate_version(ngx_connectio
                    "quic vnego packet to send len:%uz %*xs", len, len, buf);
 #endif
 
-    (void) c->send(c, buf, len);
+    (void) ngx_quic_send(c, buf, len);
 
     return NGX_ERROR;
 }
@@ -1298,8 +1299,8 @@ ngx_quic_send_retry(ngx_connection_t *c)
                    "quic packet to send len:%uz %xV", res.len, &res);
 #endif
 
-    len = c->send(c, res.data, res.len);
-    if (len == NGX_ERROR || (size_t) len != res.len) {
+    len = ngx_quic_send(c, res.data, res.len);
+    if (len == NGX_ERROR) {
         return NGX_ERROR;
     }
 
@@ -4906,8 +4907,8 @@ ngx_quic_send_frames(ngx_connection_t *c
         return NGX_ERROR;
     }
 
-    len = c->send(c, res.data, res.len);
-    if (len == NGX_ERROR || (size_t) len != res.len) {
+    len = ngx_quic_send(c, res.data, res.len);
+    if (len == NGX_ERROR) {
         ngx_quic_free_frames(c, frames);
         return NGX_ERROR;
     }
@@ -4946,6 +4947,31 @@ ngx_quic_send_frames(ngx_connection_t *c
 }
 
 
+static ssize_t
+ngx_quic_send(ngx_connection_t *c, u_char *buf, size_t len)
+{
+    ngx_buf_t    b;
+    ngx_chain_t  cl, *res;
+
+    ngx_memzero(&b, sizeof(ngx_buf_t));
+
+    b.pos = b.start = buf;
+    b.last = b.end = buf + len;
+    b.last_buf = 1;
+    b.temporary = 1;
+
+    cl.buf = &b;
+    cl.next= NULL;
+
+    res = c->send_chain(c, &cl, 0);
+    if (res == NGX_CHAIN_ERROR) {
+        return NGX_ERROR;
+    }
+
+    return len;
+}
+
+
 static void
 ngx_quic_set_packet_number(ngx_quic_header_t *pkt, ngx_quic_send_ctx_t *ctx)
 {