comparison src/event/quic/ngx_event_quic.c @ 8748:e0cb1e58ca13 quic

QUIC: separate files for connection id related processing.
author Vladimir Homutov <vl@nginx.com>
date Tue, 13 Apr 2021 14:37:41 +0300
parents c8bda5e1e662
children 660c4a2f95f3
comparison
equal deleted inserted replaced
8747:c8bda5e1e662 8748:e0cb1e58ca13
20 * Implementations MUST support buffering at least 4096 bytes of data 20 * Implementations MUST support buffering at least 4096 bytes of data
21 */ 21 */
22 #define NGX_QUIC_MAX_BUFFERED 65535 22 #define NGX_QUIC_MAX_BUFFERED 65535
23 23
24 #define NGX_QUIC_STREAM_GONE (void *) -1 24 #define NGX_QUIC_STREAM_GONE (void *) -1
25
26 #define NGX_QUIC_UNSET_PN (uint64_t) -1
27 25
28 /* 26 /*
29 * Endpoints MUST discard packets that are too small to be valid QUIC 27 * Endpoints MUST discard packets that are too small to be valid QUIC
30 * packets. With the set of AEAD functions defined in [QUIC-TLS], 28 * packets. With the set of AEAD functions defined in [QUIC-TLS],
31 * packets that are smaller than 21 bytes are never valid. 29 * packets that are smaller than 21 bytes are never valid.
64 62
65 static ngx_int_t ngx_quic_apply_transport_params(ngx_connection_t *c, 63 static ngx_int_t ngx_quic_apply_transport_params(ngx_connection_t *c,
66 ngx_quic_tp_t *ctp); 64 ngx_quic_tp_t *ctp);
67 static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c, 65 static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c,
68 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); 66 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
69 static ngx_int_t ngx_quic_setup_connection_ids(ngx_connection_t *c,
70 ngx_quic_connection_t *qc, ngx_quic_header_t *pkt);
71 static ngx_int_t ngx_quic_send_stateless_reset(ngx_connection_t *c, 67 static ngx_int_t ngx_quic_send_stateless_reset(ngx_connection_t *c,
72 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); 68 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
73 static ngx_int_t ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid,
74 u_char *secret, u_char *token);
75 static ngx_int_t ngx_quic_process_stateless_reset(ngx_connection_t *c, 69 static ngx_int_t ngx_quic_process_stateless_reset(ngx_connection_t *c,
76 ngx_quic_header_t *pkt); 70 ngx_quic_header_t *pkt);
77 static ngx_int_t ngx_quic_negotiate_version(ngx_connection_t *c, 71 static ngx_int_t ngx_quic_negotiate_version(ngx_connection_t *c,
78 ngx_quic_header_t *inpkt); 72 ngx_quic_header_t *inpkt);
79 static ngx_int_t ngx_quic_create_server_id(ngx_connection_t *c, u_char *id);
80 #if (NGX_QUIC_BPF)
81 static ngx_int_t ngx_quic_bpf_attach_id(ngx_connection_t *c, u_char *id);
82 #endif
83 static ngx_int_t ngx_quic_send_retry(ngx_connection_t *c, 73 static ngx_int_t ngx_quic_send_retry(ngx_connection_t *c,
84 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); 74 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
85 static ngx_int_t ngx_quic_new_token(ngx_connection_t *c, u_char *key, 75 static ngx_int_t ngx_quic_new_token(ngx_connection_t *c, u_char *key,
86 ngx_str_t *token, ngx_str_t *odcid, time_t expires, ngx_uint_t is_retry); 76 ngx_str_t *token, ngx_str_t *odcid, time_t expires, ngx_uint_t is_retry);
87 static void ngx_quic_address_hash(ngx_connection_t *c, ngx_uint_t no_port, 77 static void ngx_quic_address_hash(ngx_connection_t *c, ngx_uint_t no_port,
161 ngx_quic_header_t *pkt, ngx_quic_reset_stream_frame_t *f); 151 ngx_quic_header_t *pkt, ngx_quic_reset_stream_frame_t *f);
162 static ngx_int_t ngx_quic_handle_stop_sending_frame(ngx_connection_t *c, 152 static ngx_int_t ngx_quic_handle_stop_sending_frame(ngx_connection_t *c,
163 ngx_quic_header_t *pkt, ngx_quic_stop_sending_frame_t *f); 153 ngx_quic_header_t *pkt, ngx_quic_stop_sending_frame_t *f);
164 static ngx_int_t ngx_quic_handle_max_streams_frame(ngx_connection_t *c, 154 static ngx_int_t ngx_quic_handle_max_streams_frame(ngx_connection_t *c,
165 ngx_quic_header_t *pkt, ngx_quic_max_streams_frame_t *f); 155 ngx_quic_header_t *pkt, ngx_quic_max_streams_frame_t *f);
166 static ngx_int_t ngx_quic_handle_new_connection_id_frame(ngx_connection_t *c,
167 ngx_quic_header_t *pkt, ngx_quic_new_conn_id_frame_t *f);
168 static ngx_int_t ngx_quic_retire_connection_id(ngx_connection_t *c,
169 enum ssl_encryption_level_t level, uint64_t seqnum);
170 static ngx_int_t ngx_quic_handle_retire_connection_id_frame(ngx_connection_t *c,
171 ngx_quic_header_t *pkt, ngx_quic_retire_cid_frame_t *f);
172 static ngx_int_t ngx_quic_issue_server_ids(ngx_connection_t *c);
173 static void ngx_quic_clear_temp_server_ids(ngx_connection_t *c);
174 static ngx_quic_server_id_t *ngx_quic_insert_server_id(ngx_connection_t *c,
175 ngx_quic_connection_t *qc, ngx_str_t *id);
176 static ngx_quic_client_id_t *ngx_quic_alloc_client_id(ngx_connection_t *c,
177 ngx_quic_connection_t *qc);
178 static ngx_quic_server_id_t *ngx_quic_alloc_server_id(ngx_connection_t *c,
179 ngx_quic_connection_t *qc);
180 156
181 static ngx_int_t ngx_quic_output(ngx_connection_t *c); 157 static ngx_int_t ngx_quic_output(ngx_connection_t *c);
182 static ngx_uint_t ngx_quic_get_padding_level(ngx_connection_t *c); 158 static ngx_uint_t ngx_quic_get_padding_level(ngx_connection_t *c);
183 static ngx_int_t ngx_quic_generate_ack(ngx_connection_t *c, 159 static ngx_int_t ngx_quic_generate_ack(ngx_connection_t *c,
184 ngx_quic_send_ctx_t *ctx); 160 ngx_quic_send_ctx_t *ctx);
1034 return qc; 1010 return qc;
1035 } 1011 }
1036 1012
1037 1013
1038 static ngx_int_t 1014 static ngx_int_t
1039 ngx_quic_setup_connection_ids(ngx_connection_t *c, ngx_quic_connection_t *qc,
1040 ngx_quic_header_t *pkt)
1041 {
1042 ngx_quic_server_id_t *sid, *osid;
1043 ngx_quic_client_id_t *cid;
1044
1045 /*
1046 * qc->nclient_ids = 0
1047 * qc->nserver_ids = 0
1048 * qc->max_retired_seqnum = 0
1049 */
1050
1051 ngx_queue_init(&qc->client_ids);
1052 ngx_queue_init(&qc->server_ids);
1053 ngx_queue_init(&qc->free_client_ids);
1054 ngx_queue_init(&qc->free_server_ids);
1055
1056 qc->odcid.len = pkt->odcid.len;
1057 qc->odcid.data = ngx_pstrdup(c->pool, &pkt->odcid);
1058 if (qc->odcid.data == NULL) {
1059 return NGX_ERROR;
1060 }
1061
1062 qc->tp.original_dcid = qc->odcid;
1063
1064 qc->scid.len = pkt->scid.len;
1065 qc->scid.data = ngx_pstrdup(c->pool, &pkt->scid);
1066 if (qc->scid.data == NULL) {
1067 return NGX_ERROR;
1068 }
1069
1070 qc->dcid.len = NGX_QUIC_SERVER_CID_LEN;
1071 qc->dcid.data = ngx_pnalloc(c->pool, qc->dcid.len);
1072 if (qc->dcid.data == NULL) {
1073 return NGX_ERROR;
1074 }
1075
1076 if (ngx_quic_create_server_id(c, qc->dcid.data) != NGX_OK) {
1077 return NGX_ERROR;
1078 }
1079
1080 qc->tp.initial_scid = qc->dcid;
1081
1082 cid = ngx_quic_alloc_client_id(c, qc);
1083 if (cid == NULL) {
1084 return NGX_ERROR;
1085 }
1086
1087 cid->seqnum = 0;
1088 cid->len = pkt->scid.len;
1089 ngx_memcpy(cid->id, pkt->scid.data, pkt->scid.len);
1090
1091 ngx_queue_insert_tail(&qc->client_ids, &cid->queue);
1092 qc->nclient_ids++;
1093 qc->client_seqnum = 0;
1094
1095 qc->server_seqnum = NGX_QUIC_UNSET_PN;
1096
1097 osid = ngx_quic_insert_server_id(c, qc, &qc->odcid);
1098 if (osid == NULL) {
1099 return NGX_ERROR;
1100 }
1101
1102 qc->server_seqnum = 0;
1103
1104 sid = ngx_quic_insert_server_id(c, qc, &qc->dcid);
1105 if (sid == NULL) {
1106 ngx_rbtree_delete(&c->listening->rbtree, &osid->udp.node);
1107 return NGX_ERROR;
1108 }
1109
1110 c->udp = &sid->udp;
1111
1112 return NGX_OK;
1113 }
1114
1115
1116 static ngx_int_t
1117 ngx_quic_send_stateless_reset(ngx_connection_t *c, ngx_quic_conf_t *conf, 1015 ngx_quic_send_stateless_reset(ngx_connection_t *c, ngx_quic_conf_t *conf,
1118 ngx_quic_header_t *pkt) 1016 ngx_quic_header_t *pkt)
1119 { 1017 {
1120 u_char *token; 1018 u_char *token;
1121 size_t len, max; 1019 size_t len, max;
1162 1060
1163 return NGX_DECLINED; 1061 return NGX_DECLINED;
1164 } 1062 }
1165 1063
1166 1064
1167 static ngx_int_t 1065 ngx_int_t
1168 ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, u_char *secret, 1066 ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, u_char *secret,
1169 u_char *token) 1067 u_char *token)
1170 { 1068 {
1171 ngx_str_t tmp; 1069 ngx_str_t tmp;
1172 1070
1258 1156
1259 (void) ngx_quic_send(c, buf, len); 1157 (void) ngx_quic_send(c, buf, len);
1260 1158
1261 return NGX_ERROR; 1159 return NGX_ERROR;
1262 } 1160 }
1263
1264
1265 static ngx_int_t
1266 ngx_quic_create_server_id(ngx_connection_t *c, u_char *id)
1267 {
1268 if (RAND_bytes(id, NGX_QUIC_SERVER_CID_LEN) != 1) {
1269 return NGX_ERROR;
1270 }
1271
1272 #if (NGX_QUIC_BPF)
1273 if (ngx_quic_bpf_attach_id(c, id) != NGX_OK) {
1274 ngx_log_error(NGX_LOG_ERR, c->log, 0,
1275 "quic bpf failed to generate socket key");
1276 /* ignore error, things still may work */
1277 }
1278 #endif
1279
1280 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
1281 "quic create server id %*xs",
1282 (size_t) NGX_QUIC_SERVER_CID_LEN, id);
1283 return NGX_OK;
1284 }
1285
1286
1287 #if (NGX_QUIC_BPF)
1288
1289 static ngx_int_t
1290 ngx_quic_bpf_attach_id(ngx_connection_t *c, u_char *id)
1291 {
1292 int fd;
1293 uint64_t cookie;
1294 socklen_t optlen;
1295
1296 fd = c->listening->fd;
1297
1298 optlen = sizeof(cookie);
1299
1300 if (getsockopt(fd, SOL_SOCKET, SO_COOKIE, &cookie, &optlen) == -1) {
1301 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
1302 "quic getsockopt(SO_COOKIE) failed");
1303
1304 return NGX_ERROR;
1305 }
1306
1307 ngx_quic_dcid_encode_key(id, cookie);
1308
1309 return NGX_OK;
1310 }
1311
1312 #endif
1313 1161
1314 1162
1315 static ngx_int_t 1163 static ngx_int_t
1316 ngx_quic_send_retry(ngx_connection_t *c, ngx_quic_conf_t *conf, 1164 ngx_quic_send_retry(ngx_connection_t *c, ngx_quic_conf_t *conf,
1317 ngx_quic_header_t *inpkt) 1165 ngx_quic_header_t *inpkt)
4388 4236
4389 return NGX_OK; 4237 return NGX_OK;
4390 } 4238 }
4391 4239
4392 4240
4393 static ngx_int_t
4394 ngx_quic_handle_new_connection_id_frame(ngx_connection_t *c,
4395 ngx_quic_header_t *pkt, ngx_quic_new_conn_id_frame_t *f)
4396 {
4397 ngx_queue_t *q;
4398 ngx_quic_client_id_t *cid, *item;
4399 ngx_quic_connection_t *qc;
4400
4401 qc = ngx_quic_get_connection(c);
4402
4403 if (f->seqnum < qc->max_retired_seqnum) {
4404 /*
4405 * An endpoint that receives a NEW_CONNECTION_ID frame with
4406 * a sequence number smaller than the Retire Prior To field
4407 * of a previously received NEW_CONNECTION_ID frame MUST send
4408 * a corresponding RETIRE_CONNECTION_ID frame that retires
4409 * the newly received connection ID, unless it has already
4410 * done so for that sequence number.
4411 */
4412
4413 if (ngx_quic_retire_connection_id(c, pkt->level, f->seqnum) != NGX_OK) {
4414 return NGX_ERROR;
4415 }
4416
4417 goto retire;
4418 }
4419
4420 cid = NULL;
4421
4422 for (q = ngx_queue_head(&qc->client_ids);
4423 q != ngx_queue_sentinel(&qc->client_ids);
4424 q = ngx_queue_next(q))
4425 {
4426 item = ngx_queue_data(q, ngx_quic_client_id_t, queue);
4427
4428 if (item->seqnum == f->seqnum) {
4429 cid = item;
4430 break;
4431 }
4432 }
4433
4434 if (cid) {
4435 /*
4436 * Transmission errors, timeouts and retransmissions might cause the
4437 * same NEW_CONNECTION_ID frame to be received multiple times
4438 */
4439
4440 if (cid->len != f->len
4441 || ngx_strncmp(cid->id, f->cid, f->len) != 0
4442 || ngx_strncmp(cid->sr_token, f->srt, NGX_QUIC_SR_TOKEN_LEN) != 0)
4443 {
4444 /*
4445 * ..a sequence number is used for different connection IDs,
4446 * the endpoint MAY treat that receipt as a connection error
4447 * of type PROTOCOL_VIOLATION.
4448 */
4449 qc->error = NGX_QUIC_ERR_PROTOCOL_VIOLATION;
4450 qc->error_reason = "seqnum refers to different connection id/token";
4451 return NGX_ERROR;
4452 }
4453
4454 } else {
4455
4456 cid = ngx_quic_alloc_client_id(c, qc);
4457 if (cid == NULL) {
4458 return NGX_ERROR;
4459 }
4460
4461 cid->seqnum = f->seqnum;
4462 cid->len = f->len;
4463 ngx_memcpy(cid->id, f->cid, f->len);
4464
4465 ngx_memcpy(cid->sr_token, f->srt, NGX_QUIC_SR_TOKEN_LEN);
4466
4467 ngx_queue_insert_tail(&qc->client_ids, &cid->queue);
4468 qc->nclient_ids++;
4469
4470 /* always use latest available connection id */
4471 if (f->seqnum > qc->client_seqnum) {
4472 qc->scid.len = cid->len;
4473 qc->scid.data = cid->id;
4474 qc->client_seqnum = f->seqnum;
4475 }
4476 }
4477
4478 retire:
4479
4480 if (qc->max_retired_seqnum && f->retire <= qc->max_retired_seqnum) {
4481 /*
4482 * Once a sender indicates a Retire Prior To value, smaller values sent
4483 * in subsequent NEW_CONNECTION_ID frames have no effect. A receiver
4484 * MUST ignore any Retire Prior To fields that do not increase the
4485 * largest received Retire Prior To value.
4486 */
4487 goto done;
4488 }
4489
4490 qc->max_retired_seqnum = f->retire;
4491
4492 q = ngx_queue_head(&qc->client_ids);
4493
4494 while (q != ngx_queue_sentinel(&qc->client_ids)) {
4495
4496 cid = ngx_queue_data(q, ngx_quic_client_id_t, queue);
4497 q = ngx_queue_next(q);
4498
4499 if (cid->seqnum >= f->retire) {
4500 continue;
4501 }
4502
4503 /* this connection id must be retired */
4504
4505 if (ngx_quic_retire_connection_id(c, pkt->level, cid->seqnum)
4506 != NGX_OK)
4507 {
4508 return NGX_ERROR;
4509 }
4510
4511 ngx_queue_remove(&cid->queue);
4512 ngx_queue_insert_head(&qc->free_client_ids, &cid->queue);
4513 qc->nclient_ids--;
4514 }
4515
4516 done:
4517
4518 if (qc->nclient_ids > qc->tp.active_connection_id_limit) {
4519 /*
4520 * After processing a NEW_CONNECTION_ID frame and
4521 * adding and retiring active connection IDs, if the number of active
4522 * connection IDs exceeds the value advertised in its
4523 * active_connection_id_limit transport parameter, an endpoint MUST
4524 * close the connection with an error of type CONNECTION_ID_LIMIT_ERROR.
4525 */
4526 qc->error = NGX_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR;
4527 qc->error_reason = "too many connection ids received";
4528 return NGX_ERROR;
4529 }
4530
4531 return NGX_OK;
4532 }
4533
4534
4535 static ngx_int_t
4536 ngx_quic_retire_connection_id(ngx_connection_t *c,
4537 enum ssl_encryption_level_t level, uint64_t seqnum)
4538 {
4539 ngx_quic_frame_t *frame;
4540 ngx_quic_connection_t *qc;
4541
4542 qc = ngx_quic_get_connection(c);
4543
4544 frame = ngx_quic_alloc_frame(c);
4545 if (frame == NULL) {
4546 return NGX_ERROR;
4547 }
4548
4549 frame->level = level;
4550 frame->type = NGX_QUIC_FT_RETIRE_CONNECTION_ID;
4551 frame->u.retire_cid.sequence_number = seqnum;
4552
4553 ngx_quic_queue_frame(qc, frame);
4554
4555 return NGX_OK;
4556 }
4557
4558
4559 static ngx_int_t
4560 ngx_quic_handle_retire_connection_id_frame(ngx_connection_t *c,
4561 ngx_quic_header_t *pkt, ngx_quic_retire_cid_frame_t *f)
4562 {
4563 ngx_queue_t *q;
4564 ngx_quic_server_id_t *sid;
4565 ngx_quic_connection_t *qc;
4566
4567 qc = ngx_quic_get_connection(c);
4568
4569 for (q = ngx_queue_head(&qc->server_ids);
4570 q != ngx_queue_sentinel(&qc->server_ids);
4571 q = ngx_queue_next(q))
4572 {
4573 sid = ngx_queue_data(q, ngx_quic_server_id_t, queue);
4574
4575 if (sid->seqnum == f->sequence_number) {
4576 ngx_queue_remove(q);
4577 ngx_queue_insert_tail(&qc->free_server_ids, &sid->queue);
4578 ngx_rbtree_delete(&c->listening->rbtree, &sid->udp.node);
4579 qc->nserver_ids--;
4580 break;
4581 }
4582 }
4583
4584 return ngx_quic_issue_server_ids(c);
4585 }
4586
4587
4588 static ngx_int_t
4589 ngx_quic_issue_server_ids(ngx_connection_t *c)
4590 {
4591 ngx_str_t dcid;
4592 ngx_uint_t n;
4593 ngx_quic_frame_t *frame;
4594 ngx_quic_server_id_t *sid;
4595 ngx_quic_connection_t *qc;
4596 u_char id[NGX_QUIC_SERVER_CID_LEN];
4597
4598 qc = ngx_quic_get_connection(c);
4599
4600 n = ngx_min(NGX_QUIC_MAX_SERVER_IDS, qc->ctp.active_connection_id_limit);
4601
4602 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
4603 "quic issue server ids has:%ui max:%ui", qc->nserver_ids, n);
4604
4605 while (qc->nserver_ids < n) {
4606 if (ngx_quic_create_server_id(c, id) != NGX_OK) {
4607 return NGX_ERROR;
4608 }
4609
4610 dcid.len = NGX_QUIC_SERVER_CID_LEN;
4611 dcid.data = id;
4612
4613 sid = ngx_quic_insert_server_id(c, qc, &dcid);
4614 if (sid == NULL) {
4615 return NGX_ERROR;
4616 }
4617
4618 frame = ngx_quic_alloc_frame(c);
4619 if (frame == NULL) {
4620 return NGX_ERROR;
4621 }
4622
4623 frame->level = ssl_encryption_application;
4624 frame->type = NGX_QUIC_FT_NEW_CONNECTION_ID;
4625 frame->u.ncid.seqnum = sid->seqnum;
4626 frame->u.ncid.retire = 0;
4627 frame->u.ncid.len = NGX_QUIC_SERVER_CID_LEN;
4628 ngx_memcpy(frame->u.ncid.cid, id, NGX_QUIC_SERVER_CID_LEN);
4629
4630 if (ngx_quic_new_sr_token(c, &dcid, qc->conf->sr_token_key,
4631 frame->u.ncid.srt)
4632 != NGX_OK)
4633 {
4634 return NGX_ERROR;
4635 }
4636
4637 ngx_quic_queue_frame(qc, frame);
4638 }
4639
4640 return NGX_OK;
4641 }
4642
4643
4644 static void
4645 ngx_quic_clear_temp_server_ids(ngx_connection_t *c)
4646 {
4647 ngx_queue_t *q, *next;
4648 ngx_quic_server_id_t *sid;
4649 ngx_quic_connection_t *qc;
4650
4651 qc = ngx_quic_get_connection(c);
4652
4653 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
4654 "quic clear temp server ids");
4655
4656 for (q = ngx_queue_head(&qc->server_ids);
4657 q != ngx_queue_sentinel(&qc->server_ids);
4658 q = next)
4659 {
4660 next = ngx_queue_next(q);
4661 sid = ngx_queue_data(q, ngx_quic_server_id_t, queue);
4662
4663 if (sid->seqnum != NGX_QUIC_UNSET_PN) {
4664 continue;
4665 }
4666
4667 ngx_queue_remove(q);
4668 ngx_queue_insert_tail(&qc->free_server_ids, &sid->queue);
4669 ngx_rbtree_delete(&c->listening->rbtree, &sid->udp.node);
4670 qc->nserver_ids--;
4671 }
4672 }
4673
4674
4675 static ngx_quic_server_id_t *
4676 ngx_quic_insert_server_id(ngx_connection_t *c, ngx_quic_connection_t *qc,
4677 ngx_str_t *id)
4678 {
4679 ngx_str_t dcid;
4680 ngx_quic_server_id_t *sid;
4681
4682 sid = ngx_quic_alloc_server_id(c, qc);
4683 if (sid == NULL) {
4684 return NULL;
4685 }
4686
4687 sid->quic = qc;
4688
4689 sid->seqnum = qc->server_seqnum;
4690
4691 if (qc->server_seqnum != NGX_QUIC_UNSET_PN) {
4692 qc->server_seqnum++;
4693 }
4694
4695 sid->len = id->len;
4696 ngx_memcpy(sid->id, id->data, id->len);
4697
4698 ngx_queue_insert_tail(&qc->server_ids, &sid->queue);
4699 qc->nserver_ids++;
4700
4701 dcid.data = sid->id;
4702 dcid.len = sid->len;
4703
4704 ngx_insert_udp_connection(c, &sid->udp, &dcid);
4705
4706 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
4707 "quic insert server id seqnum:%uL id len:%uz %xV",
4708 sid->seqnum, id->len, id);
4709
4710 return sid;
4711 }
4712
4713
4714 static ngx_quic_client_id_t *
4715 ngx_quic_alloc_client_id(ngx_connection_t *c, ngx_quic_connection_t *qc)
4716 {
4717 ngx_queue_t *q;
4718 ngx_quic_client_id_t *cid;
4719
4720 if (!ngx_queue_empty(&qc->free_client_ids)) {
4721
4722 q = ngx_queue_head(&qc->free_client_ids);
4723 cid = ngx_queue_data(q, ngx_quic_client_id_t, queue);
4724
4725 ngx_queue_remove(&cid->queue);
4726
4727 ngx_memzero(cid, sizeof(ngx_quic_client_id_t));
4728
4729 } else {
4730
4731 cid = ngx_pcalloc(c->pool, sizeof(ngx_quic_client_id_t));
4732 if (cid == NULL) {
4733 return NULL;
4734 }
4735 }
4736
4737 return cid;
4738 }
4739
4740
4741 static ngx_quic_server_id_t *
4742 ngx_quic_alloc_server_id(ngx_connection_t *c, ngx_quic_connection_t *qc)
4743 {
4744 ngx_queue_t *q;
4745 ngx_quic_server_id_t *sid;
4746
4747 if (!ngx_queue_empty(&qc->free_server_ids)) {
4748
4749 q = ngx_queue_head(&qc->free_server_ids);
4750 sid = ngx_queue_data(q, ngx_quic_server_id_t, queue);
4751
4752 ngx_queue_remove(&sid->queue);
4753
4754 ngx_memzero(sid, sizeof(ngx_quic_server_id_t));
4755
4756 } else {
4757
4758 sid = ngx_pcalloc(c->pool, sizeof(ngx_quic_server_id_t));
4759 if (sid == NULL) {
4760 return NULL;
4761 }
4762 }
4763
4764 return sid;
4765 }
4766
4767
4768 void 4241 void
4769 ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame) 4242 ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame)
4770 { 4243 {
4771 ngx_quic_send_ctx_t *ctx; 4244 ngx_quic_send_ctx_t *ctx;
4772 4245