From 10fd8be86d657839fbc6218891bfe9046ab5b592 Mon Sep 17 00:00:00 2001 From: Vladimir Homutov Date: Mon, 13 Dec 2021 09:48:33 +0300 Subject: [PATCH] QUIC: decoupled path state and limitation status. The path validation status and anti-amplification limit status is actually two different variables. It is possible that validating path should not be limited (for example, when re-validating former path). --- src/event/quic/ngx_event_quic.c | 1 + src/event/quic/ngx_event_quic_connection.h | 1 + src/event/quic/ngx_event_quic_migration.c | 12 +++++++++--- src/event/quic/ngx_event_quic_output.c | 6 +++--- src/event/quic/ngx_event_quic_socket.c | 1 + 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/event/quic/ngx_event_quic.c b/src/event/quic/ngx_event_quic.c index cb71a16b1..4a9526d61 100644 --- a/src/event/quic/ngx_event_quic.c +++ b/src/event/quic/ngx_event_quic.c @@ -1013,6 +1013,7 @@ ngx_quic_process_payload(ngx_connection_t *c, ngx_quic_header_t *pkt) if (qc->socket->path->state != NGX_QUIC_PATH_VALIDATED) { qc->socket->path->state = NGX_QUIC_PATH_VALIDATED; + qc->socket->path->limited = 0; ngx_post_event(&qc->push, &ngx_posted_events); } } diff --git a/src/event/quic/ngx_event_quic_connection.h b/src/event/quic/ngx_event_quic_connection.h index 7b6afb123..73268ea0a 100644 --- a/src/event/quic/ngx_event_quic_connection.h +++ b/src/event/quic/ngx_event_quic_connection.h @@ -85,6 +85,7 @@ struct ngx_quic_path_s { struct sockaddr *sockaddr; socklen_t socklen; ngx_uint_t state; + ngx_uint_t limited; /* unsigned limited:1; */ ngx_msec_t expires; ngx_msec_t last_seen; ngx_uint_t tries; diff --git a/src/event/quic/ngx_event_quic_migration.c b/src/event/quic/ngx_event_quic_migration.c index 0bfee6058..9b1ccafba 100644 --- a/src/event/quic/ngx_event_quic_migration.c +++ b/src/event/quic/ngx_event_quic_migration.c @@ -158,6 +158,7 @@ valid: "quic path #%uL successfully validated", path->seqnum); path->state = NGX_QUIC_PATH_VALIDATED; + path->limited = 0; return NGX_OK; } @@ -215,6 +216,9 @@ ngx_quic_add_path(ngx_connection_t *c, struct sockaddr *sockaddr, return NULL; } + path->state = NGX_QUIC_PATH_NEW; + path->limited = 1; + path->seqnum = qc->path_seqnum++; path->last_seen = ngx_current_msec; @@ -332,6 +336,7 @@ update: /* force limits/revalidation for paths that were not seen recently */ if (ngx_current_msec - path->last_seen > qc->tp.max_idle_timeout) { path->state = NGX_QUIC_PATH_NEW; + path->limited = 1; path->sent = 0; path->received = 0; } @@ -350,11 +355,11 @@ update: */ path->received += len; - ngx_log_debug6(NGX_LOG_DEBUG_EVENT, c->log, 0, + ngx_log_debug7(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic packet via #%uL:%uL:%uL" - " size:%O path recvd:%O sent:%O", + " size:%O path recvd:%O sent:%O limited:%ui", qsock->sid.seqnum, qsock->cid->seqnum, path->seqnum, - len, path->received, path->sent); + len, path->received, path->sent, path->limited); return NGX_OK; } @@ -607,6 +612,7 @@ ngx_quic_path_validation_handler(ngx_event_t *ev) /* found expired path */ path->state = NGX_QUIC_PATH_NEW; + path->limited = 1; /* * RFC 9000, 9.4. Loss Detection and Congestion Control diff --git a/src/event/quic/ngx_event_quic_output.c b/src/event/quic/ngx_event_quic_output.c index 3d75e9c39..3963ef006 100644 --- a/src/event/quic/ngx_event_quic_output.c +++ b/src/event/quic/ngx_event_quic_output.c @@ -160,7 +160,7 @@ ngx_quic_create_datagrams(ngx_connection_t *c, ngx_quic_socket_t *qsock) len = ngx_min(qc->ctp.max_udp_payload_size, NGX_QUIC_MAX_UDP_PAYLOAD_SIZE); - if (path->state != NGX_QUIC_PATH_VALIDATED) { + if (path->limited) { max = path->received * 3; max = (path->sent >= max) ? 0 : max - path->sent; @@ -294,7 +294,7 @@ ngx_quic_allow_segmentation(ngx_connection_t *c, ngx_quic_socket_t *qsock) return 0; } - if (qsock->path->state != NGX_QUIC_PATH_VALIDATED) { + if (qsock->path->limited) { /* don't even try to be faster on non-validated paths */ return 0; } @@ -1229,7 +1229,7 @@ ngx_quic_frame_sendto(ngx_connection_t *c, ngx_quic_frame_t *frame, ngx_quic_init_packet(c, ctx, qc->socket, &pkt); /* account for anti-amplification limit: expand to allowed size */ - if (path->state != NGX_QUIC_PATH_VALIDATED) { + if (path->limited) { max = path->received * 3; max = (path->sent >= max) ? 0 : max - path->sent; if ((off_t) min > max) { diff --git a/src/event/quic/ngx_event_quic_socket.c b/src/event/quic/ngx_event_quic_socket.c index 2b9b0fed3..a04ad6202 100644 --- a/src/event/quic/ngx_event_quic_socket.c +++ b/src/event/quic/ngx_event_quic_socket.c @@ -82,6 +82,7 @@ ngx_quic_open_sockets(ngx_connection_t *c, ngx_quic_connection_t *qc, if (pkt->validated) { path->state = NGX_QUIC_PATH_VALIDATED; + path->limited = 0; } /* now bind socket to client and path */