# HG changeset patch # User Sergey Kandaurov # Date 1590753993 -10800 # Node ID 6633f17044eb833eaffd6d6949aca143d0ef3589 # Parent 78e362f0b081ba46cbfd16cede59519a2323ab6c QUIC draft-28 transport parameters support. Draft-27 and draft-28 support can now be enabled interchangeably, it's based on the compile-time macro NGX_QUIC_DRAFT_VERSION. diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c --- a/src/event/ngx_event_quic.c +++ b/src/event/ngx_event_quic.c @@ -426,6 +426,17 @@ ngx_quic_add_handshake_data(ngx_ssl_conn return 0; } +#if (NGX_QUIC_DRAFT_VERSION >= 28) + if (qc->scid.len != qc->ctp.initial_scid.len + || ngx_memcmp(qc->scid.data, qc->ctp.initial_scid.data, + qc->scid.len) != 0) + { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "quic client initial_source_connection_id mismatch"); + return 0; + } +#endif + qc->client_tp_done = 1; } } @@ -641,6 +652,9 @@ ngx_quic_new_connection(ngx_connection_t return NGX_ERROR; } + qc->tp.original_dcid = c->quic->odcid; + qc->tp.initial_scid = c->quic->dcid; + qc->scid.len = pkt->scid.len; qc->scid.data = ngx_pnalloc(c->pool, qc->scid.len); if (qc->scid.data == NULL) { @@ -782,7 +796,7 @@ ngx_quic_retry(ngx_connection_t *c) } c->quic->token = token; - c->quic->tp.original_connection_id = c->quic->odcid; + c->quic->tp.retry_scid = c->quic->dcid; c->quic->in_retry = 1; return NGX_OK; @@ -1483,6 +1497,7 @@ ngx_quic_retry_input(ngx_connection_t *c } qc = c->quic; + qc->tp.initial_scid = c->quic->dcid; keys = &c->quic->keys[ssl_encryption_initial]; diff --git a/src/event/ngx_event_quic.h b/src/event/ngx_event_quic.h --- a/src/event/ngx_event_quic.h +++ b/src/event/ngx_event_quic.h @@ -12,6 +12,7 @@ #include +/* Supported drafts: 27, 28 */ #define NGX_QUIC_DRAFT_VERSION 27 #define NGX_QUIC_VERSION (0xff000000 + NGX_QUIC_DRAFT_VERSION) @@ -56,7 +57,9 @@ typedef struct { ngx_uint_t ack_delay_exponent; ngx_uint_t disable_active_migration; ngx_uint_t active_connection_id_limit; - ngx_str_t original_connection_id; + ngx_str_t original_dcid; + ngx_str_t initial_scid; + ngx_str_t retry_scid; ngx_flag_t retry; u_char token_key[32]; /* AES 256 */ diff --git a/src/event/ngx_event_quic_transport.c b/src/event/ngx_event_quic_transport.c --- a/src/event/ngx_event_quic_transport.c +++ b/src/event/ngx_event_quic_transport.c @@ -1354,6 +1354,10 @@ ngx_quic_parse_transport_param(u_char *p ngx_quic_tp_t *dst) { uint64_t varint; + ngx_str_t str; + + varint = 0; + ngx_str_null(&str); switch (id) { @@ -1383,6 +1387,12 @@ ngx_quic_parse_transport_param(u_char *p } break; + case NGX_QUIC_TP_INITIAL_SCID: + + str.len = end - p; + p = ngx_quic_read_bytes(p, end, str.len, &str.data); + break; + default: return NGX_DECLINED; } @@ -1433,6 +1443,10 @@ ngx_quic_parse_transport_param(u_char *p dst->active_connection_id_limit = varint; break; + case NGX_QUIC_TP_INITIAL_SCID: + dst->initial_scid = str; + break; + default: return NGX_ERROR; } @@ -1457,8 +1471,9 @@ ngx_quic_parse_transport_params(u_char * } switch (id) { - case NGX_QUIC_TP_ORIGINAL_CONNECTION_ID: + case NGX_QUIC_TP_ORIGINAL_DCID: case NGX_QUIC_TP_PREFERRED_ADDRESS: + case NGX_QUIC_TP_RETRY_SCID: case NGX_QUIC_TP_STATELESS_RESET_TOKEN: ngx_log_error(NGX_LOG_INFO, log, 0, "quic client sent forbidden transport param" @@ -1547,6 +1562,11 @@ ngx_quic_parse_transport_params(u_char * "quic tp active_connection_id_limit: %ui", tp->active_connection_id_limit); +#if (NGX_QUIC_DRAFT_VERSION >= 28) + ngx_quic_hexdump(log, "quic tp initial_source_connection_id:", + tp->initial_scid.data, tp->initial_scid.len); +#endif + return NGX_OK; } @@ -1650,9 +1670,17 @@ ngx_quic_create_transport_params(u_char len += ngx_quic_tp_len(NGX_QUIC_TP_MAX_IDLE_TIMEOUT, tp->max_idle_timeout); +#if (NGX_QUIC_DRAFT_VERSION >= 28) + len += ngx_quic_tp_strlen(NGX_QUIC_TP_ORIGINAL_DCID, tp->original_dcid); + len += ngx_quic_tp_strlen(NGX_QUIC_TP_INITIAL_SCID, tp->initial_scid); +#endif + if (tp->retry) { - len += ngx_quic_tp_strlen(NGX_QUIC_TP_ORIGINAL_CONNECTION_ID, - tp->original_connection_id); +#if (NGX_QUIC_DRAFT_VERSION >= 28) + len += ngx_quic_tp_strlen(NGX_QUIC_TP_RETRY_SCID, tp->retry_scid); +#else + len += ngx_quic_tp_strlen(NGX_QUIC_TP_ORIGINAL_DCID, tp->original_dcid); +#endif } if (pos == NULL) { @@ -1683,9 +1711,17 @@ ngx_quic_create_transport_params(u_char ngx_quic_tp_vint(NGX_QUIC_TP_MAX_IDLE_TIMEOUT, tp->max_idle_timeout); +#if (NGX_QUIC_DRAFT_VERSION >= 28) + ngx_quic_tp_str(NGX_QUIC_TP_ORIGINAL_DCID, tp->original_dcid); + ngx_quic_tp_str(NGX_QUIC_TP_INITIAL_SCID, tp->initial_scid); +#endif + if (tp->retry) { - ngx_quic_tp_str(NGX_QUIC_TP_ORIGINAL_CONNECTION_ID, - tp->original_connection_id); +#if (NGX_QUIC_DRAFT_VERSION >= 28) + ngx_quic_tp_str(NGX_QUIC_TP_RETRY_SCID, tp->retry_scid); +#else + ngx_quic_tp_str(NGX_QUIC_TP_ORIGINAL_DCID, tp->original_dcid); +#endif } return p - pos; diff --git a/src/event/ngx_event_quic_transport.h b/src/event/ngx_event_quic_transport.h --- a/src/event/ngx_event_quic_transport.h +++ b/src/event/ngx_event_quic_transport.h @@ -96,7 +96,7 @@ #define NGX_QUIC_ERR_LAST NGX_QUIC_ERR_CRYPTO_ERROR /* Transport parameters */ -#define NGX_QUIC_TP_ORIGINAL_CONNECTION_ID 0x00 +#define NGX_QUIC_TP_ORIGINAL_DCID 0x00 #define NGX_QUIC_TP_MAX_IDLE_TIMEOUT 0x01 #define NGX_QUIC_TP_STATELESS_RESET_TOKEN 0x02 #define NGX_QUIC_TP_MAX_UDP_PAYLOAD_SIZE 0x03 @@ -111,6 +111,8 @@ #define NGX_QUIC_TP_DISABLE_ACTIVE_MIGRATION 0x0C #define NGX_QUIC_TP_PREFERRED_ADDRESS 0x0D #define NGX_QUIC_TP_ACTIVE_CONNECTION_ID_LIMIT 0x0E +#define NGX_QUIC_TP_INITIAL_SCID 0x0F +#define NGX_QUIC_TP_RETRY_SCID 0x10 #define NGX_QUIC_CID_LEN_MIN 8 #define NGX_QUIC_CID_LEN_MAX 20 diff --git a/src/http/v3/ngx_http_v3_module.c b/src/http/v3/ngx_http_v3_module.c --- a/src/http/v3/ngx_http_v3_module.c +++ b/src/http/v3/ngx_http_v3_module.c @@ -245,7 +245,9 @@ ngx_http_v3_create_srv_conf(ngx_conf_t * /* * set by ngx_pcalloc(): - * v3cf->quic.original_connection_id = 0; + * v3cf->quic.original_dcid = { 0, NULL }; + * v3cf->quic.initial_scid = { 0, NULL }; + * v3cf->quic.retry_scid = { 0, NULL }; * v3cf->quic.stateless_reset_token = { 0 } * conf->quic.preferred_address = NULL */