mirror of
https://github.com/nginx/nginx.git
synced 2024-12-04 13:59:00 +08:00
QUIC: connection multiplexing per port.
Also, connection migration within a single worker is implemented.
This commit is contained in:
parent
d889cff0e5
commit
1be6d80089
@ -167,6 +167,18 @@ struct ngx_event_aio_s {
|
||||
#endif
|
||||
|
||||
|
||||
#if !(NGX_WIN32)
|
||||
|
||||
struct ngx_udp_connection_s {
|
||||
ngx_rbtree_node_t node;
|
||||
ngx_connection_t *connection;
|
||||
ngx_str_t key;
|
||||
ngx_buf_t *buffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
|
||||
ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
|
||||
@ -501,6 +513,8 @@ void ngx_event_accept(ngx_event_t *ev);
|
||||
void ngx_event_recvmsg(ngx_event_t *ev);
|
||||
void ngx_udp_rbtree_insert_value(ngx_rbtree_node_t *temp,
|
||||
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
|
||||
void ngx_insert_udp_connection(ngx_connection_t *c, ngx_udp_connection_t *udp,
|
||||
ngx_str_t *key);
|
||||
#endif
|
||||
void ngx_delete_udp_connection(void *data);
|
||||
ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle);
|
||||
|
@ -121,11 +121,18 @@ struct ngx_quic_connection_s {
|
||||
ngx_str_t odcid; /* original server ID */
|
||||
ngx_str_t token;
|
||||
|
||||
struct sockaddr *sockaddr;
|
||||
socklen_t socklen;
|
||||
|
||||
ngx_queue_t client_ids;
|
||||
ngx_queue_t server_ids;
|
||||
ngx_queue_t free_client_ids;
|
||||
ngx_queue_t free_server_ids;
|
||||
ngx_uint_t nclient_ids;
|
||||
ngx_uint_t nserver_ids;
|
||||
uint64_t max_retired_seqnum;
|
||||
uint64_t client_seqnum;
|
||||
uint64_t server_seqnum;
|
||||
|
||||
ngx_uint_t client_tp_done;
|
||||
ngx_quic_tp_t tp;
|
||||
@ -185,6 +192,15 @@ typedef struct {
|
||||
} ngx_quic_client_id_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_udp_connection_t udp;
|
||||
ngx_queue_t queue;
|
||||
uint64_t seqnum;
|
||||
size_t len;
|
||||
u_char id[NGX_QUIC_CID_LEN_MAX];
|
||||
} ngx_quic_server_id_t;
|
||||
|
||||
|
||||
typedef ngx_int_t (*ngx_quic_frame_handler_pt)(ngx_connection_t *c,
|
||||
ngx_quic_frame_t *frame, void *data);
|
||||
|
||||
@ -217,8 +233,7 @@ 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,
|
||||
ngx_quic_header_t *inpkt);
|
||||
static ngx_int_t ngx_quic_new_dcid(ngx_connection_t *c,
|
||||
ngx_quic_connection_t *qc, ngx_str_t *odcid);
|
||||
static ngx_int_t ngx_quic_create_server_id(ngx_connection_t *c, u_char *id);
|
||||
static ngx_int_t ngx_quic_send_retry(ngx_connection_t *c);
|
||||
static ngx_int_t ngx_quic_new_token(ngx_connection_t *c, ngx_str_t *token);
|
||||
static ngx_int_t ngx_quic_validate_token(ngx_connection_t *c,
|
||||
@ -304,8 +319,16 @@ static ngx_int_t ngx_quic_handle_new_connection_id_frame(ngx_connection_t *c,
|
||||
ngx_quic_header_t *pkt, ngx_quic_new_conn_id_frame_t *f);
|
||||
static ngx_int_t ngx_quic_retire_connection_id(ngx_connection_t *c,
|
||||
enum ssl_encryption_level_t level, uint64_t seqnum);
|
||||
static ngx_int_t ngx_quic_handle_retire_connection_id_frame(ngx_connection_t *c,
|
||||
ngx_quic_header_t *pkt, ngx_quic_retire_cid_frame_t *f);
|
||||
static ngx_int_t ngx_quic_issue_server_ids(ngx_connection_t *c);
|
||||
static void ngx_quic_clear_temp_server_ids(ngx_connection_t *c);
|
||||
static ngx_quic_server_id_t *ngx_quic_insert_server_id(ngx_connection_t *c,
|
||||
ngx_str_t *id);
|
||||
static ngx_quic_client_id_t *ngx_quic_alloc_client_id(ngx_connection_t *c,
|
||||
ngx_quic_connection_t *qc);
|
||||
static ngx_quic_server_id_t *ngx_quic_alloc_server_id(ngx_connection_t *c,
|
||||
ngx_quic_connection_t *qc);
|
||||
|
||||
static void ngx_quic_queue_frame(ngx_quic_connection_t *qc,
|
||||
ngx_quic_frame_t *frame);
|
||||
@ -439,7 +462,8 @@ ngx_quic_log_frame(ngx_log_t *log, ngx_quic_frame_t *f, ngx_uint_t tx)
|
||||
break;
|
||||
|
||||
case NGX_QUIC_FT_NEW_CONNECTION_ID:
|
||||
p = ngx_slprintf(p, last, "NCID seq:%uL retire:%uL len:%ud",
|
||||
p = ngx_slprintf(p, last,
|
||||
"NEW_CONNECTION_ID seq:%uL retire:%uL len:%ud",
|
||||
f->u.ncid.seqnum, f->u.ncid.retire, f->u.ncid.len);
|
||||
break;
|
||||
|
||||
@ -983,7 +1007,9 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
||||
|
||||
ngx_queue_init(&qc->free_frames);
|
||||
ngx_queue_init(&qc->client_ids);
|
||||
ngx_queue_init(&qc->server_ids);
|
||||
ngx_queue_init(&qc->free_client_ids);
|
||||
ngx_queue_init(&qc->free_server_ids);
|
||||
|
||||
qc->avg_rtt = NGX_QUIC_INITIAL_RTT;
|
||||
qc->rttvar = NGX_QUIC_INITIAL_RTT / 2;
|
||||
@ -992,6 +1018,7 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
||||
/*
|
||||
* qc->latest_rtt = 0
|
||||
* qc->nclient_ids = 0
|
||||
* qc->nserver_ids = 0
|
||||
* qc->max_retired_seqnum = 0
|
||||
*/
|
||||
|
||||
@ -1010,6 +1037,16 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
||||
qc->conf = conf;
|
||||
qc->tp = conf->tp;
|
||||
|
||||
if (qc->tp.disable_active_migration) {
|
||||
qc->sockaddr = ngx_palloc(c->pool, c->socklen);
|
||||
if (qc->sockaddr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ngx_memcpy(qc->sockaddr, c->sockaddr, c->socklen);
|
||||
qc->socklen = c->socklen;
|
||||
}
|
||||
|
||||
ctp = &qc->ctp;
|
||||
ctp->max_udp_payload_size = ngx_quic_max_udp_payload(c);
|
||||
ctp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT;
|
||||
@ -1026,7 +1063,19 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
||||
qc->congestion.ssthresh = (size_t) -1;
|
||||
qc->congestion.recovery_start = ngx_current_msec;
|
||||
|
||||
if (ngx_quic_new_dcid(c, qc, &pkt->dcid) != NGX_OK) {
|
||||
qc->odcid.len = pkt->dcid.len;
|
||||
qc->odcid.data = ngx_pstrdup(c->pool, &pkt->dcid);
|
||||
if (qc->odcid.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qc->dcid.len = NGX_QUIC_SERVER_CID_LEN;
|
||||
qc->dcid.data = ngx_pnalloc(c->pool, qc->dcid.len);
|
||||
if (qc->dcid.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ngx_quic_create_server_id(c, qc->dcid.data) != NGX_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1055,6 +1104,8 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
||||
qc->nclient_ids++;
|
||||
qc->client_seqnum = 0;
|
||||
|
||||
qc->server_seqnum = NGX_QUIC_UNSET_PN;
|
||||
|
||||
return qc;
|
||||
}
|
||||
|
||||
@ -1186,26 +1237,14 @@ ngx_quic_negotiate_version(ngx_connection_t *c, ngx_quic_header_t *inpkt)
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_quic_new_dcid(ngx_connection_t *c, ngx_quic_connection_t *qc,
|
||||
ngx_str_t *odcid)
|
||||
ngx_quic_create_server_id(ngx_connection_t *c, u_char *id)
|
||||
{
|
||||
qc->dcid.len = NGX_QUIC_SERVER_CID_LEN;
|
||||
qc->dcid.data = ngx_pnalloc(c->pool, NGX_QUIC_SERVER_CID_LEN);
|
||||
if (qc->dcid.data == NULL) {
|
||||
if (RAND_bytes(id, NGX_QUIC_SERVER_CID_LEN) != 1) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (RAND_bytes(qc->dcid.data, NGX_QUIC_SERVER_CID_LEN) != 1) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_quic_hexdump(c->log, "quic server CID", qc->dcid.data, qc->dcid.len);
|
||||
|
||||
qc->odcid.len = odcid->len;
|
||||
qc->odcid.data = ngx_pstrdup(c->pool, odcid);
|
||||
if (qc->odcid.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
ngx_quic_hexdump(c->log, "quic create server id",
|
||||
id, NGX_QUIC_SERVER_CID_LEN);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
@ -1254,6 +1293,10 @@ ngx_quic_send_retry(ngx_connection_t *c)
|
||||
c->quic->tp.retry_scid = c->quic->dcid;
|
||||
c->quic->in_retry = 1;
|
||||
|
||||
if (ngx_quic_insert_server_id(c, &c->quic->dcid) == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -1629,6 +1672,16 @@ ngx_quic_input_handler(ngx_event_t *rev)
|
||||
return;
|
||||
}
|
||||
|
||||
if (qc->tp.disable_active_migration) {
|
||||
if (c->socklen != qc->socklen
|
||||
|| ngx_memcmp(c->sockaddr, qc->sockaddr, c->socklen) != 0)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic dropping packet from new address");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
b.last += n;
|
||||
qc->received += n;
|
||||
|
||||
@ -1694,7 +1747,9 @@ static ngx_int_t
|
||||
ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_queue_t *q;
|
||||
ngx_quic_send_ctx_t *ctx;
|
||||
ngx_quic_server_id_t *sid;
|
||||
ngx_quic_connection_t *qc;
|
||||
|
||||
qc = c->quic;
|
||||
@ -1801,6 +1856,15 @@ ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc)
|
||||
ngx_quic_free_frames(c, &qc->send_ctx[i].sent);
|
||||
}
|
||||
|
||||
while (!ngx_queue_empty(&qc->server_ids)) {
|
||||
q = ngx_queue_head(&qc->server_ids);
|
||||
sid = ngx_queue_data(q, ngx_quic_server_id_t, queue);
|
||||
|
||||
ngx_queue_remove(q);
|
||||
ngx_rbtree_delete(&c->listening->rbtree, &sid->udp.node);
|
||||
qc->nserver_ids--;
|
||||
}
|
||||
|
||||
if (qc->close.timer_set) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
@ -2065,7 +2129,21 @@ ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
if (ngx_quic_new_dcid(c, qc, &pkt->dcid) != NGX_OK) {
|
||||
qc->odcid.len = pkt->dcid.len;
|
||||
qc->odcid.data = ngx_pstrdup(c->pool, &pkt->dcid);
|
||||
if (qc->odcid.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_quic_clear_temp_server_ids(c);
|
||||
|
||||
if (ngx_quic_create_server_id(c, qc->dcid.data) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
qc->server_seqnum = 0;
|
||||
|
||||
if (ngx_quic_insert_server_id(c, &qc->dcid) == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@ -2137,6 +2215,16 @@ ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_quic_insert_server_id(c, &qc->odcid) == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
qc->server_seqnum = 0;
|
||||
|
||||
if (ngx_quic_insert_server_id(c, &qc->dcid) == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
} else if (pkt->level == ssl_encryption_application) {
|
||||
return ngx_quic_send_stateless_reset(c, conf, pkt);
|
||||
|
||||
@ -2270,6 +2358,10 @@ ngx_quic_discard_ctx(ngx_connection_t *c, enum ssl_encryption_level_t level)
|
||||
ngx_quic_free_frame(c, f);
|
||||
}
|
||||
|
||||
if (level == ssl_encryption_initial) {
|
||||
ngx_quic_clear_temp_server_ids(c);
|
||||
}
|
||||
|
||||
ctx->send_ack = 0;
|
||||
}
|
||||
|
||||
@ -2277,44 +2369,13 @@ ngx_quic_discard_ctx(ngx_connection_t *c, enum ssl_encryption_level_t level)
|
||||
static ngx_int_t
|
||||
ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt)
|
||||
{
|
||||
ngx_str_t *dcid;
|
||||
ngx_queue_t *q;
|
||||
ngx_quic_send_ctx_t *ctx;
|
||||
ngx_quic_client_id_t *cid;
|
||||
|
||||
dcid = (pkt->level == ssl_encryption_early_data) ? &qc->odcid : &qc->dcid;
|
||||
|
||||
if (pkt->dcid.len == dcid->len
|
||||
&& ngx_memcmp(pkt->dcid.data, dcid->data, dcid->len) == 0)
|
||||
{
|
||||
if (pkt->level == ssl_encryption_application) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
goto found;
|
||||
if (pkt->level == ssl_encryption_application) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* a packet sent in response to an initial client packet might be lost,
|
||||
* thus check also for old dcid
|
||||
*/
|
||||
ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_initial);
|
||||
|
||||
if (pkt->level == ssl_encryption_initial
|
||||
&& ctx->largest_ack == NGX_QUIC_UNSET_PN)
|
||||
{
|
||||
if (pkt->dcid.len == qc->odcid.len
|
||||
&& ngx_memcmp(pkt->dcid.data, qc->odcid.data, qc->odcid.len) == 0)
|
||||
{
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic dcid");
|
||||
return NGX_ERROR;
|
||||
|
||||
found:
|
||||
|
||||
for (q = ngx_queue_head(&qc->client_ids);
|
||||
q != ngx_queue_sentinel(&qc->client_ids);
|
||||
q = ngx_queue_next(q))
|
||||
@ -2533,6 +2594,16 @@ ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
||||
break;
|
||||
|
||||
case NGX_QUIC_FT_RETIRE_CONNECTION_ID:
|
||||
|
||||
if (ngx_quic_handle_retire_connection_id_frame(c, pkt,
|
||||
&frame.u.retire_cid)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NGX_QUIC_FT_PATH_RESPONSE:
|
||||
|
||||
/* TODO: handle */
|
||||
@ -3638,6 +3709,10 @@ ngx_quic_crypto_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data)
|
||||
*/
|
||||
ngx_quic_discard_ctx(c, ssl_encryption_handshake);
|
||||
|
||||
if (ngx_quic_issue_server_ids(c) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -4265,6 +4340,173 @@ ngx_quic_retire_connection_id(ngx_connection_t *c,
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_quic_handle_retire_connection_id_frame(ngx_connection_t *c,
|
||||
ngx_quic_header_t *pkt, ngx_quic_retire_cid_frame_t *f)
|
||||
{
|
||||
ngx_queue_t *q;
|
||||
ngx_quic_server_id_t *sid;
|
||||
ngx_quic_connection_t *qc;
|
||||
|
||||
qc = c->quic;
|
||||
|
||||
for (q = ngx_queue_head(&qc->server_ids);
|
||||
q != ngx_queue_sentinel(&qc->server_ids);
|
||||
q = ngx_queue_next(q))
|
||||
{
|
||||
sid = ngx_queue_data(q, ngx_quic_server_id_t, queue);
|
||||
|
||||
if (sid->seqnum == f->sequence_number) {
|
||||
ngx_queue_remove(q);
|
||||
ngx_rbtree_delete(&c->listening->rbtree, &sid->udp.node);
|
||||
qc->nserver_ids--;
|
||||
|
||||
if (c->udp != &sid->udp) {
|
||||
ngx_queue_insert_tail(&qc->free_server_ids, &sid->queue);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ngx_quic_issue_server_ids(c);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_quic_issue_server_ids(ngx_connection_t *c)
|
||||
{
|
||||
ngx_str_t dcid;
|
||||
ngx_uint_t n;
|
||||
ngx_quic_frame_t *frame;
|
||||
ngx_quic_server_id_t *sid;
|
||||
ngx_quic_connection_t *qc;
|
||||
u_char id[NGX_QUIC_SERVER_CID_LEN];
|
||||
|
||||
qc = c->quic;
|
||||
|
||||
n = ngx_min(NGX_QUIC_MAX_SERVER_IDS, qc->ctp.active_connection_id_limit);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic issue server ids has:%ui max:%ui", qc->nserver_ids, n);
|
||||
|
||||
while (qc->nserver_ids < n) {
|
||||
if (ngx_quic_create_server_id(c, id) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
dcid.len = NGX_QUIC_SERVER_CID_LEN;
|
||||
dcid.data = id;
|
||||
|
||||
sid = ngx_quic_insert_server_id(c, &dcid);
|
||||
if (sid == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
frame = ngx_quic_alloc_frame(c, 0);
|
||||
if (frame == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
frame->level = ssl_encryption_application;
|
||||
frame->type = NGX_QUIC_FT_NEW_CONNECTION_ID;
|
||||
frame->u.ncid.seqnum = sid->seqnum;
|
||||
frame->u.ncid.retire = 0;
|
||||
frame->u.ncid.len = NGX_QUIC_SERVER_CID_LEN;
|
||||
ngx_memcpy(frame->u.ncid.cid, id, NGX_QUIC_SERVER_CID_LEN);
|
||||
|
||||
if (ngx_quic_new_sr_token(c, &dcid, &qc->conf->sr_token_key,
|
||||
frame->u.ncid.srt)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_quic_queue_frame(c->quic, frame);
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_quic_clear_temp_server_ids(ngx_connection_t *c)
|
||||
{
|
||||
ngx_queue_t *q, *next;
|
||||
ngx_quic_server_id_t *sid;
|
||||
ngx_quic_connection_t *qc;
|
||||
|
||||
qc = c->quic;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic clear temp server ids");
|
||||
|
||||
for (q = ngx_queue_head(&qc->server_ids);
|
||||
q != ngx_queue_sentinel(&qc->server_ids);
|
||||
q = next)
|
||||
{
|
||||
next = ngx_queue_next(q);
|
||||
sid = ngx_queue_data(q, ngx_quic_server_id_t, queue);
|
||||
|
||||
if (sid->seqnum != NGX_QUIC_UNSET_PN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_queue_remove(q);
|
||||
ngx_rbtree_delete(&c->listening->rbtree, &sid->udp.node);
|
||||
qc->nserver_ids--;
|
||||
|
||||
if (c->udp != &sid->udp) {
|
||||
ngx_queue_insert_tail(&qc->free_server_ids, &sid->queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ngx_quic_server_id_t *
|
||||
ngx_quic_insert_server_id(ngx_connection_t *c, ngx_str_t *id)
|
||||
{
|
||||
ngx_str_t dcid;
|
||||
ngx_quic_server_id_t *sid;
|
||||
ngx_quic_connection_t *qc;
|
||||
|
||||
qc = c->quic;
|
||||
|
||||
sid = ngx_quic_alloc_server_id(c, qc);
|
||||
if (sid == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sid->seqnum = qc->server_seqnum;
|
||||
|
||||
if (qc->server_seqnum != NGX_QUIC_UNSET_PN) {
|
||||
qc->server_seqnum++;
|
||||
}
|
||||
|
||||
sid->len = id->len;
|
||||
ngx_memcpy(sid->id, id->data, id->len);
|
||||
|
||||
ngx_queue_insert_tail(&qc->server_ids, &sid->queue);
|
||||
qc->nserver_ids++;
|
||||
|
||||
dcid.data = sid->id;
|
||||
dcid.len = sid->len;
|
||||
|
||||
ngx_insert_udp_connection(c, &sid->udp, &dcid);
|
||||
|
||||
if (c->udp == NULL) {
|
||||
c->udp = &sid->udp;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic insert server id seqnum:%uL", sid->seqnum);
|
||||
|
||||
ngx_quic_hexdump(c->log, "quic server id", id->data, id->len);
|
||||
|
||||
return sid;
|
||||
}
|
||||
|
||||
|
||||
static ngx_quic_client_id_t *
|
||||
ngx_quic_alloc_client_id(ngx_connection_t *c, ngx_quic_connection_t *qc)
|
||||
{
|
||||
@ -4292,6 +4534,33 @@ ngx_quic_alloc_client_id(ngx_connection_t *c, ngx_quic_connection_t *qc)
|
||||
}
|
||||
|
||||
|
||||
static ngx_quic_server_id_t *
|
||||
ngx_quic_alloc_server_id(ngx_connection_t *c, ngx_quic_connection_t *qc)
|
||||
{
|
||||
ngx_queue_t *q;
|
||||
ngx_quic_server_id_t *sid;
|
||||
|
||||
if (!ngx_queue_empty(&qc->free_server_ids)) {
|
||||
|
||||
q = ngx_queue_head(&qc->free_server_ids);
|
||||
sid = ngx_queue_data(q, ngx_quic_server_id_t, queue);
|
||||
|
||||
ngx_queue_remove(&sid->queue);
|
||||
|
||||
ngx_memzero(sid, sizeof(ngx_quic_server_id_t));
|
||||
|
||||
} else {
|
||||
|
||||
sid = ngx_pcalloc(c->pool, sizeof(ngx_quic_server_id_t));
|
||||
if (sid == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return sid;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame)
|
||||
{
|
||||
|
@ -58,6 +58,8 @@
|
||||
|
||||
#define NGX_QUIC_SR_TOKEN_LEN 16
|
||||
|
||||
#define NGX_QUIC_MAX_SERVER_IDS 8
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* configurable */
|
||||
@ -72,8 +74,8 @@ typedef struct {
|
||||
ngx_uint_t initial_max_streams_bidi;
|
||||
ngx_uint_t initial_max_streams_uni;
|
||||
ngx_uint_t ack_delay_exponent;
|
||||
ngx_uint_t disable_active_migration;
|
||||
ngx_uint_t active_connection_id_limit;
|
||||
ngx_flag_t disable_active_migration;
|
||||
ngx_str_t original_dcid;
|
||||
ngx_str_t initial_scid;
|
||||
ngx_str_t retry_scid;
|
||||
@ -123,6 +125,8 @@ ngx_connection_t *ngx_quic_open_stream(ngx_connection_t *c, ngx_uint_t bidi);
|
||||
void ngx_quic_finalize_connection(ngx_connection_t *c, ngx_uint_t err,
|
||||
const char *reason);
|
||||
uint32_t ngx_quic_version(ngx_connection_t *c);
|
||||
ngx_int_t ngx_quic_get_packet_dcid(ngx_log_t *log, u_char *data, size_t len,
|
||||
ngx_str_t *dcid);
|
||||
|
||||
|
||||
/********************************* DEBUG *************************************/
|
||||
|
@ -10,6 +10,11 @@
|
||||
#include <ngx_event_quic_transport.h>
|
||||
|
||||
|
||||
#define NGX_QUIC_LONG_DCID_LEN_OFFSET 5
|
||||
#define NGX_QUIC_LONG_DCID_OFFSET 6
|
||||
#define NGX_QUIC_SHORT_DCID_OFFSET 1
|
||||
|
||||
|
||||
#if (NGX_HAVE_NONALIGNED)
|
||||
|
||||
#define ngx_quic_parse_uint16(p) ntohs(*(uint16_t *) (p))
|
||||
@ -95,6 +100,8 @@ static size_t ngx_quic_create_max_data(u_char *p,
|
||||
ngx_quic_max_data_frame_t *md);
|
||||
static size_t ngx_quic_create_path_response(u_char *p,
|
||||
ngx_quic_path_challenge_frame_t *pc);
|
||||
static size_t ngx_quic_create_new_connection_id(u_char *p,
|
||||
ngx_quic_new_conn_id_frame_t *rcid);
|
||||
static size_t ngx_quic_create_retire_connection_id(u_char *p,
|
||||
ngx_quic_retire_cid_frame_t *rcid);
|
||||
static size_t ngx_quic_create_close(u_char *p, ngx_quic_close_frame_t *cl);
|
||||
@ -321,6 +328,46 @@ ngx_quic_parse_packet(ngx_quic_header_t *pkt)
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_quic_get_packet_dcid(ngx_log_t *log, u_char *data, size_t n,
|
||||
ngx_str_t *dcid)
|
||||
{
|
||||
size_t len, offset;
|
||||
|
||||
if (n == 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (ngx_quic_long_pkt(*data)) {
|
||||
if (n < NGX_QUIC_LONG_DCID_LEN_OFFSET + 1) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
len = data[NGX_QUIC_LONG_DCID_LEN_OFFSET];
|
||||
offset = NGX_QUIC_LONG_DCID_OFFSET;
|
||||
|
||||
} else {
|
||||
len = NGX_QUIC_SERVER_CID_LEN;
|
||||
offset = NGX_QUIC_SHORT_DCID_OFFSET;
|
||||
}
|
||||
|
||||
if (n < len + offset) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
dcid->len = len;
|
||||
dcid->data = &data[offset];
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
failed:
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0, "quic malformed packet");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_quic_parse_long_header(ngx_quic_header_t *pkt)
|
||||
{
|
||||
@ -1222,6 +1269,9 @@ ngx_quic_create_frame(u_char *p, ngx_quic_frame_t *f)
|
||||
case NGX_QUIC_FT_PATH_RESPONSE:
|
||||
return ngx_quic_create_path_response(p, &f->u.path_response);
|
||||
|
||||
case NGX_QUIC_FT_NEW_CONNECTION_ID:
|
||||
return ngx_quic_create_new_connection_id(p, &f->u.ncid);
|
||||
|
||||
case NGX_QUIC_FT_RETIRE_CONNECTION_ID:
|
||||
return ngx_quic_create_retire_connection_id(p, &f->u.retire_cid);
|
||||
|
||||
@ -1704,6 +1754,35 @@ ngx_quic_create_path_response(u_char *p, ngx_quic_path_challenge_frame_t *pc)
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
ngx_quic_create_new_connection_id(u_char *p, ngx_quic_new_conn_id_frame_t *ncid)
|
||||
{
|
||||
size_t len;
|
||||
u_char *start;
|
||||
|
||||
if (p == NULL) {
|
||||
len = ngx_quic_varint_len(NGX_QUIC_FT_NEW_CONNECTION_ID);
|
||||
len += ngx_quic_varint_len(ncid->seqnum);
|
||||
len += ngx_quic_varint_len(ncid->retire);
|
||||
len++;
|
||||
len += ncid->len;
|
||||
len += NGX_QUIC_SR_TOKEN_LEN;
|
||||
return len;
|
||||
}
|
||||
|
||||
start = p;
|
||||
|
||||
ngx_quic_build_int(&p, NGX_QUIC_FT_NEW_CONNECTION_ID);
|
||||
ngx_quic_build_int(&p, ncid->seqnum);
|
||||
ngx_quic_build_int(&p, ncid->retire);
|
||||
*p++ = ncid->len;
|
||||
p = ngx_cpymem(p, ncid->cid, ncid->len);
|
||||
p = ngx_cpymem(p, ncid->srt, NGX_QUIC_SR_TOKEN_LEN);
|
||||
|
||||
return p - start;
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
ngx_quic_create_retire_connection_id(u_char *p,
|
||||
ngx_quic_retire_cid_frame_t *rcid)
|
||||
@ -1783,6 +1862,11 @@ ngx_quic_create_transport_params(u_char *pos, u_char *end, ngx_quic_tp_t *tp,
|
||||
*clen = len;
|
||||
}
|
||||
|
||||
if (tp->disable_active_migration) {
|
||||
len += ngx_quic_varint_len(NGX_QUIC_TP_DISABLE_ACTIVE_MIGRATION);
|
||||
len += ngx_quic_varint_len(0);
|
||||
}
|
||||
|
||||
len += ngx_quic_tp_len(NGX_QUIC_TP_ACTIVE_CONNECTION_ID_LIMIT,
|
||||
tp->active_connection_id_limit);
|
||||
|
||||
@ -1830,6 +1914,11 @@ ngx_quic_create_transport_params(u_char *pos, u_char *end, ngx_quic_tp_t *tp,
|
||||
ngx_quic_tp_vint(NGX_QUIC_TP_MAX_IDLE_TIMEOUT,
|
||||
tp->max_idle_timeout);
|
||||
|
||||
if (tp->disable_active_migration) {
|
||||
ngx_quic_build_int(&p, NGX_QUIC_TP_DISABLE_ACTIVE_MIGRATION);
|
||||
ngx_quic_build_int(&p, 0);
|
||||
}
|
||||
|
||||
ngx_quic_tp_vint(NGX_QUIC_TP_ACTIVE_CONNECTION_ID_LIMIT,
|
||||
tp->active_connection_id_limit);
|
||||
|
||||
|
@ -12,19 +12,12 @@
|
||||
|
||||
#if !(NGX_WIN32)
|
||||
|
||||
struct ngx_udp_connection_s {
|
||||
ngx_rbtree_node_t node;
|
||||
ngx_connection_t *connection;
|
||||
ngx_buf_t *buffer;
|
||||
};
|
||||
|
||||
|
||||
static void ngx_close_accepted_udp_connection(ngx_connection_t *c);
|
||||
static ssize_t ngx_udp_shared_recv(ngx_connection_t *c, u_char *buf,
|
||||
size_t size);
|
||||
static ngx_int_t ngx_insert_udp_connection(ngx_connection_t *c);
|
||||
static ngx_int_t ngx_create_udp_connection(ngx_connection_t *c);
|
||||
static ngx_connection_t *ngx_lookup_udp_connection(ngx_listening_t *ls,
|
||||
struct sockaddr *sockaddr, socklen_t socklen,
|
||||
ngx_str_t *key, struct sockaddr *sockaddr, socklen_t socklen,
|
||||
struct sockaddr *local_sockaddr, socklen_t local_socklen);
|
||||
|
||||
|
||||
@ -32,6 +25,7 @@ void
|
||||
ngx_event_recvmsg(ngx_event_t *ev)
|
||||
{
|
||||
ssize_t n;
|
||||
ngx_str_t key;
|
||||
ngx_buf_t buf;
|
||||
ngx_log_t *log;
|
||||
ngx_err_t err;
|
||||
@ -229,8 +223,18 @@ ngx_event_recvmsg(ngx_event_t *ev)
|
||||
|
||||
#endif
|
||||
|
||||
c = ngx_lookup_udp_connection(ls, sockaddr, socklen, local_sockaddr,
|
||||
local_socklen);
|
||||
ngx_str_null(&key);
|
||||
|
||||
#if (NGX_QUIC)
|
||||
if (ls->quic) {
|
||||
if (ngx_quic_get_packet_dcid(ev->log, buffer, n, &key) != NGX_OK) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
c = ngx_lookup_udp_connection(ls, &key, sockaddr, socklen,
|
||||
local_sockaddr, local_socklen);
|
||||
|
||||
if (c) {
|
||||
|
||||
@ -403,7 +407,7 @@ ngx_event_recvmsg(ngx_event_t *ev)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ngx_insert_udp_connection(c) != NGX_OK) {
|
||||
if (ngx_create_udp_connection(c) != NGX_OK) {
|
||||
ngx_close_accepted_udp_connection(c);
|
||||
return;
|
||||
}
|
||||
@ -492,8 +496,13 @@ ngx_udp_rbtree_insert_value(ngx_rbtree_node_t *temp,
|
||||
udpt = (ngx_udp_connection_t *) temp;
|
||||
ct = udpt->connection;
|
||||
|
||||
rc = ngx_cmp_sockaddr(c->sockaddr, c->socklen,
|
||||
ct->sockaddr, ct->socklen, 1);
|
||||
rc = ngx_memn2cmp(udp->key.data, udpt->key.data,
|
||||
udp->key.len, udpt->key.len);
|
||||
|
||||
if (rc == 0 && udp->key.len == 0) {
|
||||
rc = ngx_cmp_sockaddr(c->sockaddr, c->socklen,
|
||||
ct->sockaddr, ct->socklen, 1);
|
||||
}
|
||||
|
||||
if (rc == 0 && c->listening->wildcard) {
|
||||
rc = ngx_cmp_sockaddr(c->local_sockaddr, c->local_socklen,
|
||||
@ -519,12 +528,18 @@ ngx_udp_rbtree_insert_value(ngx_rbtree_node_t *temp,
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_insert_udp_connection(ngx_connection_t *c)
|
||||
ngx_create_udp_connection(ngx_connection_t *c)
|
||||
{
|
||||
uint32_t hash;
|
||||
ngx_str_t key;
|
||||
ngx_pool_cleanup_t *cln;
|
||||
ngx_udp_connection_t *udp;
|
||||
|
||||
#if (NGX_QUIC)
|
||||
if (c->listening->quic) {
|
||||
return NGX_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (c->udp) {
|
||||
return NGX_OK;
|
||||
}
|
||||
@ -534,19 +549,6 @@ ngx_insert_udp_connection(ngx_connection_t *c)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
udp->connection = c;
|
||||
|
||||
ngx_crc32_init(hash);
|
||||
ngx_crc32_update(&hash, (u_char *) c->sockaddr, c->socklen);
|
||||
|
||||
if (c->listening->wildcard) {
|
||||
ngx_crc32_update(&hash, (u_char *) c->local_sockaddr, c->local_socklen);
|
||||
}
|
||||
|
||||
ngx_crc32_final(hash);
|
||||
|
||||
udp->node.key = hash;
|
||||
|
||||
cln = ngx_pool_cleanup_add(c->pool, 0);
|
||||
if (cln == NULL) {
|
||||
return NGX_ERROR;
|
||||
@ -555,7 +557,9 @@ ngx_insert_udp_connection(ngx_connection_t *c)
|
||||
cln->data = c;
|
||||
cln->handler = ngx_delete_udp_connection;
|
||||
|
||||
ngx_rbtree_insert(&c->listening->rbtree, &udp->node);
|
||||
key.len = 0;
|
||||
|
||||
ngx_insert_udp_connection(c, udp, &key);
|
||||
|
||||
c->udp = udp;
|
||||
|
||||
@ -563,6 +567,34 @@ ngx_insert_udp_connection(ngx_connection_t *c)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_insert_udp_connection(ngx_connection_t *c, ngx_udp_connection_t *udp,
|
||||
ngx_str_t *key)
|
||||
{
|
||||
uint32_t hash;
|
||||
|
||||
ngx_crc32_init(hash);
|
||||
|
||||
ngx_crc32_update(&hash, key->data, key->len);
|
||||
|
||||
if (key->len == 0) {
|
||||
ngx_crc32_update(&hash, (u_char *) c->sockaddr, c->socklen);
|
||||
}
|
||||
|
||||
if (c->listening->wildcard) {
|
||||
ngx_crc32_update(&hash, (u_char *) c->local_sockaddr, c->local_socklen);
|
||||
}
|
||||
|
||||
ngx_crc32_final(hash);
|
||||
|
||||
udp->connection = c;
|
||||
udp->key = *key;
|
||||
udp->node.key = hash;
|
||||
|
||||
ngx_rbtree_insert(&c->listening->rbtree, &udp->node);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_delete_udp_connection(void *data)
|
||||
{
|
||||
@ -579,8 +611,9 @@ ngx_delete_udp_connection(void *data)
|
||||
|
||||
|
||||
static ngx_connection_t *
|
||||
ngx_lookup_udp_connection(ngx_listening_t *ls, struct sockaddr *sockaddr,
|
||||
socklen_t socklen, struct sockaddr *local_sockaddr, socklen_t local_socklen)
|
||||
ngx_lookup_udp_connection(ngx_listening_t *ls, ngx_str_t *key,
|
||||
struct sockaddr *sockaddr, socklen_t socklen,
|
||||
struct sockaddr *local_sockaddr, socklen_t local_socklen)
|
||||
{
|
||||
uint32_t hash;
|
||||
ngx_int_t rc;
|
||||
@ -608,7 +641,12 @@ ngx_lookup_udp_connection(ngx_listening_t *ls, struct sockaddr *sockaddr,
|
||||
sentinel = ls->rbtree.sentinel;
|
||||
|
||||
ngx_crc32_init(hash);
|
||||
ngx_crc32_update(&hash, (u_char *) sockaddr, socklen);
|
||||
|
||||
ngx_crc32_update(&hash, key->data, key->len);
|
||||
|
||||
if (key->len == 0) {
|
||||
ngx_crc32_update(&hash, (u_char *) sockaddr, socklen);
|
||||
}
|
||||
|
||||
if (ls->wildcard) {
|
||||
ngx_crc32_update(&hash, (u_char *) local_sockaddr, local_socklen);
|
||||
@ -634,8 +672,12 @@ ngx_lookup_udp_connection(ngx_listening_t *ls, struct sockaddr *sockaddr,
|
||||
|
||||
c = udp->connection;
|
||||
|
||||
rc = ngx_cmp_sockaddr(sockaddr, socklen,
|
||||
c->sockaddr, c->socklen, 1);
|
||||
rc = ngx_memn2cmp(key->data, udp->key.data, key->len, udp->key.len);
|
||||
|
||||
if (rc == 0 && key->len == 0) {
|
||||
rc = ngx_cmp_sockaddr(sockaddr, socklen,
|
||||
c->sockaddr, c->socklen, 1);
|
||||
}
|
||||
|
||||
if (rc == 0 && ls->wildcard) {
|
||||
rc = ngx_cmp_sockaddr(local_sockaddr, local_socklen,
|
||||
@ -643,6 +685,37 @@ ngx_lookup_udp_connection(ngx_listening_t *ls, struct sockaddr *sockaddr,
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
if (key->len) {
|
||||
rc = ngx_cmp_sockaddr(sockaddr, socklen,
|
||||
c->sockaddr, c->socklen, 1);
|
||||
|
||||
if (rc) {
|
||||
#if (NGX_DEBUG)
|
||||
if (c->log->log_level & NGX_LOG_DEBUG_EVENT) {
|
||||
ngx_str_t addr;
|
||||
u_char text[NGX_SOCKADDR_STRLEN];
|
||||
|
||||
addr.data = text;
|
||||
addr.len = ngx_sock_ntop(sockaddr, socklen, text,
|
||||
NGX_SOCKADDR_STRLEN, 1);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"client migrated to %V", &addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (c->socklen < socklen) {
|
||||
c->sockaddr = ngx_palloc(c->pool, socklen);
|
||||
if (c->sockaddr == NULL) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_memcpy(c->sockaddr, sockaddr, socklen);
|
||||
c->socklen = socklen;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -104,9 +104,9 @@ static ngx_command_t ngx_http_quic_commands[] = {
|
||||
offsetof(ngx_quic_conf_t, tp.ack_delay_exponent),
|
||||
&ngx_http_quic_ack_delay_exponent_bounds },
|
||||
|
||||
{ ngx_string("quic_active_migration"),
|
||||
{ ngx_string("quic_disable_active_migration"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.disable_active_migration),
|
||||
NULL },
|
||||
@ -246,7 +246,7 @@ ngx_http_quic_create_srv_conf(ngx_conf_t *cf)
|
||||
conf->tp.initial_max_streams_bidi = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.initial_max_streams_uni = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.ack_delay_exponent = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.disable_active_migration = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.disable_active_migration = NGX_CONF_UNSET;
|
||||
conf->tp.active_connection_id_limit = NGX_CONF_UNSET_UINT;
|
||||
|
||||
conf->retry = NGX_CONF_UNSET;
|
||||
@ -301,8 +301,8 @@ ngx_http_quic_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
prev->tp.ack_delay_exponent,
|
||||
NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->tp.disable_active_migration,
|
||||
prev->tp.disable_active_migration, 1);
|
||||
ngx_conf_merge_value(conf->tp.disable_active_migration,
|
||||
prev->tp.disable_active_migration, 0);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->tp.active_connection_id_limit,
|
||||
prev->tp.active_connection_id_limit, 2);
|
||||
|
@ -105,9 +105,9 @@ static ngx_command_t ngx_stream_quic_commands[] = {
|
||||
offsetof(ngx_quic_conf_t, tp.ack_delay_exponent),
|
||||
&ngx_stream_quic_ack_delay_exponent_bounds },
|
||||
|
||||
{ ngx_string("quic_active_migration"),
|
||||
{ ngx_string("quic_disable_active_migration"),
|
||||
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_STREAM_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.disable_active_migration),
|
||||
NULL },
|
||||
@ -236,7 +236,7 @@ ngx_stream_quic_create_srv_conf(ngx_conf_t *cf)
|
||||
conf->tp.initial_max_streams_bidi = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.initial_max_streams_uni = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.ack_delay_exponent = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.disable_active_migration = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.disable_active_migration = NGX_CONF_UNSET;
|
||||
conf->tp.active_connection_id_limit = NGX_CONF_UNSET_UINT;
|
||||
|
||||
conf->retry = NGX_CONF_UNSET;
|
||||
@ -290,8 +290,8 @@ ngx_stream_quic_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
prev->tp.ack_delay_exponent,
|
||||
NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->tp.disable_active_migration,
|
||||
prev->tp.disable_active_migration, 1);
|
||||
ngx_conf_merge_value(conf->tp.disable_active_migration,
|
||||
prev->tp.disable_active_migration, 0);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->tp.active_connection_id_limit,
|
||||
prev->tp.active_connection_id_limit, 2);
|
||||
|
Loading…
Reference in New Issue
Block a user