Mercurial > hg > nginx-quic
comparison src/event/quic/ngx_event_quic_streams.c @ 9087:3bb003fcd682 quic
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.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 11 May 2023 19:40:11 +0400 |
parents | cc3d24a9b76f |
children |
comparison
equal
deleted
inserted
replaced
9086:cc3d24a9b76f | 9087:3bb003fcd682 |
---|---|
635 | 635 |
636 | 636 |
637 static ngx_quic_stream_t * | 637 static ngx_quic_stream_t * |
638 ngx_quic_create_stream(ngx_connection_t *c, uint64_t id) | 638 ngx_quic_create_stream(ngx_connection_t *c, uint64_t id) |
639 { | 639 { |
640 ngx_str_t addr_text; | |
640 ngx_log_t *log; | 641 ngx_log_t *log; |
641 ngx_pool_t *pool; | 642 ngx_pool_t *pool; |
642 ngx_uint_t reusable; | 643 ngx_uint_t reusable; |
643 ngx_queue_t *q; | 644 ngx_queue_t *q; |
645 struct sockaddr *sockaddr; | |
644 ngx_connection_t *sc; | 646 ngx_connection_t *sc; |
645 ngx_quic_stream_t *qs; | 647 ngx_quic_stream_t *qs; |
646 ngx_pool_cleanup_t *cln; | 648 ngx_pool_cleanup_t *cln; |
647 ngx_quic_connection_t *qc; | 649 ngx_quic_connection_t *qc; |
648 | 650 |
689 return NULL; | 691 return NULL; |
690 } | 692 } |
691 | 693 |
692 *log = *c->log; | 694 *log = *c->log; |
693 pool->log = log; | 695 pool->log = log; |
696 | |
697 sockaddr = ngx_palloc(pool, c->socklen); | |
698 if (sockaddr == NULL) { | |
699 ngx_destroy_pool(pool); | |
700 ngx_queue_insert_tail(&qc->streams.free, &qs->queue); | |
701 return NULL; | |
702 } | |
703 | |
704 ngx_memcpy(sockaddr, c->sockaddr, c->socklen); | |
705 | |
706 if (c->addr_text.data) { | |
707 addr_text.data = ngx_pnalloc(pool, c->addr_text.len); | |
708 if (addr_text.data == NULL) { | |
709 ngx_destroy_pool(pool); | |
710 ngx_queue_insert_tail(&qc->streams.free, &qs->queue); | |
711 return NULL; | |
712 } | |
713 | |
714 ngx_memcpy(addr_text.data, c->addr_text.data, c->addr_text.len); | |
715 addr_text.len = c->addr_text.len; | |
716 | |
717 } else { | |
718 addr_text.len = 0; | |
719 addr_text.data = NULL; | |
720 } | |
694 | 721 |
695 reusable = c->reusable; | 722 reusable = c->reusable; |
696 ngx_reusable_connection(c, 0); | 723 ngx_reusable_connection(c, 0); |
697 | 724 |
698 sc = ngx_get_connection(c->fd, log); | 725 sc = ngx_get_connection(c->fd, log); |
708 sc->quic = qs; | 735 sc->quic = qs; |
709 sc->shared = 1; | 736 sc->shared = 1; |
710 sc->type = SOCK_STREAM; | 737 sc->type = SOCK_STREAM; |
711 sc->pool = pool; | 738 sc->pool = pool; |
712 sc->ssl = c->ssl; | 739 sc->ssl = c->ssl; |
713 sc->sockaddr = c->sockaddr; | 740 sc->sockaddr = sockaddr; |
714 sc->socklen = c->socklen; | 741 sc->socklen = c->socklen; |
715 sc->listening = c->listening; | 742 sc->listening = c->listening; |
716 sc->addr_text = c->addr_text; | 743 sc->addr_text = addr_text; |
717 sc->local_sockaddr = c->local_sockaddr; | 744 sc->local_sockaddr = c->local_sockaddr; |
718 sc->local_socklen = c->local_socklen; | 745 sc->local_socklen = c->local_socklen; |
719 sc->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); | 746 sc->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); |
720 sc->start_time = c->start_time; | 747 sc->start_time = c->start_time; |
721 sc->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; | 748 sc->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; |