mirror of
https://github.com/nginx/nginx.git
synced 2025-06-27 09:00:38 +08:00
QUIC: added stateless reset support.
The new "quic_stateless_reset_token_key" directive is added. It sets the endpoint key used to generate stateless reset tokens and enables feature. If the endpoint receives short-header packet that can't be matched to existing connection, a stateless reset packet is generated with a proper token. If a valid stateless reset token is found in the incoming packet, the connection is closed. Example configuration: http { quic_stateless_reset_token_key "foo"; ... }
This commit is contained in:
parent
2c3ada5722
commit
f797a8a5b5
@ -36,6 +36,16 @@
|
|||||||
|
|
||||||
#define NGX_QUIC_STREAM_GONE (void *) -1
|
#define NGX_QUIC_STREAM_GONE (void *) -1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Endpoints MUST discard packets that are too small to be valid QUIC
|
||||||
|
* packets. With the set of AEAD functions defined in [QUIC-TLS],
|
||||||
|
* packets that are smaller than 21 bytes are never valid.
|
||||||
|
*/
|
||||||
|
#define NGX_QUIC_MIN_PKT_LEN 21
|
||||||
|
|
||||||
|
#define NGX_QUIC_MIN_SR_PACKET 43 /* 5 random + 16 srt + 22 padding */
|
||||||
|
#define NGX_QUIC_MAX_SR_PACKET 1200
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_rbtree_t tree;
|
ngx_rbtree_t tree;
|
||||||
@ -154,7 +164,7 @@ typedef struct {
|
|||||||
uint64_t seqnum;
|
uint64_t seqnum;
|
||||||
size_t len;
|
size_t len;
|
||||||
u_char id[NGX_QUIC_CID_LEN_MAX];
|
u_char id[NGX_QUIC_CID_LEN_MAX];
|
||||||
u_char sr_token[NGX_QUIC_SRT_LEN];
|
u_char sr_token[NGX_QUIC_SR_TOKEN_LEN];
|
||||||
} ngx_quic_client_id_t;
|
} ngx_quic_client_id_t;
|
||||||
|
|
||||||
|
|
||||||
@ -184,6 +194,10 @@ static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn,
|
|||||||
|
|
||||||
static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c,
|
static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c,
|
||||||
ngx_ssl_t *ssl, ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
|
ngx_ssl_t *ssl, ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
|
||||||
|
static ngx_int_t ngx_quic_send_stateless_reset(ngx_connection_t *c,
|
||||||
|
ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
|
||||||
|
static ngx_int_t ngx_quic_process_stateless_reset(ngx_connection_t *c,
|
||||||
|
ngx_quic_header_t *pkt);
|
||||||
static ngx_int_t ngx_quic_negotiate_version(ngx_connection_t *c,
|
static ngx_int_t ngx_quic_negotiate_version(ngx_connection_t *c,
|
||||||
ngx_quic_header_t *inpkt);
|
ngx_quic_header_t *inpkt);
|
||||||
static ngx_int_t ngx_quic_new_dcid(ngx_connection_t *c,
|
static ngx_int_t ngx_quic_new_dcid(ngx_connection_t *c,
|
||||||
@ -757,6 +771,105 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_quic_send_stateless_reset(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
||||||
|
ngx_quic_header_t *pkt)
|
||||||
|
{
|
||||||
|
u_char *token;
|
||||||
|
size_t len, max;
|
||||||
|
uint16_t rndbytes;
|
||||||
|
u_char buf[NGX_QUIC_MAX_SR_PACKET];
|
||||||
|
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||||
|
"quic handle stateless reset output");
|
||||||
|
|
||||||
|
if (conf->sr_token_key.len == 0) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkt->len <= NGX_QUIC_MIN_PKT_LEN) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkt->len <= NGX_QUIC_MIN_SR_PACKET) {
|
||||||
|
len = pkt->len - 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
max = ngx_min(NGX_QUIC_MAX_SR_PACKET, pkt->len * 3);
|
||||||
|
|
||||||
|
if (RAND_bytes((u_char *) &rndbytes, sizeof(rndbytes)) != 1) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (rndbytes % (max - NGX_QUIC_MIN_SR_PACKET + 1))
|
||||||
|
+ NGX_QUIC_MIN_SR_PACKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RAND_bytes(buf, len - NGX_QUIC_SR_TOKEN_LEN) != 1) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] &= ~NGX_QUIC_PKT_LONG;
|
||||||
|
buf[0] |= NGX_QUIC_PKT_FIXED_BIT;
|
||||||
|
|
||||||
|
token = &buf[len - NGX_QUIC_SR_TOKEN_LEN];
|
||||||
|
|
||||||
|
if (ngx_quic_new_sr_token(c, &pkt->dcid, &conf->sr_token_key, token)
|
||||||
|
!= NGX_OK)
|
||||||
|
{
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) c->send(c, buf, len);
|
||||||
|
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_quic_process_stateless_reset(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
||||||
|
{
|
||||||
|
u_char *tail, ch;
|
||||||
|
ngx_uint_t i;
|
||||||
|
ngx_queue_t *q;
|
||||||
|
ngx_quic_client_id_t *cid;
|
||||||
|
ngx_quic_connection_t *qc;
|
||||||
|
|
||||||
|
qc = c->quic;
|
||||||
|
|
||||||
|
/* A stateless reset uses an entire UDP datagram */
|
||||||
|
if (pkt->raw->start != pkt->data) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
tail = pkt->raw->last - NGX_QUIC_SR_TOKEN_LEN;
|
||||||
|
|
||||||
|
for (q = ngx_queue_head(&qc->client_ids);
|
||||||
|
q != ngx_queue_sentinel(&qc->client_ids);
|
||||||
|
q = ngx_queue_next(q))
|
||||||
|
{
|
||||||
|
cid = ngx_queue_data(q, ngx_quic_client_id_t, queue);
|
||||||
|
|
||||||
|
if (cid->seqnum == 0) {
|
||||||
|
/* no stateless reset token in initial connection id */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* constant time comparison */
|
||||||
|
|
||||||
|
for (ch = 0, i = 0; i < NGX_QUIC_SR_TOKEN_LEN; i++) {
|
||||||
|
ch |= tail[i] ^ cid->sr_token[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == 0) {
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_quic_negotiate_version(ngx_connection_t *c, ngx_quic_header_t *inpkt)
|
ngx_quic_negotiate_version(ngx_connection_t *c, ngx_quic_header_t *inpkt)
|
||||||
{
|
{
|
||||||
@ -1116,6 +1229,20 @@ ngx_quic_init_connection(ngx_connection_t *c)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (qc->conf->sr_token_key.len) {
|
||||||
|
qc->tp.sr_enabled = 1;
|
||||||
|
|
||||||
|
if (ngx_quic_new_sr_token(c, &qc->dcid, &qc->conf->sr_token_key,
|
||||||
|
qc->tp.sr_token)
|
||||||
|
!= NGX_OK)
|
||||||
|
{
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_quic_hexdump(c->log, "quic stateless reset token",
|
||||||
|
qc->tp.sr_token, NGX_QUIC_SR_TOKEN_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
len = ngx_quic_create_transport_params(NULL, NULL, &qc->tp, &clen);
|
len = ngx_quic_create_transport_params(NULL, NULL, &qc->tp, &clen);
|
||||||
/* always succeeds */
|
/* always succeeds */
|
||||||
|
|
||||||
@ -1578,6 +1705,21 @@ ngx_quic_process_packet(ngx_connection_t *c, ngx_ssl_t *ssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_quic_check_peer(qc, pkt) != NGX_OK) {
|
if (ngx_quic_check_peer(qc, pkt) != NGX_OK) {
|
||||||
|
|
||||||
|
if (pkt->level == ssl_encryption_application) {
|
||||||
|
if (ngx_quic_process_stateless_reset(c, pkt) == NGX_OK) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
|
"quic stateless reset packet detected");
|
||||||
|
|
||||||
|
qc->draining = 1;
|
||||||
|
ngx_quic_close_connection(c, NGX_OK);
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ngx_quic_send_stateless_reset(c, qc->conf, pkt);
|
||||||
|
}
|
||||||
|
|
||||||
return NGX_DECLINED;
|
return NGX_DECLINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1655,7 +1797,7 @@ ngx_quic_process_packet(ngx_connection_t *c, ngx_ssl_t *ssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (pkt->level == ssl_encryption_application) {
|
} else if (pkt->level == ssl_encryption_application) {
|
||||||
return NGX_DECLINED;
|
return ngx_quic_send_stateless_reset(c, conf, pkt);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
@ -3337,7 +3479,7 @@ ngx_quic_handle_new_connection_id_frame(ngx_connection_t *c,
|
|||||||
|
|
||||||
if (cid->len != f->len
|
if (cid->len != f->len
|
||||||
|| ngx_strncmp(cid->id, f->cid, f->len) != 0
|
|| ngx_strncmp(cid->id, f->cid, f->len) != 0
|
||||||
|| ngx_strncmp(cid->sr_token, f->srt, NGX_QUIC_SRT_LEN) != 0)
|
|| ngx_strncmp(cid->sr_token, f->srt, NGX_QUIC_SR_TOKEN_LEN) != 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* ..a sequence number is used for different connection IDs,
|
* ..a sequence number is used for different connection IDs,
|
||||||
@ -3360,7 +3502,7 @@ ngx_quic_handle_new_connection_id_frame(ngx_connection_t *c,
|
|||||||
cid->len = f->len;
|
cid->len = f->len;
|
||||||
ngx_memcpy(cid->id, f->cid, f->len);
|
ngx_memcpy(cid->id, f->cid, f->len);
|
||||||
|
|
||||||
ngx_memcpy(cid->sr_token, f->srt, NGX_QUIC_SRT_LEN);
|
ngx_memcpy(cid->sr_token, f->srt, NGX_QUIC_SR_TOKEN_LEN);
|
||||||
|
|
||||||
ngx_queue_insert_tail(&qc->client_ids, &cid->queue);
|
ngx_queue_insert_tail(&qc->client_ids, &cid->queue);
|
||||||
qc->nclient_ids++;
|
qc->nclient_ids++;
|
||||||
|
@ -56,6 +56,8 @@
|
|||||||
|
|
||||||
#define NGX_QUIC_SERVER_CID_LEN 20
|
#define NGX_QUIC_SERVER_CID_LEN 20
|
||||||
|
|
||||||
|
#define NGX_QUIC_SR_TOKEN_LEN 16
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* configurable */
|
/* configurable */
|
||||||
@ -75,9 +77,10 @@ typedef struct {
|
|||||||
ngx_str_t original_dcid;
|
ngx_str_t original_dcid;
|
||||||
ngx_str_t initial_scid;
|
ngx_str_t initial_scid;
|
||||||
ngx_str_t retry_scid;
|
ngx_str_t retry_scid;
|
||||||
|
u_char sr_token[NGX_QUIC_SR_TOKEN_LEN];
|
||||||
|
ngx_uint_t sr_enabled;
|
||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
u_char stateless_reset_token[16];
|
|
||||||
void *preferred_address;
|
void *preferred_address;
|
||||||
} ngx_quic_tp_t;
|
} ngx_quic_tp_t;
|
||||||
|
|
||||||
@ -87,6 +90,7 @@ typedef struct {
|
|||||||
ngx_flag_t retry;
|
ngx_flag_t retry;
|
||||||
ngx_flag_t require_alpn;
|
ngx_flag_t require_alpn;
|
||||||
u_char token_key[32]; /* AES 256 */
|
u_char token_key[32]; /* AES 256 */
|
||||||
|
ngx_str_t sr_token_key; /* stateless reset token key */
|
||||||
} ngx_quic_conf_t;
|
} ngx_quic_conf_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -923,6 +923,62 @@ ngx_quic_create_retry_packet(ngx_quic_header_t *pkt, ngx_str_t *res)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ngx_int_t
|
||||||
|
ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, ngx_str_t *secret,
|
||||||
|
u_char *token)
|
||||||
|
{
|
||||||
|
uint8_t *p;
|
||||||
|
size_t is_len, key_len, info_len;
|
||||||
|
ngx_str_t label;
|
||||||
|
const EVP_MD *digest;
|
||||||
|
uint8_t info[20];
|
||||||
|
uint8_t is[SHA256_DIGEST_LENGTH];
|
||||||
|
uint8_t key[SHA256_DIGEST_LENGTH];
|
||||||
|
|
||||||
|
/* 10.4.2. Calculating a Stateless Reset Token */
|
||||||
|
|
||||||
|
digest = EVP_sha256();
|
||||||
|
ngx_str_set(&label, "sr_token_key");
|
||||||
|
|
||||||
|
if (ngx_hkdf_extract(is, &is_len, digest, secret->data, secret->len,
|
||||||
|
cid->data, cid->len)
|
||||||
|
!= NGX_OK)
|
||||||
|
{
|
||||||
|
ngx_ssl_error(NGX_LOG_INFO, c->log, 0,
|
||||||
|
"ngx_hkdf_extract(%V) failed", &label);
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_len = SHA256_DIGEST_LENGTH;
|
||||||
|
|
||||||
|
info_len = 2 + 1 + label.len + 1;
|
||||||
|
|
||||||
|
info[0] = 0;
|
||||||
|
info[1] = key_len;
|
||||||
|
info[2] = label.len;
|
||||||
|
|
||||||
|
p = ngx_cpymem(&info[3], label.data, label.len);
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
if (ngx_hkdf_expand(key, key_len, digest, is, is_len, info, info_len)
|
||||||
|
!= NGX_OK)
|
||||||
|
{
|
||||||
|
ngx_ssl_error(NGX_LOG_INFO, c->log, 0,
|
||||||
|
"ngx_hkdf_expand(%V) failed", &label);
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_memcpy(token, key, NGX_QUIC_SR_TOKEN_LEN);
|
||||||
|
|
||||||
|
#if (NGX_DEBUG)
|
||||||
|
ngx_quic_hexdump(c->log, "quic stateless reset token", token,
|
||||||
|
NGX_QUIC_SR_TOKEN_LEN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask,
|
ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask,
|
||||||
uint64_t *largest_pn)
|
uint64_t *largest_pn)
|
||||||
|
@ -39,6 +39,8 @@ int ngx_quic_set_encryption_secret(ngx_pool_t *pool, ngx_ssl_conn_t *ssl_conn,
|
|||||||
|
|
||||||
ngx_int_t ngx_quic_key_update(ngx_connection_t *c,
|
ngx_int_t ngx_quic_key_update(ngx_connection_t *c,
|
||||||
ngx_quic_secrets_t *current, ngx_quic_secrets_t *next);
|
ngx_quic_secrets_t *current, ngx_quic_secrets_t *next);
|
||||||
|
ngx_int_t ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid,
|
||||||
|
ngx_str_t *key, u_char *token);
|
||||||
|
|
||||||
ngx_int_t ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
|
ngx_int_t ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
|
||||||
ngx_str_t *res);
|
ngx_str_t *res);
|
||||||
|
@ -774,7 +774,7 @@ ngx_quic_parse_frame(ngx_quic_header_t *pkt, u_char *start, u_char *end,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = ngx_quic_copy_bytes(p, end, NGX_QUIC_SRT_LEN, f->u.ncid.srt);
|
p = ngx_quic_copy_bytes(p, end, NGX_QUIC_SR_TOKEN_LEN, f->u.ncid.srt);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -1553,7 +1553,7 @@ ngx_quic_parse_transport_params(u_char *p, u_char *end, ngx_quic_tp_t *tp,
|
|||||||
case NGX_QUIC_TP_ORIGINAL_DCID:
|
case NGX_QUIC_TP_ORIGINAL_DCID:
|
||||||
case NGX_QUIC_TP_PREFERRED_ADDRESS:
|
case NGX_QUIC_TP_PREFERRED_ADDRESS:
|
||||||
case NGX_QUIC_TP_RETRY_SCID:
|
case NGX_QUIC_TP_RETRY_SCID:
|
||||||
case NGX_QUIC_TP_STATELESS_RESET_TOKEN:
|
case NGX_QUIC_TP_SR_TOKEN:
|
||||||
ngx_log_error(NGX_LOG_INFO, log, 0,
|
ngx_log_error(NGX_LOG_INFO, log, 0,
|
||||||
"quic client sent forbidden transport param"
|
"quic client sent forbidden transport param"
|
||||||
" id 0x%xL", id);
|
" id 0x%xL", id);
|
||||||
@ -1810,6 +1810,12 @@ ngx_quic_create_transport_params(u_char *pos, u_char *end, ngx_quic_tp_t *tp,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (tp->sr_enabled) {
|
||||||
|
len += ngx_quic_varint_len(NGX_QUIC_TP_SR_TOKEN);
|
||||||
|
len += ngx_quic_varint_len(NGX_QUIC_SR_TOKEN_LEN);
|
||||||
|
len += NGX_QUIC_SR_TOKEN_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
if (pos == NULL) {
|
if (pos == NULL) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -1851,6 +1857,12 @@ ngx_quic_create_transport_params(u_char *pos, u_char *end, ngx_quic_tp_t *tp,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (tp->sr_enabled) {
|
||||||
|
ngx_quic_build_int(&p, NGX_QUIC_TP_SR_TOKEN);
|
||||||
|
ngx_quic_build_int(&p, NGX_QUIC_SR_TOKEN_LEN);
|
||||||
|
p = ngx_cpymem(p, tp->sr_token, NGX_QUIC_SR_TOKEN_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
return p - pos;
|
return p - pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@
|
|||||||
/* Transport parameters */
|
/* Transport parameters */
|
||||||
#define NGX_QUIC_TP_ORIGINAL_DCID 0x00
|
#define NGX_QUIC_TP_ORIGINAL_DCID 0x00
|
||||||
#define NGX_QUIC_TP_MAX_IDLE_TIMEOUT 0x01
|
#define NGX_QUIC_TP_MAX_IDLE_TIMEOUT 0x01
|
||||||
#define NGX_QUIC_TP_STATELESS_RESET_TOKEN 0x02
|
#define NGX_QUIC_TP_SR_TOKEN 0x02
|
||||||
#define NGX_QUIC_TP_MAX_UDP_PAYLOAD_SIZE 0x03
|
#define NGX_QUIC_TP_MAX_UDP_PAYLOAD_SIZE 0x03
|
||||||
#define NGX_QUIC_TP_INITIAL_MAX_DATA 0x04
|
#define NGX_QUIC_TP_INITIAL_MAX_DATA 0x04
|
||||||
#define NGX_QUIC_TP_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL 0x05
|
#define NGX_QUIC_TP_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL 0x05
|
||||||
@ -120,9 +120,6 @@
|
|||||||
#define NGX_QUIC_CID_LEN_MIN 8
|
#define NGX_QUIC_CID_LEN_MIN 8
|
||||||
#define NGX_QUIC_CID_LEN_MAX 20
|
#define NGX_QUIC_CID_LEN_MAX 20
|
||||||
|
|
||||||
#define NGX_QUIC_SRT_LEN 16
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t largest;
|
uint64_t largest;
|
||||||
uint64_t delay;
|
uint64_t delay;
|
||||||
@ -141,7 +138,7 @@ typedef struct {
|
|||||||
uint64_t retire;
|
uint64_t retire;
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
u_char cid[NGX_QUIC_CID_LEN_MAX];
|
u_char cid[NGX_QUIC_CID_LEN_MAX];
|
||||||
u_char srt[NGX_QUIC_SRT_LEN];
|
u_char srt[NGX_QUIC_SR_TOKEN_LEN];
|
||||||
} ngx_quic_new_conn_id_frame_t;
|
} ngx_quic_new_conn_id_frame_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,6 +125,13 @@ static ngx_command_t ngx_http_quic_commands[] = {
|
|||||||
offsetof(ngx_quic_conf_t, retry),
|
offsetof(ngx_quic_conf_t, retry),
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
|
{ ngx_string("quic_stateless_reset_token_key"),
|
||||||
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||||
|
ngx_conf_set_str_slot,
|
||||||
|
NGX_HTTP_SRV_CONF_OFFSET,
|
||||||
|
offsetof(ngx_quic_conf_t, sr_token_key),
|
||||||
|
NULL },
|
||||||
|
|
||||||
ngx_null_command
|
ngx_null_command
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -223,8 +230,10 @@ ngx_http_quic_create_srv_conf(ngx_conf_t *cf)
|
|||||||
* conf->tp.original_dcid = { 0, NULL };
|
* conf->tp.original_dcid = { 0, NULL };
|
||||||
* conf->tp.initial_scid = { 0, NULL };
|
* conf->tp.initial_scid = { 0, NULL };
|
||||||
* conf->tp.retry_scid = { 0, NULL };
|
* conf->tp.retry_scid = { 0, NULL };
|
||||||
* conf->tp.stateless_reset_token = { 0 }
|
* conf->tp.sr_token = { 0 }
|
||||||
|
* conf->tp.sr_enabled = 0
|
||||||
* conf->tp.preferred_address = NULL
|
* conf->tp.preferred_address = NULL
|
||||||
|
* conf->sr_token_key = { 0, NULL }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
conf->tp.max_idle_timeout = NGX_CONF_UNSET_MSEC;
|
conf->tp.max_idle_timeout = NGX_CONF_UNSET_MSEC;
|
||||||
@ -304,6 +313,8 @@ ngx_http_quic_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngx_conf_merge_str_value(conf->sr_token_key, prev->sr_token_key, "");
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user