Mercurial > hg > nginx
changeset 8939:ddd5e5c0f87d quic
QUIC: improved path validation.
Previously, path was considered valid during arbitrary selected 10m timeout
since validation. This is quite not what RFC 9000 says; the relevant
part is:
An endpoint MAY skip validation of a peer address if that
address has been seen recently.
The patch considers a path to be 'recently seen' if packets were received
during idle timeout. If a packet is received from the path that was seen
not so recently, such path is considered new, and anti-amplification
restrictions apply.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Mon, 13 Dec 2021 17:27:29 +0300 |
parents | 23880e4ad3e2 |
children | fb41e37ddeb0 |
files | src/event/quic/ngx_event_quic_connection.h src/event/quic/ngx_event_quic_migration.c src/event/quic/ngx_event_quic_migration.h src/event/quic/ngx_event_quic_socket.c |
diffstat | 4 files changed, 15 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/src/event/quic/ngx_event_quic_connection.h Mon Dec 13 14:49:42 2021 +0300 +++ b/src/event/quic/ngx_event_quic_connection.h Mon Dec 13 17:27:29 2021 +0300 @@ -86,6 +86,7 @@ socklen_t socklen; ngx_uint_t state; ngx_msec_t expires; + ngx_msec_t last_seen; ngx_uint_t tries; off_t sent; off_t received; @@ -93,7 +94,6 @@ u_char challenge2[8]; ngx_uint_t refcnt; uint64_t seqnum; - time_t validated_at; ngx_str_t addr_text; u_char text[NGX_SOCKADDR_STRLEN]; };
--- a/src/event/quic/ngx_event_quic_migration.c Mon Dec 13 14:49:42 2021 +0300 +++ b/src/event/quic/ngx_event_quic_migration.c Mon Dec 13 17:27:29 2021 +0300 @@ -158,7 +158,6 @@ "quic path #%uL successfully validated", path->seqnum); path->state = NGX_QUIC_PATH_VALIDATED; - path->validated_at = ngx_time(); return NGX_OK; } @@ -217,6 +216,7 @@ } path->seqnum = qc->path_seqnum++; + path->last_seen = ngx_current_msec; path->socklen = socklen; ngx_memcpy(path->sockaddr, sockaddr, socklen); @@ -272,6 +272,7 @@ ngx_quic_client_id_t *cid; ngx_quic_connection_t *qc; + qc = ngx_quic_get_connection(c); qsock = ngx_quic_get_socket(c); if (c->udp->dgram == NULL) { @@ -313,7 +314,6 @@ cid = ngx_quic_used_client_id(c, path); if (cid == NULL) { - qc = ngx_quic_get_connection(c); qc->error = NGX_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR; qc->error_reason = "no available client ids for new path"; @@ -328,6 +328,17 @@ update: + if (path->state != NGX_QUIC_PATH_NEW) { + /* 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->sent = 0; + path->received = 0; + } + } + + path->last_seen = ngx_current_msec; + len = pkt->raw->last - pkt->raw->start; /* TODO: this may be too late in some cases; @@ -396,31 +407,10 @@ qsock->sid.seqnum, qsock->cid->seqnum, next->seqnum, ngx_quic_path_state_str(next)); - switch (next->state) { - case NGX_QUIC_PATH_NEW: + if (next->state == NGX_QUIC_PATH_NEW) { if (ngx_quic_validate_path(c, qsock) != NGX_OK) { return NGX_ERROR; } - break; - - /* migration to previously known path */ - - case NGX_QUIC_PATH_VALIDATING: - /* alredy validating, nothing to do */ - break; - - case NGX_QUIC_PATH_VALIDATED: - /* if path is old enough, revalidate */ - if (ngx_time() - next->validated_at > NGX_QUIC_PATH_VALID_TIME) { - - next->state = NGX_QUIC_PATH_NEW; - - if (ngx_quic_validate_path(c, qsock) != NGX_OK) { - return NGX_ERROR; - } - } - - break; } ctx = ngx_quic_get_send_ctx(qc, pkt->level);
--- a/src/event/quic/ngx_event_quic_migration.h Mon Dec 13 14:49:42 2021 +0300 +++ b/src/event/quic/ngx_event_quic_migration.h Mon Dec 13 17:27:29 2021 +0300 @@ -17,8 +17,6 @@ #define NGX_QUIC_PATH_VALIDATING 1 #define NGX_QUIC_PATH_VALIDATED 2 -#define NGX_QUIC_PATH_VALID_TIME 600 /* seconds */ - #define ngx_quic_path_state_str(p) \ ((p)->state == NGX_QUIC_PATH_NEW) ? "new" : \
--- a/src/event/quic/ngx_event_quic_socket.c Mon Dec 13 14:49:42 2021 +0300 +++ b/src/event/quic/ngx_event_quic_socket.c Mon Dec 13 17:27:29 2021 +0300 @@ -82,7 +82,6 @@ if (pkt->validated) { path->state = NGX_QUIC_PATH_VALIDATED; - path->validated_at = ngx_time(); } /* now bind socket to client and path */