diff options
author | Roman Arutyunyan <arut@nginx.com> | 2023-05-11 19:40:11 +0400 |
---|---|---|
committer | Roman Arutyunyan <arut@nginx.com> | 2023-05-11 19:40:11 +0400 |
commit | 885c4881915e28661f341b9ac3807afb84c8b779 (patch) | |
tree | a21dbe246654401b3815d8cff039c7f53254f36c /src | |
parent | a4319bc496264f94ea8a85702d9b5b8098d9d18c (diff) | |
download | nginx-885c4881915e28661f341b9ac3807afb84c8b779.tar.gz nginx-885c4881915e28661f341b9ac3807afb84c8b779.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/event/quic/ngx_event_quic_streams.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/src/event/quic/ngx_event_quic_streams.c b/src/event/quic/ngx_event_quic_streams.c index ded94af87..6664dfd7b 100644 --- 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_t *c) 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 *c, uint64_t id) *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 *c, uint64_t id) 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); |