comparison src/event/ngx_event_quic.c @ 8628:45db1b5c1706 quic

QUIC: connection multiplexing per port. Also, connection migration within a single worker is implemented.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 11 Nov 2020 11:57:50 +0000
parents 405b6e8eb523
children feec2cc762f6
comparison
equal deleted inserted replaced
8627:405b6e8eb523 8628:45db1b5c1706
119 ngx_str_t scid; /* initial client ID */ 119 ngx_str_t scid; /* initial client ID */
120 ngx_str_t dcid; /* server (our own) ID */ 120 ngx_str_t dcid; /* server (our own) ID */
121 ngx_str_t odcid; /* original server ID */ 121 ngx_str_t odcid; /* original server ID */
122 ngx_str_t token; 122 ngx_str_t token;
123 123
124 struct sockaddr *sockaddr;
125 socklen_t socklen;
126
124 ngx_queue_t client_ids; 127 ngx_queue_t client_ids;
128 ngx_queue_t server_ids;
125 ngx_queue_t free_client_ids; 129 ngx_queue_t free_client_ids;
130 ngx_queue_t free_server_ids;
126 ngx_uint_t nclient_ids; 131 ngx_uint_t nclient_ids;
132 ngx_uint_t nserver_ids;
127 uint64_t max_retired_seqnum; 133 uint64_t max_retired_seqnum;
128 uint64_t client_seqnum; 134 uint64_t client_seqnum;
135 uint64_t server_seqnum;
129 136
130 ngx_uint_t client_tp_done; 137 ngx_uint_t client_tp_done;
131 ngx_quic_tp_t tp; 138 ngx_quic_tp_t tp;
132 ngx_quic_tp_t ctp; 139 ngx_quic_tp_t ctp;
133 140
181 uint64_t seqnum; 188 uint64_t seqnum;
182 size_t len; 189 size_t len;
183 u_char id[NGX_QUIC_CID_LEN_MAX]; 190 u_char id[NGX_QUIC_CID_LEN_MAX];
184 u_char sr_token[NGX_QUIC_SR_TOKEN_LEN]; 191 u_char sr_token[NGX_QUIC_SR_TOKEN_LEN];
185 } ngx_quic_client_id_t; 192 } ngx_quic_client_id_t;
193
194
195 typedef struct {
196 ngx_udp_connection_t udp;
197 ngx_queue_t queue;
198 uint64_t seqnum;
199 size_t len;
200 u_char id[NGX_QUIC_CID_LEN_MAX];
201 } ngx_quic_server_id_t;
186 202
187 203
188 typedef ngx_int_t (*ngx_quic_frame_handler_pt)(ngx_connection_t *c, 204 typedef ngx_int_t (*ngx_quic_frame_handler_pt)(ngx_connection_t *c,
189 ngx_quic_frame_t *frame, void *data); 205 ngx_quic_frame_t *frame, void *data);
190 206
215 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); 231 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
216 static ngx_int_t ngx_quic_process_stateless_reset(ngx_connection_t *c, 232 static ngx_int_t ngx_quic_process_stateless_reset(ngx_connection_t *c,
217 ngx_quic_header_t *pkt); 233 ngx_quic_header_t *pkt);
218 static ngx_int_t ngx_quic_negotiate_version(ngx_connection_t *c, 234 static ngx_int_t ngx_quic_negotiate_version(ngx_connection_t *c,
219 ngx_quic_header_t *inpkt); 235 ngx_quic_header_t *inpkt);
220 static ngx_int_t ngx_quic_new_dcid(ngx_connection_t *c, 236 static ngx_int_t ngx_quic_create_server_id(ngx_connection_t *c, u_char *id);
221 ngx_quic_connection_t *qc, ngx_str_t *odcid);
222 static ngx_int_t ngx_quic_send_retry(ngx_connection_t *c); 237 static ngx_int_t ngx_quic_send_retry(ngx_connection_t *c);
223 static ngx_int_t ngx_quic_new_token(ngx_connection_t *c, ngx_str_t *token); 238 static ngx_int_t ngx_quic_new_token(ngx_connection_t *c, ngx_str_t *token);
224 static ngx_int_t ngx_quic_validate_token(ngx_connection_t *c, 239 static ngx_int_t ngx_quic_validate_token(ngx_connection_t *c,
225 ngx_quic_header_t *pkt); 240 ngx_quic_header_t *pkt);
226 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c); 241 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c);
302 ngx_quic_header_t *pkt, ngx_quic_path_challenge_frame_t *f); 317 ngx_quic_header_t *pkt, ngx_quic_path_challenge_frame_t *f);
303 static ngx_int_t ngx_quic_handle_new_connection_id_frame(ngx_connection_t *c, 318 static ngx_int_t ngx_quic_handle_new_connection_id_frame(ngx_connection_t *c,
304 ngx_quic_header_t *pkt, ngx_quic_new_conn_id_frame_t *f); 319 ngx_quic_header_t *pkt, ngx_quic_new_conn_id_frame_t *f);
305 static ngx_int_t ngx_quic_retire_connection_id(ngx_connection_t *c, 320 static ngx_int_t ngx_quic_retire_connection_id(ngx_connection_t *c,
306 enum ssl_encryption_level_t level, uint64_t seqnum); 321 enum ssl_encryption_level_t level, uint64_t seqnum);
322 static ngx_int_t ngx_quic_handle_retire_connection_id_frame(ngx_connection_t *c,
323 ngx_quic_header_t *pkt, ngx_quic_retire_cid_frame_t *f);
324 static ngx_int_t ngx_quic_issue_server_ids(ngx_connection_t *c);
325 static void ngx_quic_clear_temp_server_ids(ngx_connection_t *c);
326 static ngx_quic_server_id_t *ngx_quic_insert_server_id(ngx_connection_t *c,
327 ngx_str_t *id);
307 static ngx_quic_client_id_t *ngx_quic_alloc_client_id(ngx_connection_t *c, 328 static ngx_quic_client_id_t *ngx_quic_alloc_client_id(ngx_connection_t *c,
329 ngx_quic_connection_t *qc);
330 static ngx_quic_server_id_t *ngx_quic_alloc_server_id(ngx_connection_t *c,
308 ngx_quic_connection_t *qc); 331 ngx_quic_connection_t *qc);
309 332
310 static void ngx_quic_queue_frame(ngx_quic_connection_t *qc, 333 static void ngx_quic_queue_frame(ngx_quic_connection_t *qc,
311 ngx_quic_frame_t *frame); 334 ngx_quic_frame_t *frame);
312 335
437 case NGX_QUIC_FT_PING: 460 case NGX_QUIC_FT_PING:
438 p = ngx_slprintf(p, last, "PING"); 461 p = ngx_slprintf(p, last, "PING");
439 break; 462 break;
440 463
441 case NGX_QUIC_FT_NEW_CONNECTION_ID: 464 case NGX_QUIC_FT_NEW_CONNECTION_ID:
442 p = ngx_slprintf(p, last, "NCID seq:%uL retire:%uL len:%ud", 465 p = ngx_slprintf(p, last,
466 "NEW_CONNECTION_ID seq:%uL retire:%uL len:%ud",
443 f->u.ncid.seqnum, f->u.ncid.retire, f->u.ncid.len); 467 f->u.ncid.seqnum, f->u.ncid.retire, f->u.ncid.len);
444 break; 468 break;
445 469
446 case NGX_QUIC_FT_RETIRE_CONNECTION_ID: 470 case NGX_QUIC_FT_RETIRE_CONNECTION_ID:
447 p = ngx_slprintf(p, last, "RETIRE_CONNECTION_ID seqnum:%uL", 471 p = ngx_slprintf(p, last, "RETIRE_CONNECTION_ID seqnum:%uL",
981 ngx_queue_init(&qc->crypto[i].frames); 1005 ngx_queue_init(&qc->crypto[i].frames);
982 } 1006 }
983 1007
984 ngx_queue_init(&qc->free_frames); 1008 ngx_queue_init(&qc->free_frames);
985 ngx_queue_init(&qc->client_ids); 1009 ngx_queue_init(&qc->client_ids);
1010 ngx_queue_init(&qc->server_ids);
986 ngx_queue_init(&qc->free_client_ids); 1011 ngx_queue_init(&qc->free_client_ids);
1012 ngx_queue_init(&qc->free_server_ids);
987 1013
988 qc->avg_rtt = NGX_QUIC_INITIAL_RTT; 1014 qc->avg_rtt = NGX_QUIC_INITIAL_RTT;
989 qc->rttvar = NGX_QUIC_INITIAL_RTT / 2; 1015 qc->rttvar = NGX_QUIC_INITIAL_RTT / 2;
990 qc->min_rtt = NGX_TIMER_INFINITE; 1016 qc->min_rtt = NGX_TIMER_INFINITE;
991 1017
992 /* 1018 /*
993 * qc->latest_rtt = 0 1019 * qc->latest_rtt = 0
994 * qc->nclient_ids = 0 1020 * qc->nclient_ids = 0
1021 * qc->nserver_ids = 0
995 * qc->max_retired_seqnum = 0 1022 * qc->max_retired_seqnum = 0
996 */ 1023 */
997 1024
998 qc->received = pkt->raw->last - pkt->raw->start; 1025 qc->received = pkt->raw->last - pkt->raw->start;
999 1026
1007 qc->push.handler = ngx_quic_push_handler; 1034 qc->push.handler = ngx_quic_push_handler;
1008 qc->push.cancelable = 1; 1035 qc->push.cancelable = 1;
1009 1036
1010 qc->conf = conf; 1037 qc->conf = conf;
1011 qc->tp = conf->tp; 1038 qc->tp = conf->tp;
1039
1040 if (qc->tp.disable_active_migration) {
1041 qc->sockaddr = ngx_palloc(c->pool, c->socklen);
1042 if (qc->sockaddr == NULL) {
1043 return NULL;
1044 }
1045
1046 ngx_memcpy(qc->sockaddr, c->sockaddr, c->socklen);
1047 qc->socklen = c->socklen;
1048 }
1012 1049
1013 ctp = &qc->ctp; 1050 ctp = &qc->ctp;
1014 ctp->max_udp_payload_size = ngx_quic_max_udp_payload(c); 1051 ctp->max_udp_payload_size = ngx_quic_max_udp_payload(c);
1015 ctp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT; 1052 ctp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT;
1016 ctp->max_ack_delay = NGX_QUIC_DEFAULT_MAX_ACK_DELAY; 1053 ctp->max_ack_delay = NGX_QUIC_DEFAULT_MAX_ACK_DELAY;
1024 ngx_max(2 * qc->tp.max_udp_payload_size, 1061 ngx_max(2 * qc->tp.max_udp_payload_size,
1025 14720)); 1062 14720));
1026 qc->congestion.ssthresh = (size_t) -1; 1063 qc->congestion.ssthresh = (size_t) -1;
1027 qc->congestion.recovery_start = ngx_current_msec; 1064 qc->congestion.recovery_start = ngx_current_msec;
1028 1065
1029 if (ngx_quic_new_dcid(c, qc, &pkt->dcid) != NGX_OK) { 1066 qc->odcid.len = pkt->dcid.len;
1067 qc->odcid.data = ngx_pstrdup(c->pool, &pkt->dcid);
1068 if (qc->odcid.data == NULL) {
1069 return NULL;
1070 }
1071
1072 qc->dcid.len = NGX_QUIC_SERVER_CID_LEN;
1073 qc->dcid.data = ngx_pnalloc(c->pool, qc->dcid.len);
1074 if (qc->dcid.data == NULL) {
1075 return NULL;
1076 }
1077
1078 if (ngx_quic_create_server_id(c, qc->dcid.data) != NGX_OK) {
1030 return NULL; 1079 return NULL;
1031 } 1080 }
1032 1081
1033 #if (NGX_QUIC_DRAFT_VERSION >= 28) 1082 #if (NGX_QUIC_DRAFT_VERSION >= 28)
1034 qc->tp.original_dcid = qc->odcid; 1083 qc->tp.original_dcid = qc->odcid;
1052 ngx_memcpy(cid->id, pkt->scid.data, pkt->scid.len); 1101 ngx_memcpy(cid->id, pkt->scid.data, pkt->scid.len);
1053 1102
1054 ngx_queue_insert_tail(&qc->client_ids, &cid->queue); 1103 ngx_queue_insert_tail(&qc->client_ids, &cid->queue);
1055 qc->nclient_ids++; 1104 qc->nclient_ids++;
1056 qc->client_seqnum = 0; 1105 qc->client_seqnum = 0;
1106
1107 qc->server_seqnum = NGX_QUIC_UNSET_PN;
1057 1108
1058 return qc; 1109 return qc;
1059 } 1110 }
1060 1111
1061 1112
1184 return NGX_ERROR; 1235 return NGX_ERROR;
1185 } 1236 }
1186 1237
1187 1238
1188 static ngx_int_t 1239 static ngx_int_t
1189 ngx_quic_new_dcid(ngx_connection_t *c, ngx_quic_connection_t *qc, 1240 ngx_quic_create_server_id(ngx_connection_t *c, u_char *id)
1190 ngx_str_t *odcid) 1241 {
1191 { 1242 if (RAND_bytes(id, NGX_QUIC_SERVER_CID_LEN) != 1) {
1192 qc->dcid.len = NGX_QUIC_SERVER_CID_LEN;
1193 qc->dcid.data = ngx_pnalloc(c->pool, NGX_QUIC_SERVER_CID_LEN);
1194 if (qc->dcid.data == NULL) {
1195 return NGX_ERROR; 1243 return NGX_ERROR;
1196 } 1244 }
1197 1245
1198 if (RAND_bytes(qc->dcid.data, NGX_QUIC_SERVER_CID_LEN) != 1) { 1246 ngx_quic_hexdump(c->log, "quic create server id",
1199 return NGX_ERROR; 1247 id, NGX_QUIC_SERVER_CID_LEN);
1200 }
1201
1202 ngx_quic_hexdump(c->log, "quic server CID", qc->dcid.data, qc->dcid.len);
1203
1204 qc->odcid.len = odcid->len;
1205 qc->odcid.data = ngx_pstrdup(c->pool, odcid);
1206 if (qc->odcid.data == NULL) {
1207 return NGX_ERROR;
1208 }
1209 1248
1210 return NGX_OK; 1249 return NGX_OK;
1211 } 1250 }
1212 1251
1213 1252
1251 #if (NGX_QUIC_DRAFT_VERSION < 28) 1290 #if (NGX_QUIC_DRAFT_VERSION < 28)
1252 c->quic->tp.original_dcid = c->quic->odcid; 1291 c->quic->tp.original_dcid = c->quic->odcid;
1253 #endif 1292 #endif
1254 c->quic->tp.retry_scid = c->quic->dcid; 1293 c->quic->tp.retry_scid = c->quic->dcid;
1255 c->quic->in_retry = 1; 1294 c->quic->in_retry = 1;
1295
1296 if (ngx_quic_insert_server_id(c, &c->quic->dcid) == NULL) {
1297 return NGX_ERROR;
1298 }
1256 1299
1257 return NGX_OK; 1300 return NGX_OK;
1258 } 1301 }
1259 1302
1260 1303
1627 c->read->eof = 1; 1670 c->read->eof = 1;
1628 ngx_quic_close_connection(c, NGX_ERROR); 1671 ngx_quic_close_connection(c, NGX_ERROR);
1629 return; 1672 return;
1630 } 1673 }
1631 1674
1675 if (qc->tp.disable_active_migration) {
1676 if (c->socklen != qc->socklen
1677 || ngx_memcmp(c->sockaddr, qc->sockaddr, c->socklen) != 0)
1678 {
1679 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
1680 "quic dropping packet from new address");
1681 return;
1682 }
1683 }
1684
1632 b.last += n; 1685 b.last += n;
1633 qc->received += n; 1686 qc->received += n;
1634 1687
1635 rc = ngx_quic_input(c, &b, NULL); 1688 rc = ngx_quic_input(c, &b, NULL);
1636 1689
1692 1745
1693 static ngx_int_t 1746 static ngx_int_t
1694 ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc) 1747 ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc)
1695 { 1748 {
1696 ngx_uint_t i; 1749 ngx_uint_t i;
1750 ngx_queue_t *q;
1697 ngx_quic_send_ctx_t *ctx; 1751 ngx_quic_send_ctx_t *ctx;
1752 ngx_quic_server_id_t *sid;
1698 ngx_quic_connection_t *qc; 1753 ngx_quic_connection_t *qc;
1699 1754
1700 qc = c->quic; 1755 qc = c->quic;
1701 1756
1702 if (!qc->closing) { 1757 if (!qc->closing) {
1797 } 1852 }
1798 1853
1799 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { 1854 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
1800 ngx_quic_free_frames(c, &qc->send_ctx[i].frames); 1855 ngx_quic_free_frames(c, &qc->send_ctx[i].frames);
1801 ngx_quic_free_frames(c, &qc->send_ctx[i].sent); 1856 ngx_quic_free_frames(c, &qc->send_ctx[i].sent);
1857 }
1858
1859 while (!ngx_queue_empty(&qc->server_ids)) {
1860 q = ngx_queue_head(&qc->server_ids);
1861 sid = ngx_queue_data(q, ngx_quic_server_id_t, queue);
1862
1863 ngx_queue_remove(q);
1864 ngx_rbtree_delete(&c->listening->rbtree, &sid->udp.node);
1865 qc->nserver_ids--;
1802 } 1866 }
1803 1867
1804 if (qc->close.timer_set) { 1868 if (qc->close.timer_set) {
1805 return NGX_AGAIN; 1869 return NGX_AGAIN;
1806 } 1870 }
2063 ngx_log_error(NGX_LOG_INFO, c->log, 0, 2127 ngx_log_error(NGX_LOG_INFO, c->log, 0,
2064 "quic discard retry packet without token"); 2128 "quic discard retry packet without token");
2065 return NGX_DECLINED; 2129 return NGX_DECLINED;
2066 } 2130 }
2067 2131
2068 if (ngx_quic_new_dcid(c, qc, &pkt->dcid) != NGX_OK) { 2132 qc->odcid.len = pkt->dcid.len;
2133 qc->odcid.data = ngx_pstrdup(c->pool, &pkt->dcid);
2134 if (qc->odcid.data == NULL) {
2135 return NGX_ERROR;
2136 }
2137
2138 ngx_quic_clear_temp_server_ids(c);
2139
2140 if (ngx_quic_create_server_id(c, qc->dcid.data) != NGX_OK) {
2141 return NGX_ERROR;
2142 }
2143
2144 qc->server_seqnum = 0;
2145
2146 if (ngx_quic_insert_server_id(c, &qc->dcid) == NULL) {
2069 return NGX_ERROR; 2147 return NGX_ERROR;
2070 } 2148 }
2071 2149
2072 qc->tp.initial_scid = qc->dcid; 2150 qc->tp.initial_scid = qc->dcid;
2073 qc->in_retry = 0; 2151 qc->in_retry = 0;
2135 2213
2136 if (ngx_quic_init_secrets(c) != NGX_OK) { 2214 if (ngx_quic_init_secrets(c) != NGX_OK) {
2137 return NGX_ERROR; 2215 return NGX_ERROR;
2138 } 2216 }
2139 2217
2218 if (ngx_quic_insert_server_id(c, &qc->odcid) == NULL) {
2219 return NGX_ERROR;
2220 }
2221
2222 qc->server_seqnum = 0;
2223
2224 if (ngx_quic_insert_server_id(c, &qc->dcid) == NULL) {
2225 return NGX_ERROR;
2226 }
2227
2140 } else if (pkt->level == ssl_encryption_application) { 2228 } else if (pkt->level == ssl_encryption_application) {
2141 return ngx_quic_send_stateless_reset(c, conf, pkt); 2229 return ngx_quic_send_stateless_reset(c, conf, pkt);
2142 2230
2143 } else { 2231 } else {
2144 return NGX_ERROR; 2232 return NGX_ERROR;
2268 f = ngx_queue_data(q, ngx_quic_frame_t, queue); 2356 f = ngx_queue_data(q, ngx_quic_frame_t, queue);
2269 ngx_quic_congestion_ack(c, f); 2357 ngx_quic_congestion_ack(c, f);
2270 ngx_quic_free_frame(c, f); 2358 ngx_quic_free_frame(c, f);
2271 } 2359 }
2272 2360
2361 if (level == ssl_encryption_initial) {
2362 ngx_quic_clear_temp_server_ids(c);
2363 }
2364
2273 ctx->send_ack = 0; 2365 ctx->send_ack = 0;
2274 } 2366 }
2275 2367
2276 2368
2277 static ngx_int_t 2369 static ngx_int_t
2278 ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt) 2370 ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt)
2279 { 2371 {
2280 ngx_str_t *dcid;
2281 ngx_queue_t *q; 2372 ngx_queue_t *q;
2282 ngx_quic_send_ctx_t *ctx;
2283 ngx_quic_client_id_t *cid; 2373 ngx_quic_client_id_t *cid;
2284 2374
2285 dcid = (pkt->level == ssl_encryption_early_data) ? &qc->odcid : &qc->dcid; 2375 if (pkt->level == ssl_encryption_application) {
2286 2376 return NGX_OK;
2287 if (pkt->dcid.len == dcid->len 2377 }
2288 && ngx_memcmp(pkt->dcid.data, dcid->data, dcid->len) == 0)
2289 {
2290 if (pkt->level == ssl_encryption_application) {
2291 return NGX_OK;
2292 }
2293
2294 goto found;
2295 }
2296
2297 /*
2298 * a packet sent in response to an initial client packet might be lost,
2299 * thus check also for old dcid
2300 */
2301 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_initial);
2302
2303 if (pkt->level == ssl_encryption_initial
2304 && ctx->largest_ack == NGX_QUIC_UNSET_PN)
2305 {
2306 if (pkt->dcid.len == qc->odcid.len
2307 && ngx_memcmp(pkt->dcid.data, qc->odcid.data, qc->odcid.len) == 0)
2308 {
2309 goto found;
2310 }
2311 }
2312
2313 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic dcid");
2314 return NGX_ERROR;
2315
2316 found:
2317 2378
2318 for (q = ngx_queue_head(&qc->client_ids); 2379 for (q = ngx_queue_head(&qc->client_ids);
2319 q != ngx_queue_sentinel(&qc->client_ids); 2380 q != ngx_queue_sentinel(&qc->client_ids);
2320 q = ngx_queue_next(q)) 2381 q = ngx_queue_next(q))
2321 { 2382 {
2531 } 2592 }
2532 2593
2533 break; 2594 break;
2534 2595
2535 case NGX_QUIC_FT_RETIRE_CONNECTION_ID: 2596 case NGX_QUIC_FT_RETIRE_CONNECTION_ID:
2597
2598 if (ngx_quic_handle_retire_connection_id_frame(c, pkt,
2599 &frame.u.retire_cid)
2600 != NGX_OK)
2601 {
2602 return NGX_ERROR;
2603 }
2604
2605 break;
2606
2536 case NGX_QUIC_FT_PATH_RESPONSE: 2607 case NGX_QUIC_FT_PATH_RESPONSE:
2537 2608
2538 /* TODO: handle */ 2609 /* TODO: handle */
2539 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, 2610 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
2540 "quic frame handler not implemented"); 2611 "quic frame handler not implemented");
3635 /* 3706 /*
3636 * 4.10.2 An endpoint MUST discard its handshake keys 3707 * 4.10.2 An endpoint MUST discard its handshake keys
3637 * when the TLS handshake is confirmed 3708 * when the TLS handshake is confirmed
3638 */ 3709 */
3639 ngx_quic_discard_ctx(c, ssl_encryption_handshake); 3710 ngx_quic_discard_ctx(c, ssl_encryption_handshake);
3711
3712 if (ngx_quic_issue_server_ids(c) != NGX_OK) {
3713 return NGX_ERROR;
3714 }
3640 3715
3641 return NGX_OK; 3716 return NGX_OK;
3642 } 3717 }
3643 3718
3644 3719
4263 4338
4264 return NGX_OK; 4339 return NGX_OK;
4265 } 4340 }
4266 4341
4267 4342
4343 static ngx_int_t
4344 ngx_quic_handle_retire_connection_id_frame(ngx_connection_t *c,
4345 ngx_quic_header_t *pkt, ngx_quic_retire_cid_frame_t *f)
4346 {
4347 ngx_queue_t *q;
4348 ngx_quic_server_id_t *sid;
4349 ngx_quic_connection_t *qc;
4350
4351 qc = c->quic;
4352
4353 for (q = ngx_queue_head(&qc->server_ids);
4354 q != ngx_queue_sentinel(&qc->server_ids);
4355 q = ngx_queue_next(q))
4356 {
4357 sid = ngx_queue_data(q, ngx_quic_server_id_t, queue);
4358
4359 if (sid->seqnum == f->sequence_number) {
4360 ngx_queue_remove(q);
4361 ngx_rbtree_delete(&c->listening->rbtree, &sid->udp.node);
4362 qc->nserver_ids--;
4363
4364 if (c->udp != &sid->udp) {
4365 ngx_queue_insert_tail(&qc->free_server_ids, &sid->queue);
4366 }
4367
4368 break;
4369 }
4370 }
4371
4372 return ngx_quic_issue_server_ids(c);
4373 }
4374
4375
4376 static ngx_int_t
4377 ngx_quic_issue_server_ids(ngx_connection_t *c)
4378 {
4379 ngx_str_t dcid;
4380 ngx_uint_t n;
4381 ngx_quic_frame_t *frame;
4382 ngx_quic_server_id_t *sid;
4383 ngx_quic_connection_t *qc;
4384 u_char id[NGX_QUIC_SERVER_CID_LEN];
4385
4386 qc = c->quic;
4387
4388 n = ngx_min(NGX_QUIC_MAX_SERVER_IDS, qc->ctp.active_connection_id_limit);
4389
4390 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
4391 "quic issue server ids has:%ui max:%ui", qc->nserver_ids, n);
4392
4393 while (qc->nserver_ids < n) {
4394 if (ngx_quic_create_server_id(c, id) != NGX_OK) {
4395 return NGX_ERROR;
4396 }
4397
4398 dcid.len = NGX_QUIC_SERVER_CID_LEN;
4399 dcid.data = id;
4400
4401 sid = ngx_quic_insert_server_id(c, &dcid);
4402 if (sid == NULL) {
4403 return NGX_ERROR;
4404 }
4405
4406 frame = ngx_quic_alloc_frame(c, 0);
4407 if (frame == NULL) {
4408 return NGX_ERROR;
4409 }
4410
4411 frame->level = ssl_encryption_application;
4412 frame->type = NGX_QUIC_FT_NEW_CONNECTION_ID;
4413 frame->u.ncid.seqnum = sid->seqnum;
4414 frame->u.ncid.retire = 0;
4415 frame->u.ncid.len = NGX_QUIC_SERVER_CID_LEN;
4416 ngx_memcpy(frame->u.ncid.cid, id, NGX_QUIC_SERVER_CID_LEN);
4417
4418 if (ngx_quic_new_sr_token(c, &dcid, &qc->conf->sr_token_key,
4419 frame->u.ncid.srt)
4420 != NGX_OK)
4421 {
4422 return NGX_ERROR;
4423 }
4424
4425 ngx_quic_queue_frame(c->quic, frame);
4426 }
4427
4428 return NGX_OK;
4429 }
4430
4431
4432 static void
4433 ngx_quic_clear_temp_server_ids(ngx_connection_t *c)
4434 {
4435 ngx_queue_t *q, *next;
4436 ngx_quic_server_id_t *sid;
4437 ngx_quic_connection_t *qc;
4438
4439 qc = c->quic;
4440
4441 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
4442 "quic clear temp server ids");
4443
4444 for (q = ngx_queue_head(&qc->server_ids);
4445 q != ngx_queue_sentinel(&qc->server_ids);
4446 q = next)
4447 {
4448 next = ngx_queue_next(q);
4449 sid = ngx_queue_data(q, ngx_quic_server_id_t, queue);
4450
4451 if (sid->seqnum != NGX_QUIC_UNSET_PN) {
4452 continue;
4453 }
4454
4455 ngx_queue_remove(q);
4456 ngx_rbtree_delete(&c->listening->rbtree, &sid->udp.node);
4457 qc->nserver_ids--;
4458
4459 if (c->udp != &sid->udp) {
4460 ngx_queue_insert_tail(&qc->free_server_ids, &sid->queue);
4461 }
4462 }
4463 }
4464
4465
4466 static ngx_quic_server_id_t *
4467 ngx_quic_insert_server_id(ngx_connection_t *c, ngx_str_t *id)
4468 {
4469 ngx_str_t dcid;
4470 ngx_quic_server_id_t *sid;
4471 ngx_quic_connection_t *qc;
4472
4473 qc = c->quic;
4474
4475 sid = ngx_quic_alloc_server_id(c, qc);
4476 if (sid == NULL) {
4477 return NULL;
4478 }
4479
4480 sid->seqnum = qc->server_seqnum;
4481
4482 if (qc->server_seqnum != NGX_QUIC_UNSET_PN) {
4483 qc->server_seqnum++;
4484 }
4485
4486 sid->len = id->len;
4487 ngx_memcpy(sid->id, id->data, id->len);
4488
4489 ngx_queue_insert_tail(&qc->server_ids, &sid->queue);
4490 qc->nserver_ids++;
4491
4492 dcid.data = sid->id;
4493 dcid.len = sid->len;
4494
4495 ngx_insert_udp_connection(c, &sid->udp, &dcid);
4496
4497 if (c->udp == NULL) {
4498 c->udp = &sid->udp;
4499 }
4500
4501 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
4502 "quic insert server id seqnum:%uL", sid->seqnum);
4503
4504 ngx_quic_hexdump(c->log, "quic server id", id->data, id->len);
4505
4506 return sid;
4507 }
4508
4509
4268 static ngx_quic_client_id_t * 4510 static ngx_quic_client_id_t *
4269 ngx_quic_alloc_client_id(ngx_connection_t *c, ngx_quic_connection_t *qc) 4511 ngx_quic_alloc_client_id(ngx_connection_t *c, ngx_quic_connection_t *qc)
4270 { 4512 {
4271 ngx_queue_t *q; 4513 ngx_queue_t *q;
4272 ngx_quic_client_id_t *cid; 4514 ngx_quic_client_id_t *cid;
4287 return NULL; 4529 return NULL;
4288 } 4530 }
4289 } 4531 }
4290 4532
4291 return cid; 4533 return cid;
4534 }
4535
4536
4537 static ngx_quic_server_id_t *
4538 ngx_quic_alloc_server_id(ngx_connection_t *c, ngx_quic_connection_t *qc)
4539 {
4540 ngx_queue_t *q;
4541 ngx_quic_server_id_t *sid;
4542
4543 if (!ngx_queue_empty(&qc->free_server_ids)) {
4544
4545 q = ngx_queue_head(&qc->free_server_ids);
4546 sid = ngx_queue_data(q, ngx_quic_server_id_t, queue);
4547
4548 ngx_queue_remove(&sid->queue);
4549
4550 ngx_memzero(sid, sizeof(ngx_quic_server_id_t));
4551
4552 } else {
4553
4554 sid = ngx_pcalloc(c->pool, sizeof(ngx_quic_server_id_t));
4555 if (sid == NULL) {
4556 return NULL;
4557 }
4558 }
4559
4560 return sid;
4292 } 4561 }
4293 4562
4294 4563
4295 static void 4564 static void
4296 ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame) 4565 ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame)