# HG changeset patch # User Roman Arutyunyan # Date 1683819611 -14400 # Node ID 3bb003fcd682e4fea86ee3c2194067a1d2edfb8e # Parent cc3d24a9b76f0e7e6483440c2d6d59f84583e91d QUIC: keep stream sockaddr and addr_text constant. HTTP and Stream variables $remote_addr and $binary_remote_addr rely on constant client address, particularly because they are cacheable. However, QUIC client may migrate to a new address. While there's no perfect way to handle this, the proposed solution is to copy client address to QUIC stream at stream creation. The change also fixes truncated $remote_addr if migration happened while the stream was active. The reason is addr_text string was copied to stream by value. diff --git a/src/event/quic/ngx_event_quic_streams.c b/src/event/quic/ngx_event_quic_streams.c --- a/src/event/quic/ngx_event_quic_streams.c +++ b/src/event/quic/ngx_event_quic_streams.c @@ -637,10 +637,12 @@ ngx_quic_do_init_streams(ngx_connection_ static ngx_quic_stream_t * ngx_quic_create_stream(ngx_connection_t *c, uint64_t id) { + ngx_str_t addr_text; ngx_log_t *log; ngx_pool_t *pool; ngx_uint_t reusable; ngx_queue_t *q; + struct sockaddr *sockaddr; ngx_connection_t *sc; ngx_quic_stream_t *qs; ngx_pool_cleanup_t *cln; @@ -692,6 +694,31 @@ ngx_quic_create_stream(ngx_connection_t *log = *c->log; pool->log = log; + sockaddr = ngx_palloc(pool, c->socklen); + if (sockaddr == NULL) { + ngx_destroy_pool(pool); + ngx_queue_insert_tail(&qc->streams.free, &qs->queue); + return NULL; + } + + ngx_memcpy(sockaddr, c->sockaddr, c->socklen); + + if (c->addr_text.data) { + addr_text.data = ngx_pnalloc(pool, c->addr_text.len); + if (addr_text.data == NULL) { + ngx_destroy_pool(pool); + ngx_queue_insert_tail(&qc->streams.free, &qs->queue); + return NULL; + } + + ngx_memcpy(addr_text.data, c->addr_text.data, c->addr_text.len); + addr_text.len = c->addr_text.len; + + } else { + addr_text.len = 0; + addr_text.data = NULL; + } + reusable = c->reusable; ngx_reusable_connection(c, 0); @@ -710,10 +737,10 @@ ngx_quic_create_stream(ngx_connection_t sc->type = SOCK_STREAM; sc->pool = pool; sc->ssl = c->ssl; - sc->sockaddr = c->sockaddr; + sc->sockaddr = sockaddr; sc->socklen = c->socklen; sc->listening = c->listening; - sc->addr_text = c->addr_text; + sc->addr_text = addr_text; sc->local_sockaddr = c->local_sockaddr; sc->local_socklen = c->local_socklen; sc->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);