mirror of
https://github.com/nginx/nginx.git
synced 2024-12-18 07:37:49 +08:00
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.
This commit is contained in:
parent
6e7f192804
commit
a31745499b
@ -86,6 +86,7 @@ struct ngx_quic_path_s {
|
||||
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 @@ struct ngx_quic_path_s {
|
||||
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];
|
||||
};
|
||||
|
@ -158,7 +158,6 @@ valid:
|
||||
"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 @@ ngx_quic_add_path(ngx_connection_t *c, struct sockaddr *sockaddr,
|
||||
}
|
||||
|
||||
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_update_paths(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
||||
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 @@ ngx_quic_update_paths(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
||||
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 @@ ngx_quic_update_paths(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
||||
|
||||
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 @@ ngx_quic_handle_migration(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
||||
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);
|
||||
|
@ -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" : \
|
||||
|
@ -82,7 +82,6 @@ ngx_quic_open_sockets(ngx_connection_t *c, ngx_quic_connection_t *qc,
|
||||
|
||||
if (pkt->validated) {
|
||||
path->state = NGX_QUIC_PATH_VALIDATED;
|
||||
path->validated_at = ngx_time();
|
||||
}
|
||||
|
||||
/* now bind socket to client and path */
|
||||
|
Loading…
Reference in New Issue
Block a user