1 /*
2 * ngtcp2
3 *
4 * Copyright (c) 2017 ngtcp2 contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25 #include "ngtcp2_conn.h"
26
27 #include <string.h>
28 #include <assert.h>
29
30 #include "ngtcp2_macro.h"
31 #include "ngtcp2_log.h"
32 #include "ngtcp2_cid.h"
33 #include "ngtcp2_conv.h"
34 #include "ngtcp2_vec.h"
35 #include "ngtcp2_addr.h"
36 #include "ngtcp2_path.h"
37 #include "ngtcp2_rcvry.h"
38
39 /* NGTCP2_FLOW_WINDOW_RTT_FACTOR is the factor of RTT when flow
40 control window auto-tuning is triggered. */
41 #define NGTCP2_FLOW_WINDOW_RTT_FACTOR 2
42 /* NGTCP2_FLOW_WINDOW_SCALING_FACTOR is the growth factor of flow
43 control window. */
44 #define NGTCP2_FLOW_WINDOW_SCALING_FACTOR 2
45 /* NGTCP2_MIN_COALESCED_PAYLOADLEN is the minimum length of QUIC
46 packet payload that should be coalesced to a long packet. */
47 #define NGTCP2_MIN_COALESCED_PAYLOADLEN 128
48
49 /*
50 * conn_local_stream returns nonzero if |stream_id| indicates that it
51 * is the stream initiated by local endpoint.
52 */
conn_local_stream(ngtcp2_conn * conn,int64_t stream_id)53 static int conn_local_stream(ngtcp2_conn *conn, int64_t stream_id) {
54 return (uint8_t)(stream_id & 1) == conn->server;
55 }
56
57 /*
58 * bidi_stream returns nonzero if |stream_id| is a bidirectional
59 * stream ID.
60 */
bidi_stream(int64_t stream_id)61 static int bidi_stream(int64_t stream_id) { return (stream_id & 0x2) == 0; }
62
63 /*
64 * conn_is_handshake_completed returns nonzero if QUIC handshake has
65 * completed.
66 */
conn_is_handshake_completed(ngtcp2_conn * conn)67 static int conn_is_handshake_completed(ngtcp2_conn *conn) {
68 return (conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_COMPLETED) &&
69 conn->pktns.crypto.rx.ckm && conn->pktns.crypto.tx.ckm;
70 }
71
conn_call_recv_client_initial(ngtcp2_conn * conn,const ngtcp2_cid * dcid)72 static int conn_call_recv_client_initial(ngtcp2_conn *conn,
73 const ngtcp2_cid *dcid) {
74 int rv;
75
76 assert(conn->callbacks.recv_client_initial);
77
78 rv = conn->callbacks.recv_client_initial(conn, dcid, conn->user_data);
79 if (rv != 0) {
80 return NGTCP2_ERR_CALLBACK_FAILURE;
81 }
82
83 return 0;
84 }
85
conn_call_handshake_completed(ngtcp2_conn * conn)86 static int conn_call_handshake_completed(ngtcp2_conn *conn) {
87 int rv;
88
89 if (!conn->callbacks.handshake_completed) {
90 return 0;
91 }
92
93 rv = conn->callbacks.handshake_completed(conn, conn->user_data);
94 if (rv != 0) {
95 return NGTCP2_ERR_CALLBACK_FAILURE;
96 }
97
98 return 0;
99 }
100
conn_call_recv_stream_data(ngtcp2_conn * conn,ngtcp2_strm * strm,uint32_t flags,uint64_t offset,const uint8_t * data,size_t datalen)101 static int conn_call_recv_stream_data(ngtcp2_conn *conn, ngtcp2_strm *strm,
102 uint32_t flags, uint64_t offset,
103 const uint8_t *data, size_t datalen) {
104 int rv;
105
106 if (!conn->callbacks.recv_stream_data) {
107 return 0;
108 }
109
110 rv = conn->callbacks.recv_stream_data(conn, flags, strm->stream_id, offset,
111 data, datalen, conn->user_data,
112 strm->stream_user_data);
113 if (rv != 0) {
114 return NGTCP2_ERR_CALLBACK_FAILURE;
115 }
116
117 return 0;
118 }
119
conn_call_recv_crypto_data(ngtcp2_conn * conn,ngtcp2_crypto_level crypto_level,uint64_t offset,const uint8_t * data,size_t datalen)120 static int conn_call_recv_crypto_data(ngtcp2_conn *conn,
121 ngtcp2_crypto_level crypto_level,
122 uint64_t offset, const uint8_t *data,
123 size_t datalen) {
124 int rv;
125
126 assert(conn->callbacks.recv_crypto_data);
127
128 rv = conn->callbacks.recv_crypto_data(conn, crypto_level, offset, data,
129 datalen, conn->user_data);
130 switch (rv) {
131 case 0:
132 case NGTCP2_ERR_CRYPTO:
133 case NGTCP2_ERR_REQUIRED_TRANSPORT_PARAM:
134 case NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM:
135 case NGTCP2_ERR_TRANSPORT_PARAM:
136 case NGTCP2_ERR_PROTO:
137 case NGTCP2_ERR_VERSION_NEGOTIATION_FAILURE:
138 case NGTCP2_ERR_NOMEM:
139 case NGTCP2_ERR_CALLBACK_FAILURE:
140 return rv;
141 default:
142 return NGTCP2_ERR_CALLBACK_FAILURE;
143 }
144 }
145
conn_call_stream_open(ngtcp2_conn * conn,ngtcp2_strm * strm)146 static int conn_call_stream_open(ngtcp2_conn *conn, ngtcp2_strm *strm) {
147 int rv;
148
149 if (!conn->callbacks.stream_open) {
150 return 0;
151 }
152
153 rv = conn->callbacks.stream_open(conn, strm->stream_id, conn->user_data);
154 if (rv != 0) {
155 return NGTCP2_ERR_CALLBACK_FAILURE;
156 }
157
158 return 0;
159 }
160
conn_call_stream_close(ngtcp2_conn * conn,ngtcp2_strm * strm)161 static int conn_call_stream_close(ngtcp2_conn *conn, ngtcp2_strm *strm) {
162 int rv;
163 uint32_t flags = NGTCP2_STREAM_CLOSE_FLAG_NONE;
164
165 if (!conn->callbacks.stream_close) {
166 return 0;
167 }
168
169 if (strm->flags & NGTCP2_STRM_FLAG_APP_ERROR_CODE_SET) {
170 flags |= NGTCP2_STREAM_CLOSE_FLAG_APP_ERROR_CODE_SET;
171 }
172
173 rv = conn->callbacks.stream_close(conn, flags, strm->stream_id,
174 strm->app_error_code, conn->user_data,
175 strm->stream_user_data);
176 if (rv != 0) {
177 return NGTCP2_ERR_CALLBACK_FAILURE;
178 }
179
180 return 0;
181 }
182
conn_call_stream_reset(ngtcp2_conn * conn,int64_t stream_id,uint64_t final_size,uint64_t app_error_code,void * stream_user_data)183 static int conn_call_stream_reset(ngtcp2_conn *conn, int64_t stream_id,
184 uint64_t final_size, uint64_t app_error_code,
185 void *stream_user_data) {
186 int rv;
187
188 if (!conn->callbacks.stream_reset) {
189 return 0;
190 }
191
192 rv = conn->callbacks.stream_reset(conn, stream_id, final_size, app_error_code,
193 conn->user_data, stream_user_data);
194 if (rv != 0) {
195 return NGTCP2_ERR_CALLBACK_FAILURE;
196 }
197
198 return 0;
199 }
200
conn_call_extend_max_local_streams_bidi(ngtcp2_conn * conn,uint64_t max_streams)201 static int conn_call_extend_max_local_streams_bidi(ngtcp2_conn *conn,
202 uint64_t max_streams) {
203 int rv;
204
205 if (!conn->callbacks.extend_max_local_streams_bidi) {
206 return 0;
207 }
208
209 rv = conn->callbacks.extend_max_local_streams_bidi(conn, max_streams,
210 conn->user_data);
211 if (rv != 0) {
212 return NGTCP2_ERR_CALLBACK_FAILURE;
213 }
214
215 return 0;
216 }
217
conn_call_extend_max_local_streams_uni(ngtcp2_conn * conn,uint64_t max_streams)218 static int conn_call_extend_max_local_streams_uni(ngtcp2_conn *conn,
219 uint64_t max_streams) {
220 int rv;
221
222 if (!conn->callbacks.extend_max_local_streams_uni) {
223 return 0;
224 }
225
226 rv = conn->callbacks.extend_max_local_streams_uni(conn, max_streams,
227 conn->user_data);
228 if (rv != 0) {
229 return NGTCP2_ERR_CALLBACK_FAILURE;
230 }
231
232 return 0;
233 }
234
conn_call_get_new_connection_id(ngtcp2_conn * conn,ngtcp2_cid * cid,uint8_t * token,size_t cidlen)235 static int conn_call_get_new_connection_id(ngtcp2_conn *conn, ngtcp2_cid *cid,
236 uint8_t *token, size_t cidlen) {
237 int rv;
238
239 assert(conn->callbacks.get_new_connection_id);
240
241 rv = conn->callbacks.get_new_connection_id(conn, cid, token, cidlen,
242 conn->user_data);
243 if (rv != 0) {
244 return NGTCP2_ERR_CALLBACK_FAILURE;
245 }
246
247 return 0;
248 }
249
conn_call_remove_connection_id(ngtcp2_conn * conn,const ngtcp2_cid * cid)250 static int conn_call_remove_connection_id(ngtcp2_conn *conn,
251 const ngtcp2_cid *cid) {
252 int rv;
253
254 if (!conn->callbacks.remove_connection_id) {
255 return 0;
256 }
257
258 rv = conn->callbacks.remove_connection_id(conn, cid, conn->user_data);
259 if (rv != 0) {
260 return NGTCP2_ERR_CALLBACK_FAILURE;
261 }
262
263 return 0;
264 }
265
conn_call_path_validation(ngtcp2_conn * conn,const ngtcp2_pv * pv,ngtcp2_path_validation_result res)266 static int conn_call_path_validation(ngtcp2_conn *conn, const ngtcp2_pv *pv,
267 ngtcp2_path_validation_result res) {
268 int rv;
269 uint32_t flags = NGTCP2_PATH_VALIDATION_FLAG_NONE;
270
271 if (!conn->callbacks.path_validation) {
272 return 0;
273 }
274
275 if (pv->flags & NGTCP2_PV_FLAG_PREFERRED_ADDR) {
276 flags |= NGTCP2_PATH_VALIDATION_FLAG_PREFERRED_ADDR;
277 }
278
279 rv = conn->callbacks.path_validation(conn, flags, &pv->dcid.ps.path, res,
280 conn->user_data);
281 if (rv != 0) {
282 return NGTCP2_ERR_CALLBACK_FAILURE;
283 }
284
285 return 0;
286 }
287
conn_call_select_preferred_addr(ngtcp2_conn * conn,ngtcp2_path * dest)288 static int conn_call_select_preferred_addr(ngtcp2_conn *conn,
289 ngtcp2_path *dest) {
290 int rv;
291
292 if (!conn->callbacks.select_preferred_addr) {
293 return 0;
294 }
295
296 assert(conn->remote.transport_params);
297 assert(conn->remote.transport_params->preferred_address_present);
298
299 rv = conn->callbacks.select_preferred_addr(
300 conn, dest, &conn->remote.transport_params->preferred_address,
301 conn->user_data);
302 if (rv != 0) {
303 return NGTCP2_ERR_CALLBACK_FAILURE;
304 }
305
306 return 0;
307 }
308
conn_call_extend_max_remote_streams_bidi(ngtcp2_conn * conn,uint64_t max_streams)309 static int conn_call_extend_max_remote_streams_bidi(ngtcp2_conn *conn,
310 uint64_t max_streams) {
311 int rv;
312
313 if (!conn->callbacks.extend_max_remote_streams_bidi) {
314 return 0;
315 }
316
317 rv = conn->callbacks.extend_max_remote_streams_bidi(conn, max_streams,
318 conn->user_data);
319 if (rv != 0) {
320 return NGTCP2_ERR_CALLBACK_FAILURE;
321 }
322
323 return 0;
324 }
325
conn_call_extend_max_remote_streams_uni(ngtcp2_conn * conn,uint64_t max_streams)326 static int conn_call_extend_max_remote_streams_uni(ngtcp2_conn *conn,
327 uint64_t max_streams) {
328 int rv;
329
330 if (!conn->callbacks.extend_max_remote_streams_uni) {
331 return 0;
332 }
333
334 rv = conn->callbacks.extend_max_remote_streams_uni(conn, max_streams,
335 conn->user_data);
336 if (rv != 0) {
337 return NGTCP2_ERR_CALLBACK_FAILURE;
338 }
339
340 return 0;
341 }
342
conn_call_extend_max_stream_data(ngtcp2_conn * conn,ngtcp2_strm * strm,int64_t stream_id,uint64_t datalen)343 static int conn_call_extend_max_stream_data(ngtcp2_conn *conn,
344 ngtcp2_strm *strm,
345 int64_t stream_id,
346 uint64_t datalen) {
347 int rv;
348
349 if (!conn->callbacks.extend_max_stream_data) {
350 return 0;
351 }
352
353 rv = conn->callbacks.extend_max_stream_data(
354 conn, stream_id, datalen, conn->user_data, strm->stream_user_data);
355 if (rv != 0) {
356 return NGTCP2_ERR_CALLBACK_FAILURE;
357 }
358
359 return 0;
360 }
361
conn_call_dcid_status(ngtcp2_conn * conn,ngtcp2_connection_id_status_type type,const ngtcp2_dcid * dcid)362 static int conn_call_dcid_status(ngtcp2_conn *conn,
363 ngtcp2_connection_id_status_type type,
364 const ngtcp2_dcid *dcid) {
365 int rv;
366
367 if (!conn->callbacks.dcid_status) {
368 return 0;
369 }
370
371 rv = conn->callbacks.dcid_status(
372 conn, (int)type, dcid->seq, &dcid->cid,
373 (dcid->flags & NGTCP2_DCID_FLAG_TOKEN_PRESENT) ? dcid->token : NULL,
374 conn->user_data);
375 if (rv != 0) {
376 return NGTCP2_ERR_CALLBACK_FAILURE;
377 }
378
379 return 0;
380 }
381
conn_call_activate_dcid(ngtcp2_conn * conn,const ngtcp2_dcid * dcid)382 static int conn_call_activate_dcid(ngtcp2_conn *conn, const ngtcp2_dcid *dcid) {
383 return conn_call_dcid_status(conn, NGTCP2_CONNECTION_ID_STATUS_TYPE_ACTIVATE,
384 dcid);
385 }
386
conn_call_deactivate_dcid(ngtcp2_conn * conn,const ngtcp2_dcid * dcid)387 static int conn_call_deactivate_dcid(ngtcp2_conn *conn,
388 const ngtcp2_dcid *dcid) {
389 return conn_call_dcid_status(
390 conn, NGTCP2_CONNECTION_ID_STATUS_TYPE_DEACTIVATE, dcid);
391 }
392
conn_call_stream_stop_sending(ngtcp2_conn * conn,int64_t stream_id,uint64_t app_error_code,void * stream_user_data)393 static int conn_call_stream_stop_sending(ngtcp2_conn *conn, int64_t stream_id,
394 uint64_t app_error_code,
395 void *stream_user_data) {
396 int rv;
397
398 if (!conn->callbacks.stream_stop_sending) {
399 return 0;
400 }
401
402 rv = conn->callbacks.stream_stop_sending(conn, stream_id, app_error_code,
403 conn->user_data, stream_user_data);
404 if (rv != 0) {
405 return NGTCP2_ERR_CALLBACK_FAILURE;
406 }
407
408 return 0;
409 }
410
conn_call_delete_crypto_aead_ctx(ngtcp2_conn * conn,ngtcp2_crypto_aead_ctx * aead_ctx)411 static void conn_call_delete_crypto_aead_ctx(ngtcp2_conn *conn,
412 ngtcp2_crypto_aead_ctx *aead_ctx) {
413 if (!aead_ctx->native_handle) {
414 return;
415 }
416
417 assert(conn->callbacks.delete_crypto_aead_ctx);
418
419 conn->callbacks.delete_crypto_aead_ctx(conn, aead_ctx, conn->user_data);
420 }
421
422 static void
conn_call_delete_crypto_cipher_ctx(ngtcp2_conn * conn,ngtcp2_crypto_cipher_ctx * cipher_ctx)423 conn_call_delete_crypto_cipher_ctx(ngtcp2_conn *conn,
424 ngtcp2_crypto_cipher_ctx *cipher_ctx) {
425 if (!cipher_ctx->native_handle) {
426 return;
427 }
428
429 assert(conn->callbacks.delete_crypto_cipher_ctx);
430
431 conn->callbacks.delete_crypto_cipher_ctx(conn, cipher_ctx, conn->user_data);
432 }
433
conn_call_client_initial(ngtcp2_conn * conn)434 static int conn_call_client_initial(ngtcp2_conn *conn) {
435 int rv;
436
437 assert(conn->callbacks.client_initial);
438
439 rv = conn->callbacks.client_initial(conn, conn->user_data);
440 if (rv != 0) {
441 return NGTCP2_ERR_CALLBACK_FAILURE;
442 }
443
444 return 0;
445 }
446
conn_call_get_path_challenge_data(ngtcp2_conn * conn,uint8_t * data)447 static int conn_call_get_path_challenge_data(ngtcp2_conn *conn, uint8_t *data) {
448 int rv;
449
450 assert(conn->callbacks.get_path_challenge_data);
451
452 rv = conn->callbacks.get_path_challenge_data(conn, data, conn->user_data);
453 if (rv != 0) {
454 return NGTCP2_ERR_CALLBACK_FAILURE;
455 }
456
457 return 0;
458 }
459
conn_call_recv_version_negotiation(ngtcp2_conn * conn,const ngtcp2_pkt_hd * hd,const uint32_t * sv,size_t nsv)460 static int conn_call_recv_version_negotiation(ngtcp2_conn *conn,
461 const ngtcp2_pkt_hd *hd,
462 const uint32_t *sv, size_t nsv) {
463 int rv;
464
465 if (!conn->callbacks.recv_version_negotiation) {
466 return 0;
467 }
468
469 rv = conn->callbacks.recv_version_negotiation(conn, hd, sv, nsv,
470 conn->user_data);
471 if (rv != 0) {
472 return NGTCP2_ERR_CALLBACK_FAILURE;
473 }
474
475 return 0;
476 }
477
conn_call_recv_retry(ngtcp2_conn * conn,const ngtcp2_pkt_hd * hd)478 static int conn_call_recv_retry(ngtcp2_conn *conn, const ngtcp2_pkt_hd *hd) {
479 int rv;
480
481 assert(conn->callbacks.recv_retry);
482
483 rv = conn->callbacks.recv_retry(conn, hd, conn->user_data);
484 if (rv != 0) {
485 return NGTCP2_ERR_CALLBACK_FAILURE;
486 }
487
488 return 0;
489 }
490
491 static int
conn_call_recv_stateless_reset(ngtcp2_conn * conn,const ngtcp2_pkt_stateless_reset * sr)492 conn_call_recv_stateless_reset(ngtcp2_conn *conn,
493 const ngtcp2_pkt_stateless_reset *sr) {
494 int rv;
495
496 if (!conn->callbacks.recv_stateless_reset) {
497 return 0;
498 }
499
500 rv = conn->callbacks.recv_stateless_reset(conn, sr, conn->user_data);
501 if (rv != 0) {
502 return NGTCP2_ERR_CALLBACK_FAILURE;
503 }
504
505 return 0;
506 }
507
conn_call_recv_new_token(ngtcp2_conn * conn,const ngtcp2_vec * token)508 static int conn_call_recv_new_token(ngtcp2_conn *conn,
509 const ngtcp2_vec *token) {
510 int rv;
511
512 if (!conn->callbacks.recv_new_token) {
513 return 0;
514 }
515
516 rv = conn->callbacks.recv_new_token(conn, token, conn->user_data);
517 if (rv != 0) {
518 return NGTCP2_ERR_CALLBACK_FAILURE;
519 }
520
521 return 0;
522 }
523
conn_call_handshake_confirmed(ngtcp2_conn * conn)524 static int conn_call_handshake_confirmed(ngtcp2_conn *conn) {
525 int rv;
526
527 if (!conn->callbacks.handshake_confirmed) {
528 return 0;
529 }
530
531 rv = conn->callbacks.handshake_confirmed(conn, conn->user_data);
532 if (rv != 0) {
533 return NGTCP2_ERR_CALLBACK_FAILURE;
534 }
535
536 return 0;
537 }
538
conn_call_recv_datagram(ngtcp2_conn * conn,const ngtcp2_datagram * fr)539 static int conn_call_recv_datagram(ngtcp2_conn *conn,
540 const ngtcp2_datagram *fr) {
541 const uint8_t *data;
542 size_t datalen;
543 int rv;
544 uint32_t flags = NGTCP2_DATAGRAM_FLAG_NONE;
545
546 if (!conn->callbacks.recv_datagram) {
547 return 0;
548 }
549
550 if (fr->datacnt) {
551 assert(fr->datacnt == 1);
552
553 data = fr->data->base;
554 datalen = fr->data->len;
555 } else {
556 data = NULL;
557 datalen = 0;
558 }
559
560 if (!conn_is_handshake_completed(conn)) {
561 flags |= NGTCP2_DATAGRAM_FLAG_EARLY;
562 }
563
564 rv = conn->callbacks.recv_datagram(conn, flags, data, datalen,
565 conn->user_data);
566 if (rv != 0) {
567 return NGTCP2_ERR_CALLBACK_FAILURE;
568 }
569
570 return 0;
571 }
572
573 static int
conn_call_update_key(ngtcp2_conn * conn,uint8_t * rx_secret,uint8_t * tx_secret,ngtcp2_crypto_aead_ctx * rx_aead_ctx,uint8_t * rx_iv,ngtcp2_crypto_aead_ctx * tx_aead_ctx,uint8_t * tx_iv,const uint8_t * current_rx_secret,const uint8_t * current_tx_secret,size_t secretlen)574 conn_call_update_key(ngtcp2_conn *conn, uint8_t *rx_secret, uint8_t *tx_secret,
575 ngtcp2_crypto_aead_ctx *rx_aead_ctx, uint8_t *rx_iv,
576 ngtcp2_crypto_aead_ctx *tx_aead_ctx, uint8_t *tx_iv,
577 const uint8_t *current_rx_secret,
578 const uint8_t *current_tx_secret, size_t secretlen) {
579 int rv;
580
581 assert(conn->callbacks.update_key);
582
583 rv = conn->callbacks.update_key(
584 conn, rx_secret, tx_secret, rx_aead_ctx, rx_iv, tx_aead_ctx, tx_iv,
585 current_rx_secret, current_tx_secret, secretlen, conn->user_data);
586 if (rv != 0) {
587 return NGTCP2_ERR_CALLBACK_FAILURE;
588 }
589
590 return 0;
591 }
592
conn_call_version_negotiation(ngtcp2_conn * conn,uint32_t version,const ngtcp2_cid * dcid)593 static int conn_call_version_negotiation(ngtcp2_conn *conn, uint32_t version,
594 const ngtcp2_cid *dcid) {
595 int rv;
596
597 assert(conn->callbacks.version_negotiation);
598
599 rv =
600 conn->callbacks.version_negotiation(conn, version, dcid, conn->user_data);
601 if (rv != 0) {
602 return NGTCP2_ERR_CALLBACK_FAILURE;
603 }
604
605 return 0;
606 }
607
conn_call_recv_rx_key(ngtcp2_conn * conn,ngtcp2_crypto_level level)608 static int conn_call_recv_rx_key(ngtcp2_conn *conn, ngtcp2_crypto_level level) {
609 int rv;
610
611 if (!conn->callbacks.recv_rx_key) {
612 return 0;
613 }
614
615 rv = conn->callbacks.recv_rx_key(conn, level, conn->user_data);
616 if (rv != 0) {
617 return NGTCP2_ERR_CALLBACK_FAILURE;
618 }
619
620 return 0;
621 }
622
conn_call_recv_tx_key(ngtcp2_conn * conn,ngtcp2_crypto_level level)623 static int conn_call_recv_tx_key(ngtcp2_conn *conn, ngtcp2_crypto_level level) {
624 int rv;
625
626 if (!conn->callbacks.recv_tx_key) {
627 return 0;
628 }
629
630 rv = conn->callbacks.recv_tx_key(conn, level, conn->user_data);
631 if (rv != 0) {
632 return NGTCP2_ERR_CALLBACK_FAILURE;
633 }
634
635 return 0;
636 }
637
crypto_offset_less(const ngtcp2_ksl_key * lhs,const ngtcp2_ksl_key * rhs)638 static int crypto_offset_less(const ngtcp2_ksl_key *lhs,
639 const ngtcp2_ksl_key *rhs) {
640 return *(int64_t *)lhs < *(int64_t *)rhs;
641 }
642
pktns_init(ngtcp2_pktns * pktns,ngtcp2_pktns_id pktns_id,ngtcp2_rst * rst,ngtcp2_cc * cc,ngtcp2_log * log,ngtcp2_qlog * qlog,ngtcp2_objalloc * rtb_entry_objalloc,ngtcp2_objalloc * frc_objalloc,const ngtcp2_mem * mem)643 static int pktns_init(ngtcp2_pktns *pktns, ngtcp2_pktns_id pktns_id,
644 ngtcp2_rst *rst, ngtcp2_cc *cc, ngtcp2_log *log,
645 ngtcp2_qlog *qlog, ngtcp2_objalloc *rtb_entry_objalloc,
646 ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem) {
647 int rv;
648
649 memset(pktns, 0, sizeof(*pktns));
650
651 ngtcp2_gaptr_init(&pktns->rx.pngap, mem);
652
653 pktns->tx.last_pkt_num = -1;
654 pktns->rx.max_pkt_num = -1;
655 pktns->rx.max_ack_eliciting_pkt_num = -1;
656
657 rv = ngtcp2_acktr_init(&pktns->acktr, log, mem);
658 if (rv != 0) {
659 goto fail_acktr_init;
660 }
661
662 ngtcp2_strm_init(&pktns->crypto.strm, 0, NGTCP2_STRM_FLAG_NONE, 0, 0, NULL,
663 NULL, mem);
664
665 ngtcp2_ksl_init(&pktns->crypto.tx.frq, crypto_offset_less, sizeof(uint64_t),
666 mem);
667
668 ngtcp2_rtb_init(&pktns->rtb, pktns_id, &pktns->crypto.strm, rst, cc, log,
669 qlog, rtb_entry_objalloc, frc_objalloc, mem);
670
671 return 0;
672
673 fail_acktr_init:
674 ngtcp2_gaptr_free(&pktns->rx.pngap);
675
676 return rv;
677 }
678
pktns_new(ngtcp2_pktns ** ppktns,ngtcp2_pktns_id pktns_id,ngtcp2_rst * rst,ngtcp2_cc * cc,ngtcp2_log * log,ngtcp2_qlog * qlog,ngtcp2_objalloc * rtb_entry_objalloc,ngtcp2_objalloc * frc_objalloc,const ngtcp2_mem * mem)679 static int pktns_new(ngtcp2_pktns **ppktns, ngtcp2_pktns_id pktns_id,
680 ngtcp2_rst *rst, ngtcp2_cc *cc, ngtcp2_log *log,
681 ngtcp2_qlog *qlog, ngtcp2_objalloc *rtb_entry_objalloc,
682 ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem) {
683 int rv;
684
685 *ppktns = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_pktns));
686 if (*ppktns == NULL) {
687 return NGTCP2_ERR_NOMEM;
688 }
689
690 rv = pktns_init(*ppktns, pktns_id, rst, cc, log, qlog, rtb_entry_objalloc,
691 frc_objalloc, mem);
692 if (rv != 0) {
693 ngtcp2_mem_free(mem, *ppktns);
694 }
695
696 return rv;
697 }
698
cycle_less(const ngtcp2_pq_entry * lhs,const ngtcp2_pq_entry * rhs)699 static int cycle_less(const ngtcp2_pq_entry *lhs, const ngtcp2_pq_entry *rhs) {
700 ngtcp2_strm *ls = ngtcp2_struct_of(lhs, ngtcp2_strm, pe);
701 ngtcp2_strm *rs = ngtcp2_struct_of(rhs, ngtcp2_strm, pe);
702
703 if (ls->cycle == rs->cycle) {
704 return ls->stream_id < rs->stream_id;
705 }
706
707 return rs->cycle - ls->cycle <= 1;
708 }
709
delete_buffed_pkts(ngtcp2_pkt_chain * pc,const ngtcp2_mem * mem)710 static void delete_buffed_pkts(ngtcp2_pkt_chain *pc, const ngtcp2_mem *mem) {
711 ngtcp2_pkt_chain *next;
712
713 for (; pc;) {
714 next = pc->next;
715 ngtcp2_pkt_chain_del(pc, mem);
716 pc = next;
717 }
718 }
719
delete_buf_chain(ngtcp2_buf_chain * bufchain,const ngtcp2_mem * mem)720 static void delete_buf_chain(ngtcp2_buf_chain *bufchain,
721 const ngtcp2_mem *mem) {
722 ngtcp2_buf_chain *next;
723
724 for (; bufchain;) {
725 next = bufchain->next;
726 ngtcp2_buf_chain_del(bufchain, mem);
727 bufchain = next;
728 }
729 }
730
pktns_free(ngtcp2_pktns * pktns,const ngtcp2_mem * mem)731 static void pktns_free(ngtcp2_pktns *pktns, const ngtcp2_mem *mem) {
732 ngtcp2_frame_chain *frc;
733 ngtcp2_ksl_it it;
734
735 delete_buf_chain(pktns->crypto.tx.data, mem);
736
737 delete_buffed_pkts(pktns->rx.buffed_pkts, mem);
738
739 ngtcp2_frame_chain_list_objalloc_del(pktns->tx.frq, pktns->rtb.frc_objalloc,
740 mem);
741
742 ngtcp2_crypto_km_del(pktns->crypto.rx.ckm, mem);
743 ngtcp2_crypto_km_del(pktns->crypto.tx.ckm, mem);
744
745 for (it = ngtcp2_ksl_begin(&pktns->crypto.tx.frq); !ngtcp2_ksl_it_end(&it);
746 ngtcp2_ksl_it_next(&it)) {
747 frc = ngtcp2_ksl_it_get(&it);
748 ngtcp2_frame_chain_objalloc_del(frc, pktns->rtb.frc_objalloc, mem);
749 }
750
751 ngtcp2_ksl_free(&pktns->crypto.tx.frq);
752 ngtcp2_rtb_free(&pktns->rtb);
753 ngtcp2_strm_free(&pktns->crypto.strm);
754 ngtcp2_acktr_free(&pktns->acktr);
755 ngtcp2_gaptr_free(&pktns->rx.pngap);
756 }
757
pktns_del(ngtcp2_pktns * pktns,const ngtcp2_mem * mem)758 static void pktns_del(ngtcp2_pktns *pktns, const ngtcp2_mem *mem) {
759 if (pktns == NULL) {
760 return;
761 }
762
763 pktns_free(pktns, mem);
764
765 ngtcp2_mem_free(mem, pktns);
766 }
767
cc_del(ngtcp2_cc * cc,ngtcp2_cc_algo cc_algo,const ngtcp2_mem * mem)768 static void cc_del(ngtcp2_cc *cc, ngtcp2_cc_algo cc_algo,
769 const ngtcp2_mem *mem) {
770 switch (cc_algo) {
771 case NGTCP2_CC_ALGO_RENO:
772 ngtcp2_cc_reno_cc_free(cc, mem);
773 break;
774 case NGTCP2_CC_ALGO_CUBIC:
775 ngtcp2_cc_cubic_cc_free(cc, mem);
776 break;
777 case NGTCP2_CC_ALGO_BBR:
778 ngtcp2_cc_bbr_cc_free(cc, mem);
779 break;
780 case NGTCP2_CC_ALGO_BBR2:
781 ngtcp2_cc_bbr2_cc_free(cc, mem);
782 break;
783 default:
784 break;
785 }
786 }
787
cid_less(const ngtcp2_ksl_key * lhs,const ngtcp2_ksl_key * rhs)788 static int cid_less(const ngtcp2_ksl_key *lhs, const ngtcp2_ksl_key *rhs) {
789 return ngtcp2_cid_less(lhs, rhs);
790 }
791
retired_ts_less(const ngtcp2_pq_entry * lhs,const ngtcp2_pq_entry * rhs)792 static int retired_ts_less(const ngtcp2_pq_entry *lhs,
793 const ngtcp2_pq_entry *rhs) {
794 const ngtcp2_scid *a = ngtcp2_struct_of(lhs, ngtcp2_scid, pe);
795 const ngtcp2_scid *b = ngtcp2_struct_of(rhs, ngtcp2_scid, pe);
796
797 return a->retired_ts < b->retired_ts;
798 }
799
800 /*
801 * conn_reset_conn_stat_cc resets congestion state in |cstat|.
802 */
conn_reset_conn_stat_cc(ngtcp2_conn * conn,ngtcp2_conn_stat * cstat)803 static void conn_reset_conn_stat_cc(ngtcp2_conn *conn,
804 ngtcp2_conn_stat *cstat) {
805 cstat->latest_rtt = 0;
806 cstat->min_rtt = UINT64_MAX;
807 cstat->smoothed_rtt = conn->local.settings.initial_rtt;
808 cstat->rttvar = conn->local.settings.initial_rtt / 2;
809 cstat->first_rtt_sample_ts = UINT64_MAX;
810 cstat->pto_count = 0;
811 cstat->loss_detection_timer = UINT64_MAX;
812 cstat->cwnd =
813 ngtcp2_cc_compute_initcwnd(conn->local.settings.max_udp_payload_size);
814 cstat->ssthresh = UINT64_MAX;
815 cstat->congestion_recovery_start_ts = UINT64_MAX;
816 cstat->bytes_in_flight = 0;
817 cstat->delivery_rate_sec = 0;
818 cstat->pacing_rate = 0.0;
819 cstat->send_quantum = SIZE_MAX;
820 }
821
822 /*
823 * reset_conn_stat_recovery resets the fields related to the recovery
824 * function
825 */
reset_conn_stat_recovery(ngtcp2_conn_stat * cstat)826 static void reset_conn_stat_recovery(ngtcp2_conn_stat *cstat) {
827 /* Initializes them with UINT64_MAX. */
828 memset(cstat->loss_time, 0xff, sizeof(cstat->loss_time));
829 memset(cstat->last_tx_pkt_ts, 0xff, sizeof(cstat->last_tx_pkt_ts));
830 }
831
832 /*
833 * conn_reset_conn_stat resets |cstat|. The following fields are not
834 * reset: initial_rtt and max_udp_payload_size.
835 */
conn_reset_conn_stat(ngtcp2_conn * conn,ngtcp2_conn_stat * cstat)836 static void conn_reset_conn_stat(ngtcp2_conn *conn, ngtcp2_conn_stat *cstat) {
837 conn_reset_conn_stat_cc(conn, cstat);
838 reset_conn_stat_recovery(cstat);
839 }
840
delete_scid(ngtcp2_ksl * scids,const ngtcp2_mem * mem)841 static void delete_scid(ngtcp2_ksl *scids, const ngtcp2_mem *mem) {
842 ngtcp2_ksl_it it;
843
844 for (it = ngtcp2_ksl_begin(scids); !ngtcp2_ksl_it_end(&it);
845 ngtcp2_ksl_it_next(&it)) {
846 ngtcp2_mem_free(mem, ngtcp2_ksl_it_get(&it));
847 }
848 }
849
850 /*
851 * compute_pto computes PTO.
852 */
compute_pto(ngtcp2_duration smoothed_rtt,ngtcp2_duration rttvar,ngtcp2_duration max_ack_delay)853 static ngtcp2_duration compute_pto(ngtcp2_duration smoothed_rtt,
854 ngtcp2_duration rttvar,
855 ngtcp2_duration max_ack_delay) {
856 ngtcp2_duration var = ngtcp2_max(4 * rttvar, NGTCP2_GRANULARITY);
857 return smoothed_rtt + var + max_ack_delay;
858 }
859
860 /*
861 * conn_compute_initial_pto computes PTO using the initial RTT.
862 */
conn_compute_initial_pto(ngtcp2_conn * conn,ngtcp2_pktns * pktns)863 static ngtcp2_duration conn_compute_initial_pto(ngtcp2_conn *conn,
864 ngtcp2_pktns *pktns) {
865 ngtcp2_duration initial_rtt = conn->local.settings.initial_rtt;
866 ngtcp2_duration max_ack_delay;
867
868 if (pktns->rtb.pktns_id == NGTCP2_PKTNS_ID_APPLICATION &&
869 conn->remote.transport_params) {
870 max_ack_delay = conn->remote.transport_params->max_ack_delay;
871 } else {
872 max_ack_delay = 0;
873 }
874 return compute_pto(initial_rtt, initial_rtt / 2, max_ack_delay);
875 }
876
877 /*
878 * conn_compute_pto computes the current PTO.
879 */
conn_compute_pto(ngtcp2_conn * conn,ngtcp2_pktns * pktns)880 static ngtcp2_duration conn_compute_pto(ngtcp2_conn *conn,
881 ngtcp2_pktns *pktns) {
882 ngtcp2_conn_stat *cstat = &conn->cstat;
883 ngtcp2_duration max_ack_delay;
884
885 if (pktns->rtb.pktns_id == NGTCP2_PKTNS_ID_APPLICATION &&
886 conn->remote.transport_params) {
887 max_ack_delay = conn->remote.transport_params->max_ack_delay;
888 } else {
889 max_ack_delay = 0;
890 }
891 return compute_pto(cstat->smoothed_rtt, cstat->rttvar, max_ack_delay);
892 }
893
ngtcp2_conn_compute_pto(ngtcp2_conn * conn,ngtcp2_pktns * pktns)894 ngtcp2_duration ngtcp2_conn_compute_pto(ngtcp2_conn *conn,
895 ngtcp2_pktns *pktns) {
896 return conn_compute_pto(conn, pktns);
897 }
898
conn_handle_tx_ecn(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint16_t * prtb_entry_flags,ngtcp2_pktns * pktns,const ngtcp2_pkt_hd * hd,ngtcp2_tstamp ts)899 static void conn_handle_tx_ecn(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
900 uint16_t *prtb_entry_flags, ngtcp2_pktns *pktns,
901 const ngtcp2_pkt_hd *hd, ngtcp2_tstamp ts) {
902 assert(pi);
903
904 if (pi->ecn != NGTCP2_ECN_NOT_ECT) {
905 /* We have already made a transition of validation state and
906 deceided to send UDP datagram with ECN bit set. Coalesced QUIC
907 packets also bear ECN bits set. */
908 if (pktns->tx.ecn.start_pkt_num == INT64_MAX) {
909 pktns->tx.ecn.start_pkt_num = hd->pkt_num;
910 }
911
912 ++pktns->tx.ecn.validation_pkt_sent;
913
914 if (prtb_entry_flags) {
915 *prtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ECN;
916 }
917
918 ++pktns->tx.ecn.ect0;
919
920 return;
921 }
922
923 switch (conn->tx.ecn.state) {
924 case NGTCP2_ECN_STATE_TESTING:
925 if (conn->tx.ecn.validation_start_ts == UINT64_MAX) {
926 assert(0 == pktns->tx.ecn.validation_pkt_sent);
927 assert(0 == pktns->tx.ecn.validation_pkt_lost);
928
929 conn->tx.ecn.validation_start_ts = ts;
930 } else if (ts - conn->tx.ecn.validation_start_ts >=
931 3 * conn_compute_pto(conn, pktns)) {
932 conn->tx.ecn.state = NGTCP2_ECN_STATE_UNKNOWN;
933 break;
934 }
935
936 if (pktns->tx.ecn.start_pkt_num == INT64_MAX) {
937 pktns->tx.ecn.start_pkt_num = hd->pkt_num;
938 }
939
940 ++pktns->tx.ecn.validation_pkt_sent;
941
942 if (++conn->tx.ecn.dgram_sent == NGTCP2_ECN_MAX_NUM_VALIDATION_PKTS) {
943 conn->tx.ecn.state = NGTCP2_ECN_STATE_UNKNOWN;
944 }
945 /* fall through */
946 case NGTCP2_ECN_STATE_CAPABLE:
947 /* pi is provided per UDP datagram. */
948 assert(NGTCP2_ECN_NOT_ECT == pi->ecn);
949
950 pi->ecn = NGTCP2_ECN_ECT_0;
951
952 if (prtb_entry_flags) {
953 *prtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ECN;
954 }
955
956 ++pktns->tx.ecn.ect0;
957 break;
958 case NGTCP2_ECN_STATE_UNKNOWN:
959 case NGTCP2_ECN_STATE_FAILED:
960 break;
961 default:
962 assert(0);
963 }
964 }
965
conn_reset_ecn_validation_state(ngtcp2_conn * conn)966 static void conn_reset_ecn_validation_state(ngtcp2_conn *conn) {
967 ngtcp2_pktns *in_pktns = conn->in_pktns;
968 ngtcp2_pktns *hs_pktns = conn->hs_pktns;
969 ngtcp2_pktns *pktns = &conn->pktns;
970
971 conn->tx.ecn.state = NGTCP2_ECN_STATE_TESTING;
972 conn->tx.ecn.validation_start_ts = UINT64_MAX;
973 conn->tx.ecn.dgram_sent = 0;
974
975 if (in_pktns) {
976 in_pktns->tx.ecn.start_pkt_num = INT64_MAX;
977 in_pktns->tx.ecn.validation_pkt_sent = 0;
978 in_pktns->tx.ecn.validation_pkt_lost = 0;
979 }
980
981 if (hs_pktns) {
982 hs_pktns->tx.ecn.start_pkt_num = INT64_MAX;
983 hs_pktns->tx.ecn.validation_pkt_sent = 0;
984 hs_pktns->tx.ecn.validation_pkt_lost = 0;
985 }
986
987 pktns->tx.ecn.start_pkt_num = INT64_MAX;
988 pktns->tx.ecn.validation_pkt_sent = 0;
989 pktns->tx.ecn.validation_pkt_lost = 0;
990 }
991
992 /* server_default_other_versions is the default other_versions field
993 sent by server. */
994 static uint8_t server_default_other_versions[] = {0, 0, 0, 1};
995
996 /*
997 * other_versions_new allocates new buffer, and writes |versions| of
998 * length |versionslen| in network byte order, suitable for sending in
999 * other_versions field of version_information QUIC transport
1000 * parameter. The pointer to the allocated buffer is assigned to
1001 * |*pbuf|.
1002 *
1003 * This function returns 0 if it succeeds, or one of the negative
1004 * error codes:
1005 *
1006 * NGTCP2_ERR_NOMEM
1007 * Out of memory.
1008 */
other_versions_new(uint8_t ** pbuf,const uint32_t * versions,size_t versionslen,const ngtcp2_mem * mem)1009 static int other_versions_new(uint8_t **pbuf, const uint32_t *versions,
1010 size_t versionslen, const ngtcp2_mem *mem) {
1011 size_t i;
1012 uint8_t *buf = ngtcp2_mem_malloc(mem, sizeof(uint32_t) * versionslen);
1013
1014 if (buf == NULL) {
1015 return NGTCP2_ERR_NOMEM;
1016 }
1017
1018 *pbuf = buf;
1019
1020 for (i = 0; i < versionslen; ++i) {
1021 buf = ngtcp2_put_uint32be(buf, versions[i]);
1022 }
1023
1024 return 0;
1025 }
1026
1027 static void
conn_set_local_transport_params(ngtcp2_conn * conn,const ngtcp2_transport_params * params)1028 conn_set_local_transport_params(ngtcp2_conn *conn,
1029 const ngtcp2_transport_params *params) {
1030 ngtcp2_transport_params *p = &conn->local.transport_params;
1031 uint32_t chosen_version = p->version_info.chosen_version;
1032
1033 *p = *params;
1034
1035 /* grease_quic_bit is always enabled. */
1036 p->grease_quic_bit = 1;
1037
1038 if (conn->server) {
1039 p->version_info.chosen_version = chosen_version;
1040 } else {
1041 p->version_info.chosen_version = conn->client_chosen_version;
1042 }
1043 p->version_info.other_versions = conn->vneg.other_versions;
1044 p->version_info.other_versionslen = conn->vneg.other_versionslen;
1045 p->version_info_present = 1;
1046 }
1047
conn_new(ngtcp2_conn ** pconn,const ngtcp2_cid * dcid,const ngtcp2_cid * scid,const ngtcp2_path * path,uint32_t client_chosen_version,int callbacks_version,const ngtcp2_callbacks * callbacks,int settings_version,const ngtcp2_settings * settings,int transport_params_version,const ngtcp2_transport_params * params,const ngtcp2_mem * mem,void * user_data,int server)1048 static int conn_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid,
1049 const ngtcp2_cid *scid, const ngtcp2_path *path,
1050 uint32_t client_chosen_version, int callbacks_version,
1051 const ngtcp2_callbacks *callbacks, int settings_version,
1052 const ngtcp2_settings *settings,
1053 int transport_params_version,
1054 const ngtcp2_transport_params *params,
1055 const ngtcp2_mem *mem, void *user_data, int server) {
1056 int rv;
1057 ngtcp2_scid *scident;
1058 uint8_t *buf;
1059 uint8_t fixed_bit_byte;
1060 size_t i;
1061 uint32_t *preferred_versions;
1062 (void)callbacks_version;
1063 (void)settings_version;
1064 (void)transport_params_version;
1065
1066 assert(settings->max_window <= NGTCP2_MAX_VARINT);
1067 assert(settings->max_stream_window <= NGTCP2_MAX_VARINT);
1068 assert(settings->max_udp_payload_size);
1069 assert(settings->max_udp_payload_size <= NGTCP2_HARD_MAX_UDP_PAYLOAD_SIZE);
1070 assert(params->active_connection_id_limit <= NGTCP2_MAX_DCID_POOL_SIZE);
1071 assert(params->initial_max_data <= NGTCP2_MAX_VARINT);
1072 assert(params->initial_max_stream_data_bidi_local <= NGTCP2_MAX_VARINT);
1073 assert(params->initial_max_stream_data_bidi_remote <= NGTCP2_MAX_VARINT);
1074 assert(params->initial_max_stream_data_uni <= NGTCP2_MAX_VARINT);
1075 assert(server || callbacks->client_initial);
1076 assert(!server || callbacks->recv_client_initial);
1077 assert(callbacks->recv_crypto_data);
1078 assert(callbacks->encrypt);
1079 assert(callbacks->decrypt);
1080 assert(callbacks->hp_mask);
1081 assert(server || callbacks->recv_retry);
1082 assert(callbacks->rand);
1083 assert(callbacks->get_new_connection_id);
1084 assert(callbacks->update_key);
1085 assert(callbacks->delete_crypto_aead_ctx);
1086 assert(callbacks->delete_crypto_cipher_ctx);
1087 assert(callbacks->get_path_challenge_data);
1088 assert(!server || !ngtcp2_is_reserved_version(client_chosen_version));
1089
1090 if (mem == NULL) {
1091 mem = ngtcp2_mem_default();
1092 }
1093
1094 *pconn = ngtcp2_mem_calloc(mem, 1, sizeof(ngtcp2_conn));
1095 if (*pconn == NULL) {
1096 rv = NGTCP2_ERR_NOMEM;
1097 goto fail_conn;
1098 }
1099
1100 ngtcp2_objalloc_frame_chain_init(&(*pconn)->frc_objalloc, 64, mem);
1101 ngtcp2_objalloc_rtb_entry_init(&(*pconn)->rtb_entry_objalloc, 64, mem);
1102 ngtcp2_objalloc_strm_init(&(*pconn)->strm_objalloc, 64, mem);
1103
1104 ngtcp2_static_ringbuf_dcid_bound_init(&(*pconn)->dcid.bound);
1105
1106 ngtcp2_static_ringbuf_dcid_unused_init(&(*pconn)->dcid.unused);
1107
1108 ngtcp2_static_ringbuf_dcid_retired_init(&(*pconn)->dcid.retired);
1109
1110 ngtcp2_gaptr_init(&(*pconn)->dcid.seqgap, mem);
1111
1112 ngtcp2_ksl_init(&(*pconn)->scid.set, cid_less, sizeof(ngtcp2_cid), mem);
1113
1114 ngtcp2_pq_init(&(*pconn)->scid.used, retired_ts_less, mem);
1115
1116 ngtcp2_map_init(&(*pconn)->strms, mem);
1117
1118 ngtcp2_pq_init(&(*pconn)->tx.strmq, cycle_less, mem);
1119
1120 ngtcp2_idtr_init(&(*pconn)->remote.bidi.idtr, !server, mem);
1121
1122 ngtcp2_idtr_init(&(*pconn)->remote.uni.idtr, !server, mem);
1123
1124 ngtcp2_static_ringbuf_path_challenge_init(&(*pconn)->rx.path_challenge);
1125
1126 ngtcp2_log_init(&(*pconn)->log, scid, settings->log_printf,
1127 settings->initial_ts, user_data);
1128 ngtcp2_qlog_init(&(*pconn)->qlog, settings->qlog.write, settings->initial_ts,
1129 user_data);
1130 if ((*pconn)->qlog.write) {
1131 buf = ngtcp2_mem_malloc(mem, NGTCP2_QLOG_BUFLEN);
1132 if (buf == NULL) {
1133 rv = NGTCP2_ERR_NOMEM;
1134 goto fail_qlog_buf;
1135 }
1136 ngtcp2_buf_init(&(*pconn)->qlog.buf, buf, NGTCP2_QLOG_BUFLEN);
1137 }
1138
1139 (*pconn)->local.settings = *settings;
1140
1141 if (settings->token.len) {
1142 buf = ngtcp2_mem_malloc(mem, settings->token.len);
1143 if (buf == NULL) {
1144 rv = NGTCP2_ERR_NOMEM;
1145 goto fail_token;
1146 }
1147 memcpy(buf, settings->token.base, settings->token.len);
1148 (*pconn)->local.settings.token.base = buf;
1149 } else {
1150 (*pconn)->local.settings.token.base = NULL;
1151 (*pconn)->local.settings.token.len = 0;
1152 }
1153
1154 if (!(*pconn)->local.settings.original_version) {
1155 (*pconn)->local.settings.original_version = client_chosen_version;
1156 }
1157
1158 conn_reset_conn_stat(*pconn, &(*pconn)->cstat);
1159 (*pconn)->cstat.initial_rtt = settings->initial_rtt;
1160 (*pconn)->cstat.max_udp_payload_size =
1161 (*pconn)->local.settings.max_udp_payload_size;
1162
1163 ngtcp2_rst_init(&(*pconn)->rst);
1164
1165 (*pconn)->cc_algo = settings->cc_algo;
1166
1167 switch (settings->cc_algo) {
1168 case NGTCP2_CC_ALGO_RENO:
1169 rv = ngtcp2_cc_reno_cc_init(&(*pconn)->cc, &(*pconn)->log, mem);
1170 if (rv != 0) {
1171 goto fail_cc_init;
1172 }
1173 break;
1174 case NGTCP2_CC_ALGO_CUBIC:
1175 rv = ngtcp2_cc_cubic_cc_init(&(*pconn)->cc, &(*pconn)->log, mem);
1176 if (rv != 0) {
1177 goto fail_cc_init;
1178 }
1179 break;
1180 case NGTCP2_CC_ALGO_BBR:
1181 rv = ngtcp2_cc_bbr_cc_init(&(*pconn)->cc, &(*pconn)->log, &(*pconn)->cstat,
1182 &(*pconn)->rst, settings->initial_ts,
1183 callbacks->rand, &settings->rand_ctx, mem);
1184 if (rv != 0) {
1185 goto fail_cc_init;
1186 }
1187 break;
1188 case NGTCP2_CC_ALGO_BBR2:
1189 rv = ngtcp2_cc_bbr2_cc_init(&(*pconn)->cc, &(*pconn)->log, &(*pconn)->cstat,
1190 &(*pconn)->rst, settings->initial_ts,
1191 callbacks->rand, &settings->rand_ctx, mem);
1192 if (rv != 0) {
1193 goto fail_cc_init;
1194 }
1195 break;
1196 default:
1197 assert(0);
1198 }
1199
1200 rv = pktns_new(&(*pconn)->in_pktns, NGTCP2_PKTNS_ID_INITIAL, &(*pconn)->rst,
1201 &(*pconn)->cc, &(*pconn)->log, &(*pconn)->qlog,
1202 &(*pconn)->rtb_entry_objalloc, &(*pconn)->frc_objalloc, mem);
1203 if (rv != 0) {
1204 goto fail_in_pktns_init;
1205 }
1206
1207 rv = pktns_new(&(*pconn)->hs_pktns, NGTCP2_PKTNS_ID_HANDSHAKE, &(*pconn)->rst,
1208 &(*pconn)->cc, &(*pconn)->log, &(*pconn)->qlog,
1209 &(*pconn)->rtb_entry_objalloc, &(*pconn)->frc_objalloc, mem);
1210 if (rv != 0) {
1211 goto fail_hs_pktns_init;
1212 }
1213
1214 rv = pktns_init(&(*pconn)->pktns, NGTCP2_PKTNS_ID_APPLICATION, &(*pconn)->rst,
1215 &(*pconn)->cc, &(*pconn)->log, &(*pconn)->qlog,
1216 &(*pconn)->rtb_entry_objalloc, &(*pconn)->frc_objalloc, mem);
1217 if (rv != 0) {
1218 goto fail_pktns_init;
1219 }
1220
1221 scident = ngtcp2_mem_malloc(mem, sizeof(*scident));
1222 if (scident == NULL) {
1223 rv = NGTCP2_ERR_NOMEM;
1224 goto fail_scident;
1225 }
1226
1227 /* Set stateless reset token later if it is available in the local
1228 transport parameters */
1229 ngtcp2_scid_init(scident, 0, scid);
1230
1231 rv = ngtcp2_ksl_insert(&(*pconn)->scid.set, NULL, &scident->cid, scident);
1232 if (rv != 0) {
1233 goto fail_scid_set_insert;
1234 }
1235
1236 scident = NULL;
1237
1238 ngtcp2_dcid_init(&(*pconn)->dcid.current, 0, dcid, NULL);
1239 ngtcp2_dcid_set_path(&(*pconn)->dcid.current, path);
1240
1241 rv = ngtcp2_gaptr_push(&(*pconn)->dcid.seqgap, 0, 1);
1242 if (rv != 0) {
1243 goto fail_seqgap_push;
1244 }
1245
1246 if (settings->preferred_versionslen) {
1247 if (!server && !ngtcp2_is_reserved_version(client_chosen_version)) {
1248 for (i = 0; i < settings->preferred_versionslen; ++i) {
1249 if (settings->preferred_versions[i] == client_chosen_version) {
1250 break;
1251 }
1252 }
1253
1254 assert(i < settings->preferred_versionslen);
1255 }
1256
1257 preferred_versions = ngtcp2_mem_malloc(
1258 mem, sizeof(uint32_t) * settings->preferred_versionslen);
1259 if (preferred_versions == NULL) {
1260 rv = NGTCP2_ERR_NOMEM;
1261 goto fail_preferred_versions;
1262 }
1263
1264 for (i = 0; i < settings->preferred_versionslen; ++i) {
1265 assert(ngtcp2_is_supported_version(settings->preferred_versions[i]));
1266
1267 preferred_versions[i] = settings->preferred_versions[i];
1268 }
1269
1270 (*pconn)->vneg.preferred_versions = preferred_versions;
1271 (*pconn)->vneg.preferred_versionslen = settings->preferred_versionslen;
1272 }
1273
1274 if (settings->other_versionslen) {
1275 if (!server && !ngtcp2_is_reserved_version(client_chosen_version)) {
1276 for (i = 0; i < settings->other_versionslen; ++i) {
1277 if (settings->other_versions[i] == client_chosen_version) {
1278 break;
1279 }
1280 }
1281
1282 assert(i < settings->other_versionslen);
1283 }
1284
1285 for (i = 0; i < settings->other_versionslen; ++i) {
1286 assert(ngtcp2_is_reserved_version(settings->other_versions[i]) ||
1287 ngtcp2_is_supported_version(settings->other_versions[i]));
1288 }
1289
1290 rv = other_versions_new(&buf, settings->other_versions,
1291 settings->other_versionslen, mem);
1292 if (rv != 0) {
1293 goto fail_other_versions;
1294 }
1295
1296 (*pconn)->vneg.other_versions = buf;
1297 (*pconn)->vneg.other_versionslen =
1298 sizeof(uint32_t) * settings->other_versionslen;
1299 } else if (server) {
1300 if (settings->preferred_versionslen) {
1301 rv = other_versions_new(&buf, settings->preferred_versions,
1302 settings->preferred_versionslen, mem);
1303 if (rv != 0) {
1304 goto fail_other_versions;
1305 }
1306
1307 (*pconn)->vneg.other_versions = buf;
1308 (*pconn)->vneg.other_versionslen =
1309 sizeof(uint32_t) * settings->preferred_versionslen;
1310 } else {
1311 (*pconn)->vneg.other_versions = server_default_other_versions;
1312 (*pconn)->vneg.other_versionslen = sizeof(server_default_other_versions);
1313 }
1314 } else if (!server && !ngtcp2_is_reserved_version(client_chosen_version)) {
1315 rv = other_versions_new(&buf, &client_chosen_version, 1, mem);
1316 if (rv != 0) {
1317 goto fail_other_versions;
1318 }
1319
1320 (*pconn)->vneg.other_versions = buf;
1321 (*pconn)->vneg.other_versionslen = sizeof(uint32_t);
1322 }
1323
1324 (*pconn)->client_chosen_version = client_chosen_version;
1325
1326 conn_set_local_transport_params(*pconn, params);
1327
1328 callbacks->rand(&fixed_bit_byte, 1, &settings->rand_ctx);
1329 if (fixed_bit_byte & 1) {
1330 (*pconn)->flags |= NGTCP2_CONN_FLAG_CLEAR_FIXED_BIT;
1331 }
1332
1333 (*pconn)->keep_alive.last_ts = UINT64_MAX;
1334
1335 (*pconn)->server = server;
1336 (*pconn)->oscid = *scid;
1337 (*pconn)->callbacks = *callbacks;
1338 (*pconn)->mem = mem;
1339 (*pconn)->user_data = user_data;
1340 (*pconn)->idle_ts = settings->initial_ts;
1341 (*pconn)->crypto.key_update.confirmed_ts = UINT64_MAX;
1342 (*pconn)->tx.last_max_data_ts = UINT64_MAX;
1343 (*pconn)->tx.pacing.next_ts = UINT64_MAX;
1344 (*pconn)->early.discard_started_ts = UINT64_MAX;
1345
1346 conn_reset_ecn_validation_state(*pconn);
1347
1348 ngtcp2_qlog_start(&(*pconn)->qlog, server ? &settings->qlog.odcid : dcid,
1349 server);
1350
1351 return 0;
1352
1353 fail_other_versions:
1354 ngtcp2_mem_free(mem, (*pconn)->vneg.preferred_versions);
1355 fail_preferred_versions:
1356 fail_seqgap_push:
1357 fail_scid_set_insert:
1358 ngtcp2_mem_free(mem, scident);
1359 fail_scident:
1360 pktns_free(&(*pconn)->pktns, mem);
1361 fail_pktns_init:
1362 pktns_del((*pconn)->hs_pktns, mem);
1363 fail_hs_pktns_init:
1364 pktns_del((*pconn)->in_pktns, mem);
1365 fail_in_pktns_init:
1366 cc_del(&(*pconn)->cc, settings->cc_algo, mem);
1367 fail_cc_init:
1368 ngtcp2_mem_free(mem, (*pconn)->local.settings.token.base);
1369 fail_token:
1370 ngtcp2_mem_free(mem, (*pconn)->qlog.buf.begin);
1371 fail_qlog_buf:
1372 ngtcp2_idtr_free(&(*pconn)->remote.uni.idtr);
1373 ngtcp2_idtr_free(&(*pconn)->remote.bidi.idtr);
1374 ngtcp2_map_free(&(*pconn)->strms);
1375 delete_scid(&(*pconn)->scid.set, mem);
1376 ngtcp2_ksl_free(&(*pconn)->scid.set);
1377 ngtcp2_gaptr_free(&(*pconn)->dcid.seqgap);
1378 ngtcp2_objalloc_free(&(*pconn)->strm_objalloc);
1379 ngtcp2_objalloc_free(&(*pconn)->rtb_entry_objalloc);
1380 ngtcp2_objalloc_free(&(*pconn)->frc_objalloc);
1381 ngtcp2_mem_free(mem, *pconn);
1382 fail_conn:
1383 return rv;
1384 }
1385
ngtcp2_conn_client_new_versioned(ngtcp2_conn ** pconn,const ngtcp2_cid * dcid,const ngtcp2_cid * scid,const ngtcp2_path * path,uint32_t client_chosen_version,int callbacks_version,const ngtcp2_callbacks * callbacks,int settings_version,const ngtcp2_settings * settings,int transport_params_version,const ngtcp2_transport_params * params,const ngtcp2_mem * mem,void * user_data)1386 int ngtcp2_conn_client_new_versioned(
1387 ngtcp2_conn **pconn, const ngtcp2_cid *dcid, const ngtcp2_cid *scid,
1388 const ngtcp2_path *path, uint32_t client_chosen_version,
1389 int callbacks_version, const ngtcp2_callbacks *callbacks,
1390 int settings_version, const ngtcp2_settings *settings,
1391 int transport_params_version, const ngtcp2_transport_params *params,
1392 const ngtcp2_mem *mem, void *user_data) {
1393 int rv;
1394
1395 rv = conn_new(pconn, dcid, scid, path, client_chosen_version,
1396 callbacks_version, callbacks, settings_version, settings,
1397 transport_params_version, params, mem, user_data, 0);
1398 if (rv != 0) {
1399 return rv;
1400 }
1401 (*pconn)->rcid = *dcid;
1402 (*pconn)->state = NGTCP2_CS_CLIENT_INITIAL;
1403 (*pconn)->local.bidi.next_stream_id = 0;
1404 (*pconn)->local.uni.next_stream_id = 2;
1405
1406 rv = ngtcp2_conn_commit_local_transport_params(*pconn);
1407 if (rv != 0) {
1408 ngtcp2_conn_del(*pconn);
1409 return rv;
1410 }
1411
1412 return 0;
1413 }
1414
ngtcp2_conn_server_new_versioned(ngtcp2_conn ** pconn,const ngtcp2_cid * dcid,const ngtcp2_cid * scid,const ngtcp2_path * path,uint32_t client_chosen_version,int callbacks_version,const ngtcp2_callbacks * callbacks,int settings_version,const ngtcp2_settings * settings,int transport_params_version,const ngtcp2_transport_params * params,const ngtcp2_mem * mem,void * user_data)1415 int ngtcp2_conn_server_new_versioned(
1416 ngtcp2_conn **pconn, const ngtcp2_cid *dcid, const ngtcp2_cid *scid,
1417 const ngtcp2_path *path, uint32_t client_chosen_version,
1418 int callbacks_version, const ngtcp2_callbacks *callbacks,
1419 int settings_version, const ngtcp2_settings *settings,
1420 int transport_params_version, const ngtcp2_transport_params *params,
1421 const ngtcp2_mem *mem, void *user_data) {
1422 int rv;
1423
1424 rv = conn_new(pconn, dcid, scid, path, client_chosen_version,
1425 callbacks_version, callbacks, settings_version, settings,
1426 transport_params_version, params, mem, user_data, 1);
1427 if (rv != 0) {
1428 return rv;
1429 }
1430
1431 (*pconn)->state = NGTCP2_CS_SERVER_INITIAL;
1432 (*pconn)->local.bidi.next_stream_id = 1;
1433 (*pconn)->local.uni.next_stream_id = 3;
1434
1435 if ((*pconn)->local.settings.token.len) {
1436 /* Usage of token lifts amplification limit */
1437 (*pconn)->dcid.current.flags |= NGTCP2_DCID_FLAG_PATH_VALIDATED;
1438 }
1439
1440 return 0;
1441 }
1442
1443 /*
1444 * conn_fc_credits returns the number of bytes allowed to be sent to
1445 * the given stream. Both connection and stream level flow control
1446 * credits are considered.
1447 */
conn_fc_credits(ngtcp2_conn * conn,ngtcp2_strm * strm)1448 static uint64_t conn_fc_credits(ngtcp2_conn *conn, ngtcp2_strm *strm) {
1449 return ngtcp2_min(strm->tx.max_offset - strm->tx.offset,
1450 conn->tx.max_offset - conn->tx.offset);
1451 }
1452
1453 /*
1454 * conn_enforce_flow_control returns the number of bytes allowed to be
1455 * sent to the given stream. |len| might be shorted because of
1456 * available flow control credits.
1457 */
conn_enforce_flow_control(ngtcp2_conn * conn,ngtcp2_strm * strm,uint64_t len)1458 static uint64_t conn_enforce_flow_control(ngtcp2_conn *conn, ngtcp2_strm *strm,
1459 uint64_t len) {
1460 uint64_t fc_credits = conn_fc_credits(conn, strm);
1461 return ngtcp2_min(len, fc_credits);
1462 }
1463
delete_strms_each(void * data,void * ptr)1464 static int delete_strms_each(void *data, void *ptr) {
1465 ngtcp2_conn *conn = ptr;
1466 ngtcp2_strm *s = data;
1467
1468 ngtcp2_strm_free(s);
1469 ngtcp2_objalloc_strm_release(&conn->strm_objalloc, s);
1470
1471 return 0;
1472 }
1473
conn_vneg_crypto_free(ngtcp2_conn * conn)1474 static void conn_vneg_crypto_free(ngtcp2_conn *conn) {
1475 if (conn->vneg.rx.ckm) {
1476 conn_call_delete_crypto_aead_ctx(conn, &conn->vneg.rx.ckm->aead_ctx);
1477 }
1478 conn_call_delete_crypto_cipher_ctx(conn, &conn->vneg.rx.hp_ctx);
1479
1480 if (conn->vneg.tx.ckm) {
1481 conn_call_delete_crypto_aead_ctx(conn, &conn->vneg.tx.ckm->aead_ctx);
1482 }
1483 conn_call_delete_crypto_cipher_ctx(conn, &conn->vneg.tx.hp_ctx);
1484
1485 ngtcp2_crypto_km_del(conn->vneg.rx.ckm, conn->mem);
1486 ngtcp2_crypto_km_del(conn->vneg.tx.ckm, conn->mem);
1487 }
1488
ngtcp2_conn_del(ngtcp2_conn * conn)1489 void ngtcp2_conn_del(ngtcp2_conn *conn) {
1490 if (conn == NULL) {
1491 return;
1492 }
1493
1494 ngtcp2_qlog_end(&conn->qlog);
1495
1496 if (conn->early.ckm) {
1497 conn_call_delete_crypto_aead_ctx(conn, &conn->early.ckm->aead_ctx);
1498 }
1499 conn_call_delete_crypto_cipher_ctx(conn, &conn->early.hp_ctx);
1500
1501 if (conn->crypto.key_update.old_rx_ckm) {
1502 conn_call_delete_crypto_aead_ctx(
1503 conn, &conn->crypto.key_update.old_rx_ckm->aead_ctx);
1504 }
1505 if (conn->crypto.key_update.new_rx_ckm) {
1506 conn_call_delete_crypto_aead_ctx(
1507 conn, &conn->crypto.key_update.new_rx_ckm->aead_ctx);
1508 }
1509 if (conn->crypto.key_update.new_tx_ckm) {
1510 conn_call_delete_crypto_aead_ctx(
1511 conn, &conn->crypto.key_update.new_tx_ckm->aead_ctx);
1512 }
1513
1514 if (conn->pktns.crypto.rx.ckm) {
1515 conn_call_delete_crypto_aead_ctx(conn,
1516 &conn->pktns.crypto.rx.ckm->aead_ctx);
1517 }
1518 conn_call_delete_crypto_cipher_ctx(conn, &conn->pktns.crypto.rx.hp_ctx);
1519
1520 if (conn->pktns.crypto.tx.ckm) {
1521 conn_call_delete_crypto_aead_ctx(conn,
1522 &conn->pktns.crypto.tx.ckm->aead_ctx);
1523 }
1524 conn_call_delete_crypto_cipher_ctx(conn, &conn->pktns.crypto.tx.hp_ctx);
1525
1526 if (conn->hs_pktns) {
1527 if (conn->hs_pktns->crypto.rx.ckm) {
1528 conn_call_delete_crypto_aead_ctx(
1529 conn, &conn->hs_pktns->crypto.rx.ckm->aead_ctx);
1530 }
1531 conn_call_delete_crypto_cipher_ctx(conn, &conn->hs_pktns->crypto.rx.hp_ctx);
1532
1533 if (conn->hs_pktns->crypto.tx.ckm) {
1534 conn_call_delete_crypto_aead_ctx(
1535 conn, &conn->hs_pktns->crypto.tx.ckm->aead_ctx);
1536 }
1537 conn_call_delete_crypto_cipher_ctx(conn, &conn->hs_pktns->crypto.tx.hp_ctx);
1538 }
1539 if (conn->in_pktns) {
1540 if (conn->in_pktns->crypto.rx.ckm) {
1541 conn_call_delete_crypto_aead_ctx(
1542 conn, &conn->in_pktns->crypto.rx.ckm->aead_ctx);
1543 }
1544 conn_call_delete_crypto_cipher_ctx(conn, &conn->in_pktns->crypto.rx.hp_ctx);
1545
1546 if (conn->in_pktns->crypto.tx.ckm) {
1547 conn_call_delete_crypto_aead_ctx(
1548 conn, &conn->in_pktns->crypto.tx.ckm->aead_ctx);
1549 }
1550 conn_call_delete_crypto_cipher_ctx(conn, &conn->in_pktns->crypto.tx.hp_ctx);
1551 }
1552
1553 conn_call_delete_crypto_aead_ctx(conn, &conn->crypto.retry_aead_ctx);
1554
1555 ngtcp2_transport_params_del(conn->remote.transport_params, conn->mem);
1556 ngtcp2_transport_params_del(conn->remote.pending_transport_params, conn->mem);
1557
1558 conn_vneg_crypto_free(conn);
1559
1560 ngtcp2_mem_free(conn->mem, conn->vneg.preferred_versions);
1561 if (conn->vneg.other_versions != server_default_other_versions) {
1562 ngtcp2_mem_free(conn->mem, conn->vneg.other_versions);
1563 }
1564
1565 ngtcp2_mem_free(conn->mem, conn->crypto.decrypt_buf.base);
1566 ngtcp2_mem_free(conn->mem, conn->crypto.decrypt_hp_buf.base);
1567 ngtcp2_mem_free(conn->mem, conn->local.settings.token.base);
1568
1569 ngtcp2_crypto_km_del(conn->crypto.key_update.old_rx_ckm, conn->mem);
1570 ngtcp2_crypto_km_del(conn->crypto.key_update.new_rx_ckm, conn->mem);
1571 ngtcp2_crypto_km_del(conn->crypto.key_update.new_tx_ckm, conn->mem);
1572 ngtcp2_crypto_km_del(conn->early.ckm, conn->mem);
1573
1574 pktns_free(&conn->pktns, conn->mem);
1575 pktns_del(conn->hs_pktns, conn->mem);
1576 pktns_del(conn->in_pktns, conn->mem);
1577
1578 cc_del(&conn->cc, conn->cc_algo, conn->mem);
1579
1580 ngtcp2_mem_free(conn->mem, conn->qlog.buf.begin);
1581
1582 ngtcp2_pmtud_del(conn->pmtud);
1583 ngtcp2_pv_del(conn->pv);
1584
1585 ngtcp2_mem_free(conn->mem, conn->rx.ccerr.reason);
1586
1587 ngtcp2_idtr_free(&conn->remote.uni.idtr);
1588 ngtcp2_idtr_free(&conn->remote.bidi.idtr);
1589 ngtcp2_mem_free(conn->mem, conn->tx.ack);
1590 ngtcp2_pq_free(&conn->tx.strmq);
1591 ngtcp2_map_each_free(&conn->strms, delete_strms_each, (void *)conn);
1592 ngtcp2_map_free(&conn->strms);
1593
1594 ngtcp2_pq_free(&conn->scid.used);
1595 delete_scid(&conn->scid.set, conn->mem);
1596 ngtcp2_ksl_free(&conn->scid.set);
1597 ngtcp2_gaptr_free(&conn->dcid.seqgap);
1598
1599 ngtcp2_objalloc_free(&conn->strm_objalloc);
1600 ngtcp2_objalloc_free(&conn->rtb_entry_objalloc);
1601 ngtcp2_objalloc_free(&conn->frc_objalloc);
1602
1603 ngtcp2_mem_free(conn->mem, conn);
1604 }
1605
1606 /*
1607 * conn_ensure_ack_blks makes sure that conn->tx.ack->ack.blks can
1608 * contain at least |n| additional ngtcp2_ack_blk.
1609 *
1610 * This function returns 0 if it succeeds, or one of the following
1611 * negative error codes:
1612 *
1613 * NGTCP2_ERR_NOMEM
1614 * Out of memory.
1615 */
conn_ensure_ack_blks(ngtcp2_conn * conn,size_t n)1616 static int conn_ensure_ack_blks(ngtcp2_conn *conn, size_t n) {
1617 ngtcp2_frame *fr;
1618 size_t max = conn->tx.max_ack_blks;
1619
1620 if (n <= max) {
1621 return 0;
1622 }
1623
1624 max *= 2;
1625
1626 assert(max >= n);
1627
1628 fr = ngtcp2_mem_realloc(conn->mem, conn->tx.ack,
1629 sizeof(ngtcp2_ack) + sizeof(ngtcp2_ack_blk) * max);
1630 if (fr == NULL) {
1631 return NGTCP2_ERR_NOMEM;
1632 }
1633
1634 conn->tx.ack = fr;
1635 conn->tx.max_ack_blks = max;
1636
1637 return 0;
1638 }
1639
1640 /*
1641 * conn_compute_ack_delay computes ACK delay for outgoing protected
1642 * ACK.
1643 */
conn_compute_ack_delay(ngtcp2_conn * conn)1644 static ngtcp2_duration conn_compute_ack_delay(ngtcp2_conn *conn) {
1645 return ngtcp2_min(conn->local.transport_params.max_ack_delay,
1646 conn->cstat.smoothed_rtt / 8);
1647 }
1648
1649 /*
1650 * conn_create_ack_frame creates ACK frame, and assigns its pointer to
1651 * |*pfr| if there are any received packets to acknowledge. If there
1652 * are no packets to acknowledge, this function returns 0, and |*pfr|
1653 * is untouched. The caller is advised to set |*pfr| to NULL before
1654 * calling this function, and check it after this function returns.
1655 * If |nodelay| is nonzero, delayed ACK timer is ignored.
1656 *
1657 * The memory for ACK frame is dynamically allocated by this function.
1658 * A caller is responsible to free it.
1659 *
1660 * Call ngtcp2_acktr_commit_ack after a created ACK frame is
1661 * successfully serialized into a packet.
1662 *
1663 * This function returns 0 if it succeeds, or one of the following
1664 * negative error codes:
1665 *
1666 * NGTCP2_ERR_NOMEM
1667 * Out of memory.
1668 */
conn_create_ack_frame(ngtcp2_conn * conn,ngtcp2_frame ** pfr,ngtcp2_pktns * pktns,uint8_t type,ngtcp2_tstamp ts,ngtcp2_duration ack_delay,uint64_t ack_delay_exponent)1669 static int conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr,
1670 ngtcp2_pktns *pktns, uint8_t type,
1671 ngtcp2_tstamp ts, ngtcp2_duration ack_delay,
1672 uint64_t ack_delay_exponent) {
1673 /* TODO Measure an actual size of ACK blocks to find the best
1674 default value. */
1675 const size_t initial_max_ack_blks = 8;
1676 int64_t last_pkt_num;
1677 ngtcp2_acktr *acktr = &pktns->acktr;
1678 ngtcp2_ack_blk *blk;
1679 ngtcp2_ksl_it it;
1680 ngtcp2_acktr_entry *rpkt;
1681 ngtcp2_ack *ack;
1682 size_t blk_idx;
1683 ngtcp2_tstamp largest_ack_ts;
1684 int rv;
1685
1686 if (acktr->flags & NGTCP2_ACKTR_FLAG_IMMEDIATE_ACK) {
1687 ack_delay = 0;
1688 }
1689
1690 if (!ngtcp2_acktr_require_active_ack(acktr, ack_delay, ts)) {
1691 return 0;
1692 }
1693
1694 it = ngtcp2_acktr_get(acktr);
1695 if (ngtcp2_ksl_it_end(&it)) {
1696 ngtcp2_acktr_commit_ack(acktr);
1697 return 0;
1698 }
1699
1700 if (conn->tx.ack == NULL) {
1701 conn->tx.ack = ngtcp2_mem_malloc(
1702 conn->mem,
1703 sizeof(ngtcp2_ack) + sizeof(ngtcp2_ack_blk) * initial_max_ack_blks);
1704 if (conn->tx.ack == NULL) {
1705 return NGTCP2_ERR_NOMEM;
1706 }
1707 conn->tx.max_ack_blks = initial_max_ack_blks;
1708 }
1709
1710 ack = &conn->tx.ack->ack;
1711
1712 if (pktns->rx.ecn.ect0 || pktns->rx.ecn.ect1 || pktns->rx.ecn.ce) {
1713 ack->type = NGTCP2_FRAME_ACK_ECN;
1714 ack->ecn.ect0 = pktns->rx.ecn.ect0;
1715 ack->ecn.ect1 = pktns->rx.ecn.ect1;
1716 ack->ecn.ce = pktns->rx.ecn.ce;
1717 } else {
1718 ack->type = NGTCP2_FRAME_ACK;
1719 }
1720 ack->num_blks = 0;
1721
1722 rpkt = ngtcp2_ksl_it_get(&it);
1723
1724 if (rpkt->pkt_num == pktns->rx.max_pkt_num) {
1725 last_pkt_num = rpkt->pkt_num - (int64_t)(rpkt->len - 1);
1726 largest_ack_ts = rpkt->tstamp;
1727 ack->largest_ack = rpkt->pkt_num;
1728 ack->first_ack_blklen = rpkt->len - 1;
1729
1730 ngtcp2_ksl_it_next(&it);
1731 } else {
1732 assert(rpkt->pkt_num < pktns->rx.max_pkt_num);
1733
1734 last_pkt_num = pktns->rx.max_pkt_num;
1735 largest_ack_ts = pktns->rx.max_pkt_ts;
1736 ack->largest_ack = pktns->rx.max_pkt_num;
1737 ack->first_ack_blklen = 0;
1738 }
1739
1740 if (type == NGTCP2_PKT_1RTT) {
1741 ack->ack_delay_unscaled = ts - largest_ack_ts;
1742 ack->ack_delay = ack->ack_delay_unscaled / NGTCP2_MICROSECONDS /
1743 (1ULL << ack_delay_exponent);
1744 } else {
1745 ack->ack_delay_unscaled = 0;
1746 ack->ack_delay = 0;
1747 }
1748
1749 for (; !ngtcp2_ksl_it_end(&it); ngtcp2_ksl_it_next(&it)) {
1750 if (ack->num_blks == NGTCP2_MAX_ACK_BLKS) {
1751 break;
1752 }
1753
1754 rpkt = ngtcp2_ksl_it_get(&it);
1755
1756 blk_idx = ack->num_blks++;
1757 rv = conn_ensure_ack_blks(conn, ack->num_blks);
1758 if (rv != 0) {
1759 return rv;
1760 }
1761 ack = &conn->tx.ack->ack;
1762 blk = &ack->blks[blk_idx];
1763 blk->gap = (uint64_t)(last_pkt_num - rpkt->pkt_num - 2);
1764 blk->blklen = rpkt->len - 1;
1765
1766 last_pkt_num = rpkt->pkt_num - (int64_t)(rpkt->len - 1);
1767 }
1768
1769 /* TODO Just remove entries which cannot fit into a single ACK frame
1770 for now. */
1771 if (!ngtcp2_ksl_it_end(&it)) {
1772 ngtcp2_acktr_forget(acktr, ngtcp2_ksl_it_get(&it));
1773 }
1774
1775 *pfr = conn->tx.ack;
1776
1777 return 0;
1778 }
1779
1780 /*
1781 * conn_ppe_write_frame writes |fr| to |ppe|. If |hd_logged| is not
1782 * NULL and |*hd_logged| is zero, packet header is logged, and 1 is
1783 * assigned to |*hd_logged|.
1784 *
1785 * This function returns 0 if it succeeds, or one of the following
1786 * negative error codes:
1787 *
1788 * NGTCP2_ERR_NOBUF
1789 * Buffer is too small.
1790 */
conn_ppe_write_frame_hd_log(ngtcp2_conn * conn,ngtcp2_ppe * ppe,int * hd_logged,const ngtcp2_pkt_hd * hd,ngtcp2_frame * fr)1791 static int conn_ppe_write_frame_hd_log(ngtcp2_conn *conn, ngtcp2_ppe *ppe,
1792 int *hd_logged, const ngtcp2_pkt_hd *hd,
1793 ngtcp2_frame *fr) {
1794 int rv;
1795
1796 rv = ngtcp2_ppe_encode_frame(ppe, fr);
1797 if (rv != 0) {
1798 assert(NGTCP2_ERR_NOBUF == rv);
1799 return rv;
1800 }
1801
1802 if (hd_logged && !*hd_logged) {
1803 *hd_logged = 1;
1804 ngtcp2_log_tx_pkt_hd(&conn->log, hd);
1805 ngtcp2_qlog_pkt_sent_start(&conn->qlog);
1806 }
1807
1808 ngtcp2_log_tx_fr(&conn->log, hd, fr);
1809 ngtcp2_qlog_write_frame(&conn->qlog, fr);
1810
1811 return 0;
1812 }
1813
1814 /*
1815 * conn_ppe_write_frame writes |fr| to |ppe|.
1816 *
1817 * This function returns 0 if it succeeds, or one of the following
1818 * negative error codes:
1819 *
1820 * NGTCP2_ERR_NOBUF
1821 * Buffer is too small.
1822 */
conn_ppe_write_frame(ngtcp2_conn * conn,ngtcp2_ppe * ppe,const ngtcp2_pkt_hd * hd,ngtcp2_frame * fr)1823 static int conn_ppe_write_frame(ngtcp2_conn *conn, ngtcp2_ppe *ppe,
1824 const ngtcp2_pkt_hd *hd, ngtcp2_frame *fr) {
1825 return conn_ppe_write_frame_hd_log(conn, ppe, NULL, hd, fr);
1826 }
1827
1828 /*
1829 * conn_on_pkt_sent is called when new non-ACK-only packet is sent.
1830 *
1831 * This function returns 0 if it succeeds, or one of the following
1832 * negative error codes:
1833 *
1834 * NGTCP2_ERR_NOMEM
1835 * Out of memory
1836 */
conn_on_pkt_sent(ngtcp2_conn * conn,ngtcp2_rtb * rtb,ngtcp2_rtb_entry * ent)1837 static int conn_on_pkt_sent(ngtcp2_conn *conn, ngtcp2_rtb *rtb,
1838 ngtcp2_rtb_entry *ent) {
1839 int rv;
1840
1841 /* This function implements OnPacketSent, but it handles only
1842 non-ACK-only packet. */
1843 rv = ngtcp2_rtb_add(rtb, ent, &conn->cstat);
1844 if (rv != 0) {
1845 return rv;
1846 }
1847
1848 if (ent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
1849 conn->cstat.last_tx_pkt_ts[rtb->pktns_id] = ent->ts;
1850 }
1851
1852 ngtcp2_conn_set_loss_detection_timer(conn, ent->ts);
1853
1854 return 0;
1855 }
1856
1857 /*
1858 * pktns_select_pkt_numlen selects shortest packet number encoding for
1859 * the next packet number based on the largest acknowledged packet
1860 * number. It returns the number of bytes to encode the packet
1861 * number.
1862 */
pktns_select_pkt_numlen(ngtcp2_pktns * pktns)1863 static size_t pktns_select_pkt_numlen(ngtcp2_pktns *pktns) {
1864 int64_t pkt_num = pktns->tx.last_pkt_num + 1;
1865 ngtcp2_rtb *rtb = &pktns->rtb;
1866 int64_t n = pkt_num - rtb->largest_acked_tx_pkt_num;
1867
1868 if (NGTCP2_MAX_PKT_NUM / 2 < n) {
1869 return 4;
1870 }
1871
1872 n = n * 2 - 1;
1873
1874 if (n > 0xffffff) {
1875 return 4;
1876 }
1877 if (n > 0xffff) {
1878 return 3;
1879 }
1880 if (n > 0xff) {
1881 return 2;
1882 }
1883 return 1;
1884 }
1885
1886 /*
1887 * conn_get_cwnd returns cwnd for the current path.
1888 */
conn_get_cwnd(ngtcp2_conn * conn)1889 static uint64_t conn_get_cwnd(ngtcp2_conn *conn) {
1890 return conn->pv && (conn->pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE)
1891 ? ngtcp2_cc_compute_initcwnd(conn->cstat.max_udp_payload_size)
1892 : conn->cstat.cwnd;
1893 }
1894
1895 /*
1896 * conn_cwnd_is_zero returns nonzero if the number of bytes the local
1897 * endpoint can sent at this time is zero.
1898 */
conn_cwnd_is_zero(ngtcp2_conn * conn)1899 static uint64_t conn_cwnd_is_zero(ngtcp2_conn *conn) {
1900 uint64_t bytes_in_flight = conn->cstat.bytes_in_flight;
1901 uint64_t cwnd = conn_get_cwnd(conn);
1902
1903 if (bytes_in_flight >= cwnd) {
1904 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_RCV,
1905 "cwnd limited bytes_in_flight=%lu cwnd=%lu",
1906 bytes_in_flight, cwnd);
1907 }
1908
1909 return bytes_in_flight >= cwnd;
1910 }
1911
1912 /*
1913 * conn_retry_early_payloadlen returns the estimated wire length of
1914 * the first STREAM frame of 0-RTT packet which should be
1915 * retransmitted due to Retry packet.
1916 */
conn_retry_early_payloadlen(ngtcp2_conn * conn)1917 static uint64_t conn_retry_early_payloadlen(ngtcp2_conn *conn) {
1918 ngtcp2_frame_chain *frc;
1919 ngtcp2_strm *strm;
1920 uint64_t len;
1921
1922 if (conn->flags & NGTCP2_CONN_FLAG_EARLY_DATA_REJECTED) {
1923 return 0;
1924 }
1925
1926 for (; !ngtcp2_pq_empty(&conn->tx.strmq);) {
1927 strm = ngtcp2_conn_tx_strmq_top(conn);
1928 if (ngtcp2_strm_streamfrq_empty(strm)) {
1929 ngtcp2_conn_tx_strmq_pop(conn);
1930 continue;
1931 }
1932
1933 frc = ngtcp2_strm_streamfrq_top(strm);
1934
1935 len = ngtcp2_vec_len(frc->fr.stream.data, frc->fr.stream.datacnt) +
1936 NGTCP2_STREAM_OVERHEAD;
1937
1938 /* Take the min because in conn_should_pad_pkt we take max in
1939 order to deal with unbreakable DATAGRAM. */
1940 return ngtcp2_min(len, NGTCP2_MIN_COALESCED_PAYLOADLEN);
1941 }
1942
1943 return 0;
1944 }
1945
conn_cryptofrq_clear(ngtcp2_conn * conn,ngtcp2_pktns * pktns)1946 static void conn_cryptofrq_clear(ngtcp2_conn *conn, ngtcp2_pktns *pktns) {
1947 ngtcp2_frame_chain *frc;
1948 ngtcp2_ksl_it it;
1949
1950 for (it = ngtcp2_ksl_begin(&pktns->crypto.tx.frq); !ngtcp2_ksl_it_end(&it);
1951 ngtcp2_ksl_it_next(&it)) {
1952 frc = ngtcp2_ksl_it_get(&it);
1953 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
1954 }
1955 ngtcp2_ksl_clear(&pktns->crypto.tx.frq);
1956 }
1957
1958 /*
1959 * conn_cryptofrq_unacked_offset returns the CRYPTO frame offset by
1960 * taking into account acknowledged offset. If there is no data to
1961 * send, this function returns (uint64_t)-1.
1962 */
conn_cryptofrq_unacked_offset(ngtcp2_conn * conn,ngtcp2_pktns * pktns)1963 static uint64_t conn_cryptofrq_unacked_offset(ngtcp2_conn *conn,
1964 ngtcp2_pktns *pktns) {
1965 ngtcp2_frame_chain *frc;
1966 ngtcp2_crypto *fr;
1967 ngtcp2_range gap;
1968 ngtcp2_rtb *rtb = &pktns->rtb;
1969 ngtcp2_ksl_it it;
1970 uint64_t datalen;
1971
1972 (void)conn;
1973
1974 for (it = ngtcp2_ksl_begin(&pktns->crypto.tx.frq); !ngtcp2_ksl_it_end(&it);
1975 ngtcp2_ksl_it_next(&it)) {
1976 frc = ngtcp2_ksl_it_get(&it);
1977 fr = &frc->fr.crypto;
1978
1979 gap = ngtcp2_strm_get_unacked_range_after(rtb->crypto, fr->offset);
1980
1981 datalen = ngtcp2_vec_len(fr->data, fr->datacnt);
1982
1983 if (gap.begin <= fr->offset) {
1984 return fr->offset;
1985 }
1986 if (gap.begin < fr->offset + datalen) {
1987 return gap.begin;
1988 }
1989 }
1990
1991 return (uint64_t)-1;
1992 }
1993
conn_cryptofrq_unacked_pop(ngtcp2_conn * conn,ngtcp2_pktns * pktns,ngtcp2_frame_chain ** pfrc)1994 static int conn_cryptofrq_unacked_pop(ngtcp2_conn *conn, ngtcp2_pktns *pktns,
1995 ngtcp2_frame_chain **pfrc) {
1996 ngtcp2_frame_chain *frc, *nfrc;
1997 ngtcp2_crypto *fr, *nfr;
1998 uint64_t offset, end_offset;
1999 size_t idx, end_idx;
2000 uint64_t base_offset, end_base_offset;
2001 ngtcp2_range gap;
2002 ngtcp2_rtb *rtb = &pktns->rtb;
2003 ngtcp2_vec *v;
2004 int rv;
2005 ngtcp2_ksl_it it;
2006
2007 *pfrc = NULL;
2008
2009 for (it = ngtcp2_ksl_begin(&pktns->crypto.tx.frq); !ngtcp2_ksl_it_end(&it);) {
2010 frc = ngtcp2_ksl_it_get(&it);
2011 fr = &frc->fr.crypto;
2012
2013 ngtcp2_ksl_remove_hint(&pktns->crypto.tx.frq, &it, &it, &fr->offset);
2014
2015 idx = 0;
2016 offset = fr->offset;
2017 base_offset = 0;
2018
2019 gap = ngtcp2_strm_get_unacked_range_after(rtb->crypto, offset);
2020 if (gap.begin < offset) {
2021 gap.begin = offset;
2022 }
2023
2024 for (; idx < fr->datacnt && offset < gap.begin; ++idx) {
2025 v = &fr->data[idx];
2026 if (offset + v->len > gap.begin) {
2027 base_offset = gap.begin - offset;
2028 break;
2029 }
2030
2031 offset += v->len;
2032 }
2033
2034 if (idx == fr->datacnt) {
2035 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2036 continue;
2037 }
2038
2039 assert(gap.begin == offset + base_offset);
2040
2041 end_idx = idx;
2042 end_offset = offset;
2043 end_base_offset = 0;
2044
2045 for (; end_idx < fr->datacnt; ++end_idx) {
2046 v = &fr->data[end_idx];
2047 if (end_offset + v->len > gap.end) {
2048 end_base_offset = gap.end - end_offset;
2049 break;
2050 }
2051
2052 end_offset += v->len;
2053 }
2054
2055 if (fr->offset == offset && base_offset == 0 && fr->datacnt == end_idx) {
2056 *pfrc = frc;
2057 return 0;
2058 }
2059
2060 if (fr->datacnt == end_idx) {
2061 memmove(fr->data, fr->data + idx, sizeof(fr->data[0]) * (end_idx - idx));
2062
2063 assert(fr->data[0].len > base_offset);
2064
2065 fr->offset = offset + base_offset;
2066 fr->datacnt = end_idx - idx;
2067 fr->data[0].base += base_offset;
2068 fr->data[0].len -= (size_t)base_offset;
2069
2070 *pfrc = frc;
2071 return 0;
2072 }
2073
2074 rv = ngtcp2_frame_chain_crypto_datacnt_objalloc_new(
2075 &nfrc, fr->datacnt - end_idx, &conn->frc_objalloc, conn->mem);
2076 if (rv != 0) {
2077 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2078 return rv;
2079 }
2080
2081 nfr = &nfrc->fr.crypto;
2082 nfr->type = NGTCP2_FRAME_CRYPTO;
2083 memcpy(nfr->data, fr->data + end_idx,
2084 sizeof(nfr->data[0]) * (fr->datacnt - end_idx));
2085
2086 assert(nfr->data[0].len > end_base_offset);
2087
2088 nfr->offset = end_offset + end_base_offset;
2089 nfr->datacnt = fr->datacnt - end_idx;
2090 nfr->data[0].base += end_base_offset;
2091 nfr->data[0].len -= (size_t)end_base_offset;
2092
2093 rv = ngtcp2_ksl_insert(&pktns->crypto.tx.frq, NULL, &nfr->offset, nfrc);
2094 if (rv != 0) {
2095 assert(ngtcp2_err_is_fatal(rv));
2096 ngtcp2_frame_chain_objalloc_del(nfrc, &conn->frc_objalloc, conn->mem);
2097 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2098 return rv;
2099 }
2100
2101 if (end_base_offset) {
2102 ++end_idx;
2103 }
2104
2105 memmove(fr->data, fr->data + idx, sizeof(fr->data[0]) * (end_idx - idx));
2106
2107 assert(fr->data[0].len > base_offset);
2108
2109 fr->offset = offset + base_offset;
2110 fr->datacnt = end_idx - idx;
2111 if (end_base_offset) {
2112 assert(fr->data[fr->datacnt - 1].len > end_base_offset);
2113 fr->data[fr->datacnt - 1].len = (size_t)end_base_offset;
2114 }
2115 fr->data[0].base += base_offset;
2116 fr->data[0].len -= (size_t)base_offset;
2117
2118 *pfrc = frc;
2119 return 0;
2120 }
2121
2122 return 0;
2123 }
conn_cryptofrq_pop(ngtcp2_conn * conn,ngtcp2_frame_chain ** pfrc,ngtcp2_pktns * pktns,size_t left)2124 static int conn_cryptofrq_pop(ngtcp2_conn *conn, ngtcp2_frame_chain **pfrc,
2125 ngtcp2_pktns *pktns, size_t left) {
2126 ngtcp2_crypto *fr, *nfr;
2127 ngtcp2_frame_chain *frc, *nfrc;
2128 int rv;
2129 size_t nmerged;
2130 uint64_t datalen;
2131 ngtcp2_vec a[NGTCP2_MAX_CRYPTO_DATACNT];
2132 ngtcp2_vec b[NGTCP2_MAX_CRYPTO_DATACNT];
2133 size_t acnt, bcnt;
2134 ngtcp2_ksl_it it;
2135
2136 rv = conn_cryptofrq_unacked_pop(conn, pktns, &frc);
2137 if (rv != 0) {
2138 return rv;
2139 }
2140 if (frc == NULL) {
2141 *pfrc = NULL;
2142 return 0;
2143 }
2144
2145 fr = &frc->fr.crypto;
2146 datalen = ngtcp2_vec_len(fr->data, fr->datacnt);
2147
2148 if (datalen > left) {
2149 ngtcp2_vec_copy(a, fr->data, fr->datacnt);
2150 acnt = fr->datacnt;
2151
2152 bcnt = 0;
2153 ngtcp2_vec_split(a, &acnt, b, &bcnt, left, NGTCP2_MAX_CRYPTO_DATACNT);
2154
2155 assert(acnt > 0);
2156 assert(bcnt > 0);
2157
2158 rv = ngtcp2_frame_chain_crypto_datacnt_objalloc_new(
2159 &nfrc, bcnt, &conn->frc_objalloc, conn->mem);
2160 if (rv != 0) {
2161 assert(ngtcp2_err_is_fatal(rv));
2162 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2163 return rv;
2164 }
2165
2166 nfr = &nfrc->fr.crypto;
2167 nfr->type = NGTCP2_FRAME_CRYPTO;
2168 nfr->offset = fr->offset + left;
2169 nfr->datacnt = bcnt;
2170 ngtcp2_vec_copy(nfr->data, b, bcnt);
2171
2172 rv = ngtcp2_ksl_insert(&pktns->crypto.tx.frq, NULL, &nfr->offset, nfrc);
2173 if (rv != 0) {
2174 assert(ngtcp2_err_is_fatal(rv));
2175 ngtcp2_frame_chain_objalloc_del(nfrc, &conn->frc_objalloc, conn->mem);
2176 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2177 return rv;
2178 }
2179
2180 rv = ngtcp2_frame_chain_crypto_datacnt_objalloc_new(
2181 &nfrc, acnt, &conn->frc_objalloc, conn->mem);
2182 if (rv != 0) {
2183 assert(ngtcp2_err_is_fatal(rv));
2184 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2185 return rv;
2186 }
2187
2188 nfr = &nfrc->fr.crypto;
2189 *nfr = *fr;
2190 nfr->datacnt = acnt;
2191 ngtcp2_vec_copy(nfr->data, a, acnt);
2192
2193 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2194
2195 *pfrc = nfrc;
2196
2197 return 0;
2198 }
2199
2200 left -= (size_t)datalen;
2201
2202 ngtcp2_vec_copy(a, fr->data, fr->datacnt);
2203 acnt = fr->datacnt;
2204
2205 for (; left && ngtcp2_ksl_len(&pktns->crypto.tx.frq);) {
2206 it = ngtcp2_ksl_begin(&pktns->crypto.tx.frq);
2207 nfrc = ngtcp2_ksl_it_get(&it);
2208 nfr = &nfrc->fr.crypto;
2209
2210 if (nfr->offset != fr->offset + datalen) {
2211 assert(fr->offset + datalen < nfr->offset);
2212 break;
2213 }
2214
2215 rv = conn_cryptofrq_unacked_pop(conn, pktns, &nfrc);
2216 if (rv != 0) {
2217 assert(ngtcp2_err_is_fatal(rv));
2218 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2219 return rv;
2220 }
2221 if (nfrc == NULL) {
2222 break;
2223 }
2224
2225 nfr = &nfrc->fr.crypto;
2226
2227 nmerged = ngtcp2_vec_merge(a, &acnt, nfr->data, &nfr->datacnt, left,
2228 NGTCP2_MAX_CRYPTO_DATACNT);
2229 if (nmerged == 0) {
2230 rv = ngtcp2_ksl_insert(&pktns->crypto.tx.frq, NULL, &nfr->offset, nfrc);
2231 if (rv != 0) {
2232 assert(ngtcp2_err_is_fatal(rv));
2233 ngtcp2_frame_chain_objalloc_del(nfrc, &conn->frc_objalloc, conn->mem);
2234 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2235 return rv;
2236 }
2237 break;
2238 }
2239
2240 datalen += nmerged;
2241 left -= nmerged;
2242
2243 if (nfr->datacnt == 0) {
2244 ngtcp2_frame_chain_objalloc_del(nfrc, &conn->frc_objalloc, conn->mem);
2245 continue;
2246 }
2247
2248 nfr->offset += nmerged;
2249
2250 rv = ngtcp2_ksl_insert(&pktns->crypto.tx.frq, NULL, &nfr->offset, nfrc);
2251 if (rv != 0) {
2252 ngtcp2_frame_chain_objalloc_del(nfrc, &conn->frc_objalloc, conn->mem);
2253 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2254 return rv;
2255 }
2256
2257 break;
2258 }
2259
2260 if (acnt == fr->datacnt) {
2261 assert(acnt > 0);
2262 fr->data[acnt - 1] = a[acnt - 1];
2263
2264 *pfrc = frc;
2265 return 0;
2266 }
2267
2268 assert(acnt > fr->datacnt);
2269
2270 rv = ngtcp2_frame_chain_crypto_datacnt_objalloc_new(
2271 &nfrc, acnt, &conn->frc_objalloc, conn->mem);
2272 if (rv != 0) {
2273 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2274 return rv;
2275 }
2276
2277 nfr = &nfrc->fr.crypto;
2278 *nfr = *fr;
2279 nfr->datacnt = acnt;
2280 ngtcp2_vec_copy(nfr->data, a, acnt);
2281
2282 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
2283
2284 *pfrc = nfrc;
2285
2286 return 0;
2287 }
2288
2289 /*
2290 * conn_verify_dcid verifies that destination connection ID in |hd| is
2291 * valid for the connection. If it is successfully verified and the
2292 * remote endpoint uses new DCID in the packet, nonzero value is
2293 * assigned to |*pnew_cid_used| if it is not NULL. Otherwise 0 is
2294 * assigned to it.
2295 *
2296 * This function returns 0 if it succeeds, or one of the following
2297 * negative error codes:
2298 *
2299 * NGTCP2_ERR_NOMEM
2300 * Out of memory.
2301 * NGTCP2_ERR_INVALID_ARGUMENT
2302 * |dcid| is not known to the local endpoint.
2303 */
conn_verify_dcid(ngtcp2_conn * conn,int * pnew_cid_used,const ngtcp2_pkt_hd * hd)2304 static int conn_verify_dcid(ngtcp2_conn *conn, int *pnew_cid_used,
2305 const ngtcp2_pkt_hd *hd) {
2306 ngtcp2_ksl_it it;
2307 ngtcp2_scid *scid;
2308 int rv;
2309
2310 it = ngtcp2_ksl_lower_bound(&conn->scid.set, &hd->dcid);
2311 if (ngtcp2_ksl_it_end(&it)) {
2312 return NGTCP2_ERR_INVALID_ARGUMENT;
2313 }
2314
2315 scid = ngtcp2_ksl_it_get(&it);
2316 if (!ngtcp2_cid_eq(&scid->cid, &hd->dcid)) {
2317 return NGTCP2_ERR_INVALID_ARGUMENT;
2318 }
2319
2320 if (!(scid->flags & NGTCP2_SCID_FLAG_USED)) {
2321 scid->flags |= NGTCP2_SCID_FLAG_USED;
2322
2323 if (scid->pe.index == NGTCP2_PQ_BAD_INDEX) {
2324 rv = ngtcp2_pq_push(&conn->scid.used, &scid->pe);
2325 if (rv != 0) {
2326 return rv;
2327 }
2328 }
2329
2330 if (pnew_cid_used) {
2331 *pnew_cid_used = 1;
2332 }
2333 } else if (pnew_cid_used) {
2334 *pnew_cid_used = 0;
2335 }
2336
2337 return 0;
2338 }
2339
2340 /*
2341 * conn_should_pad_pkt returns nonzero if the packet should be padded.
2342 * |type| is the type of packet. |left| is the space left in packet
2343 * buffer. |write_datalen| is the number of bytes which will be sent
2344 * in the next, coalesced 0-RTT or 1RTT packet.
2345 */
conn_should_pad_pkt(ngtcp2_conn * conn,uint8_t type,size_t left,uint64_t write_datalen,int ack_eliciting,int require_padding)2346 static int conn_should_pad_pkt(ngtcp2_conn *conn, uint8_t type, size_t left,
2347 uint64_t write_datalen, int ack_eliciting,
2348 int require_padding) {
2349 uint64_t min_payloadlen;
2350
2351 if (type == NGTCP2_PKT_INITIAL) {
2352 if (conn->server) {
2353 if (!ack_eliciting) {
2354 return 0;
2355 }
2356
2357 if (conn->hs_pktns->crypto.tx.ckm &&
2358 (conn->hs_pktns->rtb.probe_pkt_left ||
2359 ngtcp2_ksl_len(&conn->hs_pktns->crypto.tx.frq) ||
2360 !ngtcp2_acktr_empty(&conn->hs_pktns->acktr))) {
2361 /* If we have something to send in Handshake packet, then add
2362 PADDING in Handshake packet. */
2363 min_payloadlen = NGTCP2_MIN_COALESCED_PAYLOADLEN;
2364 } else {
2365 return 1;
2366 }
2367 } else {
2368 if (conn->hs_pktns->crypto.tx.ckm &&
2369 (conn->hs_pktns->rtb.probe_pkt_left ||
2370 ngtcp2_ksl_len(&conn->hs_pktns->crypto.tx.frq) ||
2371 !ngtcp2_acktr_empty(&conn->hs_pktns->acktr))) {
2372 /* If we have something to send in Handshake packet, then add
2373 PADDING in Handshake packet. */
2374 min_payloadlen = NGTCP2_MIN_COALESCED_PAYLOADLEN;
2375 } else if ((!conn->early.ckm && !conn->pktns.crypto.tx.ckm) ||
2376 write_datalen == 0) {
2377 return 1;
2378 } else {
2379 /* If we have something to send in 0RTT or 1RTT packet, then
2380 add PADDING in that packet. Take maximum in case that
2381 write_datalen includes DATAGRAM which cannot be split. */
2382 min_payloadlen =
2383 ngtcp2_max(write_datalen, NGTCP2_MIN_COALESCED_PAYLOADLEN);
2384 }
2385 }
2386 } else {
2387 assert(type == NGTCP2_PKT_HANDSHAKE);
2388
2389 if (!require_padding) {
2390 return 0;
2391 }
2392
2393 if (!conn->pktns.crypto.tx.ckm || write_datalen == 0) {
2394 return 1;
2395 }
2396
2397 min_payloadlen = ngtcp2_max(write_datalen, NGTCP2_MIN_COALESCED_PAYLOADLEN);
2398 }
2399
2400 /* TODO the next packet type should be taken into account */
2401 return left <
2402 /* TODO Assuming that pkt_num is encoded in 1 byte. */
2403 NGTCP2_MIN_LONG_HEADERLEN + conn->dcid.current.cid.datalen +
2404 conn->oscid.datalen + NGTCP2_PKT_LENGTHLEN - 1 + min_payloadlen +
2405 NGTCP2_MAX_AEAD_OVERHEAD;
2406 }
2407
conn_restart_timer_on_write(ngtcp2_conn * conn,ngtcp2_tstamp ts)2408 static void conn_restart_timer_on_write(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
2409 conn->idle_ts = ts;
2410 conn->flags &= (uint32_t)~NGTCP2_CONN_FLAG_RESTART_IDLE_TIMER_ON_WRITE;
2411 }
2412
conn_restart_timer_on_read(ngtcp2_conn * conn,ngtcp2_tstamp ts)2413 static void conn_restart_timer_on_read(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
2414 conn->idle_ts = ts;
2415 conn->flags |= NGTCP2_CONN_FLAG_RESTART_IDLE_TIMER_ON_WRITE;
2416 }
2417
2418 /*
2419 * conn_keep_alive_enabled returns nonzero if keep-alive is enabled.
2420 */
conn_keep_alive_enabled(ngtcp2_conn * conn)2421 static int conn_keep_alive_enabled(ngtcp2_conn *conn) {
2422 return conn->keep_alive.last_ts != UINT64_MAX && conn->keep_alive.timeout;
2423 }
2424
2425 /*
2426 * conn_keep_alive_expired returns nonzero if keep-alive timer has
2427 * expired.
2428 */
conn_keep_alive_expired(ngtcp2_conn * conn,ngtcp2_tstamp ts)2429 static int conn_keep_alive_expired(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
2430 return conn_keep_alive_enabled(conn) &&
2431 conn->keep_alive.last_ts + conn->keep_alive.timeout <= ts;
2432 }
2433
2434 /*
2435 * conn_keep_alive_expiry returns the expiry time of keep-alive timer.
2436 */
conn_keep_alive_expiry(ngtcp2_conn * conn)2437 static ngtcp2_tstamp conn_keep_alive_expiry(ngtcp2_conn *conn) {
2438 if ((conn->flags & NGTCP2_CONN_FLAG_KEEP_ALIVE_CANCELLED) ||
2439 !conn_keep_alive_enabled(conn)) {
2440 return UINT64_MAX;
2441 }
2442
2443 return conn->keep_alive.last_ts + conn->keep_alive.timeout;
2444 }
2445
2446 /*
2447 * conn_cancel_expired_keep_alive_timer cancels the expired keep-alive
2448 * timer.
2449 */
conn_cancel_expired_keep_alive_timer(ngtcp2_conn * conn,ngtcp2_tstamp ts)2450 static void conn_cancel_expired_keep_alive_timer(ngtcp2_conn *conn,
2451 ngtcp2_tstamp ts) {
2452 if (!(conn->flags & NGTCP2_CONN_FLAG_KEEP_ALIVE_CANCELLED) &&
2453 conn_keep_alive_expired(conn, ts)) {
2454 conn->flags |= NGTCP2_CONN_FLAG_KEEP_ALIVE_CANCELLED;
2455 }
2456 }
2457
2458 /*
2459 * conn_update_keep_alive_last_ts updates the base time point of
2460 * keep-alive timer.
2461 */
conn_update_keep_alive_last_ts(ngtcp2_conn * conn,ngtcp2_tstamp ts)2462 static void conn_update_keep_alive_last_ts(ngtcp2_conn *conn,
2463 ngtcp2_tstamp ts) {
2464 conn->keep_alive.last_ts = ts;
2465 conn->flags &= (uint32_t)~NGTCP2_CONN_FLAG_KEEP_ALIVE_CANCELLED;
2466 }
2467
ngtcp2_conn_set_keep_alive_timeout(ngtcp2_conn * conn,ngtcp2_duration timeout)2468 void ngtcp2_conn_set_keep_alive_timeout(ngtcp2_conn *conn,
2469 ngtcp2_duration timeout) {
2470 conn->keep_alive.timeout = timeout;
2471 }
2472
2473 /*
2474 * NGTCP2_PKT_PACING_OVERHEAD defines overhead of userspace event
2475 * loop. Packet pacing might require sub milliseconds packet spacing,
2476 * but userspace event loop might not offer such precision.
2477 * Typically, if delay is 0.5 microseconds, the actual delay after
2478 * which we can send packet is well over 1 millisecond when event loop
2479 * is involved (which includes other stuff, like reading packets etc
2480 * in a typical single threaded use case).
2481 */
2482 #define NGTCP2_PKT_PACING_OVERHEAD NGTCP2_MILLISECONDS
2483
conn_cancel_expired_pkt_tx_timer(ngtcp2_conn * conn,ngtcp2_tstamp ts)2484 static void conn_cancel_expired_pkt_tx_timer(ngtcp2_conn *conn,
2485 ngtcp2_tstamp ts) {
2486 if (conn->tx.pacing.next_ts == UINT64_MAX) {
2487 return;
2488 }
2489
2490 if (conn->tx.pacing.next_ts > ts + NGTCP2_PKT_PACING_OVERHEAD) {
2491 return;
2492 }
2493
2494 conn->tx.pacing.next_ts = UINT64_MAX;
2495 }
2496
conn_pacing_pkt_tx_allowed(ngtcp2_conn * conn,ngtcp2_tstamp ts)2497 static int conn_pacing_pkt_tx_allowed(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
2498 return conn->tx.pacing.next_ts == UINT64_MAX ||
2499 conn->tx.pacing.next_ts <= ts + NGTCP2_PKT_PACING_OVERHEAD;
2500 }
2501
conn_pkt_flags(ngtcp2_conn * conn)2502 static uint8_t conn_pkt_flags(ngtcp2_conn *conn) {
2503 if (conn->remote.transport_params &&
2504 conn->remote.transport_params->grease_quic_bit &&
2505 (conn->flags & NGTCP2_CONN_FLAG_CLEAR_FIXED_BIT)) {
2506 return NGTCP2_PKT_FLAG_FIXED_BIT_CLEAR;
2507 }
2508
2509 return NGTCP2_PKT_FLAG_NONE;
2510 }
2511
conn_pkt_flags_long(ngtcp2_conn * conn)2512 static uint8_t conn_pkt_flags_long(ngtcp2_conn *conn) {
2513 return NGTCP2_PKT_FLAG_LONG_FORM | conn_pkt_flags(conn);
2514 }
2515
conn_pkt_flags_short(ngtcp2_conn * conn)2516 static uint8_t conn_pkt_flags_short(ngtcp2_conn *conn) {
2517 return (uint8_t)(conn_pkt_flags(conn) | ((conn->pktns.crypto.tx.ckm->flags &
2518 NGTCP2_CRYPTO_KM_FLAG_KEY_PHASE_ONE)
2519 ? NGTCP2_PKT_FLAG_KEY_PHASE
2520 : NGTCP2_PKT_FLAG_NONE));
2521 }
2522
2523 /*
2524 * conn_write_handshake_pkt writes handshake packet in the buffer
2525 * pointed by |dest| whose length is |destlen|. |type| specifies long
2526 * packet type. It should be either NGTCP2_PKT_INITIAL or
2527 * NGTCP2_PKT_HANDSHAKE_PKT.
2528 *
2529 * |write_datalen| is the minimum length of application data ready to
2530 * send in subsequent 0RTT or 1RTT packet.
2531 *
2532 * This function returns the number of bytes written in |dest| if it
2533 * succeeds, or one of the following negative error codes:
2534 *
2535 * NGTCP2_ERR_NOMEM
2536 * Out of memory.
2537 * NGTCP2_ERR_CALLBACK_FAILURE
2538 * User-defined callback function failed.
2539 */
2540 static ngtcp2_ssize
conn_write_handshake_pkt(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,uint8_t type,uint8_t flags,uint64_t write_datalen,ngtcp2_tstamp ts)2541 conn_write_handshake_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi, uint8_t *dest,
2542 size_t destlen, uint8_t type, uint8_t flags,
2543 uint64_t write_datalen, ngtcp2_tstamp ts) {
2544 int rv;
2545 ngtcp2_ppe ppe;
2546 ngtcp2_pkt_hd hd;
2547 ngtcp2_frame_chain *frq = NULL, **pfrc = &frq;
2548 ngtcp2_frame_chain *nfrc;
2549 ngtcp2_frame *ackfr = NULL, lfr;
2550 ngtcp2_ssize spktlen;
2551 ngtcp2_crypto_cc cc;
2552 ngtcp2_rtb_entry *rtbent;
2553 ngtcp2_pktns *pktns;
2554 size_t left;
2555 uint16_t rtb_entry_flags = NGTCP2_RTB_ENTRY_FLAG_NONE;
2556 int require_padding = (flags & NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING) != 0;
2557 int pkt_empty = 1;
2558 int padded = 0;
2559 int hd_logged = 0;
2560 uint64_t crypto_offset;
2561 ngtcp2_ssize num_reclaimed;
2562 uint32_t version;
2563
2564 switch (type) {
2565 case NGTCP2_PKT_INITIAL:
2566 if (!conn->in_pktns) {
2567 return 0;
2568 }
2569 assert(conn->in_pktns->crypto.tx.ckm);
2570 pktns = conn->in_pktns;
2571 version = conn->negotiated_version ? conn->negotiated_version
2572 : conn->client_chosen_version;
2573 if (version == conn->client_chosen_version) {
2574 cc.ckm = pktns->crypto.tx.ckm;
2575 cc.hp_ctx = pktns->crypto.tx.hp_ctx;
2576 } else {
2577 assert(conn->vneg.version == version);
2578
2579 cc.ckm = conn->vneg.tx.ckm;
2580 cc.hp_ctx = conn->vneg.tx.hp_ctx;
2581 }
2582 break;
2583 case NGTCP2_PKT_HANDSHAKE:
2584 if (!conn->hs_pktns || !conn->hs_pktns->crypto.tx.ckm) {
2585 return 0;
2586 }
2587 pktns = conn->hs_pktns;
2588 version = conn->negotiated_version;
2589 cc.ckm = pktns->crypto.tx.ckm;
2590 cc.hp_ctx = pktns->crypto.tx.hp_ctx;
2591 break;
2592 default:
2593 assert(0);
2594 abort();
2595 }
2596
2597 cc.aead = pktns->crypto.ctx.aead;
2598 cc.hp = pktns->crypto.ctx.hp;
2599 cc.encrypt = conn->callbacks.encrypt;
2600 cc.hp_mask = conn->callbacks.hp_mask;
2601
2602 ngtcp2_pkt_hd_init(&hd, conn_pkt_flags_long(conn), type,
2603 &conn->dcid.current.cid, &conn->oscid,
2604 pktns->tx.last_pkt_num + 1, pktns_select_pkt_numlen(pktns),
2605 version, 0);
2606
2607 if (!conn->server && type == NGTCP2_PKT_INITIAL &&
2608 conn->local.settings.token.len) {
2609 hd.token = conn->local.settings.token;
2610 }
2611
2612 ngtcp2_ppe_init(&ppe, dest, destlen, &cc);
2613
2614 rv = ngtcp2_ppe_encode_hd(&ppe, &hd);
2615 if (rv != 0) {
2616 assert(NGTCP2_ERR_NOBUF == rv);
2617 return 0;
2618 }
2619
2620 if (!ngtcp2_ppe_ensure_hp_sample(&ppe)) {
2621 return 0;
2622 }
2623
2624 rv = conn_create_ack_frame(conn, &ackfr, pktns, type, ts,
2625 /* ack_delay = */ 0,
2626 NGTCP2_DEFAULT_ACK_DELAY_EXPONENT);
2627 if (rv != 0) {
2628 ngtcp2_frame_chain_list_objalloc_del(frq, &conn->frc_objalloc, conn->mem);
2629 return rv;
2630 }
2631
2632 if (ackfr) {
2633 rv = conn_ppe_write_frame_hd_log(conn, &ppe, &hd_logged, &hd, ackfr);
2634 if (rv != 0) {
2635 assert(NGTCP2_ERR_NOBUF == rv);
2636 } else {
2637 ngtcp2_acktr_commit_ack(&pktns->acktr);
2638 ngtcp2_acktr_add_ack(&pktns->acktr, hd.pkt_num, ackfr->ack.largest_ack);
2639 pkt_empty = 0;
2640 }
2641 }
2642
2643 /* Server requires at least NGTCP2_MAX_UDP_PAYLOAD_SIZE bytes in
2644 order to send ack-eliciting Initial packet. */
2645 if (!conn->server || type != NGTCP2_PKT_INITIAL ||
2646 destlen >= NGTCP2_MAX_UDP_PAYLOAD_SIZE) {
2647 build_pkt:
2648 for (; ngtcp2_ksl_len(&pktns->crypto.tx.frq);) {
2649 left = ngtcp2_ppe_left(&ppe);
2650
2651 crypto_offset = conn_cryptofrq_unacked_offset(conn, pktns);
2652 if (crypto_offset == (size_t)-1) {
2653 conn_cryptofrq_clear(conn, pktns);
2654 break;
2655 }
2656
2657 left = ngtcp2_pkt_crypto_max_datalen(crypto_offset, left, left);
2658 if (left == (size_t)-1) {
2659 break;
2660 }
2661
2662 rv = conn_cryptofrq_pop(conn, &nfrc, pktns, left);
2663 if (rv != 0) {
2664 assert(ngtcp2_err_is_fatal(rv));
2665 ngtcp2_frame_chain_list_objalloc_del(frq, &conn->frc_objalloc,
2666 conn->mem);
2667 return rv;
2668 }
2669
2670 if (nfrc == NULL) {
2671 break;
2672 }
2673
2674 rv = conn_ppe_write_frame_hd_log(conn, &ppe, &hd_logged, &hd, &nfrc->fr);
2675 if (rv != 0) {
2676 assert(0);
2677 }
2678
2679 *pfrc = nfrc;
2680 pfrc = &(*pfrc)->next;
2681
2682 pkt_empty = 0;
2683 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING |
2684 NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING |
2685 NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE;
2686 }
2687
2688 if (!(rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) &&
2689 pktns->rtb.num_retransmittable && pktns->rtb.probe_pkt_left) {
2690 num_reclaimed = ngtcp2_rtb_reclaim_on_pto(&pktns->rtb, conn, pktns, 1);
2691 if (num_reclaimed < 0) {
2692 ngtcp2_frame_chain_list_objalloc_del(frq, &conn->frc_objalloc,
2693 conn->mem);
2694 return rv;
2695 }
2696 if (num_reclaimed) {
2697 goto build_pkt;
2698 }
2699 /* We had pktns->rtb.num_retransmittable > 0 but the contents of
2700 those packets have been acknowledged (i.e., retransmission in
2701 another packet). For server, in this case, we don't have to
2702 send any probe packet. Client needs to send probe packets
2703 until it knows that server has completed address validation or
2704 handshake has been confirmed. */
2705 if (pktns->rtb.num_pto_eliciting == 0 &&
2706 (conn->server ||
2707 (conn->flags & (NGTCP2_CONN_FLAG_SERVER_ADDR_VERIFIED |
2708 NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED)))) {
2709 pktns->rtb.probe_pkt_left = 0;
2710 ngtcp2_conn_set_loss_detection_timer(conn, ts);
2711 /* TODO If packet is empty, we should return now if cwnd is
2712 zero. */
2713 }
2714 }
2715
2716 if (!(rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) &&
2717 pktns->rtb.probe_pkt_left) {
2718 lfr.type = NGTCP2_FRAME_PING;
2719
2720 rv = conn_ppe_write_frame_hd_log(conn, &ppe, &hd_logged, &hd, &lfr);
2721 if (rv != 0) {
2722 assert(rv == NGTCP2_ERR_NOBUF);
2723 } else {
2724 rtb_entry_flags |=
2725 NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING | NGTCP2_RTB_ENTRY_FLAG_PROBE;
2726 pkt_empty = 0;
2727 }
2728 }
2729
2730 if (!pkt_empty) {
2731 if (!(rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING)) {
2732 /* The intention of smaller limit is get more chance to measure
2733 RTT samples in early phase. */
2734 if (pktns->tx.num_non_ack_pkt >= 1) {
2735 lfr.type = NGTCP2_FRAME_PING;
2736
2737 rv = conn_ppe_write_frame_hd_log(conn, &ppe, &hd_logged, &hd, &lfr);
2738 if (rv != 0) {
2739 assert(rv == NGTCP2_ERR_NOBUF);
2740 } else {
2741 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING;
2742 pktns->tx.num_non_ack_pkt = 0;
2743 }
2744 } else {
2745 ++pktns->tx.num_non_ack_pkt;
2746 }
2747 } else {
2748 pktns->tx.num_non_ack_pkt = 0;
2749 }
2750 }
2751 }
2752
2753 if (pkt_empty) {
2754 return 0;
2755 }
2756
2757 /* If we cannot write another packet, then we need to add padding to
2758 Initial here. */
2759 if (conn_should_pad_pkt(
2760 conn, type, ngtcp2_ppe_left(&ppe), write_datalen,
2761 (rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) != 0,
2762 require_padding)) {
2763 lfr.type = NGTCP2_FRAME_PADDING;
2764 lfr.padding.len = ngtcp2_ppe_padding(&ppe);
2765 } else {
2766 lfr.type = NGTCP2_FRAME_PADDING;
2767 lfr.padding.len = ngtcp2_ppe_padding_hp_sample(&ppe);
2768 }
2769
2770 if (lfr.padding.len) {
2771 padded = 1;
2772 ngtcp2_log_tx_fr(&conn->log, &hd, &lfr);
2773 ngtcp2_qlog_write_frame(&conn->qlog, &lfr);
2774 }
2775
2776 spktlen = ngtcp2_ppe_final(&ppe, NULL);
2777 if (spktlen < 0) {
2778 assert(ngtcp2_err_is_fatal((int)spktlen));
2779 ngtcp2_frame_chain_list_objalloc_del(frq, &conn->frc_objalloc, conn->mem);
2780 return spktlen;
2781 }
2782
2783 ngtcp2_qlog_pkt_sent_end(&conn->qlog, &hd, (size_t)spktlen);
2784
2785 if ((rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) || padded) {
2786 if (pi) {
2787 conn_handle_tx_ecn(conn, pi, &rtb_entry_flags, pktns, &hd, ts);
2788 }
2789
2790 rv = ngtcp2_rtb_entry_objalloc_new(&rtbent, &hd, frq, ts, (size_t)spktlen,
2791 rtb_entry_flags,
2792 &conn->rtb_entry_objalloc);
2793 if (rv != 0) {
2794 assert(ngtcp2_err_is_fatal(rv));
2795 ngtcp2_frame_chain_list_objalloc_del(frq, &conn->frc_objalloc, conn->mem);
2796 return rv;
2797 }
2798
2799 rv = conn_on_pkt_sent(conn, &pktns->rtb, rtbent);
2800 if (rv != 0) {
2801 ngtcp2_rtb_entry_objalloc_del(rtbent, &conn->rtb_entry_objalloc,
2802 &conn->frc_objalloc, conn->mem);
2803 return rv;
2804 }
2805
2806 if ((rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) &&
2807 (conn->flags & NGTCP2_CONN_FLAG_RESTART_IDLE_TIMER_ON_WRITE)) {
2808 conn_restart_timer_on_write(conn, ts);
2809 }
2810 } else if (pi && conn->tx.ecn.state == NGTCP2_ECN_STATE_CAPABLE) {
2811 conn_handle_tx_ecn(conn, pi, NULL, pktns, &hd, ts);
2812 }
2813
2814 if (pktns->rtb.probe_pkt_left &&
2815 (rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING)) {
2816 --pktns->rtb.probe_pkt_left;
2817 }
2818
2819 conn_update_keep_alive_last_ts(conn, ts);
2820
2821 conn->dcid.current.bytes_sent += (uint64_t)spktlen;
2822
2823 conn->tx.pacing.pktlen += (size_t)spktlen;
2824
2825 ngtcp2_qlog_metrics_updated(&conn->qlog, &conn->cstat);
2826
2827 ++pktns->tx.last_pkt_num;
2828
2829 return spktlen;
2830 }
2831
2832 /*
2833 * conn_write_ack_pkt writes QUIC packet for type |type| which only
2834 * includes ACK frame in the buffer pointed by |dest| whose length is
2835 * |destlen|.
2836 *
2837 * This function returns the number of bytes written in |dest| if it
2838 * succeeds, or one of the following negative error codes:
2839 *
2840 * NGTCP2_ERR_CALLBACK_FAILURE
2841 * User-defined callback function failed.
2842 * NGTCP2_ERR_NOMEM
2843 * Out of memory.
2844 */
conn_write_ack_pkt(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,uint8_t type,ngtcp2_tstamp ts)2845 static ngtcp2_ssize conn_write_ack_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
2846 uint8_t *dest, size_t destlen,
2847 uint8_t type, ngtcp2_tstamp ts) {
2848 int rv;
2849 ngtcp2_frame *ackfr;
2850 ngtcp2_pktns *pktns;
2851 ngtcp2_duration ack_delay;
2852 uint64_t ack_delay_exponent;
2853 ngtcp2_ssize spktlen;
2854
2855 assert(!(conn->flags & NGTCP2_CONN_FLAG_PPE_PENDING));
2856
2857 switch (type) {
2858 case NGTCP2_PKT_INITIAL:
2859 assert(conn->server);
2860 pktns = conn->in_pktns;
2861 ack_delay = 0;
2862 ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT;
2863 break;
2864 case NGTCP2_PKT_HANDSHAKE:
2865 pktns = conn->hs_pktns;
2866 ack_delay = 0;
2867 ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT;
2868 break;
2869 case NGTCP2_PKT_1RTT:
2870 pktns = &conn->pktns;
2871 ack_delay = conn_compute_ack_delay(conn);
2872 ack_delay_exponent = conn->local.transport_params.ack_delay_exponent;
2873 break;
2874 default:
2875 assert(0);
2876 abort();
2877 }
2878
2879 if (!pktns->crypto.tx.ckm) {
2880 return 0;
2881 }
2882
2883 ackfr = NULL;
2884 rv = conn_create_ack_frame(conn, &ackfr, pktns, type, ts, ack_delay,
2885 ack_delay_exponent);
2886 if (rv != 0) {
2887 return rv;
2888 }
2889
2890 if (!ackfr) {
2891 return 0;
2892 }
2893
2894 spktlen = ngtcp2_conn_write_single_frame_pkt(
2895 conn, pi, dest, destlen, type, NGTCP2_WRITE_PKT_FLAG_NONE,
2896 &conn->dcid.current.cid, ackfr, NGTCP2_RTB_ENTRY_FLAG_NONE, NULL, ts);
2897
2898 if (spktlen <= 0) {
2899 return spktlen;
2900 }
2901
2902 conn->dcid.current.bytes_sent += (uint64_t)spktlen;
2903
2904 return spktlen;
2905 }
2906
conn_discard_pktns(ngtcp2_conn * conn,ngtcp2_pktns ** ppktns,ngtcp2_tstamp ts)2907 static void conn_discard_pktns(ngtcp2_conn *conn, ngtcp2_pktns **ppktns,
2908 ngtcp2_tstamp ts) {
2909 ngtcp2_pktns *pktns = *ppktns;
2910 uint64_t bytes_in_flight;
2911
2912 bytes_in_flight = pktns->rtb.cc_bytes_in_flight;
2913
2914 assert(conn->cstat.bytes_in_flight >= bytes_in_flight);
2915
2916 conn->cstat.bytes_in_flight -= bytes_in_flight;
2917 conn->cstat.pto_count = 0;
2918 conn->cstat.last_tx_pkt_ts[pktns->rtb.pktns_id] = UINT64_MAX;
2919 conn->cstat.loss_time[pktns->rtb.pktns_id] = UINT64_MAX;
2920
2921 conn_call_delete_crypto_aead_ctx(conn, &pktns->crypto.rx.ckm->aead_ctx);
2922 conn_call_delete_crypto_cipher_ctx(conn, &pktns->crypto.rx.hp_ctx);
2923 conn_call_delete_crypto_aead_ctx(conn, &pktns->crypto.tx.ckm->aead_ctx);
2924 conn_call_delete_crypto_cipher_ctx(conn, &pktns->crypto.tx.hp_ctx);
2925
2926 pktns_del(pktns, conn->mem);
2927 *ppktns = NULL;
2928
2929 ngtcp2_conn_set_loss_detection_timer(conn, ts);
2930 }
2931
2932 /*
2933 * conn_discard_initial_state discards state for Initial packet number
2934 * space.
2935 */
conn_discard_initial_state(ngtcp2_conn * conn,ngtcp2_tstamp ts)2936 static void conn_discard_initial_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
2937 if (!conn->in_pktns) {
2938 return;
2939 }
2940
2941 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
2942 "discarding Initial packet number space");
2943
2944 conn_discard_pktns(conn, &conn->in_pktns, ts);
2945
2946 conn_vneg_crypto_free(conn);
2947
2948 memset(&conn->vneg.rx, 0, sizeof(conn->vneg.rx));
2949 memset(&conn->vneg.tx, 0, sizeof(conn->vneg.tx));
2950 }
2951
2952 /*
2953 * conn_discard_handshake_state discards state for Handshake packet
2954 * number space.
2955 */
conn_discard_handshake_state(ngtcp2_conn * conn,ngtcp2_tstamp ts)2956 static void conn_discard_handshake_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
2957 if (!conn->hs_pktns) {
2958 return;
2959 }
2960
2961 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
2962 "discarding Handshake packet number space");
2963
2964 conn_discard_pktns(conn, &conn->hs_pktns, ts);
2965 }
2966
2967 /*
2968 * conn_discard_early_key discards early key.
2969 */
conn_discard_early_key(ngtcp2_conn * conn)2970 static void conn_discard_early_key(ngtcp2_conn *conn) {
2971 assert(conn->early.ckm);
2972
2973 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON, "discarding early key");
2974
2975 conn_call_delete_crypto_aead_ctx(conn, &conn->early.ckm->aead_ctx);
2976 conn_call_delete_crypto_cipher_ctx(conn, &conn->early.hp_ctx);
2977 memset(&conn->early.hp_ctx, 0, sizeof(conn->early.hp_ctx));
2978
2979 ngtcp2_crypto_km_del(conn->early.ckm, conn->mem);
2980 conn->early.ckm = NULL;
2981 }
2982
2983 /*
2984 * conn_write_handshake_ack_pkts writes packets which contain ACK
2985 * frame only. This function writes at most 2 packets for each
2986 * Initial and Handshake packet.
2987 */
conn_write_handshake_ack_pkts(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,ngtcp2_tstamp ts)2988 static ngtcp2_ssize conn_write_handshake_ack_pkts(ngtcp2_conn *conn,
2989 ngtcp2_pkt_info *pi,
2990 uint8_t *dest, size_t destlen,
2991 ngtcp2_tstamp ts) {
2992 ngtcp2_ssize res = 0, nwrite = 0;
2993
2994 /* In the most cases, client sends ACK in conn_write_handshake_pkt.
2995 This function is only called when it is CWND limited. It is not
2996 required for client to send ACK for server Initial. This is
2997 because once it gets server Initial, it gets Handshake tx key and
2998 discards Initial key. The only good reason to send ACK is give
2999 server RTT measurement early. */
3000 if (conn->server && conn->in_pktns) {
3001 nwrite =
3002 conn_write_ack_pkt(conn, pi, dest, destlen, NGTCP2_PKT_INITIAL, ts);
3003 if (nwrite < 0) {
3004 assert(nwrite != NGTCP2_ERR_NOBUF);
3005 return nwrite;
3006 }
3007
3008 res += nwrite;
3009 dest += nwrite;
3010 destlen -= (size_t)nwrite;
3011 }
3012
3013 if (conn->hs_pktns->crypto.tx.ckm) {
3014 nwrite =
3015 conn_write_ack_pkt(conn, pi, dest, destlen, NGTCP2_PKT_HANDSHAKE, ts);
3016 if (nwrite < 0) {
3017 assert(nwrite != NGTCP2_ERR_NOBUF);
3018 return nwrite;
3019 }
3020
3021 res += nwrite;
3022
3023 if (!conn->server && nwrite) {
3024 conn_discard_initial_state(conn, ts);
3025 }
3026 }
3027
3028 return res;
3029 }
3030
3031 /*
3032 * conn_write_client_initial writes Initial packet in the buffer
3033 * pointed by |dest| whose length is |destlen|.
3034 *
3035 * This function returns the number of bytes written in |dest| if it
3036 * succeeds, or one of the following negative error codes:
3037 *
3038 * NGTCP2_ERR_NOMEM
3039 * Out of memory.
3040 * NGTCP2_ERR_CALLBACK_FAILURE
3041 * User-defined callback function failed.
3042 */
conn_write_client_initial(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,uint64_t early_datalen,ngtcp2_tstamp ts)3043 static ngtcp2_ssize conn_write_client_initial(ngtcp2_conn *conn,
3044 ngtcp2_pkt_info *pi,
3045 uint8_t *dest, size_t destlen,
3046 uint64_t early_datalen,
3047 ngtcp2_tstamp ts) {
3048 int rv;
3049
3050 rv = conn_call_client_initial(conn);
3051 if (rv != 0) {
3052 return rv;
3053 }
3054
3055 return conn_write_handshake_pkt(conn, pi, dest, destlen, NGTCP2_PKT_INITIAL,
3056 NGTCP2_WRITE_PKT_FLAG_NONE, early_datalen,
3057 ts);
3058 }
3059
3060 /*
3061 * dcid_tx_left returns the maximum number of bytes that server is
3062 * allowed to send to an unvalidated path associated to |dcid|.
3063 */
dcid_tx_left(ngtcp2_dcid * dcid)3064 static uint64_t dcid_tx_left(ngtcp2_dcid *dcid) {
3065 if (dcid->flags & NGTCP2_DCID_FLAG_PATH_VALIDATED) {
3066 return SIZE_MAX;
3067 }
3068 /* From QUIC spec: Prior to validating the client address, servers
3069 MUST NOT send more than three times as many bytes as the number
3070 of bytes they have received. */
3071 assert(dcid->bytes_recv * 3 >= dcid->bytes_sent);
3072
3073 return dcid->bytes_recv * 3 - dcid->bytes_sent;
3074 }
3075
3076 /*
3077 * conn_server_tx_left returns the maximum number of bytes that server
3078 * is allowed to send to an unvalidated path.
3079 */
conn_server_tx_left(ngtcp2_conn * conn,ngtcp2_dcid * dcid)3080 static uint64_t conn_server_tx_left(ngtcp2_conn *conn, ngtcp2_dcid *dcid) {
3081 assert(conn->server);
3082
3083 /* If pv->dcid has the current path, use conn->dcid.current. This
3084 is because conn->dcid.current gets update for bytes_recv and
3085 bytes_sent. */
3086 if (ngtcp2_path_eq(&dcid->ps.path, &conn->dcid.current.ps.path)) {
3087 return dcid_tx_left(&conn->dcid.current);
3088 }
3089
3090 return dcid_tx_left(dcid);
3091 }
3092
3093 /*
3094 * conn_write_handshake_pkts writes Initial and Handshake packets in
3095 * the buffer pointed by |dest| whose length is |destlen|.
3096 *
3097 * This function returns the number of bytes written in |dest| if it
3098 * succeeds, or one of the following negative error codes:
3099 *
3100 * NGTCP2_ERR_NOMEM
3101 * Out of memory.
3102 * NGTCP2_ERR_CALLBACK_FAILURE
3103 * User-defined callback function failed.
3104 */
conn_write_handshake_pkts(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,uint64_t write_datalen,ngtcp2_tstamp ts)3105 static ngtcp2_ssize conn_write_handshake_pkts(ngtcp2_conn *conn,
3106 ngtcp2_pkt_info *pi,
3107 uint8_t *dest, size_t destlen,
3108 uint64_t write_datalen,
3109 ngtcp2_tstamp ts) {
3110 ngtcp2_ssize nwrite;
3111 ngtcp2_ssize res = 0;
3112 ngtcp2_rtb_entry *rtbent;
3113 uint8_t wflags = NGTCP2_WRITE_PKT_FLAG_NONE;
3114 ngtcp2_conn_stat *cstat = &conn->cstat;
3115 ngtcp2_ksl_it it;
3116
3117 /* As a client, we would like to discard Initial packet number space
3118 when sending the first Handshake packet. When sending Handshake
3119 packet, it should be one of 1) sending ACK, 2) sending PTO probe
3120 packet, or 3) sending CRYPTO. If we have pending acknowledgement
3121 for Initial, then do not discard Initial packet number space.
3122 Otherwise, if either 1) or 2) is satisfied, discard Initial
3123 packet number space. When sending Handshake CRYPTO, it indicates
3124 that client has received Handshake CRYPTO from server. Initial
3125 packet number space is discarded because 1) is met. If there is
3126 pending Initial ACK, Initial packet number space is discarded
3127 after writing the first Handshake packet.
3128 */
3129 if (!conn->server && conn->hs_pktns->crypto.tx.ckm && conn->in_pktns &&
3130 !ngtcp2_acktr_require_active_ack(&conn->in_pktns->acktr,
3131 /* max_ack_delay = */ 0, ts) &&
3132 (ngtcp2_acktr_require_active_ack(&conn->hs_pktns->acktr,
3133 /* max_ack_delay = */ 0, ts) ||
3134 conn->hs_pktns->rtb.probe_pkt_left)) {
3135 /* Discard Initial state here so that Handshake packet is not
3136 padded. */
3137 conn_discard_initial_state(conn, ts);
3138 } else if (conn->in_pktns) {
3139 nwrite =
3140 conn_write_handshake_pkt(conn, pi, dest, destlen, NGTCP2_PKT_INITIAL,
3141 NGTCP2_WRITE_PKT_FLAG_NONE, write_datalen, ts);
3142 if (nwrite < 0) {
3143 assert(nwrite != NGTCP2_ERR_NOBUF);
3144 return nwrite;
3145 }
3146
3147 if (nwrite == 0) {
3148 if (conn->server && (conn->in_pktns->rtb.probe_pkt_left ||
3149 ngtcp2_ksl_len(&conn->in_pktns->crypto.tx.frq))) {
3150 if (cstat->loss_detection_timer != UINT64_MAX &&
3151 conn_server_tx_left(conn, &conn->dcid.current) <
3152 NGTCP2_MAX_UDP_PAYLOAD_SIZE) {
3153 ngtcp2_log_info(
3154 &conn->log, NGTCP2_LOG_EVENT_RCV,
3155 "loss detection timer canceled due to amplification limit");
3156 cstat->loss_detection_timer = UINT64_MAX;
3157 }
3158
3159 return 0;
3160 }
3161 } else {
3162 res += nwrite;
3163 dest += nwrite;
3164 destlen -= (size_t)nwrite;
3165
3166 if (destlen) {
3167 /* We might have already added padding to Initial, but in that
3168 case, we should have destlen == 0 and no Handshake packet
3169 will be written. */
3170 if (conn->server) {
3171 it = ngtcp2_rtb_head(&conn->in_pktns->rtb);
3172 if (!ngtcp2_ksl_it_end(&it)) {
3173 rtbent = ngtcp2_ksl_it_get(&it);
3174 if (rtbent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
3175 wflags |= NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
3176 }
3177 }
3178 } else {
3179 wflags |= NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
3180 }
3181 }
3182 }
3183 }
3184
3185 nwrite = conn_write_handshake_pkt(
3186 conn, pi, dest, destlen, NGTCP2_PKT_HANDSHAKE, wflags, write_datalen, ts);
3187 if (nwrite < 0) {
3188 assert(nwrite != NGTCP2_ERR_NOBUF);
3189 return nwrite;
3190 }
3191
3192 res += nwrite;
3193
3194 if (!conn->server && conn->hs_pktns->crypto.tx.ckm && nwrite) {
3195 /* We don't need to send further Initial packet if we have
3196 Handshake key and sent something with it. So discard initial
3197 state here. */
3198 conn_discard_initial_state(conn, ts);
3199 }
3200
3201 return res;
3202 }
3203
3204 /*
3205 * conn_initial_stream_rx_offset returns the initial maximum offset of
3206 * data for a stream denoted by |stream_id|.
3207 */
conn_initial_stream_rx_offset(ngtcp2_conn * conn,int64_t stream_id)3208 static uint64_t conn_initial_stream_rx_offset(ngtcp2_conn *conn,
3209 int64_t stream_id) {
3210 int local_stream = conn_local_stream(conn, stream_id);
3211
3212 if (bidi_stream(stream_id)) {
3213 if (local_stream) {
3214 return conn->local.transport_params.initial_max_stream_data_bidi_local;
3215 }
3216 return conn->local.transport_params.initial_max_stream_data_bidi_remote;
3217 }
3218
3219 if (local_stream) {
3220 return 0;
3221 }
3222 return conn->local.transport_params.initial_max_stream_data_uni;
3223 }
3224
3225 /*
3226 * conn_should_send_max_stream_data returns nonzero if MAX_STREAM_DATA
3227 * frame should be send for |strm|.
3228 */
conn_should_send_max_stream_data(ngtcp2_conn * conn,ngtcp2_strm * strm)3229 static int conn_should_send_max_stream_data(ngtcp2_conn *conn,
3230 ngtcp2_strm *strm) {
3231 uint64_t inc = strm->rx.unsent_max_offset - strm->rx.max_offset;
3232 (void)conn;
3233
3234 return strm->rx.window < 2 * inc;
3235 }
3236
3237 /*
3238 * conn_should_send_max_data returns nonzero if MAX_DATA frame should
3239 * be sent.
3240 */
conn_should_send_max_data(ngtcp2_conn * conn)3241 static int conn_should_send_max_data(ngtcp2_conn *conn) {
3242 uint64_t inc = conn->rx.unsent_max_offset - conn->rx.max_offset;
3243
3244 return conn->rx.window < 2 * inc;
3245 }
3246
3247 /*
3248 * conn_required_num_new_connection_id returns the number of
3249 * additional connection ID the local endpoint has to provide to the
3250 * remote endpoint.
3251 */
conn_required_num_new_connection_id(ngtcp2_conn * conn)3252 static size_t conn_required_num_new_connection_id(ngtcp2_conn *conn) {
3253 uint64_t n;
3254 size_t len = ngtcp2_ksl_len(&conn->scid.set);
3255
3256 if (len >= NGTCP2_MAX_SCID_POOL_SIZE) {
3257 return 0;
3258 }
3259
3260 assert(conn->remote.transport_params);
3261 assert(conn->remote.transport_params->active_connection_id_limit);
3262
3263 /* len includes retired CID. We don't provide extra CID if doing so
3264 exceeds NGTCP2_MAX_SCID_POOL_SIZE. */
3265
3266 n = conn->remote.transport_params->active_connection_id_limit +
3267 conn->scid.num_retired;
3268
3269 return (size_t)ngtcp2_min(NGTCP2_MAX_SCID_POOL_SIZE, n) - len;
3270 }
3271
3272 /*
3273 * conn_enqueue_new_connection_id generates additional connection IDs
3274 * and prepares to send them to the remote endpoint.
3275 *
3276 * This function returns 0 if it succeeds, or one of the following
3277 * negative error codes:
3278 *
3279 * NGTCP2_ERR_NOMEM
3280 * Out of memory.
3281 * NGTCP2_ERR_CALLBACK_FAILURE
3282 * User-defined callback function failed.
3283 */
conn_enqueue_new_connection_id(ngtcp2_conn * conn)3284 static int conn_enqueue_new_connection_id(ngtcp2_conn *conn) {
3285 size_t i, need = conn_required_num_new_connection_id(conn);
3286 size_t cidlen = conn->oscid.datalen;
3287 ngtcp2_cid cid;
3288 uint64_t seq;
3289 int rv;
3290 uint8_t token[NGTCP2_STATELESS_RESET_TOKENLEN];
3291 ngtcp2_frame_chain *nfrc;
3292 ngtcp2_pktns *pktns = &conn->pktns;
3293 ngtcp2_scid *scid;
3294 ngtcp2_ksl_it it;
3295
3296 for (i = 0; i < need; ++i) {
3297 rv = conn_call_get_new_connection_id(conn, &cid, token, cidlen);
3298 if (rv != 0) {
3299 return rv;
3300 }
3301
3302 if (cid.datalen != cidlen) {
3303 return NGTCP2_ERR_CALLBACK_FAILURE;
3304 }
3305
3306 /* Assert uniqueness */
3307 it = ngtcp2_ksl_lower_bound(&conn->scid.set, &cid);
3308 if (!ngtcp2_ksl_it_end(&it) &&
3309 ngtcp2_cid_eq(ngtcp2_ksl_it_key(&it), &cid)) {
3310 return NGTCP2_ERR_CALLBACK_FAILURE;
3311 }
3312
3313 seq = ++conn->scid.last_seq;
3314
3315 scid = ngtcp2_mem_malloc(conn->mem, sizeof(*scid));
3316 if (scid == NULL) {
3317 return NGTCP2_ERR_NOMEM;
3318 }
3319
3320 ngtcp2_scid_init(scid, seq, &cid);
3321
3322 rv = ngtcp2_ksl_insert(&conn->scid.set, NULL, &scid->cid, scid);
3323 if (rv != 0) {
3324 ngtcp2_mem_free(conn->mem, scid);
3325 return rv;
3326 }
3327
3328 rv = ngtcp2_frame_chain_objalloc_new(&nfrc, &conn->frc_objalloc);
3329 if (rv != 0) {
3330 return rv;
3331 }
3332
3333 nfrc->fr.type = NGTCP2_FRAME_NEW_CONNECTION_ID;
3334 nfrc->fr.new_connection_id.seq = seq;
3335 nfrc->fr.new_connection_id.retire_prior_to = 0;
3336 nfrc->fr.new_connection_id.cid = cid;
3337 memcpy(nfrc->fr.new_connection_id.stateless_reset_token, token,
3338 sizeof(token));
3339 nfrc->next = pktns->tx.frq;
3340 pktns->tx.frq = nfrc;
3341 }
3342
3343 return 0;
3344 }
3345
3346 /*
3347 * conn_remove_retired_connection_id removes the already retired
3348 * connection ID. It waits PTO before actually removing a connection
3349 * ID after it receives RETIRE_CONNECTION_ID from peer to catch
3350 * reordered packets.
3351 *
3352 * This function returns 0 if it succeeds, or one of the following
3353 * negative error codes:
3354 *
3355 * NGTCP2_ERR_NOMEM
3356 * Out of memory.
3357 * NGTCP2_ERR_CALLBACK_FAILURE
3358 * User-defined callback function failed.
3359 */
conn_remove_retired_connection_id(ngtcp2_conn * conn,ngtcp2_duration pto,ngtcp2_tstamp ts)3360 static int conn_remove_retired_connection_id(ngtcp2_conn *conn,
3361 ngtcp2_duration pto,
3362 ngtcp2_tstamp ts) {
3363 ngtcp2_duration timeout = pto;
3364 ngtcp2_scid *scid;
3365 ngtcp2_dcid *dcid;
3366 int rv;
3367
3368 for (; !ngtcp2_pq_empty(&conn->scid.used);) {
3369 scid = ngtcp2_struct_of(ngtcp2_pq_top(&conn->scid.used), ngtcp2_scid, pe);
3370
3371 if (scid->retired_ts == UINT64_MAX || scid->retired_ts + timeout >= ts) {
3372 break;
3373 }
3374
3375 assert(scid->flags & NGTCP2_SCID_FLAG_RETIRED);
3376
3377 rv = conn_call_remove_connection_id(conn, &scid->cid);
3378 if (rv != 0) {
3379 return rv;
3380 }
3381
3382 ngtcp2_ksl_remove(&conn->scid.set, NULL, &scid->cid);
3383 ngtcp2_pq_pop(&conn->scid.used);
3384 ngtcp2_mem_free(conn->mem, scid);
3385
3386 assert(conn->scid.num_retired);
3387 --conn->scid.num_retired;
3388 }
3389
3390 for (; ngtcp2_ringbuf_len(&conn->dcid.retired.rb);) {
3391 dcid = ngtcp2_ringbuf_get(&conn->dcid.retired.rb, 0);
3392 if (dcid->retired_ts + timeout >= ts) {
3393 break;
3394 }
3395
3396 rv = conn_call_deactivate_dcid(conn, dcid);
3397 if (rv != 0) {
3398 return rv;
3399 }
3400
3401 ngtcp2_ringbuf_pop_front(&conn->dcid.retired.rb);
3402 }
3403
3404 return 0;
3405 }
3406
3407 /*
3408 * conn_min_short_pktlen returns the minimum length of Short packet
3409 * this endpoint sends.
3410 */
conn_min_short_pktlen(ngtcp2_conn * conn)3411 static size_t conn_min_short_pktlen(ngtcp2_conn *conn) {
3412 return conn->dcid.current.cid.datalen + NGTCP2_MIN_PKT_EXPANDLEN;
3413 }
3414
3415 /*
3416 * conn_handle_unconfirmed_key_update_from_remote deals with key
3417 * update which has not been confirmed yet and initiated by the remote
3418 * endpoint.
3419 *
3420 * If key update was initiated by the remote endpoint, acknowledging a
3421 * packet encrypted with the new key completes key update procedure.
3422 */
conn_handle_unconfirmed_key_update_from_remote(ngtcp2_conn * conn,int64_t largest_ack,ngtcp2_tstamp ts)3423 static void conn_handle_unconfirmed_key_update_from_remote(ngtcp2_conn *conn,
3424 int64_t largest_ack,
3425 ngtcp2_tstamp ts) {
3426 if (!(conn->flags & NGTCP2_CONN_FLAG_KEY_UPDATE_NOT_CONFIRMED) ||
3427 (conn->flags & NGTCP2_CONN_FLAG_KEY_UPDATE_INITIATOR) ||
3428 largest_ack < conn->pktns.crypto.rx.ckm->pkt_num) {
3429 return;
3430 }
3431
3432 conn->flags &= (uint32_t)~NGTCP2_CONN_FLAG_KEY_UPDATE_NOT_CONFIRMED;
3433 conn->crypto.key_update.confirmed_ts = ts;
3434
3435 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CRY, "key update confirmed");
3436 }
3437
3438 /*
3439 * conn_write_pkt writes a protected packet in the buffer pointed by
3440 * |dest| whose length if |destlen|. |type| specifies the type of
3441 * packet. It can be NGTCP2_PKT_1RTT or NGTCP2_PKT_0RTT.
3442 *
3443 * This function can send new stream data. In order to send stream
3444 * data, specify the underlying stream and parameters to
3445 * |vmsg|->stream. If |vmsg|->stream.fin is set to nonzero, it
3446 * signals that the given data is the final portion of the stream.
3447 * |vmsg|->stream.data vector of length |vmsg|->stream.datacnt
3448 * specifies stream data to send. The number of bytes sent to the
3449 * stream is assigned to *|vmsg|->stream.pdatalen. If 0 length STREAM
3450 * data is sent, 0 is assigned to it. The caller should initialize
3451 * *|vmsg|->stream.pdatalen to -1.
3452 *
3453 * If |require_padding| is nonzero, padding bytes are added to occupy
3454 * the remaining packet payload.
3455 *
3456 * This function returns the number of bytes written in |dest| if it
3457 * succeeds, or one of the following negative error codes:
3458 *
3459 * NGTCP2_ERR_NOMEM
3460 * Out of memory.
3461 * NGTCP2_ERR_CALLBACK_FAILURE
3462 * User-defined callback function failed.
3463 * NGTCP2_ERR_STREAM_DATA_BLOCKED
3464 * Stream data could not be written because of flow control.
3465 */
conn_write_pkt(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,ngtcp2_vmsg * vmsg,uint8_t type,uint8_t flags,ngtcp2_tstamp ts)3466 static ngtcp2_ssize conn_write_pkt(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
3467 uint8_t *dest, size_t destlen,
3468 ngtcp2_vmsg *vmsg, uint8_t type,
3469 uint8_t flags, ngtcp2_tstamp ts) {
3470 int rv = 0;
3471 ngtcp2_crypto_cc *cc = &conn->pkt.cc;
3472 ngtcp2_ppe *ppe = &conn->pkt.ppe;
3473 ngtcp2_pkt_hd *hd = &conn->pkt.hd;
3474 ngtcp2_frame *ackfr = NULL, lfr;
3475 ngtcp2_ssize nwrite;
3476 ngtcp2_frame_chain **pfrc, *nfrc, *frc;
3477 ngtcp2_rtb_entry *ent;
3478 ngtcp2_strm *strm;
3479 int pkt_empty = 1;
3480 uint64_t ndatalen = 0;
3481 int send_stream = 0;
3482 int stream_blocked = 0;
3483 int send_datagram = 0;
3484 ngtcp2_pktns *pktns = &conn->pktns;
3485 size_t left;
3486 uint64_t datalen = 0;
3487 ngtcp2_vec data[NGTCP2_MAX_STREAM_DATACNT];
3488 size_t datacnt;
3489 uint16_t rtb_entry_flags = NGTCP2_RTB_ENTRY_FLAG_NONE;
3490 int hd_logged = 0;
3491 ngtcp2_path_challenge_entry *pcent;
3492 uint8_t hd_flags = NGTCP2_PKT_FLAG_NONE;
3493 int require_padding = (flags & NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING) != 0;
3494 int write_more = (flags & NGTCP2_WRITE_PKT_FLAG_MORE) != 0;
3495 int ppe_pending = (conn->flags & NGTCP2_CONN_FLAG_PPE_PENDING) != 0;
3496 size_t min_pktlen = conn_min_short_pktlen(conn);
3497 int padded = 0;
3498 ngtcp2_cc_pkt cc_pkt;
3499 uint64_t crypto_offset;
3500 uint64_t stream_offset;
3501 ngtcp2_ssize num_reclaimed;
3502 int fin;
3503 uint64_t target_max_data;
3504 ngtcp2_conn_stat *cstat = &conn->cstat;
3505 uint64_t delta;
3506 const ngtcp2_cid *scid = NULL;
3507 int keep_alive_expired = 0;
3508 uint32_t version = 0;
3509
3510 /* Return 0 if destlen is less than minimum packet length which can
3511 trigger Stateless Reset */
3512 if (destlen < min_pktlen) {
3513 return 0;
3514 }
3515
3516 if (vmsg) {
3517 switch (vmsg->type) {
3518 case NGTCP2_VMSG_TYPE_STREAM:
3519 datalen = ngtcp2_vec_len(vmsg->stream.data, vmsg->stream.datacnt);
3520 ndatalen = conn_enforce_flow_control(conn, vmsg->stream.strm, datalen);
3521 /* 0 length STREAM frame is allowed */
3522 if (ndatalen || datalen == 0) {
3523 send_stream = 1;
3524 } else {
3525 stream_blocked = 1;
3526 }
3527 break;
3528 case NGTCP2_VMSG_TYPE_DATAGRAM:
3529 datalen = ngtcp2_vec_len(vmsg->datagram.data, vmsg->datagram.datacnt);
3530 send_datagram = 1;
3531 break;
3532 default:
3533 break;
3534 }
3535 }
3536
3537 if (!ppe_pending) {
3538 switch (type) {
3539 case NGTCP2_PKT_1RTT:
3540 hd_flags = conn_pkt_flags_short(conn);
3541 scid = NULL;
3542 cc->aead = pktns->crypto.ctx.aead;
3543 cc->hp = pktns->crypto.ctx.hp;
3544 cc->ckm = pktns->crypto.tx.ckm;
3545 cc->hp_ctx = pktns->crypto.tx.hp_ctx;
3546
3547 assert(conn->negotiated_version);
3548
3549 version = conn->negotiated_version;
3550
3551 /* transport parameter is only valid after handshake completion
3552 which means we don't know how many connection ID that remote
3553 peer can accept before handshake completion. */
3554 if (conn->oscid.datalen && conn_is_handshake_completed(conn)) {
3555 rv = conn_enqueue_new_connection_id(conn);
3556 if (rv != 0) {
3557 return rv;
3558 }
3559 }
3560
3561 break;
3562 case NGTCP2_PKT_0RTT:
3563 assert(!conn->server);
3564 if (!conn->early.ckm) {
3565 return 0;
3566 }
3567 hd_flags = conn_pkt_flags_long(conn);
3568 scid = &conn->oscid;
3569 cc->aead = conn->early.ctx.aead;
3570 cc->hp = conn->early.ctx.hp;
3571 cc->ckm = conn->early.ckm;
3572 cc->hp_ctx = conn->early.hp_ctx;
3573 version = conn->client_chosen_version;
3574 break;
3575 default:
3576 /* Unreachable */
3577 assert(0);
3578 }
3579
3580 cc->encrypt = conn->callbacks.encrypt;
3581 cc->hp_mask = conn->callbacks.hp_mask;
3582
3583 if (conn_should_send_max_data(conn)) {
3584 rv = ngtcp2_frame_chain_objalloc_new(&nfrc, &conn->frc_objalloc);
3585 if (rv != 0) {
3586 return rv;
3587 }
3588
3589 if (conn->local.settings.max_window &&
3590 conn->tx.last_max_data_ts != UINT64_MAX &&
3591 ts - conn->tx.last_max_data_ts <
3592 NGTCP2_FLOW_WINDOW_RTT_FACTOR * cstat->smoothed_rtt &&
3593 conn->local.settings.max_window > conn->rx.window) {
3594 target_max_data = NGTCP2_FLOW_WINDOW_SCALING_FACTOR * conn->rx.window;
3595 if (target_max_data > conn->local.settings.max_window) {
3596 target_max_data = conn->local.settings.max_window;
3597 }
3598
3599 delta = target_max_data - conn->rx.window;
3600 if (conn->rx.unsent_max_offset + delta > NGTCP2_MAX_VARINT) {
3601 delta = NGTCP2_MAX_VARINT - conn->rx.unsent_max_offset;
3602 }
3603
3604 conn->rx.window = target_max_data;
3605 } else {
3606 delta = 0;
3607 }
3608
3609 conn->tx.last_max_data_ts = ts;
3610
3611 nfrc->fr.type = NGTCP2_FRAME_MAX_DATA;
3612 nfrc->fr.max_data.max_data = conn->rx.unsent_max_offset + delta;
3613 nfrc->next = pktns->tx.frq;
3614 pktns->tx.frq = nfrc;
3615
3616 conn->rx.max_offset = conn->rx.unsent_max_offset =
3617 nfrc->fr.max_data.max_data;
3618 }
3619
3620 ngtcp2_pkt_hd_init(hd, hd_flags, type, &conn->dcid.current.cid, scid,
3621 pktns->tx.last_pkt_num + 1,
3622 pktns_select_pkt_numlen(pktns), version, 0);
3623
3624 ngtcp2_ppe_init(ppe, dest, destlen, cc);
3625
3626 rv = ngtcp2_ppe_encode_hd(ppe, hd);
3627 if (rv != 0) {
3628 assert(NGTCP2_ERR_NOBUF == rv);
3629 return 0;
3630 }
3631
3632 if (!ngtcp2_ppe_ensure_hp_sample(ppe)) {
3633 return 0;
3634 }
3635
3636 if (ngtcp2_ringbuf_len(&conn->rx.path_challenge.rb)) {
3637 pcent = ngtcp2_ringbuf_get(&conn->rx.path_challenge.rb, 0);
3638
3639 /* PATH_RESPONSE is bound to the path that the corresponding
3640 PATH_CHALLENGE is received. */
3641 if (ngtcp2_path_eq(&conn->dcid.current.ps.path, &pcent->ps.path)) {
3642 lfr.type = NGTCP2_FRAME_PATH_RESPONSE;
3643 memcpy(lfr.path_response.data, pcent->data,
3644 sizeof(lfr.path_response.data));
3645
3646 rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &lfr);
3647 if (rv != 0) {
3648 assert(NGTCP2_ERR_NOBUF == rv);
3649 } else {
3650 ngtcp2_ringbuf_pop_front(&conn->rx.path_challenge.rb);
3651
3652 pkt_empty = 0;
3653 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING;
3654 require_padding =
3655 !conn->server || destlen >= NGTCP2_MAX_UDP_PAYLOAD_SIZE;
3656 /* We don't retransmit PATH_RESPONSE. */
3657 }
3658 }
3659 }
3660
3661 rv = conn_create_ack_frame(conn, &ackfr, pktns, type, ts,
3662 conn_compute_ack_delay(conn),
3663 conn->local.transport_params.ack_delay_exponent);
3664 if (rv != 0) {
3665 assert(ngtcp2_err_is_fatal(rv));
3666 return rv;
3667 }
3668
3669 if (ackfr) {
3670 rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, ackfr);
3671 if (rv != 0) {
3672 assert(NGTCP2_ERR_NOBUF == rv);
3673 } else {
3674 ngtcp2_acktr_commit_ack(&pktns->acktr);
3675 ngtcp2_acktr_add_ack(&pktns->acktr, hd->pkt_num,
3676 ackfr->ack.largest_ack);
3677 if (type == NGTCP2_PKT_1RTT) {
3678 conn_handle_unconfirmed_key_update_from_remote(
3679 conn, ackfr->ack.largest_ack, ts);
3680 }
3681 pkt_empty = 0;
3682 }
3683 }
3684
3685 build_pkt:
3686 for (pfrc = &pktns->tx.frq; *pfrc;) {
3687 if ((*pfrc)->binder &&
3688 ((*pfrc)->binder->flags & NGTCP2_FRAME_CHAIN_BINDER_FLAG_ACK)) {
3689 frc = *pfrc;
3690 *pfrc = (*pfrc)->next;
3691 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
3692 continue;
3693 }
3694
3695 switch ((*pfrc)->fr.type) {
3696 case NGTCP2_FRAME_STOP_SENDING:
3697 strm =
3698 ngtcp2_conn_find_stream(conn, (*pfrc)->fr.stop_sending.stream_id);
3699 if (strm == NULL || (strm->flags & NGTCP2_STRM_FLAG_SHUT_RD)) {
3700 frc = *pfrc;
3701 *pfrc = (*pfrc)->next;
3702 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
3703 continue;
3704 }
3705
3706 if (!(strm->flags & NGTCP2_STRM_FLAG_STREAM_STOP_SENDING_CALLED)) {
3707 strm->flags |= NGTCP2_STRM_FLAG_STREAM_STOP_SENDING_CALLED;
3708
3709 rv = conn_call_stream_stop_sending(
3710 conn, (*pfrc)->fr.stop_sending.stream_id,
3711 (*pfrc)->fr.stop_sending.app_error_code, strm->stream_user_data);
3712 if (rv != 0) {
3713 assert(ngtcp2_err_is_fatal(rv));
3714 return rv;
3715 }
3716 }
3717
3718 break;
3719 case NGTCP2_FRAME_STREAM:
3720 assert(0);
3721 break;
3722 case NGTCP2_FRAME_MAX_STREAMS_BIDI:
3723 if ((*pfrc)->fr.max_streams.max_streams <
3724 conn->remote.bidi.max_streams) {
3725 frc = *pfrc;
3726 *pfrc = (*pfrc)->next;
3727 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
3728 continue;
3729 }
3730 break;
3731 case NGTCP2_FRAME_MAX_STREAMS_UNI:
3732 if ((*pfrc)->fr.max_streams.max_streams <
3733 conn->remote.uni.max_streams) {
3734 frc = *pfrc;
3735 *pfrc = (*pfrc)->next;
3736 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
3737 continue;
3738 }
3739 break;
3740 case NGTCP2_FRAME_MAX_STREAM_DATA:
3741 strm = ngtcp2_conn_find_stream(conn,
3742 (*pfrc)->fr.max_stream_data.stream_id);
3743 if (strm == NULL || (strm->flags & NGTCP2_STRM_FLAG_SHUT_RD) ||
3744 (*pfrc)->fr.max_stream_data.max_stream_data < strm->rx.max_offset) {
3745 frc = *pfrc;
3746 *pfrc = (*pfrc)->next;
3747 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
3748 continue;
3749 }
3750 break;
3751 case NGTCP2_FRAME_MAX_DATA:
3752 if ((*pfrc)->fr.max_data.max_data < conn->rx.max_offset) {
3753 frc = *pfrc;
3754 *pfrc = (*pfrc)->next;
3755 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
3756 continue;
3757 }
3758 break;
3759 case NGTCP2_FRAME_CRYPTO:
3760 assert(0);
3761 break;
3762 }
3763
3764 rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &(*pfrc)->fr);
3765 if (rv != 0) {
3766 assert(NGTCP2_ERR_NOBUF == rv);
3767 break;
3768 }
3769
3770 pkt_empty = 0;
3771 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING |
3772 NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING |
3773 NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE;
3774 pfrc = &(*pfrc)->next;
3775 }
3776
3777 if (rv != NGTCP2_ERR_NOBUF) {
3778 for (; ngtcp2_ksl_len(&pktns->crypto.tx.frq);) {
3779 left = ngtcp2_ppe_left(ppe);
3780
3781 crypto_offset = conn_cryptofrq_unacked_offset(conn, pktns);
3782 if (crypto_offset == (size_t)-1) {
3783 conn_cryptofrq_clear(conn, pktns);
3784 break;
3785 }
3786
3787 left = ngtcp2_pkt_crypto_max_datalen(crypto_offset, left, left);
3788
3789 if (left == (size_t)-1) {
3790 break;
3791 }
3792
3793 rv = conn_cryptofrq_pop(conn, &nfrc, pktns, left);
3794 if (rv != 0) {
3795 assert(ngtcp2_err_is_fatal(rv));
3796 return rv;
3797 }
3798
3799 if (nfrc == NULL) {
3800 break;
3801 }
3802
3803 rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &nfrc->fr);
3804 if (rv != 0) {
3805 assert(0);
3806 }
3807
3808 *pfrc = nfrc;
3809 pfrc = &(*pfrc)->next;
3810
3811 pkt_empty = 0;
3812 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING |
3813 NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING |
3814 NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE;
3815 }
3816 }
3817
3818 /* Write MAX_STREAM_ID after RESET_STREAM so that we can extend stream
3819 ID space in one packet. */
3820 if (rv != NGTCP2_ERR_NOBUF && *pfrc == NULL &&
3821 conn->remote.bidi.unsent_max_streams > conn->remote.bidi.max_streams) {
3822 rv = conn_call_extend_max_remote_streams_bidi(
3823 conn, conn->remote.bidi.unsent_max_streams);
3824 if (rv != 0) {
3825 assert(ngtcp2_err_is_fatal(rv));
3826 return rv;
3827 }
3828
3829 rv = ngtcp2_frame_chain_objalloc_new(&nfrc, &conn->frc_objalloc);
3830 if (rv != 0) {
3831 assert(ngtcp2_err_is_fatal(rv));
3832 return rv;
3833 }
3834 nfrc->fr.type = NGTCP2_FRAME_MAX_STREAMS_BIDI;
3835 nfrc->fr.max_streams.max_streams = conn->remote.bidi.unsent_max_streams;
3836 *pfrc = nfrc;
3837
3838 conn->remote.bidi.max_streams = conn->remote.bidi.unsent_max_streams;
3839
3840 rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &(*pfrc)->fr);
3841 if (rv != 0) {
3842 assert(NGTCP2_ERR_NOBUF == rv);
3843 } else {
3844 pkt_empty = 0;
3845 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING |
3846 NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING |
3847 NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE;
3848 pfrc = &(*pfrc)->next;
3849 }
3850 }
3851
3852 if (rv != NGTCP2_ERR_NOBUF && *pfrc == NULL) {
3853 if (conn->remote.uni.unsent_max_streams > conn->remote.uni.max_streams) {
3854 rv = conn_call_extend_max_remote_streams_uni(
3855 conn, conn->remote.uni.unsent_max_streams);
3856 if (rv != 0) {
3857 assert(ngtcp2_err_is_fatal(rv));
3858 return rv;
3859 }
3860
3861 rv = ngtcp2_frame_chain_objalloc_new(&nfrc, &conn->frc_objalloc);
3862 if (rv != 0) {
3863 assert(ngtcp2_err_is_fatal(rv));
3864 return rv;
3865 }
3866 nfrc->fr.type = NGTCP2_FRAME_MAX_STREAMS_UNI;
3867 nfrc->fr.max_streams.max_streams = conn->remote.uni.unsent_max_streams;
3868 *pfrc = nfrc;
3869
3870 conn->remote.uni.max_streams = conn->remote.uni.unsent_max_streams;
3871
3872 rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd,
3873 &(*pfrc)->fr);
3874 if (rv != 0) {
3875 assert(NGTCP2_ERR_NOBUF == rv);
3876 } else {
3877 pkt_empty = 0;
3878 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING |
3879 NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING |
3880 NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE;
3881 pfrc = &(*pfrc)->next;
3882 }
3883 }
3884 }
3885
3886 if (rv != NGTCP2_ERR_NOBUF) {
3887 for (; !ngtcp2_pq_empty(&conn->tx.strmq);) {
3888 strm = ngtcp2_conn_tx_strmq_top(conn);
3889
3890 if (!(strm->flags & NGTCP2_STRM_FLAG_SHUT_RD) &&
3891 conn_should_send_max_stream_data(conn, strm)) {
3892 rv = ngtcp2_frame_chain_objalloc_new(&nfrc, &conn->frc_objalloc);
3893 if (rv != 0) {
3894 assert(ngtcp2_err_is_fatal(rv));
3895 return rv;
3896 }
3897
3898 if (conn->local.settings.max_stream_window &&
3899 strm->tx.last_max_stream_data_ts != UINT64_MAX &&
3900 ts - strm->tx.last_max_stream_data_ts <
3901 NGTCP2_FLOW_WINDOW_RTT_FACTOR * cstat->smoothed_rtt &&
3902 conn->local.settings.max_stream_window > strm->rx.window) {
3903 target_max_data =
3904 NGTCP2_FLOW_WINDOW_SCALING_FACTOR * strm->rx.window;
3905 if (target_max_data > conn->local.settings.max_stream_window) {
3906 target_max_data = conn->local.settings.max_stream_window;
3907 }
3908
3909 delta = target_max_data - strm->rx.window;
3910 if (strm->rx.unsent_max_offset + delta > NGTCP2_MAX_VARINT) {
3911 delta = NGTCP2_MAX_VARINT - strm->rx.unsent_max_offset;
3912 }
3913
3914 strm->rx.window = target_max_data;
3915 } else {
3916 delta = 0;
3917 }
3918
3919 strm->tx.last_max_stream_data_ts = ts;
3920
3921 nfrc->fr.type = NGTCP2_FRAME_MAX_STREAM_DATA;
3922 nfrc->fr.max_stream_data.stream_id = strm->stream_id;
3923 nfrc->fr.max_stream_data.max_stream_data =
3924 strm->rx.unsent_max_offset + delta;
3925 ngtcp2_list_insert(nfrc, pfrc);
3926
3927 rv =
3928 conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &nfrc->fr);
3929 if (rv != 0) {
3930 assert(NGTCP2_ERR_NOBUF == rv);
3931 break;
3932 }
3933
3934 pkt_empty = 0;
3935 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING |
3936 NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING |
3937 NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE;
3938 pfrc = &(*pfrc)->next;
3939 strm->rx.max_offset = strm->rx.unsent_max_offset =
3940 nfrc->fr.max_stream_data.max_stream_data;
3941 }
3942
3943 if (ngtcp2_strm_streamfrq_empty(strm)) {
3944 ngtcp2_conn_tx_strmq_pop(conn);
3945 continue;
3946 }
3947
3948 stream_offset = ngtcp2_strm_streamfrq_unacked_offset(strm);
3949 if (stream_offset == (uint64_t)-1) {
3950 ngtcp2_strm_streamfrq_clear(strm);
3951 ngtcp2_conn_tx_strmq_pop(conn);
3952 assert(conn->tx.strmq_nretrans);
3953 --conn->tx.strmq_nretrans;
3954 continue;
3955 }
3956
3957 left = ngtcp2_ppe_left(ppe);
3958
3959 left = ngtcp2_pkt_stream_max_datalen(strm->stream_id, stream_offset,
3960 left, left);
3961
3962 if (left == (size_t)-1) {
3963 break;
3964 }
3965
3966 rv = ngtcp2_strm_streamfrq_pop(strm, &nfrc, left);
3967 if (rv != 0) {
3968 assert(ngtcp2_err_is_fatal(rv));
3969 return rv;
3970 }
3971
3972 if (nfrc == NULL) {
3973 /* TODO Why? */
3974 break;
3975 }
3976
3977 rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &nfrc->fr);
3978 if (rv != 0) {
3979 assert(0);
3980 }
3981
3982 *pfrc = nfrc;
3983 pfrc = &(*pfrc)->next;
3984
3985 pkt_empty = 0;
3986 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING |
3987 NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING |
3988 NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE;
3989
3990 if (ngtcp2_strm_streamfrq_empty(strm)) {
3991 ngtcp2_conn_tx_strmq_pop(conn);
3992 assert(conn->tx.strmq_nretrans);
3993 --conn->tx.strmq_nretrans;
3994 continue;
3995 }
3996
3997 ngtcp2_conn_tx_strmq_pop(conn);
3998 ++strm->cycle;
3999 rv = ngtcp2_conn_tx_strmq_push(conn, strm);
4000 if (rv != 0) {
4001 assert(ngtcp2_err_is_fatal(rv));
4002 return rv;
4003 }
4004 }
4005 }
4006
4007 if (rv != NGTCP2_ERR_NOBUF && !send_stream && !send_datagram &&
4008 !(rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) &&
4009 pktns->rtb.num_retransmittable && pktns->tx.frq == NULL &&
4010 pktns->rtb.probe_pkt_left) {
4011 num_reclaimed = ngtcp2_rtb_reclaim_on_pto(&pktns->rtb, conn, pktns, 1);
4012 if (num_reclaimed < 0) {
4013 return rv;
4014 }
4015 if (num_reclaimed) {
4016 goto build_pkt;
4017 }
4018
4019 /* We had pktns->rtb.num_retransmittable > 0 but the contents of
4020 those packets have been acknowledged (i.e., retransmission in
4021 another packet). In this case, we don't have to send any
4022 probe packet. */
4023 if (pktns->rtb.num_pto_eliciting == 0) {
4024 pktns->rtb.probe_pkt_left = 0;
4025 ngtcp2_conn_set_loss_detection_timer(conn, ts);
4026 /* TODO If packet is empty, we should return now if cwnd is
4027 zero. */
4028 }
4029 }
4030 } else {
4031 pfrc = conn->pkt.pfrc;
4032 rtb_entry_flags |= conn->pkt.rtb_entry_flags;
4033 pkt_empty = conn->pkt.pkt_empty;
4034 hd_logged = conn->pkt.hd_logged;
4035 }
4036
4037 left = ngtcp2_ppe_left(ppe);
4038
4039 if (rv != NGTCP2_ERR_NOBUF && send_stream && *pfrc == NULL &&
4040 (ndatalen = ngtcp2_pkt_stream_max_datalen(
4041 vmsg->stream.strm->stream_id, vmsg->stream.strm->tx.offset, ndatalen,
4042 left)) != (size_t)-1 &&
4043 (ndatalen || datalen == 0)) {
4044 datacnt = ngtcp2_vec_copy_at_most(data, NGTCP2_MAX_STREAM_DATACNT,
4045 vmsg->stream.data, vmsg->stream.datacnt,
4046 (size_t)ndatalen);
4047 ndatalen = ngtcp2_vec_len(data, datacnt);
4048
4049 assert((datacnt == 0 && datalen == 0) || (datacnt && datalen));
4050
4051 rv = ngtcp2_frame_chain_stream_datacnt_objalloc_new(
4052 &nfrc, datacnt, &conn->frc_objalloc, conn->mem);
4053 if (rv != 0) {
4054 assert(ngtcp2_err_is_fatal(rv));
4055 return rv;
4056 }
4057
4058 nfrc->fr.stream.type = NGTCP2_FRAME_STREAM;
4059 nfrc->fr.stream.flags = 0;
4060 nfrc->fr.stream.stream_id = vmsg->stream.strm->stream_id;
4061 nfrc->fr.stream.offset = vmsg->stream.strm->tx.offset;
4062 nfrc->fr.stream.datacnt = datacnt;
4063 ngtcp2_vec_copy(nfrc->fr.stream.data, data, datacnt);
4064
4065 fin = (vmsg->stream.flags & NGTCP2_WRITE_STREAM_FLAG_FIN) &&
4066 ndatalen == datalen;
4067 nfrc->fr.stream.fin = (uint8_t)fin;
4068
4069 rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &nfrc->fr);
4070 if (rv != 0) {
4071 assert(0);
4072 }
4073
4074 *pfrc = nfrc;
4075 pfrc = &(*pfrc)->next;
4076
4077 pkt_empty = 0;
4078 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING |
4079 NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING |
4080 NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE;
4081
4082 vmsg->stream.strm->tx.offset += ndatalen;
4083 conn->tx.offset += ndatalen;
4084
4085 if (fin) {
4086 ngtcp2_strm_shutdown(vmsg->stream.strm, NGTCP2_STRM_FLAG_SHUT_WR);
4087 }
4088
4089 if (vmsg->stream.pdatalen) {
4090 *vmsg->stream.pdatalen = (ngtcp2_ssize)ndatalen;
4091 }
4092 } else {
4093 send_stream = 0;
4094 }
4095
4096 if (rv != NGTCP2_ERR_NOBUF && send_datagram &&
4097 left >= ngtcp2_pkt_datagram_framelen((size_t)datalen)) {
4098 if (conn->callbacks.ack_datagram || conn->callbacks.lost_datagram) {
4099 rv = ngtcp2_frame_chain_objalloc_new(&nfrc, &conn->frc_objalloc);
4100 if (rv != 0) {
4101 assert(ngtcp2_err_is_fatal(rv));
4102 return rv;
4103 }
4104
4105 nfrc->fr.datagram.type = NGTCP2_FRAME_DATAGRAM_LEN;
4106 nfrc->fr.datagram.dgram_id = vmsg->datagram.dgram_id;
4107 nfrc->fr.datagram.datacnt = vmsg->datagram.datacnt;
4108 nfrc->fr.datagram.data = (ngtcp2_vec *)vmsg->datagram.data;
4109
4110 rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &nfrc->fr);
4111 assert(rv == 0);
4112
4113 /* Because DATAGRAM will not be retransmitted, we do not use
4114 data anymore. Just nullify it. The only reason to keep
4115 track a frame is keep dgram_id to pass it to
4116 ngtcp2_ack_datagram or ngtcp2_lost_datagram callbacks. */
4117 nfrc->fr.datagram.datacnt = 0;
4118 nfrc->fr.datagram.data = NULL;
4119
4120 *pfrc = nfrc;
4121 pfrc = &(*pfrc)->next;
4122 } else {
4123 lfr.datagram.type = NGTCP2_FRAME_DATAGRAM_LEN;
4124 lfr.datagram.datacnt = vmsg->datagram.datacnt;
4125 lfr.datagram.data = (ngtcp2_vec *)vmsg->datagram.data;
4126
4127 rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &lfr);
4128 assert(rv == 0);
4129 }
4130
4131 pkt_empty = 0;
4132 rtb_entry_flags |=
4133 NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING | NGTCP2_RTB_ENTRY_FLAG_DATAGRAM;
4134
4135 if (vmsg->datagram.paccepted) {
4136 *vmsg->datagram.paccepted = 1;
4137 }
4138 } else {
4139 send_datagram = 0;
4140 }
4141
4142 if (pkt_empty) {
4143 assert(rv == 0 || NGTCP2_ERR_NOBUF == rv);
4144 if (rv == 0 && stream_blocked && ngtcp2_conn_get_max_data_left(conn)) {
4145 return NGTCP2_ERR_STREAM_DATA_BLOCKED;
4146 }
4147
4148 keep_alive_expired = conn_keep_alive_expired(conn, ts);
4149
4150 if (conn->pktns.rtb.probe_pkt_left == 0 && !keep_alive_expired) {
4151 return 0;
4152 }
4153 } else if (write_more) {
4154 conn->pkt.pfrc = pfrc;
4155 conn->pkt.pkt_empty = pkt_empty;
4156 conn->pkt.rtb_entry_flags = rtb_entry_flags;
4157 conn->pkt.hd_logged = hd_logged;
4158 conn->flags |= NGTCP2_CONN_FLAG_PPE_PENDING;
4159
4160 assert(vmsg);
4161
4162 switch (vmsg->type) {
4163 case NGTCP2_VMSG_TYPE_STREAM:
4164 if (send_stream) {
4165 if (ngtcp2_ppe_left(ppe)) {
4166 return NGTCP2_ERR_WRITE_MORE;
4167 }
4168 } else if (ngtcp2_conn_get_max_data_left(conn) && stream_blocked) {
4169 return NGTCP2_ERR_STREAM_DATA_BLOCKED;
4170 }
4171 break;
4172 case NGTCP2_VMSG_TYPE_DATAGRAM:
4173 if (send_datagram && ngtcp2_ppe_left(ppe)) {
4174 return NGTCP2_ERR_WRITE_MORE;
4175 }
4176 /* If DATAGRAM cannot be written due to insufficient space,
4177 continue to create a packet with the hope that application
4178 calls ngtcp2_conn_writev_datagram again. */
4179 break;
4180 default:
4181 assert(0);
4182 }
4183 }
4184
4185 if (!(rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING)) {
4186 if (pktns->tx.num_non_ack_pkt >= NGTCP2_MAX_NON_ACK_TX_PKT ||
4187 keep_alive_expired || conn->pktns.rtb.probe_pkt_left) {
4188 lfr.type = NGTCP2_FRAME_PING;
4189
4190 rv = conn_ppe_write_frame_hd_log(conn, ppe, &hd_logged, hd, &lfr);
4191 if (rv != 0) {
4192 assert(rv == NGTCP2_ERR_NOBUF);
4193 /* TODO If buffer is too small, PING cannot be written if
4194 packet is still empty. */
4195 } else {
4196 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING;
4197 if (conn->pktns.rtb.probe_pkt_left) {
4198 rtb_entry_flags |= NGTCP2_RTB_ENTRY_FLAG_PROBE;
4199 }
4200 pktns->tx.num_non_ack_pkt = 0;
4201 }
4202 } else {
4203 ++pktns->tx.num_non_ack_pkt;
4204 }
4205 } else {
4206 pktns->tx.num_non_ack_pkt = 0;
4207 }
4208
4209 /* TODO Push STREAM frame back to ngtcp2_strm if there is an error
4210 before ngtcp2_rtb_entry is safely created and added. */
4211 if (require_padding ||
4212 /* Making full sized packet will help GSO a bit */
4213 ngtcp2_ppe_left(ppe) < 10) {
4214 lfr.padding.len = ngtcp2_ppe_padding(ppe);
4215 } else {
4216 lfr.padding.len = ngtcp2_ppe_padding_size(ppe, min_pktlen);
4217 }
4218
4219 if (lfr.padding.len) {
4220 lfr.type = NGTCP2_FRAME_PADDING;
4221 padded = 1;
4222 ngtcp2_log_tx_fr(&conn->log, hd, &lfr);
4223 ngtcp2_qlog_write_frame(&conn->qlog, &lfr);
4224 }
4225
4226 nwrite = ngtcp2_ppe_final(ppe, NULL);
4227 if (nwrite < 0) {
4228 assert(ngtcp2_err_is_fatal((int)nwrite));
4229 return nwrite;
4230 }
4231
4232 ++cc->ckm->use_count;
4233
4234 ngtcp2_qlog_pkt_sent_end(&conn->qlog, hd, (size_t)nwrite);
4235
4236 /* TODO ack-eliciting vs needs-tracking */
4237 /* probe packet needs tracking but it does not need ACK, could be lost. */
4238 if ((rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) || padded) {
4239 if (pi) {
4240 conn_handle_tx_ecn(conn, pi, &rtb_entry_flags, pktns, hd, ts);
4241 }
4242
4243 rv = ngtcp2_rtb_entry_objalloc_new(&ent, hd, NULL, ts, (size_t)nwrite,
4244 rtb_entry_flags,
4245 &conn->rtb_entry_objalloc);
4246 if (rv != 0) {
4247 assert(ngtcp2_err_is_fatal((int)nwrite));
4248 return rv;
4249 }
4250
4251 if (*pfrc != pktns->tx.frq) {
4252 ent->frc = pktns->tx.frq;
4253 pktns->tx.frq = *pfrc;
4254 *pfrc = NULL;
4255 }
4256
4257 if ((rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) &&
4258 pktns->rtb.num_ack_eliciting == 0 && conn->cc.event) {
4259 conn->cc.event(&conn->cc, &conn->cstat, NGTCP2_CC_EVENT_TYPE_TX_START,
4260 ts);
4261 }
4262
4263 rv = conn_on_pkt_sent(conn, &pktns->rtb, ent);
4264 if (rv != 0) {
4265 assert(ngtcp2_err_is_fatal(rv));
4266 ngtcp2_rtb_entry_objalloc_del(ent, &conn->rtb_entry_objalloc,
4267 &conn->frc_objalloc, conn->mem);
4268 return rv;
4269 }
4270
4271 if (rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
4272 if (conn->cc.on_pkt_sent) {
4273 conn->cc.on_pkt_sent(
4274 &conn->cc, &conn->cstat,
4275 ngtcp2_cc_pkt_init(&cc_pkt, hd->pkt_num, (size_t)nwrite,
4276 NGTCP2_PKTNS_ID_APPLICATION, ts, ent->rst.lost,
4277 ent->rst.tx_in_flight, ent->rst.is_app_limited));
4278 }
4279
4280 if (conn->flags & NGTCP2_CONN_FLAG_RESTART_IDLE_TIMER_ON_WRITE) {
4281 conn_restart_timer_on_write(conn, ts);
4282 }
4283 }
4284 } else if (pi && conn->tx.ecn.state == NGTCP2_ECN_STATE_CAPABLE) {
4285 conn_handle_tx_ecn(conn, pi, NULL, pktns, hd, ts);
4286 }
4287
4288 conn->flags &= (uint32_t)~NGTCP2_CONN_FLAG_PPE_PENDING;
4289
4290 if (pktns->rtb.probe_pkt_left &&
4291 (rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING)) {
4292 --pktns->rtb.probe_pkt_left;
4293
4294 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON, "probe pkt size=%td",
4295 nwrite);
4296 }
4297
4298 conn_update_keep_alive_last_ts(conn, ts);
4299
4300 conn->dcid.current.bytes_sent += (uint64_t)nwrite;
4301
4302 conn->tx.pacing.pktlen += (size_t)nwrite;
4303
4304 ngtcp2_qlog_metrics_updated(&conn->qlog, &conn->cstat);
4305
4306 ++pktns->tx.last_pkt_num;
4307
4308 return nwrite;
4309 }
4310
ngtcp2_conn_write_single_frame_pkt(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,uint8_t type,uint8_t flags,const ngtcp2_cid * dcid,ngtcp2_frame * fr,uint16_t rtb_entry_flags,const ngtcp2_path * path,ngtcp2_tstamp ts)4311 ngtcp2_ssize ngtcp2_conn_write_single_frame_pkt(
4312 ngtcp2_conn *conn, ngtcp2_pkt_info *pi, uint8_t *dest, size_t destlen,
4313 uint8_t type, uint8_t flags, const ngtcp2_cid *dcid, ngtcp2_frame *fr,
4314 uint16_t rtb_entry_flags, const ngtcp2_path *path, ngtcp2_tstamp ts) {
4315 int rv;
4316 ngtcp2_ppe ppe;
4317 ngtcp2_pkt_hd hd;
4318 ngtcp2_frame lfr;
4319 ngtcp2_ssize nwrite;
4320 ngtcp2_crypto_cc cc;
4321 ngtcp2_pktns *pktns;
4322 uint8_t hd_flags;
4323 ngtcp2_rtb_entry *rtbent;
4324 int padded = 0;
4325 const ngtcp2_cid *scid;
4326 uint32_t version;
4327
4328 switch (type) {
4329 case NGTCP2_PKT_INITIAL:
4330 pktns = conn->in_pktns;
4331 hd_flags = conn_pkt_flags_long(conn);
4332 scid = &conn->oscid;
4333 version = conn->negotiated_version ? conn->negotiated_version
4334 : conn->client_chosen_version;
4335 if (version == conn->client_chosen_version) {
4336 cc.ckm = pktns->crypto.tx.ckm;
4337 cc.hp_ctx = pktns->crypto.tx.hp_ctx;
4338 } else {
4339 assert(version == conn->vneg.version);
4340
4341 cc.ckm = conn->vneg.tx.ckm;
4342 cc.hp_ctx = conn->vneg.tx.hp_ctx;
4343 }
4344 break;
4345 case NGTCP2_PKT_HANDSHAKE:
4346 pktns = conn->hs_pktns;
4347 hd_flags = conn_pkt_flags_long(conn);
4348 scid = &conn->oscid;
4349 version = conn->negotiated_version;
4350 cc.ckm = pktns->crypto.tx.ckm;
4351 cc.hp_ctx = pktns->crypto.tx.hp_ctx;
4352 break;
4353 case NGTCP2_PKT_1RTT:
4354 pktns = &conn->pktns;
4355 hd_flags = conn_pkt_flags_short(conn);
4356 scid = NULL;
4357 version = conn->negotiated_version;
4358 cc.ckm = pktns->crypto.tx.ckm;
4359 cc.hp_ctx = pktns->crypto.tx.hp_ctx;
4360 break;
4361 default:
4362 /* We don't support 0-RTT packet in this function. */
4363 assert(0);
4364 abort();
4365 }
4366
4367 cc.aead = pktns->crypto.ctx.aead;
4368 cc.hp = pktns->crypto.ctx.hp;
4369 cc.encrypt = conn->callbacks.encrypt;
4370 cc.hp_mask = conn->callbacks.hp_mask;
4371
4372 ngtcp2_pkt_hd_init(&hd, hd_flags, type, dcid, scid,
4373 pktns->tx.last_pkt_num + 1, pktns_select_pkt_numlen(pktns),
4374 version, 0);
4375
4376 ngtcp2_ppe_init(&ppe, dest, destlen, &cc);
4377
4378 rv = ngtcp2_ppe_encode_hd(&ppe, &hd);
4379 if (rv != 0) {
4380 assert(NGTCP2_ERR_NOBUF == rv);
4381 return 0;
4382 }
4383
4384 if (!ngtcp2_ppe_ensure_hp_sample(&ppe)) {
4385 return 0;
4386 }
4387
4388 ngtcp2_log_tx_pkt_hd(&conn->log, &hd);
4389 ngtcp2_qlog_pkt_sent_start(&conn->qlog);
4390
4391 rv = conn_ppe_write_frame(conn, &ppe, &hd, fr);
4392 if (rv != 0) {
4393 assert(NGTCP2_ERR_NOBUF == rv);
4394 return 0;
4395 }
4396
4397 lfr.type = NGTCP2_FRAME_PADDING;
4398 if (flags & NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING) {
4399 lfr.padding.len = ngtcp2_ppe_padding(&ppe);
4400 } else {
4401 switch (fr->type) {
4402 case NGTCP2_FRAME_PATH_CHALLENGE:
4403 case NGTCP2_FRAME_PATH_RESPONSE:
4404 if (!conn->server || destlen >= NGTCP2_MAX_UDP_PAYLOAD_SIZE) {
4405 lfr.padding.len = ngtcp2_ppe_padding(&ppe);
4406 } else {
4407 lfr.padding.len = 0;
4408 }
4409 break;
4410 default:
4411 if (type == NGTCP2_PKT_1RTT) {
4412 lfr.padding.len =
4413 ngtcp2_ppe_padding_size(&ppe, conn_min_short_pktlen(conn));
4414 } else {
4415 lfr.padding.len = ngtcp2_ppe_padding_hp_sample(&ppe);
4416 }
4417 }
4418 }
4419 if (lfr.padding.len) {
4420 padded = 1;
4421 ngtcp2_log_tx_fr(&conn->log, &hd, &lfr);
4422 ngtcp2_qlog_write_frame(&conn->qlog, &lfr);
4423 }
4424
4425 nwrite = ngtcp2_ppe_final(&ppe, NULL);
4426 if (nwrite < 0) {
4427 return nwrite;
4428 }
4429
4430 if (type == NGTCP2_PKT_1RTT) {
4431 ++cc.ckm->use_count;
4432 }
4433
4434 ngtcp2_qlog_pkt_sent_end(&conn->qlog, &hd, (size_t)nwrite);
4435
4436 /* Do this when we are sure that there is no error. */
4437 switch (fr->type) {
4438 case NGTCP2_FRAME_ACK:
4439 case NGTCP2_FRAME_ACK_ECN:
4440 ngtcp2_acktr_commit_ack(&pktns->acktr);
4441 ngtcp2_acktr_add_ack(&pktns->acktr, hd.pkt_num, fr->ack.largest_ack);
4442 if (type == NGTCP2_PKT_1RTT) {
4443 conn_handle_unconfirmed_key_update_from_remote(conn, fr->ack.largest_ack,
4444 ts);
4445 }
4446 break;
4447 }
4448
4449 if (((rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) || padded) &&
4450 (!path || ngtcp2_path_eq(&conn->dcid.current.ps.path, path))) {
4451 if (pi && !(rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE)) {
4452 conn_handle_tx_ecn(conn, pi, &rtb_entry_flags, pktns, &hd, ts);
4453 }
4454
4455 rv = ngtcp2_rtb_entry_objalloc_new(&rtbent, &hd, NULL, ts, (size_t)nwrite,
4456 rtb_entry_flags,
4457 &conn->rtb_entry_objalloc);
4458 if (rv != 0) {
4459 return rv;
4460 }
4461
4462 rv = conn_on_pkt_sent(conn, &pktns->rtb, rtbent);
4463 if (rv != 0) {
4464 ngtcp2_rtb_entry_objalloc_del(rtbent, &conn->rtb_entry_objalloc,
4465 &conn->frc_objalloc, conn->mem);
4466 return rv;
4467 }
4468
4469 if (rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING) {
4470 if (conn->flags & NGTCP2_CONN_FLAG_RESTART_IDLE_TIMER_ON_WRITE) {
4471 conn_restart_timer_on_write(conn, ts);
4472 }
4473
4474 if (pktns->rtb.probe_pkt_left && path &&
4475 ngtcp2_path_eq(&conn->dcid.current.ps.path, path)) {
4476 --pktns->rtb.probe_pkt_left;
4477
4478 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON, "probe pkt size=%td",
4479 nwrite);
4480 }
4481 }
4482 } else if (pi && !(rtb_entry_flags & NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE) &&
4483 conn->tx.ecn.state == NGTCP2_ECN_STATE_CAPABLE) {
4484 conn_handle_tx_ecn(conn, pi, NULL, pktns, &hd, ts);
4485 }
4486
4487 if (path && ngtcp2_path_eq(&conn->dcid.current.ps.path, path)) {
4488 conn_update_keep_alive_last_ts(conn, ts);
4489 }
4490
4491 conn->tx.pacing.pktlen += (size_t)nwrite;
4492
4493 ngtcp2_qlog_metrics_updated(&conn->qlog, &conn->cstat);
4494
4495 ++pktns->tx.last_pkt_num;
4496
4497 return nwrite;
4498 }
4499
4500 /*
4501 * conn_process_early_rtb makes any pending 0RTT packet 1RTT packet.
4502 */
conn_process_early_rtb(ngtcp2_conn * conn)4503 static void conn_process_early_rtb(ngtcp2_conn *conn) {
4504 ngtcp2_rtb_entry *ent;
4505 ngtcp2_rtb *rtb = &conn->pktns.rtb;
4506 ngtcp2_ksl_it it;
4507
4508 for (it = ngtcp2_rtb_head(rtb); !ngtcp2_ksl_it_end(&it);
4509 ngtcp2_ksl_it_next(&it)) {
4510 ent = ngtcp2_ksl_it_get(&it);
4511
4512 if ((ent->hd.flags & NGTCP2_PKT_FLAG_LONG_FORM) == 0 ||
4513 ent->hd.type != NGTCP2_PKT_0RTT) {
4514 continue;
4515 }
4516
4517 /* 0-RTT packet is retransmitted as a 1RTT packet. */
4518 ent->hd.flags &= (uint8_t)~NGTCP2_PKT_FLAG_LONG_FORM;
4519 ent->hd.type = NGTCP2_PKT_1RTT;
4520 }
4521 }
4522
4523 /*
4524 * conn_handshake_remnants_left returns nonzero if there may be
4525 * handshake packets the local endpoint has to send, including new
4526 * packets and lost ones.
4527 */
conn_handshake_remnants_left(ngtcp2_conn * conn)4528 static int conn_handshake_remnants_left(ngtcp2_conn *conn) {
4529 ngtcp2_pktns *in_pktns = conn->in_pktns;
4530 ngtcp2_pktns *hs_pktns = conn->hs_pktns;
4531
4532 return !conn_is_handshake_completed(conn) ||
4533 (in_pktns && (in_pktns->rtb.num_pto_eliciting ||
4534 ngtcp2_ksl_len(&in_pktns->crypto.tx.frq))) ||
4535 (hs_pktns && (hs_pktns->rtb.num_pto_eliciting ||
4536 ngtcp2_ksl_len(&hs_pktns->crypto.tx.frq)));
4537 }
4538
4539 /*
4540 * conn_retire_dcid_seq retires destination connection ID denoted by
4541 * |seq|.
4542 *
4543 * This function returns 0 if it succeeds, or one of the following
4544 * negative error codes:
4545 *
4546 * NGTCP2_ERR_NOMEM
4547 * Out of memory.
4548 * NGTCP2_ERR_CONNECTION_ID_LIMIT
4549 * The number of unacknowledged retirement exceeds the limit.
4550 */
conn_retire_dcid_seq(ngtcp2_conn * conn,uint64_t seq)4551 static int conn_retire_dcid_seq(ngtcp2_conn *conn, uint64_t seq) {
4552 ngtcp2_pktns *pktns = &conn->pktns;
4553 ngtcp2_frame_chain *nfrc;
4554 int rv;
4555
4556 rv = ngtcp2_conn_track_retired_dcid_seq(conn, seq);
4557 if (rv != 0) {
4558 return rv;
4559 }
4560
4561 rv = ngtcp2_frame_chain_objalloc_new(&nfrc, &conn->frc_objalloc);
4562 if (rv != 0) {
4563 return rv;
4564 }
4565
4566 nfrc->fr.type = NGTCP2_FRAME_RETIRE_CONNECTION_ID;
4567 nfrc->fr.retire_connection_id.seq = seq;
4568 nfrc->next = pktns->tx.frq;
4569 pktns->tx.frq = nfrc;
4570
4571 return 0;
4572 }
4573
4574 /*
4575 * conn_retire_dcid retires |dcid|.
4576 *
4577 * This function returns 0 if it succeeds, or one of the following
4578 * negative error codes:
4579 *
4580 * NGTCP2_ERR_NOMEM
4581 * Out of memory
4582 */
conn_retire_dcid(ngtcp2_conn * conn,const ngtcp2_dcid * dcid,ngtcp2_tstamp ts)4583 static int conn_retire_dcid(ngtcp2_conn *conn, const ngtcp2_dcid *dcid,
4584 ngtcp2_tstamp ts) {
4585 ngtcp2_ringbuf *rb = &conn->dcid.retired.rb;
4586 ngtcp2_dcid *dest, *stale_dcid;
4587 int rv;
4588
4589 assert(dcid->cid.datalen);
4590
4591 if (ngtcp2_ringbuf_full(rb)) {
4592 stale_dcid = ngtcp2_ringbuf_get(rb, 0);
4593 rv = conn_call_deactivate_dcid(conn, stale_dcid);
4594 if (rv != 0) {
4595 return rv;
4596 }
4597
4598 ngtcp2_ringbuf_pop_front(rb);
4599 }
4600
4601 dest = ngtcp2_ringbuf_push_back(rb);
4602 ngtcp2_dcid_copy(dest, dcid);
4603 dest->retired_ts = ts;
4604
4605 return conn_retire_dcid_seq(conn, dcid->seq);
4606 }
4607
4608 /*
4609 * conn_bind_dcid stores the DCID to |*pdcid| bound to |path|. If
4610 * such DCID is not found, bind the new DCID to |path| and stores it
4611 * to |*pdcid|. If a remote endpoint uses zero-length connection ID,
4612 * the pointer to conn->dcid.current is assigned to |*pdcid|.
4613 *
4614 * This function returns 0 if it succeeds, or one of the following
4615 * negative error codes:
4616 *
4617 * NGTCP2_ERR_CONN_ID_BLOCKED
4618 * No unused DCID is available
4619 * NGTCP2_ERR_NOMEM
4620 * Out of memory
4621 */
conn_bind_dcid(ngtcp2_conn * conn,ngtcp2_dcid ** pdcid,const ngtcp2_path * path,ngtcp2_tstamp ts)4622 static int conn_bind_dcid(ngtcp2_conn *conn, ngtcp2_dcid **pdcid,
4623 const ngtcp2_path *path, ngtcp2_tstamp ts) {
4624 ngtcp2_dcid *dcid, *ndcid;
4625 ngtcp2_cid cid;
4626 size_t i, len;
4627 int rv;
4628
4629 assert(!ngtcp2_path_eq(&conn->dcid.current.ps.path, path));
4630 assert(!conn->pv || !ngtcp2_path_eq(&conn->pv->dcid.ps.path, path));
4631 assert(!conn->pv || !(conn->pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) ||
4632 !ngtcp2_path_eq(&conn->pv->fallback_dcid.ps.path, path));
4633
4634 len = ngtcp2_ringbuf_len(&conn->dcid.bound.rb);
4635 for (i = 0; i < len; ++i) {
4636 dcid = ngtcp2_ringbuf_get(&conn->dcid.bound.rb, i);
4637
4638 if (ngtcp2_path_eq(&dcid->ps.path, path)) {
4639 *pdcid = dcid;
4640 return 0;
4641 }
4642 }
4643
4644 if (conn->dcid.current.cid.datalen == 0) {
4645 ndcid = ngtcp2_ringbuf_push_back(&conn->dcid.bound.rb);
4646 ngtcp2_cid_zero(&cid);
4647 ngtcp2_dcid_init(ndcid, ++conn->dcid.zerolen_seq, &cid, NULL);
4648 ngtcp2_dcid_set_path(ndcid, path);
4649
4650 *pdcid = ndcid;
4651
4652 return 0;
4653 }
4654
4655 if (ngtcp2_ringbuf_len(&conn->dcid.unused.rb) == 0) {
4656 return NGTCP2_ERR_CONN_ID_BLOCKED;
4657 }
4658
4659 if (ngtcp2_ringbuf_full(&conn->dcid.bound.rb)) {
4660 dcid = ngtcp2_ringbuf_get(&conn->dcid.bound.rb, 0);
4661 rv = conn_retire_dcid(conn, dcid, ts);
4662 if (rv != 0) {
4663 return rv;
4664 }
4665 }
4666
4667 dcid = ngtcp2_ringbuf_get(&conn->dcid.unused.rb, 0);
4668 ndcid = ngtcp2_ringbuf_push_back(&conn->dcid.bound.rb);
4669
4670 ngtcp2_dcid_copy(ndcid, dcid);
4671 ndcid->bound_ts = ts;
4672 ngtcp2_dcid_set_path(ndcid, path);
4673
4674 ngtcp2_ringbuf_pop_front(&conn->dcid.unused.rb);
4675
4676 *pdcid = ndcid;
4677
4678 return 0;
4679 }
4680
conn_start_pmtud(ngtcp2_conn * conn)4681 static int conn_start_pmtud(ngtcp2_conn *conn) {
4682 int rv;
4683 size_t hard_max_udp_payload_size;
4684
4685 assert(!conn->local.settings.no_pmtud);
4686 assert(!conn->pmtud);
4687 assert(conn_is_handshake_completed(conn));
4688 assert(conn->remote.transport_params);
4689 assert(conn->remote.transport_params->max_udp_payload_size >=
4690 NGTCP2_MAX_UDP_PAYLOAD_SIZE);
4691
4692 hard_max_udp_payload_size =
4693 (size_t)ngtcp2_min(conn->remote.transport_params->max_udp_payload_size,
4694 (uint64_t)conn->local.settings.max_udp_payload_size);
4695
4696 rv = ngtcp2_pmtud_new(&conn->pmtud, conn->dcid.current.max_udp_payload_size,
4697 hard_max_udp_payload_size,
4698 conn->pktns.tx.last_pkt_num + 1, conn->mem);
4699 if (rv != 0) {
4700 return rv;
4701 }
4702
4703 if (ngtcp2_pmtud_finished(conn->pmtud)) {
4704 ngtcp2_conn_stop_pmtud(conn);
4705 }
4706
4707 return 0;
4708 }
4709
ngtcp2_conn_start_pmtud(ngtcp2_conn * conn)4710 int ngtcp2_conn_start_pmtud(ngtcp2_conn *conn) {
4711 return conn_start_pmtud(conn);
4712 }
4713
ngtcp2_conn_stop_pmtud(ngtcp2_conn * conn)4714 void ngtcp2_conn_stop_pmtud(ngtcp2_conn *conn) {
4715 if (!conn->pmtud) {
4716 return;
4717 }
4718
4719 ngtcp2_pmtud_del(conn->pmtud);
4720
4721 conn->pmtud = NULL;
4722 }
4723
conn_write_pmtud_probe(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,ngtcp2_tstamp ts)4724 static ngtcp2_ssize conn_write_pmtud_probe(ngtcp2_conn *conn,
4725 ngtcp2_pkt_info *pi, uint8_t *dest,
4726 size_t destlen, ngtcp2_tstamp ts) {
4727 size_t probelen;
4728 ngtcp2_ssize nwrite;
4729 ngtcp2_frame lfr;
4730
4731 assert(conn->pmtud);
4732 assert(!ngtcp2_pmtud_finished(conn->pmtud));
4733
4734 if (!ngtcp2_pmtud_require_probe(conn->pmtud)) {
4735 return 0;
4736 }
4737
4738 probelen = ngtcp2_pmtud_probelen(conn->pmtud);
4739 if (probelen > destlen) {
4740 return 0;
4741 }
4742
4743 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
4744 "sending PMTUD probe packet len=%zu", probelen);
4745
4746 lfr.type = NGTCP2_FRAME_PING;
4747
4748 nwrite = ngtcp2_conn_write_single_frame_pkt(
4749 conn, pi, dest, probelen, NGTCP2_PKT_1RTT,
4750 NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING, &conn->dcid.current.cid, &lfr,
4751 NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING |
4752 NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING |
4753 NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE,
4754 NULL, ts);
4755 if (nwrite < 0) {
4756 return nwrite;
4757 }
4758
4759 assert(nwrite);
4760
4761 ngtcp2_pmtud_probe_sent(conn->pmtud, conn_compute_pto(conn, &conn->pktns),
4762 ts);
4763
4764 return nwrite;
4765 }
4766
4767 /*
4768 * conn_stop_pv stops the path validation which is currently running.
4769 * This function does nothing if no path validation is currently being
4770 * performed.
4771 *
4772 * This function returns 0 if it succeeds, or one of the following
4773 * negative error codes:
4774 *
4775 * NGTCP2_ERR_NOMEM
4776 * Out of memory
4777 */
conn_stop_pv(ngtcp2_conn * conn,ngtcp2_tstamp ts)4778 static int conn_stop_pv(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
4779 int rv = 0;
4780 ngtcp2_pv *pv = conn->pv;
4781
4782 if (pv == NULL) {
4783 return 0;
4784 }
4785
4786 if (pv->dcid.cid.datalen && pv->dcid.seq != conn->dcid.current.seq) {
4787 rv = conn_retire_dcid(conn, &pv->dcid, ts);
4788 if (rv != 0) {
4789 goto fin;
4790 }
4791 }
4792
4793 if ((pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) &&
4794 pv->fallback_dcid.cid.datalen &&
4795 pv->fallback_dcid.seq != conn->dcid.current.seq &&
4796 pv->fallback_dcid.seq != pv->dcid.seq) {
4797 rv = conn_retire_dcid(conn, &pv->fallback_dcid, ts);
4798 if (rv != 0) {
4799 goto fin;
4800 }
4801 }
4802
4803 fin:
4804 ngtcp2_pv_del(pv);
4805 conn->pv = NULL;
4806
4807 return rv;
4808 }
4809
4810 /*
4811 * conn_abort_pv aborts the current path validation and frees
4812 * resources allocated for it. This function assumes that conn->pv is
4813 * not NULL.
4814 *
4815 * This function returns 0 if it succeeds, or one of the following
4816 * negative error codes:
4817 *
4818 * NGTCP2_ERR_NOMEM
4819 * Out of memory
4820 * NGTCP2_ERR_CALLBACK_FAILURE
4821 * User-defined callback function failed.
4822 */
conn_abort_pv(ngtcp2_conn * conn,ngtcp2_tstamp ts)4823 static int conn_abort_pv(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
4824 ngtcp2_pv *pv = conn->pv;
4825 int rv;
4826
4827 assert(pv);
4828
4829 if (!(pv->flags & NGTCP2_PV_FLAG_DONT_CARE)) {
4830 rv = conn_call_path_validation(conn, pv,
4831 NGTCP2_PATH_VALIDATION_RESULT_ABORTED);
4832 if (rv != 0) {
4833 return rv;
4834 }
4835 }
4836
4837 return conn_stop_pv(conn, ts);
4838 }
4839
conn_shape_udp_payload(ngtcp2_conn * conn,const ngtcp2_dcid * dcid,size_t payloadlen)4840 static size_t conn_shape_udp_payload(ngtcp2_conn *conn, const ngtcp2_dcid *dcid,
4841 size_t payloadlen) {
4842 if (conn->remote.transport_params &&
4843 conn->remote.transport_params->max_udp_payload_size) {
4844 assert(conn->remote.transport_params->max_udp_payload_size >=
4845 NGTCP2_MAX_UDP_PAYLOAD_SIZE);
4846
4847 payloadlen =
4848 (size_t)ngtcp2_min((uint64_t)payloadlen,
4849 conn->remote.transport_params->max_udp_payload_size);
4850 }
4851
4852 payloadlen =
4853 ngtcp2_min(payloadlen, conn->local.settings.max_udp_payload_size);
4854
4855 if (conn->local.settings.no_udp_payload_size_shaping) {
4856 return payloadlen;
4857 }
4858
4859 return ngtcp2_min(payloadlen, dcid->max_udp_payload_size);
4860 }
4861
4862 static void conn_reset_congestion_state(ngtcp2_conn *conn, ngtcp2_tstamp ts);
4863
4864 /*
4865 * conn_on_path_validation_failed is called when path validation
4866 * fails. This function may delete |pv|.
4867 *
4868 * This function returns 0 if it succeeds, or one of the following
4869 * negative error codes:
4870 *
4871 * NGTCP2_ERR_NOMEM
4872 * Out of memory
4873 * NGTCP2_ERR_CALLBACK_FAILURE
4874 * User-defined callback function failed.
4875 */
conn_on_path_validation_failed(ngtcp2_conn * conn,ngtcp2_pv * pv,ngtcp2_tstamp ts)4876 static int conn_on_path_validation_failed(ngtcp2_conn *conn, ngtcp2_pv *pv,
4877 ngtcp2_tstamp ts) {
4878 int rv;
4879
4880 if (!(pv->flags & NGTCP2_PV_FLAG_DONT_CARE)) {
4881 rv = conn_call_path_validation(conn, pv,
4882 NGTCP2_PATH_VALIDATION_RESULT_FAILURE);
4883 if (rv != 0) {
4884 return rv;
4885 }
4886 }
4887
4888 if (pv->flags & NGTCP2_PV_FLAG_MTU_PROBE) {
4889 return NGTCP2_ERR_NO_VIABLE_PATH;
4890 }
4891
4892 if (pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) {
4893 ngtcp2_dcid_copy(&conn->dcid.current, &pv->fallback_dcid);
4894 conn_reset_congestion_state(conn, ts);
4895 }
4896
4897 return conn_stop_pv(conn, ts);
4898 }
4899
4900 /*
4901 * conn_write_path_challenge writes a packet which includes
4902 * PATH_CHALLENGE frame into |dest| of length |destlen|.
4903 *
4904 * This function returns the number of bytes written to |dest|, or one
4905 * of the following negative error codes:
4906 *
4907 * NGTCP2_ERR_NOMEM
4908 * Out of memory
4909 * NGTCP2_ERR_CALLBACK_FAILURE
4910 * User-defined callback function failed.
4911 */
conn_write_path_challenge(ngtcp2_conn * conn,ngtcp2_path * path,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,ngtcp2_tstamp ts)4912 static ngtcp2_ssize conn_write_path_challenge(ngtcp2_conn *conn,
4913 ngtcp2_path *path,
4914 ngtcp2_pkt_info *pi,
4915 uint8_t *dest, size_t destlen,
4916 ngtcp2_tstamp ts) {
4917 ngtcp2_ssize nwrite;
4918 ngtcp2_tstamp expiry;
4919 ngtcp2_pv *pv = conn->pv;
4920 ngtcp2_frame lfr;
4921 ngtcp2_duration timeout;
4922 uint8_t flags;
4923 uint64_t tx_left;
4924 int rv;
4925
4926 if (ngtcp2_pv_validation_timed_out(pv, ts)) {
4927 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PTV,
4928 "path validation was timed out");
4929 rv = conn_on_path_validation_failed(conn, pv, ts);
4930 if (rv != 0) {
4931 return rv;
4932 }
4933
4934 /* We might set path to the one which we just failed validate.
4935 Set it to the current path here. */
4936 if (path) {
4937 ngtcp2_path_copy(path, &conn->dcid.current.ps.path);
4938 }
4939
4940 return 0;
4941 }
4942
4943 ngtcp2_pv_handle_entry_expiry(pv, ts);
4944
4945 if (!ngtcp2_pv_should_send_probe(pv)) {
4946 return 0;
4947 }
4948
4949 rv = conn_call_get_path_challenge_data(conn, lfr.path_challenge.data);
4950 if (rv != 0) {
4951 return rv;
4952 }
4953
4954 lfr.type = NGTCP2_FRAME_PATH_CHALLENGE;
4955
4956 timeout = conn_compute_pto(conn, &conn->pktns);
4957 timeout = ngtcp2_max(timeout, 3 * conn->cstat.initial_rtt);
4958 expiry = ts + timeout * (1ULL << pv->round);
4959
4960 destlen = ngtcp2_min(destlen, NGTCP2_MAX_UDP_PAYLOAD_SIZE);
4961
4962 if (conn->server) {
4963 if (!(pv->dcid.flags & NGTCP2_DCID_FLAG_PATH_VALIDATED)) {
4964 tx_left = conn_server_tx_left(conn, &pv->dcid);
4965 destlen = (size_t)ngtcp2_min((uint64_t)destlen, tx_left);
4966 if (destlen == 0) {
4967 return 0;
4968 }
4969 }
4970
4971 if (destlen < NGTCP2_MAX_UDP_PAYLOAD_SIZE) {
4972 flags = NGTCP2_PV_ENTRY_FLAG_UNDERSIZED;
4973 } else {
4974 flags = NGTCP2_PV_ENTRY_FLAG_NONE;
4975 }
4976 } else {
4977 flags = NGTCP2_PV_ENTRY_FLAG_NONE;
4978 }
4979
4980 ngtcp2_pv_add_entry(pv, lfr.path_challenge.data, expiry, flags, ts);
4981
4982 nwrite = ngtcp2_conn_write_single_frame_pkt(
4983 conn, pi, dest, destlen, NGTCP2_PKT_1RTT, NGTCP2_WRITE_PKT_FLAG_NONE,
4984 &pv->dcid.cid, &lfr,
4985 NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING | NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING,
4986 &pv->dcid.ps.path, ts);
4987 if (nwrite <= 0) {
4988 return nwrite;
4989 }
4990
4991 if (path) {
4992 ngtcp2_path_copy(path, &pv->dcid.ps.path);
4993 }
4994
4995 if (ngtcp2_path_eq(&pv->dcid.ps.path, &conn->dcid.current.ps.path)) {
4996 conn->dcid.current.bytes_sent += (uint64_t)nwrite;
4997 } else {
4998 pv->dcid.bytes_sent += (uint64_t)nwrite;
4999 }
5000
5001 return nwrite;
5002 }
5003
5004 /*
5005 * conn_write_path_response writes a packet which includes
5006 * PATH_RESPONSE frame into |dest| of length |destlen|.
5007 *
5008 * This function returns the number of bytes written to |dest|, or one
5009 * of the following negative error codes:
5010 *
5011 * NGTCP2_ERR_NOMEM
5012 * Out of memory
5013 * NGTCP2_ERR_CALLBACK_FAILURE
5014 * User-defined callback function failed.
5015 */
conn_write_path_response(ngtcp2_conn * conn,ngtcp2_path * path,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,ngtcp2_tstamp ts)5016 static ngtcp2_ssize conn_write_path_response(ngtcp2_conn *conn,
5017 ngtcp2_path *path,
5018 ngtcp2_pkt_info *pi, uint8_t *dest,
5019 size_t destlen, ngtcp2_tstamp ts) {
5020 ngtcp2_pv *pv = conn->pv;
5021 ngtcp2_path_challenge_entry *pcent = NULL;
5022 ngtcp2_dcid *dcid = NULL;
5023 ngtcp2_frame lfr;
5024 ngtcp2_ssize nwrite;
5025 int rv;
5026 uint64_t tx_left;
5027
5028 for (; ngtcp2_ringbuf_len(&conn->rx.path_challenge.rb);) {
5029 pcent = ngtcp2_ringbuf_get(&conn->rx.path_challenge.rb, 0);
5030
5031 if (ngtcp2_path_eq(&conn->dcid.current.ps.path, &pcent->ps.path)) {
5032 /* Send PATH_RESPONSE from conn_write_pkt. */
5033 return 0;
5034 }
5035
5036 if (pv) {
5037 if (ngtcp2_path_eq(&pv->dcid.ps.path, &pcent->ps.path)) {
5038 dcid = &pv->dcid;
5039 break;
5040 }
5041 if ((pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) &&
5042 ngtcp2_path_eq(&pv->fallback_dcid.ps.path, &pcent->ps.path)) {
5043 dcid = &pv->fallback_dcid;
5044 break;
5045 }
5046 }
5047
5048 if (conn->server) {
5049 break;
5050 }
5051
5052 /* Client does not expect to respond to path validation against
5053 unknown path */
5054 ngtcp2_ringbuf_pop_front(&conn->rx.path_challenge.rb);
5055 pcent = NULL;
5056 }
5057
5058 if (pcent == NULL) {
5059 return 0;
5060 }
5061
5062 if (dcid == NULL) {
5063 /* client is expected to have |path| in conn->dcid.current or
5064 conn->pv. */
5065 assert(conn->server);
5066
5067 rv = conn_bind_dcid(conn, &dcid, &pcent->ps.path, ts);
5068 if (rv != 0) {
5069 if (ngtcp2_err_is_fatal(rv)) {
5070 return rv;
5071 }
5072 return 0;
5073 }
5074 }
5075
5076 destlen = ngtcp2_min(destlen, NGTCP2_MAX_UDP_PAYLOAD_SIZE);
5077
5078 if (conn->server && !(dcid->flags & NGTCP2_DCID_FLAG_PATH_VALIDATED)) {
5079 tx_left = conn_server_tx_left(conn, dcid);
5080 destlen = (size_t)ngtcp2_min((uint64_t)destlen, tx_left);
5081 if (destlen == 0) {
5082 return 0;
5083 }
5084 }
5085
5086 lfr.type = NGTCP2_FRAME_PATH_RESPONSE;
5087 memcpy(lfr.path_response.data, pcent->data, sizeof(lfr.path_response.data));
5088
5089 nwrite = ngtcp2_conn_write_single_frame_pkt(
5090 conn, pi, dest, destlen, NGTCP2_PKT_1RTT, NGTCP2_WRITE_PKT_FLAG_NONE,
5091 &dcid->cid, &lfr, NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING, &pcent->ps.path,
5092 ts);
5093 if (nwrite <= 0) {
5094 return nwrite;
5095 }
5096
5097 if (path) {
5098 ngtcp2_path_copy(path, &pcent->ps.path);
5099 }
5100
5101 ngtcp2_ringbuf_pop_front(&conn->rx.path_challenge.rb);
5102
5103 dcid->bytes_sent += (uint64_t)nwrite;
5104
5105 return nwrite;
5106 }
5107
ngtcp2_conn_write_pkt_versioned(ngtcp2_conn * conn,ngtcp2_path * path,int pkt_info_version,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,ngtcp2_tstamp ts)5108 ngtcp2_ssize ngtcp2_conn_write_pkt_versioned(ngtcp2_conn *conn,
5109 ngtcp2_path *path,
5110 int pkt_info_version,
5111 ngtcp2_pkt_info *pi, uint8_t *dest,
5112 size_t destlen, ngtcp2_tstamp ts) {
5113 return ngtcp2_conn_writev_stream_versioned(
5114 conn, path, pkt_info_version, pi, dest, destlen,
5115 /* pdatalen = */ NULL, NGTCP2_WRITE_STREAM_FLAG_NONE,
5116 /* stream_id = */ -1,
5117 /* datav = */ NULL, /* datavcnt = */ 0, ts);
5118 }
5119
5120 /*
5121 * conn_on_version_negotiation is called when Version Negotiation
5122 * packet is received. The function decodes the data in the buffer
5123 * pointed by |payload| whose length is |payloadlen| as Version
5124 * Negotiation packet payload. The packet header is given in |hd|.
5125 *
5126 * This function returns 0 if it succeeds, or one of the following
5127 * negative error codes:
5128 *
5129 * NGTCP2_ERR_NOMEM
5130 * Out of memory.
5131 * NGTCP2_ERR_CALLBACK_FAILURE
5132 * User-defined callback function failed.
5133 * NGTCP2_ERR_INVALID_ARGUMENT
5134 * Packet payload is badly formatted.
5135 */
conn_on_version_negotiation(ngtcp2_conn * conn,const ngtcp2_pkt_hd * hd,const uint8_t * payload,size_t payloadlen)5136 static int conn_on_version_negotiation(ngtcp2_conn *conn,
5137 const ngtcp2_pkt_hd *hd,
5138 const uint8_t *payload,
5139 size_t payloadlen) {
5140 uint32_t sv[16];
5141 uint32_t *p;
5142 int rv = 0;
5143 size_t nsv;
5144 size_t i;
5145
5146 if (payloadlen % sizeof(uint32_t)) {
5147 return NGTCP2_ERR_INVALID_ARGUMENT;
5148 }
5149
5150 /* Version Negotiation packet is ignored if client has reacted upon
5151 Version Negotiation packet. */
5152 if (conn->local.settings.original_version != conn->client_chosen_version) {
5153 return NGTCP2_ERR_INVALID_ARGUMENT;
5154 }
5155
5156 if (payloadlen > sizeof(sv)) {
5157 p = ngtcp2_mem_malloc(conn->mem, payloadlen);
5158 if (p == NULL) {
5159 return NGTCP2_ERR_NOMEM;
5160 }
5161 } else {
5162 p = sv;
5163 }
5164
5165 nsv = ngtcp2_pkt_decode_version_negotiation(p, payload, payloadlen);
5166
5167 ngtcp2_log_rx_vn(&conn->log, hd, p, nsv);
5168
5169 ngtcp2_qlog_version_negotiation_pkt_received(&conn->qlog, hd, p, nsv);
5170
5171 if (!ngtcp2_is_reserved_version(conn->local.settings.original_version)) {
5172 for (i = 0; i < nsv; ++i) {
5173 if (p[i] == conn->local.settings.original_version) {
5174 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
5175 "ignore Version Negotiation because it contains the "
5176 "original version");
5177
5178 rv = NGTCP2_ERR_INVALID_ARGUMENT;
5179 goto fin;
5180 }
5181 }
5182 }
5183
5184 rv = conn_call_recv_version_negotiation(conn, hd, p, nsv);
5185 if (rv != 0) {
5186 goto fin;
5187 }
5188
5189 fin:
5190 if (p != sv) {
5191 ngtcp2_mem_free(conn->mem, p);
5192 }
5193
5194 return rv;
5195 }
5196
conn_tx_strmq_first_cycle(ngtcp2_conn * conn)5197 static uint64_t conn_tx_strmq_first_cycle(ngtcp2_conn *conn) {
5198 ngtcp2_strm *strm;
5199
5200 if (ngtcp2_pq_empty(&conn->tx.strmq)) {
5201 return 0;
5202 }
5203
5204 strm = ngtcp2_struct_of(ngtcp2_pq_top(&conn->tx.strmq), ngtcp2_strm, pe);
5205 return strm->cycle;
5206 }
5207
ngtcp2_conn_tx_strmq_first_cycle(ngtcp2_conn * conn)5208 uint64_t ngtcp2_conn_tx_strmq_first_cycle(ngtcp2_conn *conn) {
5209 ngtcp2_strm *strm;
5210
5211 if (ngtcp2_pq_empty(&conn->tx.strmq)) {
5212 return 0;
5213 }
5214
5215 strm = ngtcp2_struct_of(ngtcp2_pq_top(&conn->tx.strmq), ngtcp2_strm, pe);
5216 return strm->cycle;
5217 }
5218
ngtcp2_conn_resched_frames(ngtcp2_conn * conn,ngtcp2_pktns * pktns,ngtcp2_frame_chain ** pfrc)5219 int ngtcp2_conn_resched_frames(ngtcp2_conn *conn, ngtcp2_pktns *pktns,
5220 ngtcp2_frame_chain **pfrc) {
5221 ngtcp2_frame_chain **first = pfrc;
5222 ngtcp2_frame_chain *frc;
5223 ngtcp2_stream *sfr;
5224 ngtcp2_strm *strm;
5225 int rv;
5226 int streamfrq_empty;
5227
5228 if (*pfrc == NULL) {
5229 return 0;
5230 }
5231
5232 for (; *pfrc;) {
5233 switch ((*pfrc)->fr.type) {
5234 case NGTCP2_FRAME_STREAM:
5235 frc = *pfrc;
5236
5237 *pfrc = frc->next;
5238 frc->next = NULL;
5239 sfr = &frc->fr.stream;
5240
5241 strm = ngtcp2_conn_find_stream(conn, sfr->stream_id);
5242 if (!strm) {
5243 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
5244 break;
5245 }
5246 streamfrq_empty = ngtcp2_strm_streamfrq_empty(strm);
5247 rv = ngtcp2_strm_streamfrq_push(strm, frc);
5248 if (rv != 0) {
5249 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
5250 return rv;
5251 }
5252 if (!ngtcp2_strm_is_tx_queued(strm)) {
5253 strm->cycle = conn_tx_strmq_first_cycle(conn);
5254 rv = ngtcp2_conn_tx_strmq_push(conn, strm);
5255 if (rv != 0) {
5256 return rv;
5257 }
5258 }
5259 if (streamfrq_empty) {
5260 ++conn->tx.strmq_nretrans;
5261 }
5262 break;
5263 case NGTCP2_FRAME_CRYPTO:
5264 frc = *pfrc;
5265
5266 *pfrc = frc->next;
5267 frc->next = NULL;
5268
5269 rv = ngtcp2_ksl_insert(&pktns->crypto.tx.frq, NULL,
5270 &frc->fr.crypto.offset, frc);
5271 if (rv != 0) {
5272 assert(ngtcp2_err_is_fatal(rv));
5273 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
5274 return rv;
5275 }
5276 break;
5277 default:
5278 pfrc = &(*pfrc)->next;
5279 }
5280 }
5281
5282 *pfrc = pktns->tx.frq;
5283 pktns->tx.frq = *first;
5284
5285 return 0;
5286 }
5287
5288 /*
5289 * conn_on_retry is called when Retry packet is received. The
5290 * function decodes the data in the buffer pointed by |pkt| whose
5291 * length is |pktlen| as Retry packet. The length of long packet
5292 * header is given in |hdpktlen|. |pkt| includes packet header.
5293 *
5294 * This function returns 0 if it succeeds, or one of the following
5295 * negative error codes:
5296 *
5297 * NGTCP2_ERR_NOMEM
5298 * Out of memory.
5299 * NGTCP2_ERR_CALLBACK_FAILURE
5300 * User-defined callback function failed.
5301 * NGTCP2_ERR_INVALID_ARGUMENT
5302 * Packet payload is badly formatted.
5303 * NGTCP2_ERR_PROTO
5304 * ODCID does not match; or Token is empty.
5305 */
conn_on_retry(ngtcp2_conn * conn,const ngtcp2_pkt_hd * hd,size_t hdpktlen,const uint8_t * pkt,size_t pktlen,ngtcp2_tstamp ts)5306 static int conn_on_retry(ngtcp2_conn *conn, const ngtcp2_pkt_hd *hd,
5307 size_t hdpktlen, const uint8_t *pkt, size_t pktlen,
5308 ngtcp2_tstamp ts) {
5309 int rv;
5310 ngtcp2_pkt_retry retry;
5311 ngtcp2_pktns *in_pktns = conn->in_pktns;
5312 ngtcp2_rtb *rtb = &conn->pktns.rtb;
5313 ngtcp2_rtb *in_rtb;
5314 uint8_t cidbuf[sizeof(retry.odcid.data) * 2 + 1];
5315 ngtcp2_vec *token;
5316
5317 if (!in_pktns || conn->flags & NGTCP2_CONN_FLAG_RECV_RETRY) {
5318 return 0;
5319 }
5320
5321 in_rtb = &in_pktns->rtb;
5322
5323 rv = ngtcp2_pkt_decode_retry(&retry, pkt + hdpktlen, pktlen - hdpktlen);
5324 if (rv != 0) {
5325 return rv;
5326 }
5327
5328 retry.odcid = conn->dcid.current.cid;
5329
5330 rv = ngtcp2_pkt_verify_retry_tag(
5331 conn->client_chosen_version, &retry, pkt, pktlen, conn->callbacks.encrypt,
5332 &conn->crypto.retry_aead, &conn->crypto.retry_aead_ctx);
5333 if (rv != 0) {
5334 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
5335 "unable to verify Retry packet integrity");
5336 return rv;
5337 }
5338
5339 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT, "odcid=0x%s",
5340 (const char *)ngtcp2_encode_hex(cidbuf, retry.odcid.data,
5341 retry.odcid.datalen));
5342
5343 if (retry.token.len == 0) {
5344 return NGTCP2_ERR_PROTO;
5345 }
5346
5347 if (ngtcp2_cid_eq(&conn->dcid.current.cid, &hd->scid)) {
5348 return 0;
5349 }
5350
5351 ngtcp2_qlog_retry_pkt_received(&conn->qlog, hd, &retry);
5352
5353 /* DCID must be updated before invoking callback because client
5354 generates new initial keys there. */
5355 conn->dcid.current.cid = hd->scid;
5356 conn->retry_scid = hd->scid;
5357
5358 conn->flags |= NGTCP2_CONN_FLAG_RECV_RETRY;
5359
5360 rv = conn_call_recv_retry(conn, hd);
5361 if (rv != 0) {
5362 return rv;
5363 }
5364
5365 conn->state = NGTCP2_CS_CLIENT_INITIAL;
5366
5367 /* Just freeing memory is dangerous because we might free twice. */
5368
5369 rv = ngtcp2_rtb_remove_all(rtb, conn, &conn->pktns, &conn->cstat);
5370 if (rv != 0) {
5371 return rv;
5372 }
5373
5374 rv = ngtcp2_rtb_remove_all(in_rtb, conn, in_pktns, &conn->cstat);
5375 if (rv != 0) {
5376 return rv;
5377 }
5378
5379 token = &conn->local.settings.token;
5380
5381 ngtcp2_mem_free(conn->mem, token->base);
5382 token->base = NULL;
5383 token->len = 0;
5384
5385 token->base = ngtcp2_mem_malloc(conn->mem, retry.token.len);
5386 if (token->base == NULL) {
5387 return NGTCP2_ERR_NOMEM;
5388 }
5389 token->len = retry.token.len;
5390
5391 ngtcp2_cpymem(token->base, retry.token.base, retry.token.len);
5392
5393 reset_conn_stat_recovery(&conn->cstat);
5394 conn_reset_congestion_state(conn, ts);
5395 conn_reset_ecn_validation_state(conn);
5396
5397 return 0;
5398 }
5399
ngtcp2_conn_detect_lost_pkt(ngtcp2_conn * conn,ngtcp2_pktns * pktns,ngtcp2_conn_stat * cstat,ngtcp2_tstamp ts)5400 int ngtcp2_conn_detect_lost_pkt(ngtcp2_conn *conn, ngtcp2_pktns *pktns,
5401 ngtcp2_conn_stat *cstat, ngtcp2_tstamp ts) {
5402 return ngtcp2_rtb_detect_lost_pkt(&pktns->rtb, conn, pktns, cstat, ts);
5403 }
5404
5405 /*
5406 * conn_recv_ack processes received ACK frame |fr|. |pkt_ts| is the
5407 * timestamp when packet is received. |ts| should be the current
5408 * time. Usually they are the same, but for buffered packets,
5409 * |pkt_ts| would be earlier than |ts|.
5410 *
5411 * This function returns 0 if it succeeds, or one of the following
5412 * negative error codes:
5413 *
5414 * NGTCP2_ERR_NOMEM
5415 * Out of memory
5416 * NGTCP2_ERR_ACK_FRAME
5417 * ACK frame is malformed.
5418 * NGTCP2_ERR_PROTO
5419 * |fr| acknowledges a packet this endpoint has not sent.
5420 * NGTCP2_ERR_CALLBACK_FAILURE
5421 * User callback failed.
5422 */
conn_recv_ack(ngtcp2_conn * conn,ngtcp2_pktns * pktns,ngtcp2_ack * fr,ngtcp2_tstamp pkt_ts,ngtcp2_tstamp ts)5423 static int conn_recv_ack(ngtcp2_conn *conn, ngtcp2_pktns *pktns, ngtcp2_ack *fr,
5424 ngtcp2_tstamp pkt_ts, ngtcp2_tstamp ts) {
5425 int rv;
5426 ngtcp2_frame_chain *frc = NULL;
5427 ngtcp2_ssize num_acked;
5428 ngtcp2_conn_stat *cstat = &conn->cstat;
5429
5430 if (pktns->tx.last_pkt_num < fr->largest_ack) {
5431 return NGTCP2_ERR_PROTO;
5432 }
5433
5434 rv = ngtcp2_pkt_validate_ack(fr);
5435 if (rv != 0) {
5436 return rv;
5437 }
5438
5439 ngtcp2_acktr_recv_ack(&pktns->acktr, fr);
5440
5441 num_acked = ngtcp2_rtb_recv_ack(&pktns->rtb, fr, &conn->cstat, conn, pktns,
5442 pkt_ts, ts);
5443 if (num_acked < 0) {
5444 /* TODO assert this */
5445 assert(ngtcp2_err_is_fatal((int)num_acked));
5446 ngtcp2_frame_chain_list_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
5447 return (int)num_acked;
5448 }
5449
5450 if (num_acked == 0) {
5451 return 0;
5452 }
5453
5454 pktns->rtb.probe_pkt_left = 0;
5455
5456 if (cstat->pto_count &&
5457 (conn->server || (conn->flags & NGTCP2_CONN_FLAG_SERVER_ADDR_VERIFIED))) {
5458 /* Reset PTO count but no less than 2 to avoid frequent probe
5459 packet transmission. */
5460 cstat->pto_count = ngtcp2_min(cstat->pto_count, 2);
5461 }
5462
5463 ngtcp2_conn_set_loss_detection_timer(conn, ts);
5464
5465 return 0;
5466 }
5467
5468 /*
5469 * conn_assign_recved_ack_delay_unscaled assigns
5470 * fr->ack_delay_unscaled.
5471 */
assign_recved_ack_delay_unscaled(ngtcp2_ack * fr,uint64_t ack_delay_exponent)5472 static void assign_recved_ack_delay_unscaled(ngtcp2_ack *fr,
5473 uint64_t ack_delay_exponent) {
5474 fr->ack_delay_unscaled =
5475 fr->ack_delay * (1ULL << ack_delay_exponent) * NGTCP2_MICROSECONDS;
5476 }
5477
5478 /*
5479 * conn_recv_max_stream_data processes received MAX_STREAM_DATA frame
5480 * |fr|.
5481 *
5482 * This function returns 0 if it succeeds, or one of the following
5483 * negative error codes:
5484 *
5485 * NGTCP2_ERR_STREAM_STATE
5486 * Stream ID indicates that it is a local stream, and the local
5487 * endpoint has not initiated it; or stream is peer initiated
5488 * unidirectional stream.
5489 * NGTCP2_ERR_STREAM_LIMIT
5490 * Stream ID exceeds allowed limit.
5491 * NGTCP2_ERR_NOMEM
5492 * Out of memory.
5493 */
conn_recv_max_stream_data(ngtcp2_conn * conn,const ngtcp2_max_stream_data * fr)5494 static int conn_recv_max_stream_data(ngtcp2_conn *conn,
5495 const ngtcp2_max_stream_data *fr) {
5496 ngtcp2_strm *strm;
5497 ngtcp2_idtr *idtr;
5498 int local_stream = conn_local_stream(conn, fr->stream_id);
5499 int bidi = bidi_stream(fr->stream_id);
5500 int rv;
5501
5502 if (bidi) {
5503 if (local_stream) {
5504 if (conn->local.bidi.next_stream_id <= fr->stream_id) {
5505 return NGTCP2_ERR_STREAM_STATE;
5506 }
5507 } else if (conn->remote.bidi.max_streams <
5508 ngtcp2_ord_stream_id(fr->stream_id)) {
5509 return NGTCP2_ERR_STREAM_LIMIT;
5510 }
5511
5512 idtr = &conn->remote.bidi.idtr;
5513 } else {
5514 if (!local_stream || conn->local.uni.next_stream_id <= fr->stream_id) {
5515 return NGTCP2_ERR_STREAM_STATE;
5516 }
5517
5518 idtr = &conn->remote.uni.idtr;
5519 }
5520
5521 strm = ngtcp2_conn_find_stream(conn, fr->stream_id);
5522 if (strm == NULL) {
5523 if (local_stream) {
5524 /* Stream has been closed. */
5525 return 0;
5526 }
5527
5528 rv = ngtcp2_idtr_open(idtr, fr->stream_id);
5529 if (rv != 0) {
5530 if (ngtcp2_err_is_fatal(rv)) {
5531 return rv;
5532 }
5533 assert(rv == NGTCP2_ERR_STREAM_IN_USE);
5534 /* Stream has been closed. */
5535 return 0;
5536 }
5537
5538 strm = ngtcp2_objalloc_strm_get(&conn->strm_objalloc);
5539 if (strm == NULL) {
5540 return NGTCP2_ERR_NOMEM;
5541 }
5542 rv = ngtcp2_conn_init_stream(conn, strm, fr->stream_id, NULL);
5543 if (rv != 0) {
5544 ngtcp2_objalloc_strm_release(&conn->strm_objalloc, strm);
5545 return rv;
5546 }
5547
5548 rv = conn_call_stream_open(conn, strm);
5549 if (rv != 0) {
5550 return rv;
5551 }
5552 }
5553
5554 if (strm->tx.max_offset < fr->max_stream_data) {
5555 strm->tx.max_offset = fr->max_stream_data;
5556
5557 /* Don't call callback if stream is half-closed local */
5558 if (strm->flags & NGTCP2_STRM_FLAG_SHUT_WR) {
5559 return 0;
5560 }
5561
5562 rv = conn_call_extend_max_stream_data(conn, strm, fr->stream_id,
5563 fr->max_stream_data);
5564 if (rv != 0) {
5565 return rv;
5566 }
5567 }
5568
5569 return 0;
5570 }
5571
5572 /*
5573 * conn_recv_max_data processes received MAX_DATA frame |fr|.
5574 */
conn_recv_max_data(ngtcp2_conn * conn,const ngtcp2_max_data * fr)5575 static void conn_recv_max_data(ngtcp2_conn *conn, const ngtcp2_max_data *fr) {
5576 conn->tx.max_offset = ngtcp2_max(conn->tx.max_offset, fr->max_data);
5577 }
5578
5579 /*
5580 * conn_buffer_pkt buffers |pkt| of length |pktlen|, chaining it from
5581 * |*ppc|.
5582 *
5583 * This function returns 0 if it succeeds, or one of the following
5584 * negative error codes:
5585 *
5586 * NGTCP2_ERR_NOMEM
5587 * Out of memory.
5588 */
conn_buffer_pkt(ngtcp2_conn * conn,ngtcp2_pktns * pktns,const ngtcp2_path * path,const ngtcp2_pkt_info * pi,const uint8_t * pkt,size_t pktlen,size_t dgramlen,ngtcp2_tstamp ts)5589 static int conn_buffer_pkt(ngtcp2_conn *conn, ngtcp2_pktns *pktns,
5590 const ngtcp2_path *path, const ngtcp2_pkt_info *pi,
5591 const uint8_t *pkt, size_t pktlen, size_t dgramlen,
5592 ngtcp2_tstamp ts) {
5593 int rv;
5594 ngtcp2_pkt_chain **ppc = &pktns->rx.buffed_pkts, *pc;
5595 size_t i;
5596 for (i = 0; *ppc && i < NGTCP2_MAX_NUM_BUFFED_RX_PKTS;
5597 ppc = &(*ppc)->next, ++i)
5598 ;
5599
5600 if (i == NGTCP2_MAX_NUM_BUFFED_RX_PKTS) {
5601 return 0;
5602 }
5603
5604 rv =
5605 ngtcp2_pkt_chain_new(&pc, path, pi, pkt, pktlen, dgramlen, ts, conn->mem);
5606 if (rv != 0) {
5607 return rv;
5608 }
5609
5610 *ppc = pc;
5611
5612 return 0;
5613 }
5614
ensure_decrypt_buffer(ngtcp2_vec * vec,size_t n,size_t initial,const ngtcp2_mem * mem)5615 static int ensure_decrypt_buffer(ngtcp2_vec *vec, size_t n, size_t initial,
5616 const ngtcp2_mem *mem) {
5617 uint8_t *nbuf;
5618 size_t len;
5619
5620 if (vec->len >= n) {
5621 return 0;
5622 }
5623
5624 len = vec->len == 0 ? initial : vec->len * 2;
5625 for (; len < n; len *= 2)
5626 ;
5627 nbuf = ngtcp2_mem_realloc(mem, vec->base, len);
5628 if (nbuf == NULL) {
5629 return NGTCP2_ERR_NOMEM;
5630 }
5631 vec->base = nbuf;
5632 vec->len = len;
5633
5634 return 0;
5635 }
5636
5637 /*
5638 * conn_ensure_decrypt_hp_buffer ensures that
5639 * conn->crypto.decrypt_hp_buf has at least |n| bytes space.
5640 *
5641 * This function returns 0 if it succeeds, or one of the following
5642 * negative error codes:
5643 *
5644 * NGTCP2_ERR_NOMEM
5645 * Out of memory.
5646 */
conn_ensure_decrypt_hp_buffer(ngtcp2_conn * conn,size_t n)5647 static int conn_ensure_decrypt_hp_buffer(ngtcp2_conn *conn, size_t n) {
5648 return ensure_decrypt_buffer(&conn->crypto.decrypt_hp_buf, n, 256, conn->mem);
5649 }
5650
5651 /*
5652 * conn_ensure_decrypt_buffer ensures that conn->crypto.decrypt_buf
5653 * has at least |n| bytes space.
5654 *
5655 * This function returns 0 if it succeeds, or one of the following
5656 * negative error codes:
5657 *
5658 * NGTCP2_ERR_NOMEM
5659 * Out of memory.
5660 */
conn_ensure_decrypt_buffer(ngtcp2_conn * conn,size_t n)5661 static int conn_ensure_decrypt_buffer(ngtcp2_conn *conn, size_t n) {
5662 return ensure_decrypt_buffer(&conn->crypto.decrypt_buf, n, 2048, conn->mem);
5663 }
5664
5665 /*
5666 * decrypt_pkt decrypts the data pointed by |payload| whose length is
5667 * |payloadlen|, and writes plaintext data to the buffer pointed by
5668 * |dest|. The buffer pointed by |aad| is the Additional
5669 * Authenticated Data, and its length is |aadlen|. |pkt_num| is used
5670 * to create a nonce. |ckm| is the cryptographic key, and iv to use.
5671 * |decrypt| is a callback function which actually decrypts a packet.
5672 *
5673 * This function returns the number of bytes written in |dest| if it
5674 * succeeds, or one of the following negative error codes:
5675 *
5676 * NGTCP2_ERR_CALLBACK_FAILURE
5677 * User callback failed.
5678 * NGTCP2_ERR_DECRYPT
5679 * Failed to decrypt a packet.
5680 */
decrypt_pkt(uint8_t * dest,const ngtcp2_crypto_aead * aead,const uint8_t * payload,size_t payloadlen,const uint8_t * aad,size_t aadlen,int64_t pkt_num,ngtcp2_crypto_km * ckm,ngtcp2_decrypt decrypt)5681 static ngtcp2_ssize decrypt_pkt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
5682 const uint8_t *payload, size_t payloadlen,
5683 const uint8_t *aad, size_t aadlen,
5684 int64_t pkt_num, ngtcp2_crypto_km *ckm,
5685 ngtcp2_decrypt decrypt) {
5686 /* TODO nonce is limited to 64 bytes. */
5687 uint8_t nonce[64];
5688 int rv;
5689
5690 assert(sizeof(nonce) >= ckm->iv.len);
5691
5692 ngtcp2_crypto_create_nonce(nonce, ckm->iv.base, ckm->iv.len, pkt_num);
5693
5694 rv = decrypt(dest, aead, &ckm->aead_ctx, payload, payloadlen, nonce,
5695 ckm->iv.len, aad, aadlen);
5696
5697 if (rv != 0) {
5698 if (rv == NGTCP2_ERR_DECRYPT) {
5699 return rv;
5700 }
5701 return NGTCP2_ERR_CALLBACK_FAILURE;
5702 }
5703
5704 assert(payloadlen >= aead->max_overhead);
5705
5706 return (ngtcp2_ssize)(payloadlen - aead->max_overhead);
5707 }
5708
5709 /*
5710 * decrypt_hp decryptes packet header. The packet number starts at
5711 * |pkt| + |pkt_num_offset|. The entire plaintext QUIC packet header
5712 * will be written to the buffer pointed by |dest| whose capacity is
5713 * |destlen|.
5714 *
5715 * This function returns the number of bytes written to |dest|, or one
5716 * of the following negative error codes:
5717 *
5718 * NGTCP2_ERR_PROTO
5719 * Packet is badly formatted
5720 * NGTCP2_ERR_CALLBACK_FAILURE
5721 * User-defined callback function failed; or it does not return
5722 * expected result.
5723 */
5724 static ngtcp2_ssize
decrypt_hp(ngtcp2_pkt_hd * hd,uint8_t * dest,const ngtcp2_crypto_cipher * hp,const uint8_t * pkt,size_t pktlen,size_t pkt_num_offset,const ngtcp2_crypto_cipher_ctx * hp_ctx,ngtcp2_hp_mask hp_mask)5725 decrypt_hp(ngtcp2_pkt_hd *hd, uint8_t *dest, const ngtcp2_crypto_cipher *hp,
5726 const uint8_t *pkt, size_t pktlen, size_t pkt_num_offset,
5727 const ngtcp2_crypto_cipher_ctx *hp_ctx, ngtcp2_hp_mask hp_mask) {
5728 size_t sample_offset;
5729 uint8_t *p = dest;
5730 uint8_t mask[NGTCP2_HP_SAMPLELEN];
5731 size_t i;
5732 int rv;
5733
5734 assert(hp_mask);
5735
5736 if (pkt_num_offset + 4 + NGTCP2_HP_SAMPLELEN > pktlen) {
5737 return NGTCP2_ERR_PROTO;
5738 }
5739
5740 p = ngtcp2_cpymem(p, pkt, pkt_num_offset);
5741
5742 sample_offset = pkt_num_offset + 4;
5743
5744 rv = hp_mask(mask, hp, hp_ctx, pkt + sample_offset);
5745 if (rv != 0) {
5746 return NGTCP2_ERR_CALLBACK_FAILURE;
5747 }
5748
5749 if (hd->flags & NGTCP2_PKT_FLAG_LONG_FORM) {
5750 dest[0] = (uint8_t)(dest[0] ^ (mask[0] & 0x0f));
5751 } else {
5752 dest[0] = (uint8_t)(dest[0] ^ (mask[0] & 0x1f));
5753 if (dest[0] & NGTCP2_SHORT_KEY_PHASE_BIT) {
5754 hd->flags |= NGTCP2_PKT_FLAG_KEY_PHASE;
5755 }
5756 }
5757
5758 hd->pkt_numlen = (size_t)((dest[0] & NGTCP2_PKT_NUMLEN_MASK) + 1);
5759
5760 for (i = 0; i < hd->pkt_numlen; ++i) {
5761 *p++ = *(pkt + pkt_num_offset + i) ^ mask[i + 1];
5762 }
5763
5764 hd->pkt_num = ngtcp2_get_pkt_num(p - hd->pkt_numlen, hd->pkt_numlen);
5765
5766 return p - dest;
5767 }
5768
5769 /*
5770 * conn_emit_pending_crypto_data delivers pending stream data to the
5771 * application due to packet reordering.
5772 *
5773 * This function returns 0 if it succeeds, or one of the following
5774 * negative error codes:
5775 *
5776 * NGTCP2_ERR_CALLBACK_FAILURE
5777 * User callback failed
5778 * NGTCP2_ERR_CRYPTO
5779 * TLS backend reported error
5780 */
conn_emit_pending_crypto_data(ngtcp2_conn * conn,ngtcp2_crypto_level crypto_level,ngtcp2_strm * strm,uint64_t rx_offset)5781 static int conn_emit_pending_crypto_data(ngtcp2_conn *conn,
5782 ngtcp2_crypto_level crypto_level,
5783 ngtcp2_strm *strm,
5784 uint64_t rx_offset) {
5785 size_t datalen;
5786 const uint8_t *data;
5787 int rv;
5788 uint64_t offset;
5789
5790 if (!strm->rx.rob) {
5791 return 0;
5792 }
5793
5794 for (;;) {
5795 datalen = ngtcp2_rob_data_at(strm->rx.rob, &data, rx_offset);
5796 if (datalen == 0) {
5797 assert(rx_offset == ngtcp2_strm_rx_offset(strm));
5798 return 0;
5799 }
5800
5801 offset = rx_offset;
5802 rx_offset += datalen;
5803
5804 rv = conn_call_recv_crypto_data(conn, crypto_level, offset, data, datalen);
5805 if (rv != 0) {
5806 return rv;
5807 }
5808
5809 ngtcp2_rob_pop(strm->rx.rob, rx_offset - datalen, datalen);
5810 }
5811 }
5812
5813 /*
5814 * conn_recv_connection_close is called when CONNECTION_CLOSE or
5815 * APPLICATION_CLOSE frame is received.
5816 */
conn_recv_connection_close(ngtcp2_conn * conn,ngtcp2_connection_close * fr)5817 static int conn_recv_connection_close(ngtcp2_conn *conn,
5818 ngtcp2_connection_close *fr) {
5819 ngtcp2_connection_close_error *ccerr = &conn->rx.ccerr;
5820
5821 conn->state = NGTCP2_CS_DRAINING;
5822 if (fr->type == NGTCP2_FRAME_CONNECTION_CLOSE) {
5823 ccerr->type = NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT;
5824 } else {
5825 ccerr->type = NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_APPLICATION;
5826 }
5827 ccerr->error_code = fr->error_code;
5828 ccerr->frame_type = fr->frame_type;
5829
5830 if (!fr->reasonlen) {
5831 ccerr->reasonlen = 0;
5832
5833 return 0;
5834 }
5835
5836 if (ccerr->reason == NULL) {
5837 ccerr->reason = ngtcp2_mem_malloc(
5838 conn->mem, NGTCP2_CONNECTION_CLOSE_ERROR_MAX_REASONLEN);
5839 if (ccerr->reason == NULL) {
5840 return NGTCP2_ERR_NOMEM;
5841 }
5842 }
5843
5844 ccerr->reasonlen =
5845 ngtcp2_min(fr->reasonlen, NGTCP2_CONNECTION_CLOSE_ERROR_MAX_REASONLEN);
5846 ngtcp2_cpymem(ccerr->reason, fr->reason, ccerr->reasonlen);
5847
5848 return 0;
5849 }
5850
conn_recv_path_challenge(ngtcp2_conn * conn,const ngtcp2_path * path,ngtcp2_path_challenge * fr)5851 static void conn_recv_path_challenge(ngtcp2_conn *conn, const ngtcp2_path *path,
5852 ngtcp2_path_challenge *fr) {
5853 ngtcp2_path_challenge_entry *ent;
5854
5855 /* client only responds to PATH_CHALLENGE from the current path or
5856 path which client is migrating to. */
5857 if (!conn->server && !ngtcp2_path_eq(&conn->dcid.current.ps.path, path) &&
5858 (!conn->pv || !ngtcp2_path_eq(&conn->pv->dcid.ps.path, path))) {
5859 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
5860 "discard PATH_CHALLENGE from the path which is not current "
5861 "or endpoint is migrating to");
5862 return;
5863 }
5864
5865 ent = ngtcp2_ringbuf_push_front(&conn->rx.path_challenge.rb);
5866 ngtcp2_path_challenge_entry_init(ent, path, fr->data);
5867 }
5868
5869 /*
5870 * conn_reset_congestion_state resets congestion state.
5871 */
conn_reset_congestion_state(ngtcp2_conn * conn,ngtcp2_tstamp ts)5872 static void conn_reset_congestion_state(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
5873 conn_reset_conn_stat_cc(conn, &conn->cstat);
5874
5875 conn->cc.reset(&conn->cc, &conn->cstat, ts);
5876
5877 if (conn->hs_pktns) {
5878 ngtcp2_rtb_reset_cc_state(&conn->hs_pktns->rtb,
5879 conn->hs_pktns->tx.last_pkt_num + 1);
5880 }
5881 ngtcp2_rtb_reset_cc_state(&conn->pktns.rtb, conn->pktns.tx.last_pkt_num + 1);
5882 ngtcp2_rst_init(&conn->rst);
5883
5884 conn->tx.pacing.next_ts = UINT64_MAX;
5885 }
5886
conn_recv_path_response(ngtcp2_conn * conn,ngtcp2_path_response * fr,ngtcp2_tstamp ts)5887 static int conn_recv_path_response(ngtcp2_conn *conn, ngtcp2_path_response *fr,
5888 ngtcp2_tstamp ts) {
5889 int rv;
5890 ngtcp2_duration pto, timeout;
5891 ngtcp2_pv *pv = conn->pv, *npv;
5892 uint8_t ent_flags;
5893
5894 if (!pv) {
5895 return 0;
5896 }
5897
5898 rv = ngtcp2_pv_validate(pv, &ent_flags, fr->data);
5899 if (rv != 0) {
5900 assert(!ngtcp2_err_is_fatal(rv));
5901
5902 return 0;
5903 }
5904
5905 if (!(pv->flags & NGTCP2_PV_FLAG_DONT_CARE)) {
5906 if (!(pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE)) {
5907 if (pv->dcid.seq != conn->dcid.current.seq) {
5908 assert(conn->dcid.current.cid.datalen);
5909
5910 rv = conn_retire_dcid(conn, &conn->dcid.current, ts);
5911 if (rv != 0) {
5912 return rv;
5913 }
5914 ngtcp2_dcid_copy(&conn->dcid.current, &pv->dcid);
5915 }
5916 conn_reset_congestion_state(conn, ts);
5917 conn_reset_ecn_validation_state(conn);
5918 }
5919
5920 if (ngtcp2_path_eq(&pv->dcid.ps.path, &conn->dcid.current.ps.path)) {
5921 conn->dcid.current.flags |= NGTCP2_DCID_FLAG_PATH_VALIDATED;
5922 }
5923
5924 rv = conn_call_path_validation(conn, pv,
5925 NGTCP2_PATH_VALIDATION_RESULT_SUCCESS);
5926 if (rv != 0) {
5927 return rv;
5928 }
5929
5930 if (!conn->local.settings.no_pmtud) {
5931 ngtcp2_conn_stop_pmtud(conn);
5932
5933 if (!(pv->flags & NGTCP2_PV_ENTRY_FLAG_UNDERSIZED)) {
5934 rv = conn_start_pmtud(conn);
5935 if (rv != 0) {
5936 return rv;
5937 }
5938 }
5939 }
5940 }
5941
5942 if (pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) {
5943 pto = conn_compute_pto(conn, &conn->pktns);
5944 timeout = 3 * ngtcp2_max(pto, pv->fallback_pto);
5945
5946 if (ent_flags & NGTCP2_PV_ENTRY_FLAG_UNDERSIZED) {
5947 assert(conn->server);
5948
5949 /* Validate path again */
5950 rv = ngtcp2_pv_new(&npv, &pv->dcid, timeout,
5951 NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE |
5952 NGTCP2_PV_FLAG_MTU_PROBE,
5953 &conn->log, conn->mem);
5954 if (rv != 0) {
5955 return rv;
5956 }
5957
5958 npv->dcid.flags |= NGTCP2_DCID_FLAG_PATH_VALIDATED;
5959 ngtcp2_dcid_copy(&npv->fallback_dcid, &pv->fallback_dcid);
5960 npv->fallback_pto = pv->fallback_pto;
5961 } else {
5962 rv = ngtcp2_pv_new(&npv, &pv->fallback_dcid, timeout,
5963 NGTCP2_PV_FLAG_DONT_CARE, &conn->log, conn->mem);
5964 if (rv != 0) {
5965 return rv;
5966 }
5967 }
5968
5969 /* Unset the flag bit so that conn_stop_pv does not retire
5970 DCID. */
5971 pv->flags &= (uint8_t)~NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE;
5972
5973 rv = conn_stop_pv(conn, ts);
5974 if (rv != 0) {
5975 ngtcp2_pv_del(npv);
5976 return rv;
5977 }
5978
5979 conn->pv = npv;
5980
5981 return 0;
5982 }
5983
5984 return conn_stop_pv(conn, ts);
5985 }
5986
5987 /*
5988 * pkt_num_bits returns the number of bits available when packet
5989 * number is encoded in |pkt_numlen| bytes.
5990 */
pkt_num_bits(size_t pkt_numlen)5991 static size_t pkt_num_bits(size_t pkt_numlen) {
5992 switch (pkt_numlen) {
5993 case 1:
5994 return 8;
5995 case 2:
5996 return 16;
5997 case 3:
5998 return 24;
5999 case 4:
6000 return 32;
6001 default:
6002 assert(0);
6003 abort();
6004 }
6005 }
6006
6007 /*
6008 * pktns_pkt_num_is_duplicate returns nonzero if |pkt_num| is
6009 * duplicated packet number.
6010 */
pktns_pkt_num_is_duplicate(ngtcp2_pktns * pktns,int64_t pkt_num)6011 static int pktns_pkt_num_is_duplicate(ngtcp2_pktns *pktns, int64_t pkt_num) {
6012 return ngtcp2_gaptr_is_pushed(&pktns->rx.pngap, (uint64_t)pkt_num, 1);
6013 }
6014
6015 /*
6016 * pktns_commit_recv_pkt_num marks packet number |pkt_num| as
6017 * received.
6018 */
pktns_commit_recv_pkt_num(ngtcp2_pktns * pktns,int64_t pkt_num,int ack_eliciting,ngtcp2_tstamp ts)6019 static int pktns_commit_recv_pkt_num(ngtcp2_pktns *pktns, int64_t pkt_num,
6020 int ack_eliciting, ngtcp2_tstamp ts) {
6021 int rv;
6022
6023 if (ack_eliciting && pktns->rx.max_ack_eliciting_pkt_num + 1 != pkt_num) {
6024 ngtcp2_acktr_immediate_ack(&pktns->acktr);
6025 }
6026 if (pktns->rx.max_pkt_num < pkt_num) {
6027 pktns->rx.max_pkt_num = pkt_num;
6028 pktns->rx.max_pkt_ts = ts;
6029 }
6030 if (ack_eliciting && pktns->rx.max_ack_eliciting_pkt_num < pkt_num) {
6031 pktns->rx.max_ack_eliciting_pkt_num = pkt_num;
6032 }
6033
6034 rv = ngtcp2_gaptr_push(&pktns->rx.pngap, (uint64_t)pkt_num, 1);
6035 if (rv != 0) {
6036 return rv;
6037 }
6038
6039 if (ngtcp2_ksl_len(&pktns->rx.pngap.gap) > 256) {
6040 ngtcp2_gaptr_drop_first_gap(&pktns->rx.pngap);
6041 }
6042
6043 return 0;
6044 }
6045
6046 /*
6047 * verify_token verifies |hd| contains |token| in its token field. It
6048 * returns 0 if it succeeds, or NGTCP2_ERR_PROTO.
6049 */
verify_token(const ngtcp2_vec * token,const ngtcp2_pkt_hd * hd)6050 static int verify_token(const ngtcp2_vec *token, const ngtcp2_pkt_hd *hd) {
6051 if (token->len == hd->token.len &&
6052 ngtcp2_cmemeq(token->base, hd->token.base, token->len)) {
6053 return 0;
6054 }
6055 return NGTCP2_ERR_PROTO;
6056 }
6057
pktns_increase_ecn_counts(ngtcp2_pktns * pktns,const ngtcp2_pkt_info * pi)6058 static void pktns_increase_ecn_counts(ngtcp2_pktns *pktns,
6059 const ngtcp2_pkt_info *pi) {
6060 switch (pi->ecn & NGTCP2_ECN_MASK) {
6061 case NGTCP2_ECN_ECT_0:
6062 ++pktns->rx.ecn.ect0;
6063 break;
6064 case NGTCP2_ECN_ECT_1:
6065 ++pktns->rx.ecn.ect1;
6066 break;
6067 case NGTCP2_ECN_CE:
6068 ++pktns->rx.ecn.ce;
6069 break;
6070 }
6071 }
6072
6073 /*
6074 * vneg_other_versions_includes returns nonzero if |other_versions| of
6075 * length |other_versionslen| includes |version|. |other_versions| is
6076 * the wire image of other_versions field of version_information
6077 * transport parameter, and each version is encoded in network byte
6078 * order.
6079 */
vneg_other_versions_includes(const uint8_t * other_versions,size_t other_versionslen,uint32_t version)6080 static int vneg_other_versions_includes(const uint8_t *other_versions,
6081 size_t other_versionslen,
6082 uint32_t version) {
6083 size_t i;
6084
6085 assert(!(other_versionslen & 0x3));
6086
6087 if (other_versionslen == 0) {
6088 return 0;
6089 }
6090
6091 for (i = 0; i < other_versionslen; i += sizeof(uint32_t)) {
6092 if (version == ngtcp2_get_uint32(&other_versions[i])) {
6093 return 1;
6094 }
6095 }
6096
6097 return 0;
6098 }
6099
6100 static int conn_recv_crypto(ngtcp2_conn *conn, ngtcp2_crypto_level crypto_level,
6101 ngtcp2_strm *strm, const ngtcp2_crypto *fr);
6102
6103 static ngtcp2_ssize conn_recv_pkt(ngtcp2_conn *conn, const ngtcp2_path *path,
6104 const ngtcp2_pkt_info *pi, const uint8_t *pkt,
6105 size_t pktlen, size_t dgramlen,
6106 ngtcp2_tstamp pkt_ts, ngtcp2_tstamp ts);
6107
6108 static int conn_process_buffered_protected_pkt(ngtcp2_conn *conn,
6109 ngtcp2_pktns *pktns,
6110 ngtcp2_tstamp ts);
6111
6112 /*
6113 * conn_recv_handshake_pkt processes received packet |pkt| whose
6114 * length is |pktlen| during handshake period. The buffer pointed by
6115 * |pkt| might contain multiple packets. This function only processes
6116 * one packet. |pkt_ts| is the timestamp when packet is received.
6117 * |ts| should be the current time. Usually they are the same, but
6118 * for buffered packets, |pkt_ts| would be earlier than |ts|.
6119 *
6120 * This function returns the number of bytes it reads if it succeeds,
6121 * or one of the following negative error codes:
6122 *
6123 * NGTCP2_ERR_RECV_VERSION_NEGOTIATION
6124 * Version Negotiation packet is received.
6125 * NGTCP2_ERR_NOMEM
6126 * Out of memory.
6127 * NGTCP2_ERR_CALLBACK_FAILURE
6128 * User-defined callback function failed.
6129 * NGTCP2_ERR_DISCARD_PKT
6130 * Packet was discarded because plain text header was malformed;
6131 * or its payload could not be decrypted.
6132 * NGTCP2_ERR_FRAME_FORMAT
6133 * Frame is badly formatted
6134 * NGTCP2_ERR_ACK_FRAME
6135 * ACK frame is malformed.
6136 * NGTCP2_ERR_CRYPTO
6137 * TLS stack reported error.
6138 * NGTCP2_ERR_PROTO
6139 * Generic QUIC protocol error.
6140 *
6141 * In addition to the above error codes, error codes returned from
6142 * conn_recv_pkt are also returned.
6143 */
6144 static ngtcp2_ssize
conn_recv_handshake_pkt(ngtcp2_conn * conn,const ngtcp2_path * path,const ngtcp2_pkt_info * pi,const uint8_t * pkt,size_t pktlen,size_t dgramlen,ngtcp2_tstamp pkt_ts,ngtcp2_tstamp ts)6145 conn_recv_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_path *path,
6146 const ngtcp2_pkt_info *pi, const uint8_t *pkt,
6147 size_t pktlen, size_t dgramlen, ngtcp2_tstamp pkt_ts,
6148 ngtcp2_tstamp ts) {
6149 ngtcp2_ssize nread;
6150 ngtcp2_pkt_hd hd;
6151 ngtcp2_max_frame mfr;
6152 ngtcp2_frame *fr = &mfr.fr;
6153 int rv;
6154 int require_ack = 0;
6155 size_t hdpktlen;
6156 const uint8_t *payload;
6157 size_t payloadlen;
6158 ngtcp2_ssize nwrite;
6159 ngtcp2_crypto_aead *aead;
6160 ngtcp2_crypto_cipher *hp;
6161 ngtcp2_crypto_km *ckm;
6162 ngtcp2_crypto_cipher_ctx *hp_ctx;
6163 ngtcp2_hp_mask hp_mask;
6164 ngtcp2_decrypt decrypt;
6165 ngtcp2_pktns *pktns;
6166 ngtcp2_strm *crypto;
6167 ngtcp2_crypto_level crypto_level;
6168 int invalid_reserved_bits = 0;
6169
6170 if (pktlen == 0) {
6171 return 0;
6172 }
6173
6174 if (!(pkt[0] & NGTCP2_HEADER_FORM_BIT)) {
6175 if (conn->state == NGTCP2_CS_SERVER_INITIAL) {
6176 /* Ignore 1RTT packet unless server's first Handshake packet has
6177 been transmitted. */
6178 return (ngtcp2_ssize)pktlen;
6179 }
6180
6181 if (conn->pktns.crypto.rx.ckm) {
6182 return 0;
6183 }
6184
6185 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
6186 "buffering 1RTT packet len=%zu", pktlen);
6187
6188 rv = conn_buffer_pkt(conn, &conn->pktns, path, pi, pkt, pktlen, dgramlen,
6189 ts);
6190 if (rv != 0) {
6191 assert(ngtcp2_err_is_fatal(rv));
6192 return rv;
6193 }
6194 return (ngtcp2_ssize)pktlen;
6195 }
6196
6197 nread = ngtcp2_pkt_decode_hd_long(&hd, pkt, pktlen);
6198 if (nread < 0) {
6199 return NGTCP2_ERR_DISCARD_PKT;
6200 }
6201
6202 if (hd.type == NGTCP2_PKT_VERSION_NEGOTIATION) {
6203 hdpktlen = (size_t)nread;
6204
6205 ngtcp2_log_rx_pkt_hd(&conn->log, &hd);
6206
6207 if (conn->server) {
6208 return NGTCP2_ERR_DISCARD_PKT;
6209 }
6210
6211 /* Receiving Version Negotiation packet after getting Handshake
6212 packet from server is invalid. */
6213 if (conn->flags & NGTCP2_CONN_FLAG_CONN_ID_NEGOTIATED) {
6214 return NGTCP2_ERR_DISCARD_PKT;
6215 }
6216
6217 if (!ngtcp2_cid_eq(&conn->oscid, &hd.dcid)) {
6218 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6219 "packet was ignored because of mismatched DCID");
6220 return NGTCP2_ERR_DISCARD_PKT;
6221 }
6222
6223 if (!ngtcp2_cid_eq(&conn->dcid.current.cid, &hd.scid)) {
6224 /* Just discard invalid Version Negotiation packet */
6225 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6226 "packet was ignored because of mismatched SCID");
6227 return NGTCP2_ERR_DISCARD_PKT;
6228 }
6229 rv = conn_on_version_negotiation(conn, &hd, pkt + hdpktlen,
6230 pktlen - hdpktlen);
6231 if (rv != 0) {
6232 if (ngtcp2_err_is_fatal(rv)) {
6233 return rv;
6234 }
6235 return NGTCP2_ERR_DISCARD_PKT;
6236 }
6237 return NGTCP2_ERR_RECV_VERSION_NEGOTIATION;
6238 } else if (hd.type == NGTCP2_PKT_RETRY) {
6239 hdpktlen = (size_t)nread;
6240
6241 ngtcp2_log_rx_pkt_hd(&conn->log, &hd);
6242
6243 if (conn->server) {
6244 return NGTCP2_ERR_DISCARD_PKT;
6245 }
6246
6247 /* Receiving Retry packet after getting Initial packet from server
6248 is invalid. */
6249 if (conn->flags & NGTCP2_CONN_FLAG_CONN_ID_NEGOTIATED) {
6250 return NGTCP2_ERR_DISCARD_PKT;
6251 }
6252
6253 if (conn->client_chosen_version != hd.version) {
6254 return NGTCP2_ERR_DISCARD_PKT;
6255 }
6256
6257 rv = conn_on_retry(conn, &hd, hdpktlen, pkt, pktlen, ts);
6258 if (rv != 0) {
6259 if (ngtcp2_err_is_fatal(rv)) {
6260 return rv;
6261 }
6262 return NGTCP2_ERR_DISCARD_PKT;
6263 }
6264 return (ngtcp2_ssize)pktlen;
6265 }
6266
6267 if (pktlen < (size_t)nread + hd.len) {
6268 return NGTCP2_ERR_DISCARD_PKT;
6269 }
6270
6271 pktlen = (size_t)nread + hd.len;
6272
6273 if (!ngtcp2_is_supported_version(hd.version)) {
6274 return NGTCP2_ERR_DISCARD_PKT;
6275 }
6276
6277 if (conn->server) {
6278 if (hd.version != conn->client_chosen_version &&
6279 (!conn->negotiated_version || hd.version != conn->negotiated_version)) {
6280 return NGTCP2_ERR_DISCARD_PKT;
6281 }
6282 } else if (hd.version != conn->client_chosen_version &&
6283 conn->negotiated_version &&
6284 hd.version != conn->negotiated_version) {
6285 return NGTCP2_ERR_DISCARD_PKT;
6286 }
6287
6288 /* Quoted from spec: if subsequent packets of those types include a
6289 different Source Connection ID, they MUST be discarded. */
6290 if ((conn->flags & NGTCP2_CONN_FLAG_CONN_ID_NEGOTIATED) &&
6291 !ngtcp2_cid_eq(&conn->dcid.current.cid, &hd.scid)) {
6292 ngtcp2_log_rx_pkt_hd(&conn->log, &hd);
6293 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6294 "packet was ignored because of mismatched SCID");
6295 return NGTCP2_ERR_DISCARD_PKT;
6296 }
6297
6298 switch (hd.type) {
6299 case NGTCP2_PKT_0RTT:
6300 if (!conn->server) {
6301 return NGTCP2_ERR_DISCARD_PKT;
6302 }
6303
6304 if (hd.version != conn->client_chosen_version) {
6305 return NGTCP2_ERR_DISCARD_PKT;
6306 }
6307
6308 if (conn->flags & NGTCP2_CONN_FLAG_CONN_ID_NEGOTIATED) {
6309 if (conn->early.ckm) {
6310 ngtcp2_ssize nread2;
6311 /* TODO Avoid to parse header twice. */
6312 nread2 =
6313 conn_recv_pkt(conn, path, pi, pkt, pktlen, dgramlen, pkt_ts, ts);
6314 if (nread2 < 0) {
6315 return nread2;
6316 }
6317 }
6318
6319 /* Discard 0-RTT packet if we don't have a key to decrypt it. */
6320 return (ngtcp2_ssize)pktlen;
6321 }
6322
6323 /* Buffer re-ordered 0-RTT packet. */
6324 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
6325 "buffering 0-RTT packet len=%zu", pktlen);
6326
6327 rv = conn_buffer_pkt(conn, conn->in_pktns, path, pi, pkt, pktlen, dgramlen,
6328 ts);
6329 if (rv != 0) {
6330 assert(ngtcp2_err_is_fatal(rv));
6331 return rv;
6332 }
6333
6334 return (ngtcp2_ssize)pktlen;
6335 case NGTCP2_PKT_INITIAL:
6336 if (!conn->in_pktns) {
6337 ngtcp2_log_info(
6338 &conn->log, NGTCP2_LOG_EVENT_PKT,
6339 "Initial packet is discarded because keys have been discarded");
6340 return (ngtcp2_ssize)pktlen;
6341 }
6342
6343 assert(conn->in_pktns);
6344
6345 if (conn->server) {
6346 if (dgramlen < NGTCP2_MAX_UDP_PAYLOAD_SIZE) {
6347 ngtcp2_log_info(
6348 &conn->log, NGTCP2_LOG_EVENT_PKT,
6349 "Initial packet was ignored because it is included in UDP datagram "
6350 "less than %zu bytes: %zu bytes",
6351 NGTCP2_MAX_UDP_PAYLOAD_SIZE, dgramlen);
6352 return NGTCP2_ERR_DISCARD_PKT;
6353 }
6354 if (conn->local.settings.token.len) {
6355 rv = verify_token(&conn->local.settings.token, &hd);
6356 if (rv != 0) {
6357 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6358 "packet was ignored because token is invalid");
6359 return NGTCP2_ERR_DISCARD_PKT;
6360 }
6361 }
6362 if ((conn->flags & NGTCP2_CONN_FLAG_CONN_ID_NEGOTIATED) == 0) {
6363 /* Set rcid here so that it is available to callback. If this
6364 packet is discarded later in this function and no packet is
6365 processed in this connection attempt so far, connection
6366 will be dropped. */
6367 conn->rcid = hd.dcid;
6368
6369 rv = conn_call_recv_client_initial(conn, &hd.dcid);
6370 if (rv != 0) {
6371 return rv;
6372 }
6373 }
6374 } else {
6375 if (hd.token.len != 0) {
6376 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6377 "packet was ignored because token is not empty");
6378 return NGTCP2_ERR_DISCARD_PKT;
6379 }
6380
6381 if (hd.version != conn->client_chosen_version &&
6382 !conn->negotiated_version && conn->vneg.version != hd.version) {
6383 if (!vneg_other_versions_includes(conn->vneg.other_versions,
6384 conn->vneg.other_versionslen,
6385 hd.version)) {
6386 return NGTCP2_ERR_DISCARD_PKT;
6387 }
6388
6389 /* Install new Initial keys using QUIC version = hd.version */
6390 rv = conn_call_version_negotiation(
6391 conn, hd.version,
6392 (conn->flags & NGTCP2_CONN_FLAG_RECV_RETRY)
6393 ? &conn->dcid.current.cid
6394 : &conn->rcid);
6395 if (rv != 0) {
6396 return rv;
6397 }
6398
6399 assert(conn->vneg.version == hd.version);
6400 }
6401 }
6402
6403 pktns = conn->in_pktns;
6404 crypto = &pktns->crypto.strm;
6405 crypto_level = NGTCP2_CRYPTO_LEVEL_INITIAL;
6406
6407 if (hd.version == conn->client_chosen_version) {
6408 ckm = pktns->crypto.rx.ckm;
6409 hp_ctx = &pktns->crypto.rx.hp_ctx;
6410 } else {
6411 assert(conn->vneg.version == hd.version);
6412
6413 ckm = conn->vneg.rx.ckm;
6414 hp_ctx = &conn->vneg.rx.hp_ctx;
6415 }
6416
6417 break;
6418 case NGTCP2_PKT_HANDSHAKE:
6419 if (hd.version != conn->negotiated_version) {
6420 return NGTCP2_ERR_DISCARD_PKT;
6421 }
6422
6423 if (!conn->hs_pktns->crypto.rx.ckm) {
6424 if (conn->server) {
6425 ngtcp2_log_info(
6426 &conn->log, NGTCP2_LOG_EVENT_PKT,
6427 "Handshake packet at this point is unexpected and discarded");
6428 return (ngtcp2_ssize)pktlen;
6429 }
6430 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
6431 "buffering Handshake packet len=%zu", pktlen);
6432
6433 rv = conn_buffer_pkt(conn, conn->hs_pktns, path, pi, pkt, pktlen,
6434 dgramlen, ts);
6435 if (rv != 0) {
6436 assert(ngtcp2_err_is_fatal(rv));
6437 return rv;
6438 }
6439 return (ngtcp2_ssize)pktlen;
6440 }
6441
6442 pktns = conn->hs_pktns;
6443 crypto = &pktns->crypto.strm;
6444 crypto_level = NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
6445 ckm = pktns->crypto.rx.ckm;
6446 hp_ctx = &pktns->crypto.rx.hp_ctx;
6447
6448 break;
6449 default:
6450 /* unknown packet type */
6451 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6452 "packet was ignored because of unknown packet type");
6453 return (ngtcp2_ssize)pktlen;
6454 }
6455
6456 hp_mask = conn->callbacks.hp_mask;
6457 decrypt = conn->callbacks.decrypt;
6458 aead = &pktns->crypto.ctx.aead;
6459 hp = &pktns->crypto.ctx.hp;
6460
6461 assert(ckm);
6462 assert(hp_mask);
6463 assert(decrypt);
6464
6465 rv = conn_ensure_decrypt_hp_buffer(conn, (size_t)nread + 4);
6466 if (rv != 0) {
6467 return rv;
6468 }
6469
6470 nwrite = decrypt_hp(&hd, conn->crypto.decrypt_hp_buf.base, hp, pkt, pktlen,
6471 (size_t)nread, hp_ctx, hp_mask);
6472 if (nwrite < 0) {
6473 if (ngtcp2_err_is_fatal((int)nwrite)) {
6474 return nwrite;
6475 }
6476 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6477 "could not decrypt packet number");
6478 return NGTCP2_ERR_DISCARD_PKT;
6479 }
6480
6481 hdpktlen = (size_t)nwrite;
6482 payload = pkt + hdpktlen;
6483 payloadlen = hd.len - hd.pkt_numlen;
6484
6485 hd.pkt_num = ngtcp2_pkt_adjust_pkt_num(pktns->rx.max_pkt_num, hd.pkt_num,
6486 pkt_num_bits(hd.pkt_numlen));
6487 if (hd.pkt_num > NGTCP2_MAX_PKT_NUM) {
6488 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6489 "pkn=%" PRId64 " is greater than maximum pkn", hd.pkt_num);
6490 return NGTCP2_ERR_DISCARD_PKT;
6491 }
6492
6493 ngtcp2_log_rx_pkt_hd(&conn->log, &hd);
6494
6495 rv = ngtcp2_pkt_verify_reserved_bits(conn->crypto.decrypt_hp_buf.base[0]);
6496 if (rv != 0) {
6497 invalid_reserved_bits = 1;
6498
6499 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6500 "packet has incorrect reserved bits");
6501
6502 /* Will return error after decrypting payload */
6503 }
6504
6505 if (pktns_pkt_num_is_duplicate(pktns, hd.pkt_num)) {
6506 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6507 "packet was discarded because of duplicated packet number");
6508 return NGTCP2_ERR_DISCARD_PKT;
6509 }
6510
6511 rv = conn_ensure_decrypt_buffer(conn, payloadlen);
6512 if (rv != 0) {
6513 return rv;
6514 }
6515
6516 nwrite = decrypt_pkt(conn->crypto.decrypt_buf.base, aead, payload, payloadlen,
6517 conn->crypto.decrypt_hp_buf.base, hdpktlen, hd.pkt_num,
6518 ckm, decrypt);
6519 if (nwrite < 0) {
6520 if (ngtcp2_err_is_fatal((int)nwrite)) {
6521 return nwrite;
6522 }
6523 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6524 "could not decrypt packet payload");
6525 return NGTCP2_ERR_DISCARD_PKT;
6526 }
6527
6528 if (invalid_reserved_bits) {
6529 return NGTCP2_ERR_PROTO;
6530 }
6531
6532 if (!conn->server && hd.version != conn->client_chosen_version &&
6533 !conn->negotiated_version) {
6534 conn->negotiated_version = hd.version;
6535
6536 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
6537 "the negotiated version is 0x%08x",
6538 conn->negotiated_version);
6539 }
6540
6541 payload = conn->crypto.decrypt_buf.base;
6542 payloadlen = (size_t)nwrite;
6543
6544 switch (hd.type) {
6545 case NGTCP2_PKT_INITIAL:
6546 if (!conn->server || ((conn->flags & NGTCP2_CONN_FLAG_CONN_ID_NEGOTIATED) &&
6547 !ngtcp2_cid_eq(&conn->rcid, &hd.dcid))) {
6548 rv = conn_verify_dcid(conn, NULL, &hd);
6549 if (rv != 0) {
6550 if (ngtcp2_err_is_fatal(rv)) {
6551 return rv;
6552 }
6553 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6554 "packet was ignored because of mismatched DCID");
6555 return NGTCP2_ERR_DISCARD_PKT;
6556 }
6557 }
6558 break;
6559 case NGTCP2_PKT_HANDSHAKE:
6560 rv = conn_verify_dcid(conn, NULL, &hd);
6561 if (rv != 0) {
6562 if (ngtcp2_err_is_fatal(rv)) {
6563 return rv;
6564 }
6565 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6566 "packet was ignored because of mismatched DCID");
6567 return NGTCP2_ERR_DISCARD_PKT;
6568 }
6569 break;
6570 default:
6571 assert(0);
6572 }
6573
6574 if (payloadlen == 0) {
6575 /* QUIC packet must contain at least one frame */
6576 if (hd.type == NGTCP2_PKT_INITIAL) {
6577 return NGTCP2_ERR_DISCARD_PKT;
6578 }
6579 return NGTCP2_ERR_PROTO;
6580 }
6581
6582 if (hd.type == NGTCP2_PKT_INITIAL &&
6583 !(conn->flags & NGTCP2_CONN_FLAG_CONN_ID_NEGOTIATED)) {
6584 conn->flags |= NGTCP2_CONN_FLAG_CONN_ID_NEGOTIATED;
6585 if (!conn->server) {
6586 conn->dcid.current.cid = hd.scid;
6587 }
6588 }
6589
6590 ngtcp2_qlog_pkt_received_start(&conn->qlog);
6591
6592 for (; payloadlen;) {
6593 nread = ngtcp2_pkt_decode_frame(fr, payload, payloadlen);
6594 if (nread < 0) {
6595 return nread;
6596 }
6597
6598 payload += nread;
6599 payloadlen -= (size_t)nread;
6600
6601 switch (fr->type) {
6602 case NGTCP2_FRAME_ACK:
6603 case NGTCP2_FRAME_ACK_ECN:
6604 fr->ack.ack_delay = 0;
6605 fr->ack.ack_delay_unscaled = 0;
6606 break;
6607 }
6608
6609 ngtcp2_log_rx_fr(&conn->log, &hd, fr);
6610
6611 switch (fr->type) {
6612 case NGTCP2_FRAME_ACK:
6613 case NGTCP2_FRAME_ACK_ECN:
6614 if (!conn->server && hd.type == NGTCP2_PKT_HANDSHAKE) {
6615 conn->flags |= NGTCP2_CONN_FLAG_SERVER_ADDR_VERIFIED;
6616 }
6617 rv = conn_recv_ack(conn, pktns, &fr->ack, pkt_ts, ts);
6618 if (rv != 0) {
6619 return rv;
6620 }
6621 break;
6622 case NGTCP2_FRAME_PADDING:
6623 break;
6624 case NGTCP2_FRAME_CRYPTO:
6625 if (!conn->server && !conn->negotiated_version &&
6626 ngtcp2_vec_len(fr->crypto.data, fr->crypto.datacnt)) {
6627 conn->negotiated_version = hd.version;
6628
6629 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
6630 "the negotiated version is 0x%08x",
6631 conn->negotiated_version);
6632 }
6633
6634 rv = conn_recv_crypto(conn, crypto_level, crypto, &fr->crypto);
6635 if (rv != 0) {
6636 return rv;
6637 }
6638 require_ack = 1;
6639 break;
6640 case NGTCP2_FRAME_CONNECTION_CLOSE:
6641 rv = conn_recv_connection_close(conn, &fr->connection_close);
6642 if (rv != 0) {
6643 return rv;
6644 }
6645 break;
6646 case NGTCP2_FRAME_PING:
6647 require_ack = 1;
6648 break;
6649 default:
6650 return NGTCP2_ERR_PROTO;
6651 }
6652
6653 ngtcp2_qlog_write_frame(&conn->qlog, fr);
6654 }
6655
6656 if (conn->server && hd.type == NGTCP2_PKT_HANDSHAKE) {
6657 /* Successful processing of Handshake packet from client verifies
6658 source address. */
6659 conn->dcid.current.flags |= NGTCP2_DCID_FLAG_PATH_VALIDATED;
6660 }
6661
6662 ngtcp2_qlog_pkt_received_end(&conn->qlog, &hd, pktlen);
6663
6664 rv = pktns_commit_recv_pkt_num(pktns, hd.pkt_num, require_ack, pkt_ts);
6665 if (rv != 0) {
6666 return rv;
6667 }
6668
6669 pktns_increase_ecn_counts(pktns, pi);
6670
6671 /* TODO Initial and Handshake are always acknowledged without
6672 delay. */
6673 if (require_ack &&
6674 (++pktns->acktr.rx_npkt >= conn->local.settings.ack_thresh ||
6675 (pi->ecn & NGTCP2_ECN_MASK) == NGTCP2_ECN_CE)) {
6676 ngtcp2_acktr_immediate_ack(&pktns->acktr);
6677 }
6678
6679 rv = ngtcp2_conn_sched_ack(conn, &pktns->acktr, hd.pkt_num, require_ack,
6680 pkt_ts);
6681 if (rv != 0) {
6682 return rv;
6683 }
6684
6685 conn_restart_timer_on_read(conn, ts);
6686
6687 ngtcp2_qlog_metrics_updated(&conn->qlog, &conn->cstat);
6688
6689 return conn->state == NGTCP2_CS_DRAINING ? NGTCP2_ERR_DRAINING
6690 : (ngtcp2_ssize)pktlen;
6691 }
6692
is_unrecoverable_error(int liberr)6693 static int is_unrecoverable_error(int liberr) {
6694 switch (liberr) {
6695 case NGTCP2_ERR_CRYPTO:
6696 case NGTCP2_ERR_REQUIRED_TRANSPORT_PARAM:
6697 case NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM:
6698 case NGTCP2_ERR_TRANSPORT_PARAM:
6699 case NGTCP2_ERR_VERSION_NEGOTIATION_FAILURE:
6700 return 1;
6701 }
6702
6703 return 0;
6704 }
6705
6706 /*
6707 * conn_recv_handshake_cpkt processes compound packet during
6708 * handshake. The buffer pointed by |pkt| might contain multiple
6709 * packets. The 1RTT packet must be the last one because it does not
6710 * have payload length field.
6711 *
6712 * This function returns the same error code returned by
6713 * conn_recv_handshake_pkt.
6714 */
conn_recv_handshake_cpkt(ngtcp2_conn * conn,const ngtcp2_path * path,const ngtcp2_pkt_info * pi,const uint8_t * pkt,size_t pktlen,ngtcp2_tstamp ts)6715 static ngtcp2_ssize conn_recv_handshake_cpkt(ngtcp2_conn *conn,
6716 const ngtcp2_path *path,
6717 const ngtcp2_pkt_info *pi,
6718 const uint8_t *pkt, size_t pktlen,
6719 ngtcp2_tstamp ts) {
6720 ngtcp2_ssize nread;
6721 size_t dgramlen = pktlen;
6722 const uint8_t *origpkt = pkt;
6723 uint32_t version;
6724
6725 if (ngtcp2_path_eq(&conn->dcid.current.ps.path, path)) {
6726 conn->dcid.current.bytes_recv += dgramlen;
6727 }
6728
6729 while (pktlen) {
6730 nread =
6731 conn_recv_handshake_pkt(conn, path, pi, pkt, pktlen, dgramlen, ts, ts);
6732 if (nread < 0) {
6733 if (ngtcp2_err_is_fatal((int)nread)) {
6734 return nread;
6735 }
6736
6737 if (nread == NGTCP2_ERR_DRAINING) {
6738 return NGTCP2_ERR_DRAINING;
6739 }
6740
6741 if ((pkt[0] & NGTCP2_HEADER_FORM_BIT) && pktlen > 4) {
6742 /* Not a Version Negotiation packet */
6743 version = ngtcp2_get_uint32(&pkt[1]);
6744 if (ngtcp2_pkt_get_type_long(version, pkt[0]) == NGTCP2_PKT_INITIAL) {
6745 if (conn->server) {
6746 if (is_unrecoverable_error((int)nread)) {
6747 /* If server gets crypto error from TLS stack, it is
6748 unrecoverable, therefore drop connection. */
6749 return nread;
6750 }
6751
6752 /* If server discards first Initial, then drop connection
6753 state. This is because SCID in packet might be corrupted
6754 and the current connection state might wrongly discard
6755 valid packet and prevent the handshake from
6756 completing. */
6757 if (conn->in_pktns && conn->in_pktns->rx.max_pkt_num == -1) {
6758 return NGTCP2_ERR_DROP_CONN;
6759 }
6760
6761 return (ngtcp2_ssize)dgramlen;
6762 }
6763 /* client */
6764 if (is_unrecoverable_error((int)nread)) {
6765 /* If client gets crypto error from TLS stack, it is
6766 unrecoverable, therefore drop connection. */
6767 return nread;
6768 }
6769 return (ngtcp2_ssize)dgramlen;
6770 }
6771 }
6772
6773 if (nread == NGTCP2_ERR_DISCARD_PKT) {
6774 return (ngtcp2_ssize)dgramlen;
6775 }
6776
6777 return nread;
6778 }
6779
6780 if (nread == 0) {
6781 assert(!(pkt[0] & NGTCP2_HEADER_FORM_BIT));
6782 return pkt - origpkt;
6783 }
6784
6785 assert(pktlen >= (size_t)nread);
6786 pkt += nread;
6787 pktlen -= (size_t)nread;
6788
6789 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
6790 "read packet %td left %zu", nread, pktlen);
6791 }
6792
6793 return (ngtcp2_ssize)dgramlen;
6794 }
6795
ngtcp2_conn_init_stream(ngtcp2_conn * conn,ngtcp2_strm * strm,int64_t stream_id,void * stream_user_data)6796 int ngtcp2_conn_init_stream(ngtcp2_conn *conn, ngtcp2_strm *strm,
6797 int64_t stream_id, void *stream_user_data) {
6798 int rv;
6799 uint64_t max_rx_offset;
6800 uint64_t max_tx_offset;
6801 int local_stream = conn_local_stream(conn, stream_id);
6802
6803 assert(conn->remote.transport_params);
6804
6805 if (bidi_stream(stream_id)) {
6806 if (local_stream) {
6807 max_rx_offset =
6808 conn->local.transport_params.initial_max_stream_data_bidi_local;
6809 max_tx_offset =
6810 conn->remote.transport_params->initial_max_stream_data_bidi_remote;
6811 } else {
6812 max_rx_offset =
6813 conn->local.transport_params.initial_max_stream_data_bidi_remote;
6814 max_tx_offset =
6815 conn->remote.transport_params->initial_max_stream_data_bidi_local;
6816 }
6817 } else if (local_stream) {
6818 max_rx_offset = 0;
6819 max_tx_offset = conn->remote.transport_params->initial_max_stream_data_uni;
6820 } else {
6821 max_rx_offset = conn->local.transport_params.initial_max_stream_data_uni;
6822 max_tx_offset = 0;
6823 }
6824
6825 ngtcp2_strm_init(strm, stream_id, NGTCP2_STRM_FLAG_NONE, max_rx_offset,
6826 max_tx_offset, stream_user_data, &conn->frc_objalloc,
6827 conn->mem);
6828
6829 rv = ngtcp2_map_insert(&conn->strms, (ngtcp2_map_key_type)strm->stream_id,
6830 strm);
6831 if (rv != 0) {
6832 assert(rv != NGTCP2_ERR_INVALID_ARGUMENT);
6833 goto fail;
6834 }
6835
6836 return 0;
6837
6838 fail:
6839 ngtcp2_strm_free(strm);
6840 return rv;
6841 }
6842
6843 /*
6844 * conn_emit_pending_stream_data passes buffered ordered stream data
6845 * to the application. |rx_offset| is the first offset to deliver to
6846 * the application. This function assumes that the data up to
6847 * |rx_offset| has been delivered already. This function only passes
6848 * the ordered data without any gap. If there is a gap, it stops
6849 * providing the data to the application, and returns.
6850 *
6851 * This function returns 0 if it succeeds, or one of the following
6852 * negative error codes:
6853 *
6854 * NGTCP2_ERR_CALLBACK_FAILURE
6855 * User callback failed.
6856 * NGTCP2_ERR_NOMEM
6857 * Out of memory.
6858 */
conn_emit_pending_stream_data(ngtcp2_conn * conn,ngtcp2_strm * strm,uint64_t rx_offset)6859 static int conn_emit_pending_stream_data(ngtcp2_conn *conn, ngtcp2_strm *strm,
6860 uint64_t rx_offset) {
6861 size_t datalen;
6862 const uint8_t *data;
6863 int rv;
6864 uint64_t offset;
6865 uint32_t sdflags;
6866 int handshake_completed = conn_is_handshake_completed(conn);
6867
6868 if (!strm->rx.rob) {
6869 return 0;
6870 }
6871
6872 for (;;) {
6873 /* Stop calling callback if application has called
6874 ngtcp2_conn_shutdown_stream_read() inside the callback.
6875 Because it doubly counts connection window. */
6876 if (strm->flags & NGTCP2_STRM_FLAG_STOP_SENDING) {
6877 return 0;
6878 }
6879
6880 datalen = ngtcp2_rob_data_at(strm->rx.rob, &data, rx_offset);
6881 if (datalen == 0) {
6882 assert(rx_offset == ngtcp2_strm_rx_offset(strm));
6883 return 0;
6884 }
6885
6886 offset = rx_offset;
6887 rx_offset += datalen;
6888
6889 sdflags = NGTCP2_STREAM_DATA_FLAG_NONE;
6890 if ((strm->flags & NGTCP2_STRM_FLAG_SHUT_RD) &&
6891 rx_offset == strm->rx.last_offset) {
6892 sdflags |= NGTCP2_STREAM_DATA_FLAG_FIN;
6893 }
6894 if (!handshake_completed) {
6895 sdflags |= NGTCP2_STREAM_DATA_FLAG_EARLY;
6896 }
6897
6898 rv = conn_call_recv_stream_data(conn, strm, sdflags, offset, data, datalen);
6899 if (rv != 0) {
6900 return rv;
6901 }
6902
6903 ngtcp2_rob_pop(strm->rx.rob, rx_offset - datalen, datalen);
6904 }
6905 }
6906
6907 /*
6908 * conn_recv_crypto is called when CRYPTO frame |fr| is received.
6909 * |rx_offset_base| is the offset in the entire TLS handshake stream.
6910 * fr->offset specifies the offset in each encryption level.
6911 * |max_rx_offset| is, if it is nonzero, the maximum offset in the
6912 * entire TLS handshake stream that |fr| can carry. |crypto_level| is
6913 * the encryption level where this data is received.
6914 *
6915 * This function returns 0 if it succeeds, or one of the following
6916 * negative error codes:
6917 *
6918 * NGTCP2_ERR_PROTO
6919 * CRYPTO frame has invalid offset.
6920 * NGTCP2_ERR_NOMEM
6921 * Out of memory.
6922 * NGTCP2_ERR_CRYPTO
6923 * TLS stack reported error.
6924 * NGTCP2_ERR_FRAME_ENCODING
6925 * The end offset exceeds the maximum value.
6926 * NGTCP2_ERR_CALLBACK_FAILURE
6927 * User-defined callback function failed.
6928 */
conn_recv_crypto(ngtcp2_conn * conn,ngtcp2_crypto_level crypto_level,ngtcp2_strm * crypto,const ngtcp2_crypto * fr)6929 static int conn_recv_crypto(ngtcp2_conn *conn, ngtcp2_crypto_level crypto_level,
6930 ngtcp2_strm *crypto, const ngtcp2_crypto *fr) {
6931 uint64_t fr_end_offset;
6932 uint64_t rx_offset;
6933 int rv;
6934
6935 if (fr->datacnt == 0) {
6936 return 0;
6937 }
6938
6939 fr_end_offset = fr->offset + fr->data[0].len;
6940
6941 if (NGTCP2_MAX_VARINT < fr_end_offset) {
6942 return NGTCP2_ERR_FRAME_ENCODING;
6943 }
6944
6945 rx_offset = ngtcp2_strm_rx_offset(crypto);
6946
6947 if (fr_end_offset <= rx_offset) {
6948 if (conn->server &&
6949 !(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_EARLY_RETRANSMIT) &&
6950 crypto_level == NGTCP2_CRYPTO_LEVEL_INITIAL) {
6951 /* recovery draft: Speeding Up Handshake Completion
6952
6953 When a server receives an Initial packet containing duplicate
6954 CRYPTO data, it can assume the client did not receive all of
6955 the server's CRYPTO data sent in Initial packets, or the
6956 client's estimated RTT is too small. ... To speed up
6957 handshake completion under these conditions, an endpoint MAY
6958 send a packet containing unacknowledged CRYPTO data earlier
6959 than the PTO expiry, subject to address validation limits;
6960 ... */
6961 conn->flags |= NGTCP2_CONN_FLAG_HANDSHAKE_EARLY_RETRANSMIT;
6962 conn->in_pktns->rtb.probe_pkt_left = 1;
6963 conn->hs_pktns->rtb.probe_pkt_left = 1;
6964 }
6965 return 0;
6966 }
6967
6968 crypto->rx.last_offset = ngtcp2_max(crypto->rx.last_offset, fr_end_offset);
6969
6970 /* TODO Before dispatching incoming data to TLS stack, make sure
6971 that previous data in previous encryption level has been
6972 completely sent to TLS stack. Usually, if data is left, it is an
6973 error because key is generated after consuming all data in the
6974 previous encryption level. */
6975 if (fr->offset <= rx_offset) {
6976 size_t ncut = (size_t)(rx_offset - fr->offset);
6977 const uint8_t *data = fr->data[0].base + ncut;
6978 size_t datalen = fr->data[0].len - ncut;
6979 uint64_t offset = rx_offset;
6980
6981 rx_offset += datalen;
6982 rv = ngtcp2_strm_update_rx_offset(crypto, rx_offset);
6983 if (rv != 0) {
6984 return rv;
6985 }
6986
6987 rv = conn_call_recv_crypto_data(conn, crypto_level, offset, data, datalen);
6988 if (rv != 0) {
6989 return rv;
6990 }
6991
6992 rv = conn_emit_pending_crypto_data(conn, crypto_level, crypto, rx_offset);
6993 if (rv != 0) {
6994 return rv;
6995 }
6996
6997 return 0;
6998 }
6999
7000 if (fr_end_offset - rx_offset > NGTCP2_MAX_REORDERED_CRYPTO_DATA) {
7001 return NGTCP2_ERR_CRYPTO_BUFFER_EXCEEDED;
7002 }
7003
7004 return ngtcp2_strm_recv_reordering(crypto, fr->data[0].base, fr->data[0].len,
7005 fr->offset);
7006 }
7007
7008 /*
7009 * conn_max_data_violated returns nonzero if receiving |datalen|
7010 * violates connection flow control on local endpoint.
7011 */
conn_max_data_violated(ngtcp2_conn * conn,uint64_t datalen)7012 static int conn_max_data_violated(ngtcp2_conn *conn, uint64_t datalen) {
7013 return conn->rx.max_offset - conn->rx.offset < datalen;
7014 }
7015
7016 /*
7017 * conn_recv_stream is called when STREAM frame |fr| is received.
7018 *
7019 * This function returns 0 if it succeeds, or one of the following
7020 * negative error codes:
7021 *
7022 * NGTCP2_ERR_STREAM_STATE
7023 * STREAM frame is received for a local stream which is not
7024 * initiated; or STREAM frame is received for a local
7025 * unidirectional stream
7026 * NGTCP2_ERR_STREAM_LIMIT
7027 * STREAM frame has remote stream ID which is strictly greater
7028 * than the allowed limit.
7029 * NGTCP2_ERR_NOMEM
7030 * Out of memory.
7031 * NGTCP2_ERR_CALLBACK_FAILURE
7032 * User-defined callback function failed.
7033 * NGTCP2_ERR_FLOW_CONTROL
7034 * Flow control limit is violated; or the end offset of stream
7035 * data is beyond the NGTCP2_MAX_VARINT.
7036 * NGTCP2_ERR_FINAL_SIZE
7037 * STREAM frame has strictly larger end offset than it is
7038 * permitted.
7039 */
conn_recv_stream(ngtcp2_conn * conn,const ngtcp2_stream * fr)7040 static int conn_recv_stream(ngtcp2_conn *conn, const ngtcp2_stream *fr) {
7041 int rv;
7042 ngtcp2_strm *strm;
7043 ngtcp2_idtr *idtr;
7044 uint64_t rx_offset, fr_end_offset;
7045 int local_stream;
7046 int bidi;
7047 uint64_t datalen = ngtcp2_vec_len(fr->data, fr->datacnt);
7048 uint32_t sdflags = NGTCP2_STREAM_DATA_FLAG_NONE;
7049
7050 local_stream = conn_local_stream(conn, fr->stream_id);
7051 bidi = bidi_stream(fr->stream_id);
7052
7053 if (bidi) {
7054 if (local_stream) {
7055 if (conn->local.bidi.next_stream_id <= fr->stream_id) {
7056 return NGTCP2_ERR_STREAM_STATE;
7057 }
7058 } else if (conn->remote.bidi.max_streams <
7059 ngtcp2_ord_stream_id(fr->stream_id)) {
7060 return NGTCP2_ERR_STREAM_LIMIT;
7061 }
7062
7063 idtr = &conn->remote.bidi.idtr;
7064 } else {
7065 if (local_stream) {
7066 return NGTCP2_ERR_STREAM_STATE;
7067 }
7068 if (conn->remote.uni.max_streams < ngtcp2_ord_stream_id(fr->stream_id)) {
7069 return NGTCP2_ERR_STREAM_LIMIT;
7070 }
7071
7072 idtr = &conn->remote.uni.idtr;
7073 }
7074
7075 if (NGTCP2_MAX_VARINT - datalen < fr->offset) {
7076 return NGTCP2_ERR_FLOW_CONTROL;
7077 }
7078
7079 strm = ngtcp2_conn_find_stream(conn, fr->stream_id);
7080 if (strm == NULL) {
7081 if (local_stream) {
7082 /* TODO The stream has been closed. This should be responded
7083 with RESET_STREAM, or simply ignored. */
7084 return 0;
7085 }
7086
7087 rv = ngtcp2_idtr_open(idtr, fr->stream_id);
7088 if (rv != 0) {
7089 if (ngtcp2_err_is_fatal(rv)) {
7090 return rv;
7091 }
7092 assert(rv == NGTCP2_ERR_STREAM_IN_USE);
7093 /* TODO The stream has been closed. This should be responded
7094 with RESET_STREAM, or simply ignored. */
7095 return 0;
7096 }
7097
7098 strm = ngtcp2_objalloc_strm_get(&conn->strm_objalloc);
7099 if (strm == NULL) {
7100 return NGTCP2_ERR_NOMEM;
7101 }
7102 /* TODO Perhaps, call new_stream callback? */
7103 rv = ngtcp2_conn_init_stream(conn, strm, fr->stream_id, NULL);
7104 if (rv != 0) {
7105 ngtcp2_objalloc_strm_release(&conn->strm_objalloc, strm);
7106 return rv;
7107 }
7108
7109 rv = conn_call_stream_open(conn, strm);
7110 if (rv != 0) {
7111 return rv;
7112 }
7113
7114 if (!bidi) {
7115 ngtcp2_strm_shutdown(strm, NGTCP2_STRM_FLAG_SHUT_WR);
7116 }
7117 }
7118
7119 fr_end_offset = fr->offset + datalen;
7120
7121 if (strm->rx.max_offset < fr_end_offset) {
7122 return NGTCP2_ERR_FLOW_CONTROL;
7123 }
7124
7125 if (strm->rx.last_offset < fr_end_offset) {
7126 uint64_t len = fr_end_offset - strm->rx.last_offset;
7127
7128 if (conn_max_data_violated(conn, len)) {
7129 return NGTCP2_ERR_FLOW_CONTROL;
7130 }
7131
7132 conn->rx.offset += len;
7133
7134 if (strm->flags & NGTCP2_STRM_FLAG_STOP_SENDING) {
7135 ngtcp2_conn_extend_max_offset(conn, len);
7136 }
7137 }
7138
7139 rx_offset = ngtcp2_strm_rx_offset(strm);
7140
7141 if (fr->fin) {
7142 if (strm->flags & NGTCP2_STRM_FLAG_SHUT_RD) {
7143 if (strm->rx.last_offset != fr_end_offset) {
7144 return NGTCP2_ERR_FINAL_SIZE;
7145 }
7146
7147 if (strm->flags & NGTCP2_STRM_FLAG_RECV_RST) {
7148 return 0;
7149 }
7150
7151 if (rx_offset == fr_end_offset) {
7152 return 0;
7153 }
7154 } else if (strm->rx.last_offset > fr_end_offset) {
7155 return NGTCP2_ERR_FINAL_SIZE;
7156 } else {
7157 strm->rx.last_offset = fr_end_offset;
7158
7159 ngtcp2_strm_shutdown(strm, NGTCP2_STRM_FLAG_SHUT_RD);
7160 }
7161 } else {
7162 if ((strm->flags & NGTCP2_STRM_FLAG_SHUT_RD) &&
7163 strm->rx.last_offset < fr_end_offset) {
7164 return NGTCP2_ERR_FINAL_SIZE;
7165 }
7166
7167 strm->rx.last_offset = ngtcp2_max(strm->rx.last_offset, fr_end_offset);
7168
7169 if (fr_end_offset <= rx_offset) {
7170 return 0;
7171 }
7172
7173 if (strm->flags & NGTCP2_STRM_FLAG_RECV_RST) {
7174 return 0;
7175 }
7176 }
7177
7178 if (fr->offset <= rx_offset) {
7179 size_t ncut = (size_t)(rx_offset - fr->offset);
7180 uint64_t offset = rx_offset;
7181 const uint8_t *data;
7182 int fin;
7183
7184 if (fr->datacnt) {
7185 data = fr->data[0].base + ncut;
7186 datalen -= ncut;
7187
7188 rx_offset += datalen;
7189 rv = ngtcp2_strm_update_rx_offset(strm, rx_offset);
7190 if (rv != 0) {
7191 return rv;
7192 }
7193 } else {
7194 data = NULL;
7195 datalen = 0;
7196 }
7197
7198 if (strm->flags & NGTCP2_STRM_FLAG_STOP_SENDING) {
7199 return ngtcp2_conn_close_stream_if_shut_rdwr(conn, strm);
7200 }
7201
7202 fin = (strm->flags & NGTCP2_STRM_FLAG_SHUT_RD) &&
7203 rx_offset == strm->rx.last_offset;
7204
7205 if (fin || datalen) {
7206 if (fin) {
7207 sdflags |= NGTCP2_STREAM_DATA_FLAG_FIN;
7208 }
7209 if (!conn_is_handshake_completed(conn)) {
7210 sdflags |= NGTCP2_STREAM_DATA_FLAG_EARLY;
7211 }
7212 rv = conn_call_recv_stream_data(conn, strm, sdflags, offset, data,
7213 (size_t)datalen);
7214 if (rv != 0) {
7215 return rv;
7216 }
7217
7218 rv = conn_emit_pending_stream_data(conn, strm, rx_offset);
7219 if (rv != 0) {
7220 return rv;
7221 }
7222 }
7223 } else if (fr->datacnt) {
7224 rv = ngtcp2_strm_recv_reordering(strm, fr->data[0].base, fr->data[0].len,
7225 fr->offset);
7226 if (rv != 0) {
7227 return rv;
7228 }
7229 }
7230 return ngtcp2_conn_close_stream_if_shut_rdwr(conn, strm);
7231 }
7232
7233 /*
7234 * conn_reset_stream adds RESET_STREAM frame to the transmission
7235 * queue.
7236 *
7237 * This function returns 0 if it succeeds, or one of the following
7238 * negative error codes:
7239 *
7240 * NGTCP2_ERR_NOMEM
7241 * Out of memory.
7242 */
conn_reset_stream(ngtcp2_conn * conn,ngtcp2_strm * strm,uint64_t app_error_code)7243 static int conn_reset_stream(ngtcp2_conn *conn, ngtcp2_strm *strm,
7244 uint64_t app_error_code) {
7245 int rv;
7246 ngtcp2_frame_chain *frc;
7247 ngtcp2_pktns *pktns = &conn->pktns;
7248
7249 rv = ngtcp2_frame_chain_objalloc_new(&frc, &conn->frc_objalloc);
7250 if (rv != 0) {
7251 return rv;
7252 }
7253
7254 frc->fr.type = NGTCP2_FRAME_RESET_STREAM;
7255 frc->fr.reset_stream.stream_id = strm->stream_id;
7256 frc->fr.reset_stream.app_error_code = app_error_code;
7257 frc->fr.reset_stream.final_size = strm->tx.offset;
7258
7259 /* TODO This prepends RESET_STREAM to pktns->tx.frq. */
7260 frc->next = pktns->tx.frq;
7261 pktns->tx.frq = frc;
7262
7263 return 0;
7264 }
7265
7266 /*
7267 * conn_stop_sending adds STOP_SENDING frame to the transmission
7268 * queue.
7269 *
7270 * This function returns 0 if it succeeds, or one of the following
7271 * negative error codes:
7272 *
7273 * NGTCP2_ERR_NOMEM
7274 * Out of memory.
7275 */
conn_stop_sending(ngtcp2_conn * conn,ngtcp2_strm * strm,uint64_t app_error_code)7276 static int conn_stop_sending(ngtcp2_conn *conn, ngtcp2_strm *strm,
7277 uint64_t app_error_code) {
7278 int rv;
7279 ngtcp2_frame_chain *frc;
7280 ngtcp2_pktns *pktns = &conn->pktns;
7281
7282 rv = ngtcp2_frame_chain_objalloc_new(&frc, &conn->frc_objalloc);
7283 if (rv != 0) {
7284 return rv;
7285 }
7286
7287 frc->fr.type = NGTCP2_FRAME_STOP_SENDING;
7288 frc->fr.stop_sending.stream_id = strm->stream_id;
7289 frc->fr.stop_sending.app_error_code = app_error_code;
7290
7291 /* TODO This prepends STOP_SENDING to pktns->tx.frq. */
7292 frc->next = pktns->tx.frq;
7293 pktns->tx.frq = frc;
7294
7295 return 0;
7296 }
7297
7298 /*
7299 * handle_max_remote_streams_extension extends
7300 * |*punsent_max_remote_streams| by |n| if a condition allows it.
7301 */
7302 static void
handle_max_remote_streams_extension(uint64_t * punsent_max_remote_streams,size_t n)7303 handle_max_remote_streams_extension(uint64_t *punsent_max_remote_streams,
7304 size_t n) {
7305 if (
7306 #if SIZE_MAX > UINT32_MAX
7307 NGTCP2_MAX_STREAMS < n ||
7308 #endif /* SIZE_MAX > UINT32_MAX */
7309 *punsent_max_remote_streams > (uint64_t)(NGTCP2_MAX_STREAMS - n)) {
7310 *punsent_max_remote_streams = NGTCP2_MAX_STREAMS;
7311 } else {
7312 *punsent_max_remote_streams += n;
7313 }
7314 }
7315
7316 /*
7317 * conn_recv_reset_stream is called when RESET_STREAM |fr| is
7318 * received.
7319 *
7320 * This function returns 0 if it succeeds, or one of the following
7321 * negative error codes:
7322 *
7323 * NGTCP2_ERR_STREAM_STATE
7324 * RESET_STREAM frame is received to the local stream which is not
7325 * initiated.
7326 * NGTCP2_ERR_STREAM_LIMIT
7327 * RESET_STREAM frame has remote stream ID which is strictly
7328 * greater than the allowed limit.
7329 * NGTCP2_ERR_PROTO
7330 * RESET_STREAM frame is received to the local unidirectional
7331 * stream
7332 * NGTCP2_ERR_NOMEM
7333 * Out of memory.
7334 * NGTCP2_ERR_CALLBACK_FAILURE
7335 * User-defined callback function failed.
7336 * NGTCP2_ERR_FLOW_CONTROL
7337 * Flow control limit is violated; or the final size is beyond the
7338 * NGTCP2_MAX_VARINT.
7339 * NGTCP2_ERR_FINAL_SIZE
7340 * The final offset is strictly larger than it is permitted.
7341 */
conn_recv_reset_stream(ngtcp2_conn * conn,const ngtcp2_reset_stream * fr)7342 static int conn_recv_reset_stream(ngtcp2_conn *conn,
7343 const ngtcp2_reset_stream *fr) {
7344 ngtcp2_strm *strm;
7345 int local_stream = conn_local_stream(conn, fr->stream_id);
7346 int bidi = bidi_stream(fr->stream_id);
7347 uint64_t datalen;
7348 ngtcp2_idtr *idtr;
7349 int rv;
7350
7351 /* TODO share this piece of code */
7352 if (bidi) {
7353 if (local_stream) {
7354 if (conn->local.bidi.next_stream_id <= fr->stream_id) {
7355 return NGTCP2_ERR_STREAM_STATE;
7356 }
7357 } else if (conn->remote.bidi.max_streams <
7358 ngtcp2_ord_stream_id(fr->stream_id)) {
7359 return NGTCP2_ERR_STREAM_LIMIT;
7360 }
7361
7362 idtr = &conn->remote.bidi.idtr;
7363 } else {
7364 if (local_stream) {
7365 return NGTCP2_ERR_PROTO;
7366 }
7367 if (conn->remote.uni.max_streams < ngtcp2_ord_stream_id(fr->stream_id)) {
7368 return NGTCP2_ERR_STREAM_LIMIT;
7369 }
7370
7371 idtr = &conn->remote.uni.idtr;
7372 }
7373
7374 if (NGTCP2_MAX_VARINT < fr->final_size) {
7375 return NGTCP2_ERR_FLOW_CONTROL;
7376 }
7377
7378 strm = ngtcp2_conn_find_stream(conn, fr->stream_id);
7379 if (strm == NULL) {
7380 if (local_stream) {
7381 return 0;
7382 }
7383
7384 rv = ngtcp2_idtr_open(idtr, fr->stream_id);
7385 if (rv != 0) {
7386 if (ngtcp2_err_is_fatal(rv)) {
7387 return rv;
7388 }
7389 assert(rv == NGTCP2_ERR_STREAM_IN_USE);
7390 return 0;
7391 }
7392
7393 if (conn_initial_stream_rx_offset(conn, fr->stream_id) < fr->final_size ||
7394 conn_max_data_violated(conn, fr->final_size)) {
7395 return NGTCP2_ERR_FLOW_CONTROL;
7396 }
7397
7398 /* Stream is reset before we create ngtcp2_strm object. */
7399 conn->rx.offset += fr->final_size;
7400 ngtcp2_conn_extend_max_offset(conn, fr->final_size);
7401
7402 rv = conn_call_stream_reset(conn, fr->stream_id, fr->final_size,
7403 fr->app_error_code, NULL);
7404 if (rv != 0) {
7405 return rv;
7406 }
7407
7408 /* There will be no activity in this stream because we got
7409 RESET_STREAM and don't write stream data any further. This
7410 effectively allows another new stream for peer. */
7411 if (bidi) {
7412 handle_max_remote_streams_extension(&conn->remote.bidi.unsent_max_streams,
7413 1);
7414 } else {
7415 handle_max_remote_streams_extension(&conn->remote.uni.unsent_max_streams,
7416 1);
7417 }
7418
7419 return 0;
7420 }
7421
7422 if ((strm->flags & NGTCP2_STRM_FLAG_SHUT_RD)) {
7423 if (strm->rx.last_offset != fr->final_size) {
7424 return NGTCP2_ERR_FINAL_SIZE;
7425 }
7426 } else if (strm->rx.last_offset > fr->final_size) {
7427 return NGTCP2_ERR_FINAL_SIZE;
7428 }
7429
7430 if (strm->flags & NGTCP2_STRM_FLAG_RECV_RST) {
7431 return 0;
7432 }
7433
7434 if (strm->rx.max_offset < fr->final_size) {
7435 return NGTCP2_ERR_FLOW_CONTROL;
7436 }
7437
7438 datalen = fr->final_size - strm->rx.last_offset;
7439
7440 if (conn_max_data_violated(conn, datalen)) {
7441 return NGTCP2_ERR_FLOW_CONTROL;
7442 }
7443
7444 rv = conn_call_stream_reset(conn, fr->stream_id, fr->final_size,
7445 fr->app_error_code, strm->stream_user_data);
7446 if (rv != 0) {
7447 return rv;
7448 }
7449
7450 /* Extend connection flow control window for the amount of data
7451 which are not passed to application. */
7452 if (!(strm->flags & NGTCP2_STRM_FLAG_STOP_SENDING)) {
7453 ngtcp2_conn_extend_max_offset(conn, strm->rx.last_offset -
7454 ngtcp2_strm_rx_offset(strm));
7455 }
7456
7457 conn->rx.offset += datalen;
7458 ngtcp2_conn_extend_max_offset(conn, datalen);
7459
7460 strm->rx.last_offset = fr->final_size;
7461 strm->flags |= NGTCP2_STRM_FLAG_SHUT_RD | NGTCP2_STRM_FLAG_RECV_RST;
7462
7463 ngtcp2_strm_set_app_error_code(strm, fr->app_error_code);
7464
7465 return ngtcp2_conn_close_stream_if_shut_rdwr(conn, strm);
7466 }
7467
7468 /*
7469 * conn_recv_stop_sending is called when STOP_SENDING |fr| is received.
7470 *
7471 * This function returns 0 if it succeeds, or one of the following
7472 * negative error codes:
7473 *
7474 * NGTCP2_ERR_STREAM_STATE
7475 * STOP_SENDING frame is received for a local stream which is not
7476 * initiated; or STOP_SENDING frame is received for a local
7477 * unidirectional stream.
7478 * NGTCP2_ERR_STREAM_LIMIT
7479 * STOP_SENDING frame has remote stream ID which is strictly
7480 * greater than the allowed limit.
7481 * NGTCP2_ERR_NOMEM
7482 * Out of memory.
7483 * NGTCP2_ERR_CALLBACK_FAILURE
7484 * User-defined callback function failed.
7485 */
conn_recv_stop_sending(ngtcp2_conn * conn,const ngtcp2_stop_sending * fr)7486 static int conn_recv_stop_sending(ngtcp2_conn *conn,
7487 const ngtcp2_stop_sending *fr) {
7488 int rv;
7489 ngtcp2_strm *strm;
7490 ngtcp2_idtr *idtr;
7491 int local_stream = conn_local_stream(conn, fr->stream_id);
7492 int bidi = bidi_stream(fr->stream_id);
7493
7494 if (bidi) {
7495 if (local_stream) {
7496 if (conn->local.bidi.next_stream_id <= fr->stream_id) {
7497 return NGTCP2_ERR_STREAM_STATE;
7498 }
7499 } else if (conn->remote.bidi.max_streams <
7500 ngtcp2_ord_stream_id(fr->stream_id)) {
7501 return NGTCP2_ERR_STREAM_LIMIT;
7502 }
7503
7504 idtr = &conn->remote.bidi.idtr;
7505 } else {
7506 if (!local_stream || conn->local.uni.next_stream_id <= fr->stream_id) {
7507 return NGTCP2_ERR_STREAM_STATE;
7508 }
7509
7510 idtr = &conn->remote.uni.idtr;
7511 }
7512
7513 strm = ngtcp2_conn_find_stream(conn, fr->stream_id);
7514 if (strm == NULL) {
7515 if (local_stream) {
7516 return 0;
7517 }
7518 rv = ngtcp2_idtr_open(idtr, fr->stream_id);
7519 if (rv != 0) {
7520 if (ngtcp2_err_is_fatal(rv)) {
7521 return rv;
7522 }
7523 assert(rv == NGTCP2_ERR_STREAM_IN_USE);
7524 return 0;
7525 }
7526
7527 /* Frame is received reset before we create ngtcp2_strm
7528 object. */
7529 strm = ngtcp2_objalloc_strm_get(&conn->strm_objalloc);
7530 if (strm == NULL) {
7531 return NGTCP2_ERR_NOMEM;
7532 }
7533 rv = ngtcp2_conn_init_stream(conn, strm, fr->stream_id, NULL);
7534 if (rv != 0) {
7535 ngtcp2_objalloc_strm_release(&conn->strm_objalloc, strm);
7536 return rv;
7537 }
7538
7539 rv = conn_call_stream_open(conn, strm);
7540 if (rv != 0) {
7541 return rv;
7542 }
7543 }
7544
7545 ngtcp2_strm_set_app_error_code(strm, fr->app_error_code);
7546
7547 /* No RESET_STREAM is required if we have sent FIN and all data have
7548 been acknowledged. */
7549 if (!ngtcp2_strm_is_all_tx_data_fin_acked(strm) &&
7550 !(strm->flags & NGTCP2_STRM_FLAG_SENT_RST)) {
7551 rv = conn_reset_stream(conn, strm, fr->app_error_code);
7552 if (rv != 0) {
7553 return rv;
7554 }
7555 }
7556
7557 strm->flags |= NGTCP2_STRM_FLAG_SHUT_WR | NGTCP2_STRM_FLAG_SENT_RST;
7558
7559 if (ngtcp2_strm_is_tx_queued(strm) && !ngtcp2_strm_streamfrq_empty(strm)) {
7560 assert(conn->tx.strmq_nretrans);
7561 --conn->tx.strmq_nretrans;
7562 }
7563
7564 ngtcp2_strm_streamfrq_clear(strm);
7565
7566 return ngtcp2_conn_close_stream_if_shut_rdwr(conn, strm);
7567 }
7568
7569 /*
7570 * check_stateless_reset returns nonzero if Stateless Reset |sr|
7571 * coming via |path| is valid against |dcid|.
7572 */
check_stateless_reset(const ngtcp2_dcid * dcid,const ngtcp2_path * path,const ngtcp2_pkt_stateless_reset * sr)7573 static int check_stateless_reset(const ngtcp2_dcid *dcid,
7574 const ngtcp2_path *path,
7575 const ngtcp2_pkt_stateless_reset *sr) {
7576 return ngtcp2_path_eq(&dcid->ps.path, path) &&
7577 ngtcp2_dcid_verify_stateless_reset_token(
7578 dcid, sr->stateless_reset_token) == 0;
7579 }
7580
7581 /*
7582 * conn_on_stateless_reset decodes Stateless Reset from the buffer
7583 * pointed by |payload| whose length is |payloadlen|. |payload|
7584 * should start after first byte of packet.
7585 *
7586 * If Stateless Reset is decoded, and the Stateless Reset Token is
7587 * validated, the connection is closed.
7588 *
7589 * This function returns 0 if it succeeds, or one of the following
7590 * negative error codes:
7591 *
7592 * NGTCP2_ERR_INVALID_ARGUMENT
7593 * Could not decode Stateless Reset; or Stateless Reset Token does
7594 * not match; or No stateless reset token is available.
7595 * NGTCP2_ERR_CALLBACK_FAILURE
7596 * User callback failed.
7597 */
conn_on_stateless_reset(ngtcp2_conn * conn,const ngtcp2_path * path,const uint8_t * payload,size_t payloadlen)7598 static int conn_on_stateless_reset(ngtcp2_conn *conn, const ngtcp2_path *path,
7599 const uint8_t *payload, size_t payloadlen) {
7600 int rv = 1;
7601 ngtcp2_pv *pv = conn->pv;
7602 ngtcp2_dcid *dcid;
7603 ngtcp2_pkt_stateless_reset sr;
7604 size_t len, i;
7605
7606 rv = ngtcp2_pkt_decode_stateless_reset(&sr, payload, payloadlen);
7607 if (rv != 0) {
7608 return rv;
7609 }
7610
7611 if (!check_stateless_reset(&conn->dcid.current, path, &sr) &&
7612 (!pv || (!check_stateless_reset(&pv->dcid, path, &sr) &&
7613 (!(pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) ||
7614 !check_stateless_reset(&pv->fallback_dcid, path, &sr))))) {
7615 len = ngtcp2_ringbuf_len(&conn->dcid.retired.rb);
7616 for (i = 0; i < len; ++i) {
7617 dcid = ngtcp2_ringbuf_get(&conn->dcid.retired.rb, i);
7618 if (check_stateless_reset(dcid, path, &sr)) {
7619 break;
7620 }
7621 }
7622
7623 if (i == len) {
7624 len = ngtcp2_ringbuf_len(&conn->dcid.bound.rb);
7625 for (i = 0; i < len; ++i) {
7626 dcid = ngtcp2_ringbuf_get(&conn->dcid.bound.rb, i);
7627 if (check_stateless_reset(dcid, path, &sr)) {
7628 break;
7629 }
7630 }
7631
7632 if (i == len) {
7633 return NGTCP2_ERR_INVALID_ARGUMENT;
7634 }
7635 }
7636 }
7637
7638 conn->state = NGTCP2_CS_DRAINING;
7639
7640 ngtcp2_log_rx_sr(&conn->log, &sr);
7641
7642 ngtcp2_qlog_stateless_reset_pkt_received(&conn->qlog, &sr);
7643
7644 return conn_call_recv_stateless_reset(conn, &sr);
7645 }
7646
7647 /*
7648 * conn_recv_max_streams processes the incoming MAX_STREAMS frame
7649 * |fr|.
7650 *
7651 * This function returns 0 if it succeeds, or one of the following
7652 * negative error codes:
7653 *
7654 * NGTCP2_ERR_CALLBACK_FAILURE
7655 * User callback failed.
7656 * NGTCP2_ERR_FRAME_ENCODING
7657 * The maximum streams field exceeds the maximum value.
7658 */
conn_recv_max_streams(ngtcp2_conn * conn,const ngtcp2_max_streams * fr)7659 static int conn_recv_max_streams(ngtcp2_conn *conn,
7660 const ngtcp2_max_streams *fr) {
7661 uint64_t n;
7662
7663 if (fr->max_streams > NGTCP2_MAX_STREAMS) {
7664 return NGTCP2_ERR_FRAME_ENCODING;
7665 }
7666
7667 n = ngtcp2_min(fr->max_streams, NGTCP2_MAX_STREAMS);
7668
7669 if (fr->type == NGTCP2_FRAME_MAX_STREAMS_BIDI) {
7670 if (conn->local.bidi.max_streams < n) {
7671 conn->local.bidi.max_streams = n;
7672 return conn_call_extend_max_local_streams_bidi(conn, n);
7673 }
7674 return 0;
7675 }
7676
7677 if (conn->local.uni.max_streams < n) {
7678 conn->local.uni.max_streams = n;
7679 return conn_call_extend_max_local_streams_uni(conn, n);
7680 }
7681 return 0;
7682 }
7683
conn_retire_dcid_prior_to(ngtcp2_conn * conn,ngtcp2_ringbuf * rb,uint64_t retire_prior_to)7684 static int conn_retire_dcid_prior_to(ngtcp2_conn *conn, ngtcp2_ringbuf *rb,
7685 uint64_t retire_prior_to) {
7686 size_t i;
7687 ngtcp2_dcid *dcid, *last;
7688 int rv;
7689
7690 for (i = 0; i < ngtcp2_ringbuf_len(rb);) {
7691 dcid = ngtcp2_ringbuf_get(rb, i);
7692 if (dcid->seq >= retire_prior_to) {
7693 ++i;
7694 continue;
7695 }
7696
7697 rv = conn_retire_dcid_seq(conn, dcid->seq);
7698 if (rv != 0) {
7699 return rv;
7700 }
7701
7702 if (i == 0) {
7703 ngtcp2_ringbuf_pop_front(rb);
7704 continue;
7705 }
7706
7707 if (i == ngtcp2_ringbuf_len(rb) - 1) {
7708 ngtcp2_ringbuf_pop_back(rb);
7709 break;
7710 }
7711
7712 last = ngtcp2_ringbuf_get(rb, ngtcp2_ringbuf_len(rb) - 1);
7713 ngtcp2_dcid_copy(dcid, last);
7714 ngtcp2_ringbuf_pop_back(rb);
7715 }
7716
7717 return 0;
7718 }
7719
7720 /*
7721 * conn_recv_new_connection_id processes the incoming
7722 * NEW_CONNECTION_ID frame |fr|.
7723 *
7724 * This function returns 0 if it succeeds, or one of the following
7725 * negative error codes:
7726 *
7727 * NGTCP2_ERR_PROTO
7728 * |fr| has the duplicated sequence number with different CID or
7729 * token; or DCID is zero-length.
7730 */
conn_recv_new_connection_id(ngtcp2_conn * conn,const ngtcp2_new_connection_id * fr)7731 static int conn_recv_new_connection_id(ngtcp2_conn *conn,
7732 const ngtcp2_new_connection_id *fr) {
7733 size_t i, len;
7734 ngtcp2_dcid *dcid;
7735 ngtcp2_pv *pv = conn->pv;
7736 int rv;
7737 int found = 0;
7738 size_t extra_dcid = 0;
7739
7740 if (conn->dcid.current.cid.datalen == 0) {
7741 return NGTCP2_ERR_PROTO;
7742 }
7743
7744 if (fr->retire_prior_to > fr->seq) {
7745 return NGTCP2_ERR_FRAME_ENCODING;
7746 }
7747
7748 rv = ngtcp2_dcid_verify_uniqueness(&conn->dcid.current, fr->seq, &fr->cid,
7749 fr->stateless_reset_token);
7750 if (rv != 0) {
7751 return rv;
7752 }
7753 if (ngtcp2_cid_eq(&conn->dcid.current.cid, &fr->cid)) {
7754 found = 1;
7755 }
7756
7757 if (pv) {
7758 rv = ngtcp2_dcid_verify_uniqueness(&pv->dcid, fr->seq, &fr->cid,
7759 fr->stateless_reset_token);
7760 if (rv != 0) {
7761 return rv;
7762 }
7763 if (ngtcp2_cid_eq(&pv->dcid.cid, &fr->cid)) {
7764 found = 1;
7765 }
7766 }
7767
7768 len = ngtcp2_ringbuf_len(&conn->dcid.bound.rb);
7769
7770 for (i = 0; i < len; ++i) {
7771 dcid = ngtcp2_ringbuf_get(&conn->dcid.bound.rb, i);
7772 rv = ngtcp2_dcid_verify_uniqueness(dcid, fr->seq, &fr->cid,
7773 fr->stateless_reset_token);
7774 if (rv != 0) {
7775 return NGTCP2_ERR_PROTO;
7776 }
7777 if (ngtcp2_cid_eq(&dcid->cid, &fr->cid)) {
7778 found = 1;
7779 }
7780 }
7781
7782 len = ngtcp2_ringbuf_len(&conn->dcid.unused.rb);
7783
7784 for (i = 0; i < len; ++i) {
7785 dcid = ngtcp2_ringbuf_get(&conn->dcid.unused.rb, i);
7786 rv = ngtcp2_dcid_verify_uniqueness(dcid, fr->seq, &fr->cid,
7787 fr->stateless_reset_token);
7788 if (rv != 0) {
7789 return NGTCP2_ERR_PROTO;
7790 }
7791 if (ngtcp2_cid_eq(&dcid->cid, &fr->cid)) {
7792 found = 1;
7793 }
7794 }
7795
7796 if (conn->dcid.retire_prior_to < fr->retire_prior_to) {
7797 conn->dcid.retire_prior_to = fr->retire_prior_to;
7798
7799 rv = conn_retire_dcid_prior_to(conn, &conn->dcid.bound.rb,
7800 fr->retire_prior_to);
7801 if (rv != 0) {
7802 return rv;
7803 }
7804
7805 rv = conn_retire_dcid_prior_to(conn, &conn->dcid.unused.rb,
7806 conn->dcid.retire_prior_to);
7807 if (rv != 0) {
7808 return rv;
7809 }
7810 } else if (fr->seq < conn->dcid.retire_prior_to) {
7811 /* If packets are reordered, we might have retire_prior_to which
7812 is larger than fr->seq.
7813
7814 A malicious peer might send crafted NEW_CONNECTION_ID to force
7815 local endpoint to create lots of RETIRE_CONNECTION_ID frames.
7816 For example, a peer might send seq = 50000 and retire_prior_to
7817 = 50000. Then send NEW_CONNECTION_ID frames with seq <
7818 50000. */
7819 return conn_retire_dcid_seq(conn, fr->seq);
7820 }
7821
7822 if (found) {
7823 return 0;
7824 }
7825
7826 if (ngtcp2_gaptr_is_pushed(&conn->dcid.seqgap, fr->seq, 1)) {
7827 return 0;
7828 }
7829
7830 rv = ngtcp2_gaptr_push(&conn->dcid.seqgap, fr->seq, 1);
7831 if (rv != 0) {
7832 return rv;
7833 }
7834
7835 if (ngtcp2_ksl_len(&conn->dcid.seqgap.gap) > 32) {
7836 ngtcp2_gaptr_drop_first_gap(&conn->dcid.seqgap);
7837 }
7838
7839 len = ngtcp2_ringbuf_len(&conn->dcid.unused.rb);
7840
7841 if (conn->dcid.current.seq >= conn->dcid.retire_prior_to) {
7842 ++extra_dcid;
7843 }
7844 if (pv) {
7845 if (pv->dcid.seq != conn->dcid.current.seq &&
7846 pv->dcid.seq >= conn->dcid.retire_prior_to) {
7847 ++extra_dcid;
7848 }
7849 if ((pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) &&
7850 pv->fallback_dcid.seq != conn->dcid.current.seq &&
7851 pv->fallback_dcid.seq >= conn->dcid.retire_prior_to) {
7852 ++extra_dcid;
7853 }
7854 }
7855
7856 if (conn->local.transport_params.active_connection_id_limit <=
7857 len + extra_dcid) {
7858 return NGTCP2_ERR_CONNECTION_ID_LIMIT;
7859 }
7860
7861 if (len >= NGTCP2_MAX_DCID_POOL_SIZE) {
7862 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON, "too many connection ID");
7863 return 0;
7864 }
7865
7866 dcid = ngtcp2_ringbuf_push_back(&conn->dcid.unused.rb);
7867 ngtcp2_dcid_init(dcid, fr->seq, &fr->cid, fr->stateless_reset_token);
7868
7869 return 0;
7870 }
7871
7872 /*
7873 * conn_post_process_recv_new_connection_id handles retirement request
7874 * of active DCIDs.
7875 *
7876 * This function returns 0 if it succeeds, or one of the following
7877 * negative error codes:
7878 *
7879 * NGTCP2_ERR_NOMEM
7880 * Out of memory.
7881 * NGTCP2_ERR_CALLBACK_FAILURE
7882 * User-defined callback function failed.
7883 */
conn_post_process_recv_new_connection_id(ngtcp2_conn * conn,ngtcp2_tstamp ts)7884 static int conn_post_process_recv_new_connection_id(ngtcp2_conn *conn,
7885 ngtcp2_tstamp ts) {
7886 ngtcp2_pv *pv = conn->pv;
7887 ngtcp2_dcid *dcid;
7888 int rv;
7889
7890 if (conn->dcid.current.seq < conn->dcid.retire_prior_to) {
7891 if (ngtcp2_ringbuf_len(&conn->dcid.unused.rb) == 0) {
7892 return 0;
7893 }
7894
7895 rv = conn_retire_dcid(conn, &conn->dcid.current, ts);
7896 if (rv != 0) {
7897 return rv;
7898 }
7899
7900 dcid = ngtcp2_ringbuf_get(&conn->dcid.unused.rb, 0);
7901 if (pv) {
7902 if (conn->dcid.current.seq == pv->dcid.seq) {
7903 ngtcp2_dcid_copy_cid_token(&pv->dcid, dcid);
7904 }
7905 if ((pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) &&
7906 conn->dcid.current.seq == pv->fallback_dcid.seq) {
7907 ngtcp2_dcid_copy_cid_token(&pv->fallback_dcid, dcid);
7908 }
7909 }
7910
7911 ngtcp2_dcid_copy_cid_token(&conn->dcid.current, dcid);
7912 ngtcp2_ringbuf_pop_front(&conn->dcid.unused.rb);
7913
7914 rv = conn_call_activate_dcid(conn, &conn->dcid.current);
7915 if (rv != 0) {
7916 return rv;
7917 }
7918 }
7919
7920 if (pv) {
7921 if (pv->dcid.seq < conn->dcid.retire_prior_to) {
7922 if (ngtcp2_ringbuf_len(&conn->dcid.unused.rb)) {
7923 rv = conn_retire_dcid(conn, &pv->dcid, ts);
7924 if (rv != 0) {
7925 return rv;
7926 }
7927
7928 dcid = ngtcp2_ringbuf_get(&conn->dcid.unused.rb, 0);
7929
7930 if ((pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) &&
7931 pv->dcid.seq == pv->fallback_dcid.seq) {
7932 ngtcp2_dcid_copy_cid_token(&pv->fallback_dcid, dcid);
7933 }
7934
7935 ngtcp2_dcid_copy_cid_token(&pv->dcid, dcid);
7936 ngtcp2_ringbuf_pop_front(&conn->dcid.unused.rb);
7937
7938 rv = conn_call_activate_dcid(conn, &pv->dcid);
7939 if (rv != 0) {
7940 return rv;
7941 }
7942 } else {
7943 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PTV,
7944 "path migration is aborted because connection ID is"
7945 "retired and no unused connection ID is available");
7946
7947 return conn_abort_pv(conn, ts);
7948 }
7949 }
7950 if ((pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) &&
7951 pv->fallback_dcid.seq < conn->dcid.retire_prior_to) {
7952 if (ngtcp2_ringbuf_len(&conn->dcid.unused.rb)) {
7953 rv = conn_retire_dcid(conn, &pv->fallback_dcid, ts);
7954 if (rv != 0) {
7955 return rv;
7956 }
7957
7958 dcid = ngtcp2_ringbuf_get(&conn->dcid.unused.rb, 0);
7959 ngtcp2_dcid_copy_cid_token(&pv->fallback_dcid, dcid);
7960 ngtcp2_ringbuf_pop_front(&conn->dcid.unused.rb);
7961
7962 rv = conn_call_activate_dcid(conn, &pv->fallback_dcid);
7963 if (rv != 0) {
7964 return rv;
7965 }
7966 } else {
7967 /* Now we have no fallback dcid. */
7968 return conn_abort_pv(conn, ts);
7969 }
7970 }
7971 }
7972
7973 return 0;
7974 }
7975
7976 /*
7977 * conn_recv_retire_connection_id processes the incoming
7978 * RETIRE_CONNECTION_ID frame |fr|. |hd| is a packet header which
7979 * |fr| is included.
7980 *
7981 * This function returns 0 if it succeeds, or one of the following
7982 * negative error codes:
7983 *
7984 * NGTCP2_ERR_NOMEM
7985 * Out of memory.
7986 * NGTCP2_ERR_PROTO
7987 * SCID is zero-length.
7988 * NGTCP2_ERR_FRAME_ENCODING
7989 * Attempt to retire CID which is used as DCID to send this frame.
7990 */
conn_recv_retire_connection_id(ngtcp2_conn * conn,const ngtcp2_pkt_hd * hd,const ngtcp2_retire_connection_id * fr,ngtcp2_tstamp ts)7991 static int conn_recv_retire_connection_id(ngtcp2_conn *conn,
7992 const ngtcp2_pkt_hd *hd,
7993 const ngtcp2_retire_connection_id *fr,
7994 ngtcp2_tstamp ts) {
7995 ngtcp2_ksl_it it;
7996 ngtcp2_scid *scid;
7997
7998 if (conn->oscid.datalen == 0 || conn->scid.last_seq < fr->seq) {
7999 return NGTCP2_ERR_PROTO;
8000 }
8001
8002 for (it = ngtcp2_ksl_begin(&conn->scid.set); !ngtcp2_ksl_it_end(&it);
8003 ngtcp2_ksl_it_next(&it)) {
8004 scid = ngtcp2_ksl_it_get(&it);
8005 if (scid->seq == fr->seq) {
8006 if (ngtcp2_cid_eq(&scid->cid, &hd->dcid)) {
8007 return NGTCP2_ERR_PROTO;
8008 }
8009
8010 if (!(scid->flags & NGTCP2_SCID_FLAG_RETIRED)) {
8011 scid->flags |= NGTCP2_SCID_FLAG_RETIRED;
8012 ++conn->scid.num_retired;
8013 }
8014
8015 if (scid->pe.index != NGTCP2_PQ_BAD_INDEX) {
8016 ngtcp2_pq_remove(&conn->scid.used, &scid->pe);
8017 scid->pe.index = NGTCP2_PQ_BAD_INDEX;
8018 }
8019
8020 scid->retired_ts = ts;
8021
8022 return ngtcp2_pq_push(&conn->scid.used, &scid->pe);
8023 }
8024 }
8025
8026 return 0;
8027 }
8028
8029 /*
8030 * conn_recv_new_token processes the incoming NEW_TOKEN frame |fr|.
8031 *
8032 * This function returns 0 if it succeeds, or one of the following
8033 * negative error codes:
8034 *
8035 * NGTCP2_ERR_FRAME_ENCODING
8036 * Token is empty
8037 * NGTCP2_ERR_PROTO:
8038 * Server received NEW_TOKEN.
8039 */
conn_recv_new_token(ngtcp2_conn * conn,const ngtcp2_new_token * fr)8040 static int conn_recv_new_token(ngtcp2_conn *conn, const ngtcp2_new_token *fr) {
8041 if (conn->server) {
8042 return NGTCP2_ERR_PROTO;
8043 }
8044
8045 if (fr->token.len == 0) {
8046 return NGTCP2_ERR_FRAME_ENCODING;
8047 }
8048
8049 return conn_call_recv_new_token(conn, &fr->token);
8050 }
8051
8052 /*
8053 * conn_recv_streams_blocked_bidi processes the incoming
8054 * STREAMS_BLOCKED (0x16).
8055 *
8056 * This function returns 0 if it succeeds, or one of the following
8057 * negative error codes:
8058 *
8059 * NGTCP2_ERR_FRAME_ENCODING
8060 * Maximum Streams is larger than advertised value.
8061 */
conn_recv_streams_blocked_bidi(ngtcp2_conn * conn,ngtcp2_streams_blocked * fr)8062 static int conn_recv_streams_blocked_bidi(ngtcp2_conn *conn,
8063 ngtcp2_streams_blocked *fr) {
8064 if (fr->max_streams > conn->remote.bidi.max_streams) {
8065 return NGTCP2_ERR_FRAME_ENCODING;
8066 }
8067
8068 return 0;
8069 }
8070
8071 /*
8072 * conn_recv_streams_blocked_uni processes the incoming
8073 * STREAMS_BLOCKED (0x17).
8074 *
8075 * This function returns 0 if it succeeds, or one of the following
8076 * negative error codes:
8077 *
8078 * NGTCP2_ERR_FRAME_ENCODING
8079 * Maximum Streams is larger than advertised value.
8080 */
conn_recv_streams_blocked_uni(ngtcp2_conn * conn,ngtcp2_streams_blocked * fr)8081 static int conn_recv_streams_blocked_uni(ngtcp2_conn *conn,
8082 ngtcp2_streams_blocked *fr) {
8083 if (fr->max_streams > conn->remote.uni.max_streams) {
8084 return NGTCP2_ERR_FRAME_ENCODING;
8085 }
8086
8087 return 0;
8088 }
8089
8090 /*
8091 * conn_select_preferred_addr asks a client application to select a
8092 * server address from preferred addresses received from server. If a
8093 * client chooses the address, path validation will start.
8094 *
8095 * This function returns 0 if it succeeds, or one of the following
8096 * negative error codes:
8097 *
8098 * NGTCP2_ERR_NOMEM
8099 * Out of memory.
8100 * NGTCP2_ERR_CALLBACK_FAILURE
8101 * User-defined callback function failed.
8102 */
conn_select_preferred_addr(ngtcp2_conn * conn)8103 static int conn_select_preferred_addr(ngtcp2_conn *conn) {
8104 ngtcp2_path_storage ps;
8105 int rv;
8106 ngtcp2_duration pto, initial_pto, timeout;
8107 ngtcp2_pv *pv;
8108 ngtcp2_dcid *dcid;
8109
8110 if (ngtcp2_ringbuf_len(&conn->dcid.unused.rb) == 0) {
8111 return 0;
8112 }
8113
8114 ngtcp2_path_storage_zero(&ps);
8115 ngtcp2_addr_copy(&ps.path.local, &conn->dcid.current.ps.path.local);
8116
8117 rv = conn_call_select_preferred_addr(conn, &ps.path);
8118 if (rv != 0) {
8119 return rv;
8120 }
8121
8122 if (ps.path.remote.addrlen == 0 ||
8123 ngtcp2_addr_eq(&conn->dcid.current.ps.path.remote, &ps.path.remote)) {
8124 return 0;
8125 }
8126
8127 assert(conn->pv == NULL);
8128
8129 dcid = ngtcp2_ringbuf_get(&conn->dcid.unused.rb, 0);
8130 ngtcp2_dcid_set_path(dcid, &ps.path);
8131
8132 pto = conn_compute_pto(conn, &conn->pktns);
8133 initial_pto = conn_compute_initial_pto(conn, &conn->pktns);
8134 timeout = 3 * ngtcp2_max(pto, initial_pto);
8135
8136 rv = ngtcp2_pv_new(&pv, dcid, timeout, NGTCP2_PV_FLAG_PREFERRED_ADDR,
8137 &conn->log, conn->mem);
8138 if (rv != 0) {
8139 /* TODO Call ngtcp2_dcid_free here if it is introduced */
8140 return rv;
8141 }
8142
8143 ngtcp2_ringbuf_pop_front(&conn->dcid.unused.rb);
8144 conn->pv = pv;
8145
8146 return conn_call_activate_dcid(conn, &pv->dcid);
8147 }
8148
8149 /*
8150 * conn_recv_handshake_done processes the incoming HANDSHAKE_DONE
8151 * frame |fr|.
8152 *
8153 * This function returns 0 if it succeeds, or one of the following
8154 * negative error codes:
8155 *
8156 * NGTCP2_ERR_PROTO
8157 * Server received HANDSHAKE_DONE frame.
8158 * NGTCP2_ERR_NOMEM
8159 * Out of memory.
8160 * NGTCP2_ERR_CALLBACK_FAILURE
8161 * User-defined callback function failed.
8162 */
conn_recv_handshake_done(ngtcp2_conn * conn,ngtcp2_tstamp ts)8163 static int conn_recv_handshake_done(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
8164 int rv;
8165
8166 if (conn->server) {
8167 return NGTCP2_ERR_PROTO;
8168 }
8169
8170 if (conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED) {
8171 return 0;
8172 }
8173
8174 conn->flags |= NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED |
8175 NGTCP2_CONN_FLAG_SERVER_ADDR_VERIFIED;
8176
8177 conn->pktns.rtb.persistent_congestion_start_ts = ts;
8178
8179 conn_discard_handshake_state(conn, ts);
8180
8181 assert(conn->remote.transport_params);
8182
8183 if (conn->remote.transport_params->preferred_address_present) {
8184 rv = conn_select_preferred_addr(conn);
8185 if (rv != 0) {
8186 return rv;
8187 }
8188 }
8189
8190 rv = conn_call_handshake_confirmed(conn);
8191 if (rv != 0) {
8192 return rv;
8193 }
8194
8195 /* Re-arm loss detection timer after handshake has been
8196 confirmed. */
8197 ngtcp2_conn_set_loss_detection_timer(conn, ts);
8198
8199 return 0;
8200 }
8201
8202 /*
8203 * conn_recv_datagram processes the incoming DATAGRAM frame |fr|.
8204 *
8205 * This function returns 0 if it succeeds, or one of the following
8206 * negative error codes:
8207 *
8208 * NGTCP2_ERR_CALLBACK_FAILURE
8209 * User-defined callback function failed.
8210 */
conn_recv_datagram(ngtcp2_conn * conn,ngtcp2_datagram * fr)8211 static int conn_recv_datagram(ngtcp2_conn *conn, ngtcp2_datagram *fr) {
8212 assert(conn->local.transport_params.max_datagram_frame_size);
8213
8214 return conn_call_recv_datagram(conn, fr);
8215 }
8216
8217 /*
8218 * conn_key_phase_changed returns nonzero if |hd| indicates that the
8219 * key phase has unexpected value.
8220 */
conn_key_phase_changed(ngtcp2_conn * conn,const ngtcp2_pkt_hd * hd)8221 static int conn_key_phase_changed(ngtcp2_conn *conn, const ngtcp2_pkt_hd *hd) {
8222 ngtcp2_pktns *pktns = &conn->pktns;
8223
8224 return !(pktns->crypto.rx.ckm->flags & NGTCP2_CRYPTO_KM_FLAG_KEY_PHASE_ONE) ^
8225 !(hd->flags & NGTCP2_PKT_FLAG_KEY_PHASE);
8226 }
8227
8228 /*
8229 * conn_prepare_key_update installs new updated keys.
8230 */
conn_prepare_key_update(ngtcp2_conn * conn,ngtcp2_tstamp ts)8231 static int conn_prepare_key_update(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
8232 int rv;
8233 ngtcp2_tstamp confirmed_ts = conn->crypto.key_update.confirmed_ts;
8234 ngtcp2_duration pto = conn_compute_pto(conn, &conn->pktns);
8235 ngtcp2_pktns *pktns = &conn->pktns;
8236 ngtcp2_crypto_km *rx_ckm = pktns->crypto.rx.ckm;
8237 ngtcp2_crypto_km *tx_ckm = pktns->crypto.tx.ckm;
8238 ngtcp2_crypto_km *new_rx_ckm, *new_tx_ckm;
8239 ngtcp2_crypto_aead_ctx rx_aead_ctx = {0}, tx_aead_ctx = {0};
8240 size_t secretlen, ivlen;
8241
8242 if ((conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED) &&
8243 tx_ckm->use_count >= pktns->crypto.ctx.max_encryption &&
8244 ngtcp2_conn_initiate_key_update(conn, ts) != 0) {
8245 return NGTCP2_ERR_AEAD_LIMIT_REACHED;
8246 }
8247
8248 if ((conn->flags & NGTCP2_CONN_FLAG_KEY_UPDATE_NOT_CONFIRMED) ||
8249 (confirmed_ts != UINT64_MAX && confirmed_ts + pto > ts)) {
8250 return 0;
8251 }
8252
8253 if (conn->crypto.key_update.new_rx_ckm ||
8254 conn->crypto.key_update.new_tx_ckm) {
8255 assert(conn->crypto.key_update.new_rx_ckm);
8256 assert(conn->crypto.key_update.new_tx_ckm);
8257 return 0;
8258 }
8259
8260 secretlen = rx_ckm->secret.len;
8261 ivlen = rx_ckm->iv.len;
8262
8263 rv = ngtcp2_crypto_km_nocopy_new(&conn->crypto.key_update.new_rx_ckm,
8264 secretlen, ivlen, conn->mem);
8265 if (rv != 0) {
8266 return rv;
8267 }
8268
8269 rv = ngtcp2_crypto_km_nocopy_new(&conn->crypto.key_update.new_tx_ckm,
8270 secretlen, ivlen, conn->mem);
8271 if (rv != 0) {
8272 return rv;
8273 }
8274
8275 new_rx_ckm = conn->crypto.key_update.new_rx_ckm;
8276 new_tx_ckm = conn->crypto.key_update.new_tx_ckm;
8277
8278 rv = conn_call_update_key(
8279 conn, new_rx_ckm->secret.base, new_tx_ckm->secret.base, &rx_aead_ctx,
8280 new_rx_ckm->iv.base, &tx_aead_ctx, new_tx_ckm->iv.base,
8281 rx_ckm->secret.base, tx_ckm->secret.base, secretlen);
8282 if (rv != 0) {
8283 return rv;
8284 }
8285
8286 new_rx_ckm->aead_ctx = rx_aead_ctx;
8287 new_tx_ckm->aead_ctx = tx_aead_ctx;
8288
8289 if (!(rx_ckm->flags & NGTCP2_CRYPTO_KM_FLAG_KEY_PHASE_ONE)) {
8290 new_rx_ckm->flags |= NGTCP2_CRYPTO_KM_FLAG_KEY_PHASE_ONE;
8291 new_tx_ckm->flags |= NGTCP2_CRYPTO_KM_FLAG_KEY_PHASE_ONE;
8292 }
8293
8294 if (conn->crypto.key_update.old_rx_ckm) {
8295 conn_call_delete_crypto_aead_ctx(
8296 conn, &conn->crypto.key_update.old_rx_ckm->aead_ctx);
8297 ngtcp2_crypto_km_del(conn->crypto.key_update.old_rx_ckm, conn->mem);
8298 conn->crypto.key_update.old_rx_ckm = NULL;
8299 }
8300
8301 return 0;
8302 }
8303
8304 /*
8305 * conn_rotate_keys rotates keys. The current key moves to old key,
8306 * and new key moves to the current key. If the local endpoint
8307 * initiated this key update, pass nonzero as |initiator|.
8308 */
conn_rotate_keys(ngtcp2_conn * conn,int64_t pkt_num,int initiator)8309 static void conn_rotate_keys(ngtcp2_conn *conn, int64_t pkt_num,
8310 int initiator) {
8311 ngtcp2_pktns *pktns = &conn->pktns;
8312
8313 assert(conn->crypto.key_update.new_rx_ckm);
8314 assert(conn->crypto.key_update.new_tx_ckm);
8315 assert(!conn->crypto.key_update.old_rx_ckm);
8316 assert(!(conn->flags & NGTCP2_CONN_FLAG_PPE_PENDING));
8317
8318 conn->crypto.key_update.old_rx_ckm = pktns->crypto.rx.ckm;
8319
8320 pktns->crypto.rx.ckm = conn->crypto.key_update.new_rx_ckm;
8321 conn->crypto.key_update.new_rx_ckm = NULL;
8322 pktns->crypto.rx.ckm->pkt_num = pkt_num;
8323
8324 assert(pktns->crypto.tx.ckm);
8325
8326 conn_call_delete_crypto_aead_ctx(conn, &pktns->crypto.tx.ckm->aead_ctx);
8327 ngtcp2_crypto_km_del(pktns->crypto.tx.ckm, conn->mem);
8328
8329 pktns->crypto.tx.ckm = conn->crypto.key_update.new_tx_ckm;
8330 conn->crypto.key_update.new_tx_ckm = NULL;
8331 pktns->crypto.tx.ckm->pkt_num = pktns->tx.last_pkt_num + 1;
8332
8333 conn->flags |= NGTCP2_CONN_FLAG_KEY_UPDATE_NOT_CONFIRMED;
8334 if (initiator) {
8335 conn->flags |= NGTCP2_CONN_FLAG_KEY_UPDATE_INITIATOR;
8336 }
8337 }
8338
8339 /*
8340 * conn_path_validation_in_progress returns nonzero if path validation
8341 * against |path| is underway.
8342 */
conn_path_validation_in_progress(ngtcp2_conn * conn,const ngtcp2_path * path)8343 static int conn_path_validation_in_progress(ngtcp2_conn *conn,
8344 const ngtcp2_path *path) {
8345 ngtcp2_pv *pv = conn->pv;
8346
8347 return pv && ngtcp2_path_eq(&pv->dcid.ps.path, path);
8348 }
8349
8350 /*
8351 * conn_recv_non_probing_pkt_on_new_path is called when non-probing
8352 * packet is received via new path. It starts path validation against
8353 * the new path.
8354 *
8355 * This function returns 0 if it succeeds, or one of the following
8356 * negative error codes:
8357 *
8358 * NGTCP2_ERR_CONN_ID_BLOCKED
8359 * No DCID is available
8360 * NGTCP2_ERR_NOMEM
8361 * Out of memory
8362 */
conn_recv_non_probing_pkt_on_new_path(ngtcp2_conn * conn,const ngtcp2_path * path,size_t dgramlen,int new_cid_used,ngtcp2_tstamp ts)8363 static int conn_recv_non_probing_pkt_on_new_path(ngtcp2_conn *conn,
8364 const ngtcp2_path *path,
8365 size_t dgramlen,
8366 int new_cid_used,
8367 ngtcp2_tstamp ts) {
8368
8369 ngtcp2_dcid dcid, *bound_dcid, *last;
8370 ngtcp2_pv *pv;
8371 int rv;
8372 ngtcp2_duration pto, initial_pto, timeout;
8373 int require_new_cid;
8374 int local_addr_eq;
8375 uint32_t remote_addr_cmp;
8376 size_t len, i;
8377
8378 assert(conn->server);
8379
8380 if (conn->pv && (conn->pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) &&
8381 ngtcp2_path_eq(&conn->pv->fallback_dcid.ps.path, path)) {
8382 /* If new path equals fallback path, that means connection
8383 migrated back to the original path. Fallback path is
8384 considered to be validated. */
8385 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PTV,
8386 "path is migrated back to the original path");
8387 ngtcp2_dcid_copy(&conn->dcid.current, &conn->pv->fallback_dcid);
8388 conn_reset_congestion_state(conn, ts);
8389 conn->dcid.current.bytes_recv += dgramlen;
8390 conn_reset_ecn_validation_state(conn);
8391
8392 rv = conn_abort_pv(conn, ts);
8393 if (rv != 0) {
8394 return rv;
8395 }
8396
8397 /* Run PMTUD just in case if it is prematurely aborted */
8398 assert(!conn->pmtud);
8399
8400 return conn_start_pmtud(conn);
8401 }
8402
8403 remote_addr_cmp =
8404 ngtcp2_addr_compare(&conn->dcid.current.ps.path.remote, &path->remote);
8405 local_addr_eq =
8406 ngtcp2_addr_eq(&conn->dcid.current.ps.path.local, &path->local);
8407
8408 /*
8409 * When to change DCID? RFC 9002 section 9.5 says:
8410 *
8411 * An endpoint MUST NOT reuse a connection ID when sending from more
8412 * than one local address -- for example, when initiating connection
8413 * migration as described in Section 9.2 or when probing a new
8414 * network path as described in Section 9.1.
8415 *
8416 * Similarly, an endpoint MUST NOT reuse a connection ID when
8417 * sending to more than one destination address. Due to network
8418 * changes outside the control of its peer, an endpoint might
8419 * receive packets from a new source address with the same
8420 * Destination Connection ID field value, in which case it MAY
8421 * continue to use the current connection ID with the new remote
8422 * address while still sending from the same local address.
8423 */
8424 require_new_cid = conn->dcid.current.cid.datalen &&
8425 ((new_cid_used && remote_addr_cmp) || !local_addr_eq);
8426
8427 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
8428 "non-probing packet was received from new remote address");
8429
8430 pto = conn_compute_pto(conn, &conn->pktns);
8431 initial_pto = conn_compute_initial_pto(conn, &conn->pktns);
8432 timeout = 3 * ngtcp2_max(pto, initial_pto);
8433
8434 len = ngtcp2_ringbuf_len(&conn->dcid.bound.rb);
8435
8436 for (i = 0; i < len; ++i) {
8437 bound_dcid = ngtcp2_ringbuf_get(&conn->dcid.bound.rb, i);
8438 if (ngtcp2_path_eq(&bound_dcid->ps.path, path)) {
8439 ngtcp2_log_info(
8440 &conn->log, NGTCP2_LOG_EVENT_CON,
8441 "Found DCID which has already been bound to the new path");
8442
8443 ngtcp2_dcid_copy(&dcid, bound_dcid);
8444 if (i == 0) {
8445 ngtcp2_ringbuf_pop_front(&conn->dcid.bound.rb);
8446 } else if (i == ngtcp2_ringbuf_len(&conn->dcid.bound.rb) - 1) {
8447 ngtcp2_ringbuf_pop_back(&conn->dcid.bound.rb);
8448 } else {
8449 last = ngtcp2_ringbuf_get(&conn->dcid.bound.rb, len - 1);
8450 ngtcp2_dcid_copy(bound_dcid, last);
8451 ngtcp2_ringbuf_pop_back(&conn->dcid.bound.rb);
8452 }
8453 require_new_cid = 0;
8454
8455 if (dcid.cid.datalen) {
8456 rv = conn_call_activate_dcid(conn, &dcid);
8457 if (rv != 0) {
8458 return rv;
8459 }
8460 }
8461 break;
8462 }
8463 }
8464
8465 if (i == len) {
8466 if (require_new_cid) {
8467 if (ngtcp2_ringbuf_len(&conn->dcid.unused.rb) == 0) {
8468 return NGTCP2_ERR_CONN_ID_BLOCKED;
8469 }
8470 ngtcp2_dcid_copy(&dcid, ngtcp2_ringbuf_get(&conn->dcid.unused.rb, 0));
8471 ngtcp2_ringbuf_pop_front(&conn->dcid.unused.rb);
8472
8473 rv = conn_call_activate_dcid(conn, &dcid);
8474 if (rv != 0) {
8475 return rv;
8476 }
8477 } else {
8478 /* Use the current DCID if a remote endpoint does not change
8479 DCID. */
8480 ngtcp2_dcid_copy(&dcid, &conn->dcid.current);
8481 dcid.bytes_sent = 0;
8482 dcid.bytes_recv = 0;
8483 dcid.flags &= (uint8_t)~NGTCP2_DCID_FLAG_PATH_VALIDATED;
8484 }
8485 }
8486
8487 ngtcp2_dcid_set_path(&dcid, path);
8488 dcid.bytes_recv += dgramlen;
8489
8490 rv = ngtcp2_pv_new(&pv, &dcid, timeout, NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE,
8491 &conn->log, conn->mem);
8492 if (rv != 0) {
8493 return rv;
8494 }
8495
8496 if (conn->pv && (conn->pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE)) {
8497 ngtcp2_dcid_copy(&pv->fallback_dcid, &conn->pv->fallback_dcid);
8498 pv->fallback_pto = conn->pv->fallback_pto;
8499 /* Unset the flag bit so that conn_stop_pv does not retire
8500 DCID. */
8501 conn->pv->flags &= (uint8_t)~NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE;
8502 } else {
8503 ngtcp2_dcid_copy(&pv->fallback_dcid, &conn->dcid.current);
8504 pv->fallback_pto = pto;
8505 }
8506
8507 if (!local_addr_eq || (remote_addr_cmp & (NGTCP2_ADDR_COMPARE_FLAG_ADDR |
8508 NGTCP2_ADDR_COMPARE_FLAG_FAMILY))) {
8509 conn_reset_congestion_state(conn, ts);
8510 } else {
8511 /* For NAT rebinding, keep max_udp_payload_size since client most
8512 likely does not send a padded PATH_CHALLENGE. */
8513 dcid.max_udp_payload_size = ngtcp2_max(
8514 dcid.max_udp_payload_size, conn->dcid.current.max_udp_payload_size);
8515 }
8516
8517 ngtcp2_dcid_copy(&conn->dcid.current, &dcid);
8518
8519 conn_reset_ecn_validation_state(conn);
8520
8521 ngtcp2_conn_stop_pmtud(conn);
8522
8523 if (conn->pv) {
8524 ngtcp2_log_info(
8525 &conn->log, NGTCP2_LOG_EVENT_PTV,
8526 "path migration is aborted because new migration has started");
8527 rv = conn_abort_pv(conn, ts);
8528 if (rv != 0) {
8529 return rv;
8530 }
8531 }
8532
8533 conn->pv = pv;
8534
8535 return 0;
8536 }
8537
8538 /*
8539 * conn_recv_pkt_from_new_path is called when a 1RTT packet is
8540 * received from new path (not current path). This packet would be a
8541 * packet which only contains probing frame, or reordered packet, or a
8542 * path is being validated.
8543 *
8544 * This function returns 0 if it succeeds, or one of the following
8545 * negative error codes:
8546 *
8547 * NGTCP2_ERR_CONN_ID_BLOCKED
8548 * No unused DCID is available
8549 * NGTCP2_ERR_NOMEM
8550 * Out of memory
8551 */
conn_recv_pkt_from_new_path(ngtcp2_conn * conn,const ngtcp2_path * path,size_t dgramlen,int path_challenge_recved,ngtcp2_tstamp ts)8552 static int conn_recv_pkt_from_new_path(ngtcp2_conn *conn,
8553 const ngtcp2_path *path, size_t dgramlen,
8554 int path_challenge_recved,
8555 ngtcp2_tstamp ts) {
8556 ngtcp2_pv *pv = conn->pv;
8557 ngtcp2_dcid *bound_dcid;
8558 int rv;
8559
8560 if (pv) {
8561 if (ngtcp2_path_eq(&pv->dcid.ps.path, path)) {
8562 pv->dcid.bytes_recv += dgramlen;
8563 return 0;
8564 }
8565
8566 if ((pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) &&
8567 ngtcp2_path_eq(&pv->fallback_dcid.ps.path, path)) {
8568 pv->fallback_dcid.bytes_recv += dgramlen;
8569 return 0;
8570 }
8571 }
8572
8573 if (!path_challenge_recved) {
8574 return 0;
8575 }
8576
8577 rv = conn_bind_dcid(conn, &bound_dcid, path, ts);
8578 if (rv != 0) {
8579 return rv;
8580 }
8581
8582 ngtcp2_dcid_set_path(bound_dcid, path);
8583 bound_dcid->bytes_recv += dgramlen;
8584
8585 return 0;
8586 }
8587
8588 /*
8589 * conn_recv_delayed_handshake_pkt processes the received Handshake
8590 * packet which is received after handshake completed. This function
8591 * does the minimal job, and its purpose is send acknowledgement of
8592 * this packet to the peer. We assume that hd->type ==
8593 * NGTCP2_PKT_HANDSHAKE.
8594 *
8595 * This function returns 0 if it succeeds, or one of the following
8596 * negative error codes:
8597 *
8598 * NGTCP2_ERR_FRAME_ENCODING
8599 * Frame is badly formatted; or frame type is unknown.
8600 * NGTCP2_ERR_NOMEM
8601 * Out of memory
8602 * NGTCP2_ERR_DISCARD_PKT
8603 * Packet was discarded.
8604 * NGTCP2_ERR_ACK_FRAME
8605 * ACK frame is malformed.
8606 * NGTCP2_ERR_PROTO
8607 * Frame that is not allowed in Handshake packet is received.
8608 */
8609 static int
conn_recv_delayed_handshake_pkt(ngtcp2_conn * conn,const ngtcp2_pkt_info * pi,const ngtcp2_pkt_hd * hd,size_t pktlen,const uint8_t * payload,size_t payloadlen,ngtcp2_tstamp pkt_ts,ngtcp2_tstamp ts)8610 conn_recv_delayed_handshake_pkt(ngtcp2_conn *conn, const ngtcp2_pkt_info *pi,
8611 const ngtcp2_pkt_hd *hd, size_t pktlen,
8612 const uint8_t *payload, size_t payloadlen,
8613 ngtcp2_tstamp pkt_ts, ngtcp2_tstamp ts) {
8614 ngtcp2_ssize nread;
8615 ngtcp2_max_frame mfr;
8616 ngtcp2_frame *fr = &mfr.fr;
8617 int rv;
8618 int require_ack = 0;
8619 ngtcp2_pktns *pktns;
8620
8621 assert(hd->type == NGTCP2_PKT_HANDSHAKE);
8622
8623 pktns = conn->hs_pktns;
8624
8625 if (payloadlen == 0) {
8626 /* QUIC packet must contain at least one frame */
8627 return NGTCP2_ERR_PROTO;
8628 }
8629
8630 ngtcp2_qlog_pkt_received_start(&conn->qlog);
8631
8632 for (; payloadlen;) {
8633 nread = ngtcp2_pkt_decode_frame(fr, payload, payloadlen);
8634 if (nread < 0) {
8635 return (int)nread;
8636 }
8637
8638 payload += nread;
8639 payloadlen -= (size_t)nread;
8640
8641 switch (fr->type) {
8642 case NGTCP2_FRAME_ACK:
8643 case NGTCP2_FRAME_ACK_ECN:
8644 fr->ack.ack_delay = 0;
8645 fr->ack.ack_delay_unscaled = 0;
8646 break;
8647 }
8648
8649 ngtcp2_log_rx_fr(&conn->log, hd, fr);
8650
8651 switch (fr->type) {
8652 case NGTCP2_FRAME_ACK:
8653 case NGTCP2_FRAME_ACK_ECN:
8654 if (!conn->server) {
8655 conn->flags |= NGTCP2_CONN_FLAG_SERVER_ADDR_VERIFIED;
8656 }
8657 rv = conn_recv_ack(conn, pktns, &fr->ack, pkt_ts, ts);
8658 if (rv != 0) {
8659 return rv;
8660 }
8661 break;
8662 case NGTCP2_FRAME_PADDING:
8663 break;
8664 case NGTCP2_FRAME_CONNECTION_CLOSE:
8665 rv = conn_recv_connection_close(conn, &fr->connection_close);
8666 if (rv != 0) {
8667 return rv;
8668 }
8669 break;
8670 case NGTCP2_FRAME_CRYPTO:
8671 case NGTCP2_FRAME_PING:
8672 require_ack = 1;
8673 break;
8674 default:
8675 return NGTCP2_ERR_PROTO;
8676 }
8677
8678 ngtcp2_qlog_write_frame(&conn->qlog, fr);
8679 }
8680
8681 ngtcp2_qlog_pkt_received_end(&conn->qlog, hd, pktlen);
8682
8683 rv = pktns_commit_recv_pkt_num(pktns, hd->pkt_num, require_ack, pkt_ts);
8684 if (rv != 0) {
8685 return rv;
8686 }
8687
8688 pktns_increase_ecn_counts(pktns, pi);
8689
8690 if (require_ack &&
8691 (++pktns->acktr.rx_npkt >= conn->local.settings.ack_thresh ||
8692 (pi->ecn & NGTCP2_ECN_MASK) == NGTCP2_ECN_CE)) {
8693 ngtcp2_acktr_immediate_ack(&pktns->acktr);
8694 }
8695
8696 rv = ngtcp2_conn_sched_ack(conn, &pktns->acktr, hd->pkt_num, require_ack,
8697 pkt_ts);
8698 if (rv != 0) {
8699 return rv;
8700 }
8701
8702 conn_restart_timer_on_read(conn, ts);
8703
8704 ngtcp2_qlog_metrics_updated(&conn->qlog, &conn->cstat);
8705
8706 return 0;
8707 }
8708
8709 /*
8710 * conn_recv_pkt processes a packet contained in the buffer pointed by
8711 * |pkt| of length |pktlen|. |pkt| may contain multiple QUIC packets.
8712 * This function only processes the first packet. |pkt_ts| is the
8713 * timestamp when packet is received. |ts| should be the current
8714 * time. Usually they are the same, but for buffered packets,
8715 * |pkt_ts| would be earlier than |ts|.
8716 *
8717 * This function returns the number of bytes processed if it succeeds,
8718 * or one of the following negative error codes:
8719 *
8720 * NGTCP2_ERR_DISCARD_PKT
8721 * Packet was discarded because plain text header was malformed;
8722 * or its payload could not be decrypted.
8723 * NGTCP2_ERR_PROTO
8724 * Packet is badly formatted; or 0RTT packet contains other than
8725 * PADDING or STREAM frames; or other QUIC protocol violation is
8726 * found.
8727 * NGTCP2_ERR_CALLBACK_FAILURE
8728 * User-defined callback function failed.
8729 * NGTCP2_ERR_NOMEM
8730 * Out of memory.
8731 * NGTCP2_ERR_FRAME_ENCODING
8732 * Frame is badly formatted; or frame type is unknown.
8733 * NGTCP2_ERR_ACK_FRAME
8734 * ACK frame is malformed.
8735 * NGTCP2_ERR_STREAM_STATE
8736 * Frame is received to the local stream which is not initiated.
8737 * NGTCP2_ERR_STREAM_LIMIT
8738 * Frame has remote stream ID which is strictly greater than the
8739 * allowed limit.
8740 * NGTCP2_ERR_FLOW_CONTROL
8741 * Flow control limit is violated.
8742 * NGTCP2_ERR_FINAL_SIZE
8743 * Frame has strictly larger end offset than it is permitted.
8744 */
conn_recv_pkt(ngtcp2_conn * conn,const ngtcp2_path * path,const ngtcp2_pkt_info * pi,const uint8_t * pkt,size_t pktlen,size_t dgramlen,ngtcp2_tstamp pkt_ts,ngtcp2_tstamp ts)8745 static ngtcp2_ssize conn_recv_pkt(ngtcp2_conn *conn, const ngtcp2_path *path,
8746 const ngtcp2_pkt_info *pi, const uint8_t *pkt,
8747 size_t pktlen, size_t dgramlen,
8748 ngtcp2_tstamp pkt_ts, ngtcp2_tstamp ts) {
8749 ngtcp2_pkt_hd hd;
8750 int rv = 0;
8751 size_t hdpktlen;
8752 const uint8_t *payload;
8753 size_t payloadlen;
8754 ngtcp2_ssize nread, nwrite;
8755 ngtcp2_max_frame mfr;
8756 ngtcp2_frame *fr = &mfr.fr;
8757 int require_ack = 0;
8758 ngtcp2_crypto_aead *aead;
8759 ngtcp2_crypto_cipher *hp;
8760 ngtcp2_crypto_km *ckm;
8761 ngtcp2_crypto_cipher_ctx *hp_ctx;
8762 ngtcp2_hp_mask hp_mask;
8763 ngtcp2_decrypt decrypt;
8764 ngtcp2_pktns *pktns;
8765 int non_probing_pkt = 0;
8766 int key_phase_bit_changed = 0;
8767 int force_decrypt_failure = 0;
8768 int recv_ncid = 0;
8769 int new_cid_used = 0;
8770 int path_challenge_recved = 0;
8771
8772 if (pkt[0] & NGTCP2_HEADER_FORM_BIT) {
8773 nread = ngtcp2_pkt_decode_hd_long(&hd, pkt, pktlen);
8774 if (nread < 0) {
8775 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8776 "could not decode long header");
8777 return NGTCP2_ERR_DISCARD_PKT;
8778 }
8779
8780 if (pktlen < (size_t)nread + hd.len) {
8781 return NGTCP2_ERR_DISCARD_PKT;
8782 }
8783
8784 assert(conn->negotiated_version);
8785
8786 if (hd.version != conn->client_chosen_version &&
8787 hd.version != conn->negotiated_version) {
8788 return NGTCP2_ERR_DISCARD_PKT;
8789 }
8790
8791 pktlen = (size_t)nread + hd.len;
8792
8793 /* Quoted from spec: if subsequent packets of those types include
8794 a different Source Connection ID, they MUST be discarded. */
8795 if (!ngtcp2_cid_eq(&conn->dcid.current.cid, &hd.scid)) {
8796 ngtcp2_log_rx_pkt_hd(&conn->log, &hd);
8797 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8798 "packet was ignored because of mismatched SCID");
8799 return NGTCP2_ERR_DISCARD_PKT;
8800 }
8801
8802 switch (hd.type) {
8803 case NGTCP2_PKT_INITIAL:
8804 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8805 "delayed Initial packet was discarded");
8806 return (ngtcp2_ssize)pktlen;
8807 case NGTCP2_PKT_HANDSHAKE:
8808 if (hd.version != conn->negotiated_version) {
8809 return NGTCP2_ERR_DISCARD_PKT;
8810 }
8811
8812 if (!conn->hs_pktns) {
8813 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8814 "delayed Handshake packet was discarded");
8815 return (ngtcp2_ssize)pktlen;
8816 }
8817
8818 pktns = conn->hs_pktns;
8819 aead = &pktns->crypto.ctx.aead;
8820 hp = &pktns->crypto.ctx.hp;
8821 ckm = pktns->crypto.rx.ckm;
8822 hp_ctx = &pktns->crypto.rx.hp_ctx;
8823 hp_mask = conn->callbacks.hp_mask;
8824 decrypt = conn->callbacks.decrypt;
8825 break;
8826 case NGTCP2_PKT_0RTT:
8827 if (!conn->server || hd.version != conn->client_chosen_version) {
8828 return NGTCP2_ERR_DISCARD_PKT;
8829 }
8830
8831 if (!conn->early.ckm) {
8832 return (ngtcp2_ssize)pktlen;
8833 }
8834
8835 pktns = &conn->pktns;
8836 aead = &conn->early.ctx.aead;
8837 hp = &conn->early.ctx.hp;
8838 ckm = conn->early.ckm;
8839 hp_ctx = &conn->early.hp_ctx;
8840 hp_mask = conn->callbacks.hp_mask;
8841 decrypt = conn->callbacks.decrypt;
8842 break;
8843 default:
8844 ngtcp2_log_rx_pkt_hd(&conn->log, &hd);
8845 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8846 "packet type 0x%02x was ignored", hd.type);
8847 return (ngtcp2_ssize)pktlen;
8848 }
8849 } else {
8850 nread = ngtcp2_pkt_decode_hd_short(&hd, pkt, pktlen, conn->oscid.datalen);
8851 if (nread < 0) {
8852 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8853 "could not decode short header");
8854 return NGTCP2_ERR_DISCARD_PKT;
8855 }
8856
8857 pktns = &conn->pktns;
8858 aead = &pktns->crypto.ctx.aead;
8859 hp = &pktns->crypto.ctx.hp;
8860 ckm = pktns->crypto.rx.ckm;
8861 hp_ctx = &pktns->crypto.rx.hp_ctx;
8862 hp_mask = conn->callbacks.hp_mask;
8863 decrypt = conn->callbacks.decrypt;
8864 }
8865
8866 rv = conn_ensure_decrypt_hp_buffer(conn, (size_t)nread + 4);
8867 if (rv != 0) {
8868 return rv;
8869 }
8870
8871 nwrite = decrypt_hp(&hd, conn->crypto.decrypt_hp_buf.base, hp, pkt, pktlen,
8872 (size_t)nread, hp_ctx, hp_mask);
8873 if (nwrite < 0) {
8874 if (ngtcp2_err_is_fatal((int)nwrite)) {
8875 return nwrite;
8876 }
8877 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8878 "could not decrypt packet number");
8879 return NGTCP2_ERR_DISCARD_PKT;
8880 }
8881
8882 hdpktlen = (size_t)nwrite;
8883 payload = pkt + hdpktlen;
8884 payloadlen = pktlen - hdpktlen;
8885
8886 hd.pkt_num = ngtcp2_pkt_adjust_pkt_num(pktns->rx.max_pkt_num, hd.pkt_num,
8887 pkt_num_bits(hd.pkt_numlen));
8888 if (hd.pkt_num > NGTCP2_MAX_PKT_NUM) {
8889 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8890 "pkn=%" PRId64 " is greater than maximum pkn", hd.pkt_num);
8891 return NGTCP2_ERR_DISCARD_PKT;
8892 }
8893
8894 ngtcp2_log_rx_pkt_hd(&conn->log, &hd);
8895
8896 if (hd.type == NGTCP2_PKT_1RTT) {
8897 key_phase_bit_changed = conn_key_phase_changed(conn, &hd);
8898 }
8899
8900 rv = conn_ensure_decrypt_buffer(conn, payloadlen);
8901 if (rv != 0) {
8902 return rv;
8903 }
8904
8905 if (key_phase_bit_changed) {
8906 assert(hd.type == NGTCP2_PKT_1RTT);
8907
8908 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT, "unexpected KEY_PHASE");
8909
8910 if (ckm->pkt_num > hd.pkt_num) {
8911 if (conn->crypto.key_update.old_rx_ckm) {
8912 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8913 "decrypting with old key");
8914 ckm = conn->crypto.key_update.old_rx_ckm;
8915 } else {
8916 force_decrypt_failure = 1;
8917 }
8918 } else if (pktns->rx.max_pkt_num < hd.pkt_num) {
8919 assert(ckm->pkt_num < hd.pkt_num);
8920 if (!conn->crypto.key_update.new_rx_ckm) {
8921 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8922 "new key is not available");
8923 force_decrypt_failure = 1;
8924 } else {
8925 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8926 "decrypting with new key");
8927 ckm = conn->crypto.key_update.new_rx_ckm;
8928 }
8929 } else {
8930 force_decrypt_failure = 1;
8931 }
8932 }
8933
8934 nwrite = decrypt_pkt(conn->crypto.decrypt_buf.base, aead, payload, payloadlen,
8935 conn->crypto.decrypt_hp_buf.base, hdpktlen, hd.pkt_num,
8936 ckm, decrypt);
8937
8938 if (force_decrypt_failure) {
8939 nwrite = NGTCP2_ERR_DECRYPT;
8940 }
8941
8942 if (nwrite < 0) {
8943 if (ngtcp2_err_is_fatal((int)nwrite)) {
8944 return nwrite;
8945 }
8946
8947 assert(NGTCP2_ERR_DECRYPT == nwrite);
8948
8949 if (hd.type == NGTCP2_PKT_1RTT &&
8950 ++conn->crypto.decryption_failure_count >=
8951 pktns->crypto.ctx.max_decryption_failure) {
8952 return NGTCP2_ERR_AEAD_LIMIT_REACHED;
8953 }
8954
8955 if (hd.flags & NGTCP2_PKT_FLAG_LONG_FORM) {
8956 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8957 "could not decrypt packet payload");
8958 return NGTCP2_ERR_DISCARD_PKT;
8959 }
8960
8961 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8962 "could not decrypt packet payload");
8963 return NGTCP2_ERR_DISCARD_PKT;
8964 }
8965
8966 rv = ngtcp2_pkt_verify_reserved_bits(conn->crypto.decrypt_hp_buf.base[0]);
8967 if (rv != 0) {
8968 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8969 "packet has incorrect reserved bits");
8970
8971 return NGTCP2_ERR_PROTO;
8972 }
8973
8974 if (pktns_pkt_num_is_duplicate(pktns, hd.pkt_num)) {
8975 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8976 "packet was discarded because of duplicated packet number");
8977 return NGTCP2_ERR_DISCARD_PKT;
8978 }
8979
8980 payload = conn->crypto.decrypt_buf.base;
8981 payloadlen = (size_t)nwrite;
8982
8983 if (payloadlen == 0) {
8984 /* QUIC packet must contain at least one frame */
8985 return NGTCP2_ERR_PROTO;
8986 }
8987
8988 if (hd.flags & NGTCP2_PKT_FLAG_LONG_FORM) {
8989 switch (hd.type) {
8990 case NGTCP2_PKT_HANDSHAKE:
8991 rv = conn_verify_dcid(conn, NULL, &hd);
8992 if (rv != 0) {
8993 if (ngtcp2_err_is_fatal(rv)) {
8994 return rv;
8995 }
8996 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
8997 "packet was ignored because of mismatched DCID");
8998 return NGTCP2_ERR_DISCARD_PKT;
8999 }
9000
9001 rv = conn_recv_delayed_handshake_pkt(conn, pi, &hd, pktlen, payload,
9002 payloadlen, pkt_ts, ts);
9003 if (rv < 0) {
9004 return (ngtcp2_ssize)rv;
9005 }
9006
9007 return (ngtcp2_ssize)pktlen;
9008 case NGTCP2_PKT_0RTT:
9009 if (!ngtcp2_cid_eq(&conn->rcid, &hd.dcid)) {
9010 rv = conn_verify_dcid(conn, NULL, &hd);
9011 if (rv != 0) {
9012 if (ngtcp2_err_is_fatal(rv)) {
9013 return rv;
9014 }
9015 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
9016 "packet was ignored because of mismatched DCID");
9017 return NGTCP2_ERR_DISCARD_PKT;
9018 }
9019 }
9020 break;
9021 default:
9022 /* Unreachable */
9023 assert(0);
9024 }
9025 } else {
9026 rv = conn_verify_dcid(conn, &new_cid_used, &hd);
9027 if (rv != 0) {
9028 if (ngtcp2_err_is_fatal(rv)) {
9029 return rv;
9030 }
9031 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
9032 "packet was ignored because of mismatched DCID");
9033 return NGTCP2_ERR_DISCARD_PKT;
9034 }
9035 }
9036
9037 ngtcp2_qlog_pkt_received_start(&conn->qlog);
9038
9039 for (; payloadlen;) {
9040 nread = ngtcp2_pkt_decode_frame(fr, payload, payloadlen);
9041 if (nread < 0) {
9042 return nread;
9043 }
9044
9045 payload += nread;
9046 payloadlen -= (size_t)nread;
9047
9048 switch (fr->type) {
9049 case NGTCP2_FRAME_ACK:
9050 case NGTCP2_FRAME_ACK_ECN:
9051 if ((hd.flags & NGTCP2_PKT_FLAG_LONG_FORM) &&
9052 hd.type == NGTCP2_PKT_0RTT) {
9053 return NGTCP2_ERR_PROTO;
9054 }
9055 assert(conn->remote.transport_params);
9056 assign_recved_ack_delay_unscaled(
9057 &fr->ack, conn->remote.transport_params->ack_delay_exponent);
9058 break;
9059 }
9060
9061 ngtcp2_log_rx_fr(&conn->log, &hd, fr);
9062
9063 if (hd.type == NGTCP2_PKT_0RTT) {
9064 switch (fr->type) {
9065 case NGTCP2_FRAME_PADDING:
9066 case NGTCP2_FRAME_PING:
9067 case NGTCP2_FRAME_RESET_STREAM:
9068 case NGTCP2_FRAME_STOP_SENDING:
9069 case NGTCP2_FRAME_STREAM:
9070 case NGTCP2_FRAME_MAX_DATA:
9071 case NGTCP2_FRAME_MAX_STREAM_DATA:
9072 case NGTCP2_FRAME_MAX_STREAMS_BIDI:
9073 case NGTCP2_FRAME_MAX_STREAMS_UNI:
9074 case NGTCP2_FRAME_DATA_BLOCKED:
9075 case NGTCP2_FRAME_STREAM_DATA_BLOCKED:
9076 case NGTCP2_FRAME_STREAMS_BLOCKED_BIDI:
9077 case NGTCP2_FRAME_STREAMS_BLOCKED_UNI:
9078 case NGTCP2_FRAME_NEW_CONNECTION_ID:
9079 case NGTCP2_FRAME_PATH_CHALLENGE:
9080 case NGTCP2_FRAME_CONNECTION_CLOSE:
9081 case NGTCP2_FRAME_CONNECTION_CLOSE_APP:
9082 case NGTCP2_FRAME_DATAGRAM:
9083 case NGTCP2_FRAME_DATAGRAM_LEN:
9084 break;
9085 default:
9086 return NGTCP2_ERR_PROTO;
9087 }
9088 }
9089
9090 switch (fr->type) {
9091 case NGTCP2_FRAME_ACK:
9092 case NGTCP2_FRAME_ACK_ECN:
9093 case NGTCP2_FRAME_PADDING:
9094 case NGTCP2_FRAME_CONNECTION_CLOSE:
9095 case NGTCP2_FRAME_CONNECTION_CLOSE_APP:
9096 break;
9097 default:
9098 require_ack = 1;
9099 }
9100
9101 switch (fr->type) {
9102 case NGTCP2_FRAME_ACK:
9103 case NGTCP2_FRAME_ACK_ECN:
9104 if (!conn->server) {
9105 conn->flags |= NGTCP2_CONN_FLAG_SERVER_ADDR_VERIFIED;
9106 }
9107 rv = conn_recv_ack(conn, pktns, &fr->ack, pkt_ts, ts);
9108 if (rv != 0) {
9109 return rv;
9110 }
9111 non_probing_pkt = 1;
9112 break;
9113 case NGTCP2_FRAME_STREAM:
9114 rv = conn_recv_stream(conn, &fr->stream);
9115 if (rv != 0) {
9116 return rv;
9117 }
9118 non_probing_pkt = 1;
9119 break;
9120 case NGTCP2_FRAME_CRYPTO:
9121 rv = conn_recv_crypto(conn, NGTCP2_CRYPTO_LEVEL_APPLICATION,
9122 &pktns->crypto.strm, &fr->crypto);
9123 if (rv != 0) {
9124 return rv;
9125 }
9126 non_probing_pkt = 1;
9127 break;
9128 case NGTCP2_FRAME_RESET_STREAM:
9129 rv = conn_recv_reset_stream(conn, &fr->reset_stream);
9130 if (rv != 0) {
9131 return rv;
9132 }
9133 non_probing_pkt = 1;
9134 break;
9135 case NGTCP2_FRAME_STOP_SENDING:
9136 rv = conn_recv_stop_sending(conn, &fr->stop_sending);
9137 if (rv != 0) {
9138 return rv;
9139 }
9140 non_probing_pkt = 1;
9141 break;
9142 case NGTCP2_FRAME_MAX_STREAM_DATA:
9143 rv = conn_recv_max_stream_data(conn, &fr->max_stream_data);
9144 if (rv != 0) {
9145 return rv;
9146 }
9147 non_probing_pkt = 1;
9148 break;
9149 case NGTCP2_FRAME_MAX_DATA:
9150 conn_recv_max_data(conn, &fr->max_data);
9151 non_probing_pkt = 1;
9152 break;
9153 case NGTCP2_FRAME_MAX_STREAMS_BIDI:
9154 case NGTCP2_FRAME_MAX_STREAMS_UNI:
9155 rv = conn_recv_max_streams(conn, &fr->max_streams);
9156 if (rv != 0) {
9157 return rv;
9158 }
9159 non_probing_pkt = 1;
9160 break;
9161 case NGTCP2_FRAME_CONNECTION_CLOSE:
9162 case NGTCP2_FRAME_CONNECTION_CLOSE_APP:
9163 rv = conn_recv_connection_close(conn, &fr->connection_close);
9164 if (rv != 0) {
9165 return rv;
9166 }
9167 break;
9168 case NGTCP2_FRAME_PING:
9169 non_probing_pkt = 1;
9170 break;
9171 case NGTCP2_FRAME_PATH_CHALLENGE:
9172 conn_recv_path_challenge(conn, path, &fr->path_challenge);
9173 path_challenge_recved = 1;
9174 break;
9175 case NGTCP2_FRAME_PATH_RESPONSE:
9176 rv = conn_recv_path_response(conn, &fr->path_response, ts);
9177 if (rv != 0) {
9178 return rv;
9179 }
9180 break;
9181 case NGTCP2_FRAME_NEW_CONNECTION_ID:
9182 rv = conn_recv_new_connection_id(conn, &fr->new_connection_id);
9183 if (rv != 0) {
9184 return rv;
9185 }
9186 recv_ncid = 1;
9187 break;
9188 case NGTCP2_FRAME_RETIRE_CONNECTION_ID:
9189 rv = conn_recv_retire_connection_id(conn, &hd, &fr->retire_connection_id,
9190 ts);
9191 if (rv != 0) {
9192 return rv;
9193 }
9194 non_probing_pkt = 1;
9195 break;
9196 case NGTCP2_FRAME_NEW_TOKEN:
9197 rv = conn_recv_new_token(conn, &fr->new_token);
9198 if (rv != 0) {
9199 return rv;
9200 }
9201 non_probing_pkt = 1;
9202 break;
9203 case NGTCP2_FRAME_HANDSHAKE_DONE:
9204 rv = conn_recv_handshake_done(conn, ts);
9205 if (rv != 0) {
9206 return rv;
9207 }
9208 non_probing_pkt = 1;
9209 break;
9210 case NGTCP2_FRAME_STREAMS_BLOCKED_BIDI:
9211 rv = conn_recv_streams_blocked_bidi(conn, &fr->streams_blocked);
9212 if (rv != 0) {
9213 return rv;
9214 }
9215 non_probing_pkt = 1;
9216 break;
9217 case NGTCP2_FRAME_STREAMS_BLOCKED_UNI:
9218 rv = conn_recv_streams_blocked_uni(conn, &fr->streams_blocked);
9219 if (rv != 0) {
9220 return rv;
9221 }
9222 non_probing_pkt = 1;
9223 break;
9224 case NGTCP2_FRAME_DATA_BLOCKED:
9225 /* TODO Not implemented yet */
9226 non_probing_pkt = 1;
9227 break;
9228 case NGTCP2_FRAME_DATAGRAM:
9229 case NGTCP2_FRAME_DATAGRAM_LEN:
9230 if ((uint64_t)nread >
9231 conn->local.transport_params.max_datagram_frame_size) {
9232 return NGTCP2_ERR_PROTO;
9233 }
9234 rv = conn_recv_datagram(conn, &fr->datagram);
9235 if (rv != 0) {
9236 return rv;
9237 }
9238 non_probing_pkt = 1;
9239 break;
9240 }
9241
9242 ngtcp2_qlog_write_frame(&conn->qlog, fr);
9243 }
9244
9245 ngtcp2_qlog_pkt_received_end(&conn->qlog, &hd, pktlen);
9246
9247 if (recv_ncid) {
9248 rv = conn_post_process_recv_new_connection_id(conn, ts);
9249 if (rv != 0) {
9250 return rv;
9251 }
9252 }
9253
9254 if (conn->server && hd.type == NGTCP2_PKT_1RTT &&
9255 !ngtcp2_path_eq(&conn->dcid.current.ps.path, path)) {
9256 if (non_probing_pkt && pktns->rx.max_pkt_num < hd.pkt_num &&
9257 !conn_path_validation_in_progress(conn, path)) {
9258 rv = conn_recv_non_probing_pkt_on_new_path(conn, path, dgramlen,
9259 new_cid_used, ts);
9260 if (rv != 0) {
9261 if (ngtcp2_err_is_fatal(rv)) {
9262 return rv;
9263 }
9264
9265 /* DCID is not available. Just continue. */
9266 assert(NGTCP2_ERR_CONN_ID_BLOCKED == rv);
9267 }
9268 } else {
9269 rv = conn_recv_pkt_from_new_path(conn, path, dgramlen,
9270 path_challenge_recved, ts);
9271 if (rv != 0) {
9272 if (ngtcp2_err_is_fatal(rv)) {
9273 return rv;
9274 }
9275
9276 /* DCID is not available. Just continue. */
9277 assert(NGTCP2_ERR_CONN_ID_BLOCKED == rv);
9278 }
9279 }
9280 }
9281
9282 if (hd.type == NGTCP2_PKT_1RTT) {
9283 if (ckm == conn->crypto.key_update.new_rx_ckm) {
9284 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON, "rotate keys");
9285 conn_rotate_keys(conn, hd.pkt_num, /* initiator = */ 0);
9286 } else if (ckm->pkt_num > hd.pkt_num) {
9287 ckm->pkt_num = hd.pkt_num;
9288 }
9289
9290 if (conn->server && conn->early.ckm &&
9291 conn->early.discard_started_ts == UINT64_MAX) {
9292 conn->early.discard_started_ts = ts;
9293 }
9294
9295 if (ngtcp2_path_eq(&conn->dcid.current.ps.path, path)) {
9296 conn_update_keep_alive_last_ts(conn, ts);
9297 }
9298 }
9299
9300 rv = pktns_commit_recv_pkt_num(pktns, hd.pkt_num, require_ack, pkt_ts);
9301 if (rv != 0) {
9302 return rv;
9303 }
9304
9305 pktns_increase_ecn_counts(pktns, pi);
9306
9307 if (require_ack &&
9308 (++pktns->acktr.rx_npkt >= conn->local.settings.ack_thresh ||
9309 (pi->ecn & NGTCP2_ECN_MASK) == NGTCP2_ECN_CE)) {
9310 ngtcp2_acktr_immediate_ack(&pktns->acktr);
9311 }
9312
9313 rv = ngtcp2_conn_sched_ack(conn, &pktns->acktr, hd.pkt_num, require_ack,
9314 pkt_ts);
9315 if (rv != 0) {
9316 return rv;
9317 }
9318
9319 conn_restart_timer_on_read(conn, ts);
9320
9321 ngtcp2_qlog_metrics_updated(&conn->qlog, &conn->cstat);
9322
9323 return conn->state == NGTCP2_CS_DRAINING ? NGTCP2_ERR_DRAINING
9324 : (ngtcp2_ssize)pktlen;
9325 }
9326
9327 /*
9328 * conn_process_buffered_protected_pkt processes buffered 0RTT or 1RTT
9329 * packets.
9330 *
9331 * This function returns 0 if it succeeds, or the same negative error
9332 * codes from conn_recv_pkt.
9333 */
conn_process_buffered_protected_pkt(ngtcp2_conn * conn,ngtcp2_pktns * pktns,ngtcp2_tstamp ts)9334 static int conn_process_buffered_protected_pkt(ngtcp2_conn *conn,
9335 ngtcp2_pktns *pktns,
9336 ngtcp2_tstamp ts) {
9337 ngtcp2_ssize nread;
9338 ngtcp2_pkt_chain **ppc, *next;
9339 int rv;
9340
9341 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
9342 "processing buffered protected packet");
9343
9344 for (ppc = &pktns->rx.buffed_pkts; *ppc;) {
9345 next = (*ppc)->next;
9346 nread = conn_recv_pkt(conn, &(*ppc)->path.path, &(*ppc)->pi, (*ppc)->pkt,
9347 (*ppc)->pktlen, (*ppc)->dgramlen, (*ppc)->ts, ts);
9348 if (nread < 0 && !ngtcp2_err_is_fatal((int)nread) &&
9349 nread != NGTCP2_ERR_DRAINING) {
9350 /* TODO We don't know this is the first QUIC packet in a
9351 datagram. */
9352 rv = conn_on_stateless_reset(conn, &(*ppc)->path.path, (*ppc)->pkt,
9353 (*ppc)->pktlen);
9354 if (rv == 0) {
9355 ngtcp2_pkt_chain_del(*ppc, conn->mem);
9356 *ppc = next;
9357 return NGTCP2_ERR_DRAINING;
9358 }
9359 }
9360
9361 ngtcp2_pkt_chain_del(*ppc, conn->mem);
9362 *ppc = next;
9363 if (nread < 0) {
9364 if (nread == NGTCP2_ERR_DISCARD_PKT) {
9365 continue;
9366 }
9367 return (int)nread;
9368 }
9369 }
9370
9371 return 0;
9372 }
9373
9374 /*
9375 * conn_process_buffered_handshake_pkt processes buffered Handshake
9376 * packets.
9377 *
9378 * This function returns 0 if it succeeds, or the same negative error
9379 * codes from conn_recv_handshake_pkt.
9380 */
conn_process_buffered_handshake_pkt(ngtcp2_conn * conn,ngtcp2_tstamp ts)9381 static int conn_process_buffered_handshake_pkt(ngtcp2_conn *conn,
9382 ngtcp2_tstamp ts) {
9383 ngtcp2_pktns *pktns = conn->hs_pktns;
9384 ngtcp2_ssize nread;
9385 ngtcp2_pkt_chain **ppc, *next;
9386
9387 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
9388 "processing buffered handshake packet");
9389
9390 for (ppc = &pktns->rx.buffed_pkts; *ppc;) {
9391 next = (*ppc)->next;
9392 nread = conn_recv_handshake_pkt(conn, &(*ppc)->path.path, &(*ppc)->pi,
9393 (*ppc)->pkt, (*ppc)->pktlen,
9394 (*ppc)->dgramlen, (*ppc)->ts, ts);
9395 ngtcp2_pkt_chain_del(*ppc, conn->mem);
9396 *ppc = next;
9397 if (nread < 0) {
9398 if (nread == NGTCP2_ERR_DISCARD_PKT) {
9399 continue;
9400 }
9401 return (int)nread;
9402 }
9403 }
9404
9405 return 0;
9406 }
9407
conn_sync_stream_id_limit(ngtcp2_conn * conn)9408 static void conn_sync_stream_id_limit(ngtcp2_conn *conn) {
9409 ngtcp2_transport_params *params = conn->remote.transport_params;
9410
9411 assert(params);
9412
9413 conn->local.bidi.max_streams = params->initial_max_streams_bidi;
9414 conn->local.uni.max_streams = params->initial_max_streams_uni;
9415 }
9416
strm_set_max_offset(void * data,void * ptr)9417 static int strm_set_max_offset(void *data, void *ptr) {
9418 ngtcp2_conn *conn = ptr;
9419 ngtcp2_transport_params *params = conn->remote.transport_params;
9420 ngtcp2_strm *strm = data;
9421 uint64_t max_offset;
9422 int rv;
9423
9424 assert(params);
9425
9426 if (!conn_local_stream(conn, strm->stream_id)) {
9427 return 0;
9428 }
9429
9430 if (bidi_stream(strm->stream_id)) {
9431 max_offset = params->initial_max_stream_data_bidi_remote;
9432 } else {
9433 max_offset = params->initial_max_stream_data_uni;
9434 }
9435
9436 if (strm->tx.max_offset < max_offset) {
9437 strm->tx.max_offset = max_offset;
9438
9439 /* Don't call callback if stream is half-closed local */
9440 if (strm->flags & NGTCP2_STRM_FLAG_SHUT_WR) {
9441 return 0;
9442 }
9443
9444 rv = conn_call_extend_max_stream_data(conn, strm, strm->stream_id,
9445 strm->tx.max_offset);
9446 if (rv != 0) {
9447 return rv;
9448 }
9449 }
9450
9451 return 0;
9452 }
9453
conn_sync_stream_data_limit(ngtcp2_conn * conn)9454 static int conn_sync_stream_data_limit(ngtcp2_conn *conn) {
9455 return ngtcp2_map_each(&conn->strms, strm_set_max_offset, conn);
9456 }
9457
9458 /*
9459 * conn_handshake_completed is called once cryptographic handshake has
9460 * completed.
9461 *
9462 * This function returns 0 if it succeeds, or one of the following
9463 * negative error codes:
9464 *
9465 * NGTCP2_ERR_CALLBACK_FAILURE
9466 * User callback failed.
9467 */
conn_handshake_completed(ngtcp2_conn * conn)9468 static int conn_handshake_completed(ngtcp2_conn *conn) {
9469 int rv;
9470
9471 conn->flags |= NGTCP2_CONN_FLAG_HANDSHAKE_COMPLETED_HANDLED;
9472
9473 rv = conn_call_handshake_completed(conn);
9474 if (rv != 0) {
9475 return rv;
9476 }
9477
9478 if (conn->local.bidi.max_streams > 0) {
9479 rv = conn_call_extend_max_local_streams_bidi(conn,
9480 conn->local.bidi.max_streams);
9481 if (rv != 0) {
9482 return rv;
9483 }
9484 }
9485 if (conn->local.uni.max_streams > 0) {
9486 rv = conn_call_extend_max_local_streams_uni(conn,
9487 conn->local.uni.max_streams);
9488 if (rv != 0) {
9489 return rv;
9490 }
9491 }
9492
9493 return 0;
9494 }
9495
9496 /*
9497 * conn_recv_cpkt processes compound packet after handshake. The
9498 * buffer pointed by |pkt| might contain multiple packets. The 1RTT
9499 * packet must be the last one because it does not have payload length
9500 * field.
9501 *
9502 * This function returns 0 if it succeeds, or the same negative error
9503 * codes from conn_recv_pkt except for NGTCP2_ERR_DISCARD_PKT.
9504 */
conn_recv_cpkt(ngtcp2_conn * conn,const ngtcp2_path * path,const ngtcp2_pkt_info * pi,const uint8_t * pkt,size_t pktlen,ngtcp2_tstamp ts)9505 static int conn_recv_cpkt(ngtcp2_conn *conn, const ngtcp2_path *path,
9506 const ngtcp2_pkt_info *pi, const uint8_t *pkt,
9507 size_t pktlen, ngtcp2_tstamp ts) {
9508 ngtcp2_ssize nread;
9509 int rv;
9510 const uint8_t *origpkt = pkt;
9511 size_t dgramlen = pktlen;
9512
9513 if (ngtcp2_path_eq(&conn->dcid.current.ps.path, path)) {
9514 conn->dcid.current.bytes_recv += dgramlen;
9515 }
9516
9517 while (pktlen) {
9518 nread = conn_recv_pkt(conn, path, pi, pkt, pktlen, dgramlen, ts, ts);
9519 if (nread < 0) {
9520 if (ngtcp2_err_is_fatal((int)nread)) {
9521 return (int)nread;
9522 }
9523
9524 if (nread == NGTCP2_ERR_DRAINING) {
9525 return NGTCP2_ERR_DRAINING;
9526 }
9527
9528 if (origpkt == pkt) {
9529 rv = conn_on_stateless_reset(conn, path, origpkt, dgramlen);
9530 if (rv == 0) {
9531 return NGTCP2_ERR_DRAINING;
9532 }
9533 }
9534 if (nread == NGTCP2_ERR_DISCARD_PKT) {
9535 return 0;
9536 }
9537 return (int)nread;
9538 }
9539
9540 assert(pktlen >= (size_t)nread);
9541 pkt += nread;
9542 pktlen -= (size_t)nread;
9543
9544 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_PKT,
9545 "read packet %td left %zu", nread, pktlen);
9546 }
9547
9548 return 0;
9549 }
9550
9551 /*
9552 * conn_is_retired_path returns nonzero if |path| is included in
9553 * retired path list.
9554 */
conn_is_retired_path(ngtcp2_conn * conn,const ngtcp2_path * path)9555 static int conn_is_retired_path(ngtcp2_conn *conn, const ngtcp2_path *path) {
9556 size_t i, len = ngtcp2_ringbuf_len(&conn->dcid.retired.rb);
9557 ngtcp2_dcid *dcid;
9558
9559 for (i = 0; i < len; ++i) {
9560 dcid = ngtcp2_ringbuf_get(&conn->dcid.retired.rb, i);
9561 if (ngtcp2_path_eq(&dcid->ps.path, path)) {
9562 return 1;
9563 }
9564 }
9565
9566 return 0;
9567 }
9568
9569 /*
9570 * conn_enqueue_handshake_done enqueues HANDSHAKE_DONE frame for
9571 * transmission.
9572 */
conn_enqueue_handshake_done(ngtcp2_conn * conn)9573 static int conn_enqueue_handshake_done(ngtcp2_conn *conn) {
9574 ngtcp2_pktns *pktns = &conn->pktns;
9575 ngtcp2_frame_chain *nfrc;
9576 int rv;
9577
9578 assert(conn->server);
9579
9580 rv = ngtcp2_frame_chain_objalloc_new(&nfrc, &conn->frc_objalloc);
9581 if (rv != 0) {
9582 return rv;
9583 }
9584
9585 nfrc->fr.type = NGTCP2_FRAME_HANDSHAKE_DONE;
9586 nfrc->next = pktns->tx.frq;
9587 pktns->tx.frq = nfrc;
9588
9589 return 0;
9590 }
9591
9592 /**
9593 * @function
9594 *
9595 * `conn_read_handshake` performs QUIC cryptographic handshake by
9596 * reading given data. |pkt| points to the buffer to read and
9597 * |pktlen| is the length of the buffer. |path| is the network path.
9598 *
9599 * This function returns the number of bytes processed. Unless the
9600 * last packet is 1RTT packet and an application decryption key has
9601 * been installed, it returns |pktlen| if it succeeds. If it finds
9602 * 1RTT packet and an application decryption key has been installed,
9603 * it returns the number of bytes just before 1RTT packet begins.
9604 *
9605 * This function returns the number of bytes processed if it succeeds,
9606 * or one of the following negative error codes: (TBD).
9607 */
conn_read_handshake(ngtcp2_conn * conn,const ngtcp2_path * path,const ngtcp2_pkt_info * pi,const uint8_t * pkt,size_t pktlen,ngtcp2_tstamp ts)9608 static ngtcp2_ssize conn_read_handshake(ngtcp2_conn *conn,
9609 const ngtcp2_path *path,
9610 const ngtcp2_pkt_info *pi,
9611 const uint8_t *pkt, size_t pktlen,
9612 ngtcp2_tstamp ts) {
9613 int rv;
9614 ngtcp2_ssize nread;
9615
9616 switch (conn->state) {
9617 case NGTCP2_CS_CLIENT_INITIAL:
9618 /* TODO Better to log something when we ignore input */
9619 return (ngtcp2_ssize)pktlen;
9620 case NGTCP2_CS_CLIENT_WAIT_HANDSHAKE:
9621 nread = conn_recv_handshake_cpkt(conn, path, pi, pkt, pktlen, ts);
9622 if (nread < 0) {
9623 return nread;
9624 }
9625
9626 if (conn->state == NGTCP2_CS_CLIENT_INITIAL) {
9627 /* Retry packet was received */
9628 return (ngtcp2_ssize)pktlen;
9629 }
9630
9631 assert(conn->hs_pktns);
9632
9633 if (conn->hs_pktns->crypto.rx.ckm && conn->in_pktns) {
9634 rv = conn_process_buffered_handshake_pkt(conn, ts);
9635 if (rv != 0) {
9636 return rv;
9637 }
9638 }
9639
9640 if (conn_is_handshake_completed(conn) &&
9641 !(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_COMPLETED_HANDLED)) {
9642 rv = conn_handshake_completed(conn);
9643 if (rv != 0) {
9644 return rv;
9645 }
9646
9647 rv = conn_process_buffered_protected_pkt(conn, &conn->pktns, ts);
9648 if (rv != 0) {
9649 return rv;
9650 }
9651 }
9652
9653 return nread;
9654 case NGTCP2_CS_SERVER_INITIAL:
9655 nread = conn_recv_handshake_cpkt(conn, path, pi, pkt, pktlen, ts);
9656 if (nread < 0) {
9657 return nread;
9658 }
9659
9660 /*
9661 * Client ServerHello might not fit into single Initial packet
9662 * (e.g., resuming session with client authentication). If we get
9663 * Client Initial which does not increase offset or it is 0RTT
9664 * packet buffered, perform address validation in order to buffer
9665 * validated data only.
9666 */
9667 if (ngtcp2_strm_rx_offset(&conn->in_pktns->crypto.strm) == 0) {
9668 if (conn->in_pktns->crypto.strm.rx.rob &&
9669 ngtcp2_rob_data_buffered(conn->in_pktns->crypto.strm.rx.rob)) {
9670 /* Address has been validated with token */
9671 if (conn->local.settings.token.len) {
9672 return nread;
9673 }
9674 return NGTCP2_ERR_RETRY;
9675 }
9676 if (conn->in_pktns->rx.buffed_pkts) {
9677 /* 0RTT is buffered, force retry */
9678 return NGTCP2_ERR_RETRY;
9679 }
9680 /* If neither CRYPTO frame nor 0RTT packet is processed, just
9681 drop connection. */
9682 return NGTCP2_ERR_DROP_CONN;
9683 }
9684
9685 /* Process re-ordered 0-RTT packets which arrived before Initial
9686 packet. */
9687 if (conn->early.ckm) {
9688 assert(conn->in_pktns);
9689
9690 rv = conn_process_buffered_protected_pkt(conn, conn->in_pktns, ts);
9691 if (rv != 0) {
9692 return rv;
9693 }
9694 }
9695
9696 return nread;
9697 case NGTCP2_CS_SERVER_WAIT_HANDSHAKE:
9698 nread = conn_recv_handshake_cpkt(conn, path, pi, pkt, pktlen, ts);
9699 if (nread < 0) {
9700 return nread;
9701 }
9702
9703 if (conn->hs_pktns->crypto.rx.ckm) {
9704 rv = conn_process_buffered_handshake_pkt(conn, ts);
9705 if (rv != 0) {
9706 return rv;
9707 }
9708 }
9709
9710 if (conn->hs_pktns->rx.max_pkt_num != -1) {
9711 conn_discard_initial_state(conn, ts);
9712 }
9713
9714 if (!conn_is_handshake_completed(conn)) {
9715 /* If server hits amplification limit, it cancels loss detection
9716 timer. If server receives a packet from client, the limit is
9717 increased and server can send more. If server has
9718 ack-eliciting Initial or Handshake packets, it should resend
9719 it if timer fired but timer is not armed in this case. So
9720 instead of resending Initial/Handshake packets, if server has
9721 1RTT data to send, it might send them and then might hit
9722 amplification limit again until it hits stream data limit.
9723 Initial/Handshake data is not resent. In order to avoid this
9724 situation, try to arm loss detection and check the expiry
9725 here so that on next write call, we can resend
9726 Initial/Handshake first. */
9727 if (conn->cstat.loss_detection_timer == UINT64_MAX) {
9728 ngtcp2_conn_set_loss_detection_timer(conn, ts);
9729 if (ngtcp2_conn_loss_detection_expiry(conn) <= ts) {
9730 rv = ngtcp2_conn_on_loss_detection_timer(conn, ts);
9731 if (rv != 0) {
9732 return rv;
9733 }
9734 }
9735 }
9736
9737 if ((size_t)nread < pktlen) {
9738 /* We have 1RTT packet and application rx key, but the
9739 handshake has not completed yet. */
9740 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
9741 "buffering 1RTT packet len=%zu",
9742 pktlen - (size_t)nread);
9743
9744 rv = conn_buffer_pkt(conn, &conn->pktns, path, pi, pkt + nread,
9745 pktlen - (size_t)nread, pktlen, ts);
9746 if (rv != 0) {
9747 assert(ngtcp2_err_is_fatal(rv));
9748 return rv;
9749 }
9750
9751 return (ngtcp2_ssize)pktlen;
9752 }
9753
9754 return nread;
9755 }
9756
9757 if (!(conn->flags & NGTCP2_CONN_FLAG_TRANSPORT_PARAM_RECVED)) {
9758 return NGTCP2_ERR_REQUIRED_TRANSPORT_PARAM;
9759 }
9760
9761 rv = conn_handshake_completed(conn);
9762 if (rv != 0) {
9763 return rv;
9764 }
9765 conn->state = NGTCP2_CS_POST_HANDSHAKE;
9766
9767 rv = conn_call_activate_dcid(conn, &conn->dcid.current);
9768 if (rv != 0) {
9769 return rv;
9770 }
9771
9772 rv = conn_process_buffered_protected_pkt(conn, &conn->pktns, ts);
9773 if (rv != 0) {
9774 return rv;
9775 }
9776
9777 conn_discard_handshake_state(conn, ts);
9778
9779 rv = conn_enqueue_handshake_done(conn);
9780 if (rv != 0) {
9781 return rv;
9782 }
9783
9784 if (!conn->local.settings.no_pmtud) {
9785 rv = conn_start_pmtud(conn);
9786 if (rv != 0) {
9787 return rv;
9788 }
9789 }
9790
9791 conn->pktns.rtb.persistent_congestion_start_ts = ts;
9792
9793 /* Re-arm loss detection timer here after handshake has been
9794 confirmed. */
9795 ngtcp2_conn_set_loss_detection_timer(conn, ts);
9796
9797 return nread;
9798 case NGTCP2_CS_CLOSING:
9799 return NGTCP2_ERR_CLOSING;
9800 case NGTCP2_CS_DRAINING:
9801 return NGTCP2_ERR_DRAINING;
9802 default:
9803 return (ngtcp2_ssize)pktlen;
9804 }
9805 }
9806
ngtcp2_conn_read_pkt_versioned(ngtcp2_conn * conn,const ngtcp2_path * path,int pkt_info_version,const ngtcp2_pkt_info * pi,const uint8_t * pkt,size_t pktlen,ngtcp2_tstamp ts)9807 int ngtcp2_conn_read_pkt_versioned(ngtcp2_conn *conn, const ngtcp2_path *path,
9808 int pkt_info_version,
9809 const ngtcp2_pkt_info *pi,
9810 const uint8_t *pkt, size_t pktlen,
9811 ngtcp2_tstamp ts) {
9812 int rv = 0;
9813 ngtcp2_ssize nread = 0;
9814 const ngtcp2_pkt_info zero_pi = {0};
9815 (void)pkt_info_version;
9816
9817 conn->log.last_ts = ts;
9818 conn->qlog.last_ts = ts;
9819
9820 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON, "recv packet len=%zu",
9821 pktlen);
9822
9823 if (pktlen == 0) {
9824 return NGTCP2_ERR_INVALID_ARGUMENT;
9825 }
9826
9827 /* client does not expect a packet from unknown path. */
9828 if (!conn->server && !ngtcp2_path_eq(&conn->dcid.current.ps.path, path) &&
9829 (!conn->pv || !ngtcp2_path_eq(&conn->pv->dcid.ps.path, path)) &&
9830 !conn_is_retired_path(conn, path)) {
9831 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
9832 "ignore packet from unknown path");
9833 return 0;
9834 }
9835
9836 if (!pi) {
9837 pi = &zero_pi;
9838 }
9839
9840 switch (conn->state) {
9841 case NGTCP2_CS_CLIENT_INITIAL:
9842 case NGTCP2_CS_CLIENT_WAIT_HANDSHAKE:
9843 case NGTCP2_CS_CLIENT_TLS_HANDSHAKE_FAILED:
9844 nread = conn_read_handshake(conn, path, pi, pkt, pktlen, ts);
9845 if (nread < 0) {
9846 return (int)nread;
9847 }
9848
9849 if ((size_t)nread == pktlen) {
9850 return 0;
9851 }
9852
9853 assert(conn->pktns.crypto.rx.ckm);
9854
9855 pkt += nread;
9856 pktlen -= (size_t)nread;
9857
9858 break;
9859 case NGTCP2_CS_SERVER_INITIAL:
9860 case NGTCP2_CS_SERVER_WAIT_HANDSHAKE:
9861 case NGTCP2_CS_SERVER_TLS_HANDSHAKE_FAILED:
9862 if (!ngtcp2_path_eq(&conn->dcid.current.ps.path, path)) {
9863 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
9864 "ignore packet from unknown path during handshake");
9865
9866 if (conn->state == NGTCP2_CS_SERVER_INITIAL &&
9867 ngtcp2_strm_rx_offset(&conn->in_pktns->crypto.strm) == 0 &&
9868 (!conn->in_pktns->crypto.strm.rx.rob ||
9869 !ngtcp2_rob_data_buffered(conn->in_pktns->crypto.strm.rx.rob))) {
9870 return NGTCP2_ERR_DROP_CONN;
9871 }
9872
9873 return 0;
9874 }
9875
9876 nread = conn_read_handshake(conn, path, pi, pkt, pktlen, ts);
9877 if (nread < 0) {
9878 return (int)nread;
9879 }
9880
9881 if ((size_t)nread == pktlen) {
9882 return 0;
9883 }
9884
9885 assert(conn->pktns.crypto.rx.ckm);
9886
9887 pkt += nread;
9888 pktlen -= (size_t)nread;
9889
9890 break;
9891 case NGTCP2_CS_CLOSING:
9892 return NGTCP2_ERR_CLOSING;
9893 case NGTCP2_CS_DRAINING:
9894 return NGTCP2_ERR_DRAINING;
9895 case NGTCP2_CS_POST_HANDSHAKE:
9896 rv = conn_prepare_key_update(conn, ts);
9897 if (rv != 0) {
9898 return rv;
9899 }
9900 break;
9901 default:
9902 assert(0);
9903 abort();
9904 }
9905
9906 return conn_recv_cpkt(conn, path, pi, pkt, pktlen, ts);
9907 }
9908
9909 /*
9910 * conn_check_pkt_num_exhausted returns nonzero if packet number is
9911 * exhausted in at least one of packet number space.
9912 */
conn_check_pkt_num_exhausted(ngtcp2_conn * conn)9913 static int conn_check_pkt_num_exhausted(ngtcp2_conn *conn) {
9914 ngtcp2_pktns *in_pktns = conn->in_pktns;
9915 ngtcp2_pktns *hs_pktns = conn->hs_pktns;
9916
9917 return (in_pktns && in_pktns->tx.last_pkt_num == NGTCP2_MAX_PKT_NUM) ||
9918 (hs_pktns && hs_pktns->tx.last_pkt_num == NGTCP2_MAX_PKT_NUM) ||
9919 conn->pktns.tx.last_pkt_num == NGTCP2_MAX_PKT_NUM;
9920 }
9921
9922 /*
9923 * conn_retransmit_retry_early retransmits 0RTT packet after Retry is
9924 * received from server.
9925 */
conn_retransmit_retry_early(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,uint8_t flags,ngtcp2_tstamp ts)9926 static ngtcp2_ssize conn_retransmit_retry_early(ngtcp2_conn *conn,
9927 ngtcp2_pkt_info *pi,
9928 uint8_t *dest, size_t destlen,
9929 uint8_t flags,
9930 ngtcp2_tstamp ts) {
9931 return conn_write_pkt(conn, pi, dest, destlen, NULL, NGTCP2_PKT_0RTT, flags,
9932 ts);
9933 }
9934
9935 /*
9936 * conn_handshake_probe_left returns nonzero if there are probe
9937 * packets to be sent for Initial or Handshake packet number space
9938 * left.
9939 */
conn_handshake_probe_left(ngtcp2_conn * conn)9940 static int conn_handshake_probe_left(ngtcp2_conn *conn) {
9941 return (conn->in_pktns && conn->in_pktns->rtb.probe_pkt_left) ||
9942 conn->hs_pktns->rtb.probe_pkt_left;
9943 }
9944
9945 /*
9946 * conn_validate_early_transport_params_limits validates that the
9947 * limits in transport parameters remembered by client for early data
9948 * are not reduced. This function is only used by client and should
9949 * only be called when early data is accepted by server.
9950 */
conn_validate_early_transport_params_limits(ngtcp2_conn * conn)9951 static int conn_validate_early_transport_params_limits(ngtcp2_conn *conn) {
9952 const ngtcp2_transport_params *params = conn->remote.transport_params;
9953
9954 assert(!conn->server);
9955 assert(params);
9956
9957 if (conn->early.transport_params.active_connection_id_limit >
9958 params->active_connection_id_limit ||
9959 conn->early.transport_params.initial_max_data >
9960 params->initial_max_data ||
9961 conn->early.transport_params.initial_max_stream_data_bidi_local >
9962 params->initial_max_stream_data_bidi_local ||
9963 conn->early.transport_params.initial_max_stream_data_bidi_remote >
9964 params->initial_max_stream_data_bidi_remote ||
9965 conn->early.transport_params.initial_max_stream_data_uni >
9966 params->initial_max_stream_data_uni ||
9967 conn->early.transport_params.initial_max_streams_bidi >
9968 params->initial_max_streams_bidi ||
9969 conn->early.transport_params.initial_max_streams_uni >
9970 params->initial_max_streams_uni ||
9971 conn->early.transport_params.max_datagram_frame_size >
9972 params->max_datagram_frame_size) {
9973 return NGTCP2_ERR_PROTO;
9974 }
9975
9976 return 0;
9977 }
9978
9979 /*
9980 * conn_write_handshake writes QUIC handshake packets to the buffer
9981 * pointed by |dest| of length |destlen|. |write_datalen| specifies
9982 * the expected length of 0RTT or 1RTT packet payload. Specify 0 to
9983 * |write_datalen| if there is no such data.
9984 *
9985 * This function returns the number of bytes written to the buffer, or
9986 * one of the following negative error codes:
9987 *
9988 * NGTCP2_ERR_PKT_NUM_EXHAUSTED
9989 * Packet number is exhausted.
9990 * NGTCP2_ERR_NOMEM
9991 * Out of memory
9992 * NGTCP2_ERR_REQUIRED_TRANSPORT_PARAM
9993 * Required transport parameter is missing.
9994 * NGTCP2_CS_CLOSING
9995 * Connection is in closing state.
9996 * NGTCP2_CS_DRAINING
9997 * Connection is in draining state.
9998 *
9999 * In addition to the above negative error codes, the same error codes
10000 * from conn_recv_pkt may also be returned.
10001 */
conn_write_handshake(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,uint64_t write_datalen,ngtcp2_tstamp ts)10002 static ngtcp2_ssize conn_write_handshake(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
10003 uint8_t *dest, size_t destlen,
10004 uint64_t write_datalen,
10005 ngtcp2_tstamp ts) {
10006 int rv;
10007 ngtcp2_ssize res = 0, nwrite = 0, early_spktlen = 0;
10008 size_t origlen = destlen;
10009 uint64_t pending_early_datalen;
10010 ngtcp2_dcid *dcid;
10011 ngtcp2_preferred_addr *paddr;
10012
10013 switch (conn->state) {
10014 case NGTCP2_CS_CLIENT_INITIAL:
10015 pending_early_datalen = conn_retry_early_payloadlen(conn);
10016 if (pending_early_datalen) {
10017 write_datalen = pending_early_datalen;
10018 }
10019
10020 if (!(conn->flags & NGTCP2_CONN_FLAG_RECV_RETRY)) {
10021 nwrite =
10022 conn_write_client_initial(conn, pi, dest, destlen, write_datalen, ts);
10023 if (nwrite <= 0) {
10024 return nwrite;
10025 }
10026 } else {
10027 nwrite = conn_write_handshake_pkt(
10028 conn, pi, dest, destlen, NGTCP2_PKT_INITIAL,
10029 NGTCP2_WRITE_PKT_FLAG_NONE, write_datalen, ts);
10030 if (nwrite < 0) {
10031 return nwrite;
10032 }
10033 }
10034
10035 if (pending_early_datalen) {
10036 early_spktlen = conn_retransmit_retry_early(
10037 conn, pi, dest + nwrite, destlen - (size_t)nwrite,
10038 nwrite ? NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING
10039 : NGTCP2_WRITE_PKT_FLAG_NONE,
10040 ts);
10041
10042 if (early_spktlen < 0) {
10043 assert(ngtcp2_err_is_fatal((int)early_spktlen));
10044 return early_spktlen;
10045 }
10046 }
10047
10048 conn->state = NGTCP2_CS_CLIENT_WAIT_HANDSHAKE;
10049
10050 res = nwrite + early_spktlen;
10051
10052 return res;
10053 case NGTCP2_CS_CLIENT_WAIT_HANDSHAKE:
10054 if (!conn_handshake_probe_left(conn) && conn_cwnd_is_zero(conn)) {
10055 destlen = 0;
10056 } else {
10057 if (!(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_COMPLETED_HANDLED)) {
10058 pending_early_datalen = conn_retry_early_payloadlen(conn);
10059 if (pending_early_datalen) {
10060 write_datalen = pending_early_datalen;
10061 }
10062 }
10063
10064 nwrite =
10065 conn_write_handshake_pkts(conn, pi, dest, destlen, write_datalen, ts);
10066 if (nwrite < 0) {
10067 return nwrite;
10068 }
10069
10070 res += nwrite;
10071 dest += nwrite;
10072 destlen -= (size_t)nwrite;
10073 }
10074
10075 if (!conn_is_handshake_completed(conn)) {
10076 if (!(conn->flags & NGTCP2_CONN_FLAG_EARLY_DATA_REJECTED)) {
10077 nwrite = conn_retransmit_retry_early(conn, pi, dest, destlen,
10078 NGTCP2_WRITE_PKT_FLAG_NONE, ts);
10079 if (nwrite < 0) {
10080 return nwrite;
10081 }
10082
10083 res += nwrite;
10084 }
10085
10086 if (res == 0) {
10087 nwrite = conn_write_handshake_ack_pkts(conn, pi, dest, origlen, ts);
10088 if (nwrite < 0) {
10089 return nwrite;
10090 }
10091 res = nwrite;
10092 }
10093
10094 return res;
10095 }
10096
10097 if (!(conn->flags & NGTCP2_CONN_FLAG_TRANSPORT_PARAM_RECVED)) {
10098 return NGTCP2_ERR_REQUIRED_TRANSPORT_PARAM;
10099 }
10100
10101 if ((conn->flags & NGTCP2_CONN_FLAG_EARLY_KEY_INSTALLED) &&
10102 !(conn->flags & NGTCP2_CONN_FLAG_EARLY_DATA_REJECTED)) {
10103 rv = conn_validate_early_transport_params_limits(conn);
10104 if (rv != 0) {
10105 return rv;
10106 }
10107 }
10108
10109 /* Server might increase stream data limits. Extend it if we have
10110 streams created for early data. */
10111 rv = conn_sync_stream_data_limit(conn);
10112 if (rv != 0) {
10113 return rv;
10114 }
10115
10116 conn->state = NGTCP2_CS_POST_HANDSHAKE;
10117
10118 assert(conn->remote.transport_params);
10119
10120 if (conn->remote.transport_params->preferred_address_present) {
10121 assert(!ngtcp2_ringbuf_full(&conn->dcid.unused.rb));
10122
10123 paddr = &conn->remote.transport_params->preferred_address;
10124 dcid = ngtcp2_ringbuf_push_back(&conn->dcid.unused.rb);
10125 ngtcp2_dcid_init(dcid, 1, &paddr->cid, paddr->stateless_reset_token);
10126
10127 rv = ngtcp2_gaptr_push(&conn->dcid.seqgap, 1, 1);
10128 if (rv != 0) {
10129 return (ngtcp2_ssize)rv;
10130 }
10131 }
10132
10133 if (conn->remote.transport_params->stateless_reset_token_present) {
10134 assert(conn->dcid.current.seq == 0);
10135 assert(!(conn->dcid.current.flags & NGTCP2_DCID_FLAG_TOKEN_PRESENT));
10136 ngtcp2_dcid_set_token(
10137 &conn->dcid.current,
10138 conn->remote.transport_params->stateless_reset_token);
10139 }
10140
10141 rv = conn_call_activate_dcid(conn, &conn->dcid.current);
10142 if (rv != 0) {
10143 return rv;
10144 }
10145
10146 conn_process_early_rtb(conn);
10147
10148 if (!conn->local.settings.no_pmtud) {
10149 rv = conn_start_pmtud(conn);
10150 if (rv != 0) {
10151 return rv;
10152 }
10153 }
10154
10155 return res;
10156 case NGTCP2_CS_SERVER_INITIAL:
10157 nwrite =
10158 conn_write_handshake_pkts(conn, pi, dest, destlen, write_datalen, ts);
10159 if (nwrite < 0) {
10160 return nwrite;
10161 }
10162
10163 if (nwrite) {
10164 conn->state = NGTCP2_CS_SERVER_WAIT_HANDSHAKE;
10165 }
10166
10167 return nwrite;
10168 case NGTCP2_CS_SERVER_WAIT_HANDSHAKE:
10169 if (conn_handshake_probe_left(conn) || !conn_cwnd_is_zero(conn)) {
10170 nwrite =
10171 conn_write_handshake_pkts(conn, pi, dest, destlen, write_datalen, ts);
10172 if (nwrite < 0) {
10173 return nwrite;
10174 }
10175
10176 res += nwrite;
10177 dest += nwrite;
10178 destlen -= (size_t)nwrite;
10179 }
10180
10181 if (res == 0) {
10182 nwrite = conn_write_handshake_ack_pkts(conn, pi, dest, origlen, ts);
10183 if (nwrite < 0) {
10184 return nwrite;
10185 }
10186
10187 res += nwrite;
10188 dest += nwrite;
10189 origlen -= (size_t)nwrite;
10190 }
10191
10192 return res;
10193 case NGTCP2_CS_CLOSING:
10194 return NGTCP2_ERR_CLOSING;
10195 case NGTCP2_CS_DRAINING:
10196 return NGTCP2_ERR_DRAINING;
10197 default:
10198 return 0;
10199 }
10200 }
10201
10202 /**
10203 * @function
10204 *
10205 * `conn_client_write_handshake` writes client side handshake data and
10206 * 0RTT packet.
10207 *
10208 * In order to send STREAM data in 0RTT packet, specify
10209 * |vmsg|->stream. |vmsg|->stream.strm, |vmsg|->stream.fin,
10210 * |vmsg|->stream.data, and |vmsg|->stream.datacnt are stream to which
10211 * 0-RTT data is sent, whether it is a last data chunk in this stream,
10212 * a vector of 0-RTT data, and its number of elements respectively.
10213 * The amount of 0RTT data sent is assigned to
10214 * *|vmsg|->stream.pdatalen. If no data is sent, -1 is assigned.
10215 * Note that 0 length STREAM frame is allowed in QUIC, so 0 might be
10216 * assigned to *|vmsg|->stream.pdatalen.
10217 *
10218 * This function returns 0 if it cannot write any frame because buffer
10219 * is too small, or packet is congestion limited. Application should
10220 * keep reading and wait for congestion window to grow.
10221 *
10222 * This function returns the number of bytes written to the buffer
10223 * pointed by |dest| if it succeeds, or one of the following negative
10224 * error codes: (TBD).
10225 */
conn_client_write_handshake(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,ngtcp2_vmsg * vmsg,ngtcp2_tstamp ts)10226 static ngtcp2_ssize conn_client_write_handshake(ngtcp2_conn *conn,
10227 ngtcp2_pkt_info *pi,
10228 uint8_t *dest, size_t destlen,
10229 ngtcp2_vmsg *vmsg,
10230 ngtcp2_tstamp ts) {
10231 int send_stream = 0;
10232 int send_datagram = 0;
10233 ngtcp2_ssize spktlen, early_spktlen;
10234 uint64_t datalen;
10235 uint64_t write_datalen = 0;
10236 uint8_t wflags = NGTCP2_WRITE_PKT_FLAG_NONE;
10237 int ppe_pending = (conn->flags & NGTCP2_CONN_FLAG_PPE_PENDING) != 0;
10238 uint32_t version;
10239
10240 assert(!conn->server);
10241
10242 /* conn->early.ckm might be created in the first call of
10243 conn_handshake(). Check it later. */
10244 if (vmsg) {
10245 switch (vmsg->type) {
10246 case NGTCP2_VMSG_TYPE_STREAM:
10247 datalen = ngtcp2_vec_len(vmsg->stream.data, vmsg->stream.datacnt);
10248 send_stream =
10249 conn_retry_early_payloadlen(conn) == 0 &&
10250 /* 0 length STREAM frame is allowed */
10251 (datalen == 0 ||
10252 (datalen > 0 &&
10253 (vmsg->stream.strm->tx.max_offset - vmsg->stream.strm->tx.offset) &&
10254 (conn->tx.max_offset - conn->tx.offset)));
10255 if (send_stream) {
10256 write_datalen =
10257 conn_enforce_flow_control(conn, vmsg->stream.strm, datalen);
10258 write_datalen =
10259 ngtcp2_min(write_datalen, NGTCP2_MIN_COALESCED_PAYLOADLEN);
10260 write_datalen += NGTCP2_STREAM_OVERHEAD;
10261
10262 if (vmsg->stream.flags & NGTCP2_WRITE_STREAM_FLAG_MORE) {
10263 wflags |= NGTCP2_WRITE_PKT_FLAG_MORE;
10264 }
10265 } else {
10266 vmsg = NULL;
10267 }
10268 break;
10269 case NGTCP2_VMSG_TYPE_DATAGRAM:
10270 datalen = ngtcp2_vec_len(vmsg->datagram.data, vmsg->datagram.datacnt);
10271 send_datagram = conn_retry_early_payloadlen(conn) == 0;
10272 if (send_datagram) {
10273 write_datalen = datalen + NGTCP2_DATAGRAM_OVERHEAD;
10274
10275 if (vmsg->datagram.flags & NGTCP2_WRITE_DATAGRAM_FLAG_MORE) {
10276 wflags |= NGTCP2_WRITE_PKT_FLAG_MORE;
10277 }
10278 } else {
10279 vmsg = NULL;
10280 }
10281 break;
10282 }
10283 }
10284
10285 if (!ppe_pending) {
10286 spktlen = conn_write_handshake(conn, pi, dest, destlen, write_datalen, ts);
10287
10288 if (spktlen < 0) {
10289 return spktlen;
10290 }
10291
10292 if ((conn->flags & NGTCP2_CONN_FLAG_EARLY_DATA_REJECTED) ||
10293 !conn->early.ckm || (!send_stream && !send_datagram)) {
10294 return spktlen;
10295 }
10296
10297 /* If spktlen > 0, we are making a compound packet. If Initial
10298 packet is written, we have to pad bytes to 0-RTT packet. */
10299 version = conn->negotiated_version ? conn->negotiated_version
10300 : conn->client_chosen_version;
10301 if (spktlen > 0 &&
10302 ngtcp2_pkt_get_type_long(version, dest[0]) == NGTCP2_PKT_INITIAL) {
10303 wflags |= NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
10304 conn->pkt.require_padding = 1;
10305 } else {
10306 conn->pkt.require_padding = 0;
10307 }
10308 } else {
10309 assert(!conn->pktns.crypto.rx.ckm);
10310 assert(!conn->pktns.crypto.tx.ckm);
10311 assert(conn->early.ckm);
10312
10313 if (conn->pkt.require_padding) {
10314 wflags |= NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
10315 }
10316 spktlen = conn->pkt.hs_spktlen;
10317 }
10318
10319 dest += spktlen;
10320 destlen -= (size_t)spktlen;
10321
10322 if (conn_cwnd_is_zero(conn)) {
10323 return spktlen;
10324 }
10325
10326 early_spktlen = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_0RTT,
10327 wflags, ts);
10328
10329 if (early_spktlen < 0) {
10330 switch (early_spktlen) {
10331 case NGTCP2_ERR_STREAM_DATA_BLOCKED:
10332 return spktlen;
10333 case NGTCP2_ERR_WRITE_MORE:
10334 conn->pkt.hs_spktlen = spktlen;
10335 break;
10336 }
10337 return early_spktlen;
10338 }
10339
10340 return spktlen + early_spktlen;
10341 }
10342
ngtcp2_conn_handshake_completed(ngtcp2_conn * conn)10343 void ngtcp2_conn_handshake_completed(ngtcp2_conn *conn) {
10344 conn->flags |= NGTCP2_CONN_FLAG_HANDSHAKE_COMPLETED;
10345 if (conn->server) {
10346 conn->flags |= NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED;
10347 }
10348 }
10349
ngtcp2_conn_get_handshake_completed(ngtcp2_conn * conn)10350 int ngtcp2_conn_get_handshake_completed(ngtcp2_conn *conn) {
10351 return conn_is_handshake_completed(conn) &&
10352 (conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_COMPLETED_HANDLED);
10353 }
10354
ngtcp2_conn_sched_ack(ngtcp2_conn * conn,ngtcp2_acktr * acktr,int64_t pkt_num,int active_ack,ngtcp2_tstamp ts)10355 int ngtcp2_conn_sched_ack(ngtcp2_conn *conn, ngtcp2_acktr *acktr,
10356 int64_t pkt_num, int active_ack, ngtcp2_tstamp ts) {
10357 int rv;
10358 (void)conn;
10359
10360 rv = ngtcp2_acktr_add(acktr, pkt_num, active_ack, ts);
10361 if (rv != 0) {
10362 assert(rv != NGTCP2_ERR_INVALID_ARGUMENT);
10363 return rv;
10364 }
10365
10366 return 0;
10367 }
10368
ngtcp2_accept(ngtcp2_pkt_hd * dest,const uint8_t * pkt,size_t pktlen)10369 int ngtcp2_accept(ngtcp2_pkt_hd *dest, const uint8_t *pkt, size_t pktlen) {
10370 ngtcp2_ssize nread;
10371 ngtcp2_pkt_hd hd, *p;
10372
10373 if (dest) {
10374 p = dest;
10375 } else {
10376 p = &hd;
10377 }
10378
10379 if (pktlen == 0 || (pkt[0] & NGTCP2_HEADER_FORM_BIT) == 0) {
10380 return NGTCP2_ERR_INVALID_ARGUMENT;
10381 }
10382
10383 nread = ngtcp2_pkt_decode_hd_long(p, pkt, pktlen);
10384 if (nread < 0) {
10385 return (int)nread;
10386 }
10387
10388 switch (p->type) {
10389 case NGTCP2_PKT_INITIAL:
10390 break;
10391 case NGTCP2_PKT_0RTT:
10392 /* 0-RTT packet may arrive before Initial packet due to
10393 re-ordering. ngtcp2 does not buffer 0RTT packet unless the
10394 very first Initial packet is received or token is received. */
10395 return NGTCP2_ERR_RETRY;
10396 default:
10397 return NGTCP2_ERR_INVALID_ARGUMENT;
10398 }
10399
10400 if (pktlen < NGTCP2_MAX_UDP_PAYLOAD_SIZE ||
10401 (p->token.len == 0 && p->dcid.datalen < NGTCP2_MIN_INITIAL_DCIDLEN)) {
10402 return NGTCP2_ERR_INVALID_ARGUMENT;
10403 }
10404
10405 return 0;
10406 }
10407
ngtcp2_conn_install_initial_key(ngtcp2_conn * conn,const ngtcp2_crypto_aead_ctx * rx_aead_ctx,const uint8_t * rx_iv,const ngtcp2_crypto_cipher_ctx * rx_hp_ctx,const ngtcp2_crypto_aead_ctx * tx_aead_ctx,const uint8_t * tx_iv,const ngtcp2_crypto_cipher_ctx * tx_hp_ctx,size_t ivlen)10408 int ngtcp2_conn_install_initial_key(
10409 ngtcp2_conn *conn, const ngtcp2_crypto_aead_ctx *rx_aead_ctx,
10410 const uint8_t *rx_iv, const ngtcp2_crypto_cipher_ctx *rx_hp_ctx,
10411 const ngtcp2_crypto_aead_ctx *tx_aead_ctx, const uint8_t *tx_iv,
10412 const ngtcp2_crypto_cipher_ctx *tx_hp_ctx, size_t ivlen) {
10413 ngtcp2_pktns *pktns = conn->in_pktns;
10414 int rv;
10415
10416 assert(ivlen >= 8);
10417 assert(pktns);
10418
10419 conn_call_delete_crypto_cipher_ctx(conn, &pktns->crypto.rx.hp_ctx);
10420 pktns->crypto.rx.hp_ctx.native_handle = NULL;
10421
10422 if (pktns->crypto.rx.ckm) {
10423 conn_call_delete_crypto_aead_ctx(conn, &pktns->crypto.rx.ckm->aead_ctx);
10424 ngtcp2_crypto_km_del(pktns->crypto.rx.ckm, conn->mem);
10425 pktns->crypto.rx.ckm = NULL;
10426 }
10427
10428 conn_call_delete_crypto_cipher_ctx(conn, &pktns->crypto.tx.hp_ctx);
10429 pktns->crypto.tx.hp_ctx.native_handle = NULL;
10430
10431 if (pktns->crypto.tx.ckm) {
10432 conn_call_delete_crypto_aead_ctx(conn, &pktns->crypto.tx.ckm->aead_ctx);
10433 ngtcp2_crypto_km_del(pktns->crypto.tx.ckm, conn->mem);
10434 pktns->crypto.tx.ckm = NULL;
10435 }
10436
10437 rv = ngtcp2_crypto_km_new(&pktns->crypto.rx.ckm, NULL, 0, NULL, rx_iv, ivlen,
10438 conn->mem);
10439 if (rv != 0) {
10440 return rv;
10441 }
10442
10443 rv = ngtcp2_crypto_km_new(&pktns->crypto.tx.ckm, NULL, 0, NULL, tx_iv, ivlen,
10444 conn->mem);
10445 if (rv != 0) {
10446 return rv;
10447 }
10448
10449 /* Take owner ship after we are sure that no failure occurs, so that
10450 caller can delete these contexts on failure. */
10451 pktns->crypto.rx.ckm->aead_ctx = *rx_aead_ctx;
10452 pktns->crypto.rx.hp_ctx = *rx_hp_ctx;
10453 pktns->crypto.tx.ckm->aead_ctx = *tx_aead_ctx;
10454 pktns->crypto.tx.hp_ctx = *tx_hp_ctx;
10455
10456 return 0;
10457 }
10458
ngtcp2_conn_install_vneg_initial_key(ngtcp2_conn * conn,uint32_t version,const ngtcp2_crypto_aead_ctx * rx_aead_ctx,const uint8_t * rx_iv,const ngtcp2_crypto_cipher_ctx * rx_hp_ctx,const ngtcp2_crypto_aead_ctx * tx_aead_ctx,const uint8_t * tx_iv,const ngtcp2_crypto_cipher_ctx * tx_hp_ctx,size_t ivlen)10459 int ngtcp2_conn_install_vneg_initial_key(
10460 ngtcp2_conn *conn, uint32_t version,
10461 const ngtcp2_crypto_aead_ctx *rx_aead_ctx, const uint8_t *rx_iv,
10462 const ngtcp2_crypto_cipher_ctx *rx_hp_ctx,
10463 const ngtcp2_crypto_aead_ctx *tx_aead_ctx, const uint8_t *tx_iv,
10464 const ngtcp2_crypto_cipher_ctx *tx_hp_ctx, size_t ivlen) {
10465 int rv;
10466
10467 assert(ivlen >= 8);
10468
10469 conn_call_delete_crypto_cipher_ctx(conn, &conn->vneg.rx.hp_ctx);
10470 conn->vneg.rx.hp_ctx.native_handle = NULL;
10471
10472 if (conn->vneg.rx.ckm) {
10473 conn_call_delete_crypto_aead_ctx(conn, &conn->vneg.rx.ckm->aead_ctx);
10474 ngtcp2_crypto_km_del(conn->vneg.rx.ckm, conn->mem);
10475 conn->vneg.rx.ckm = NULL;
10476 }
10477
10478 conn_call_delete_crypto_cipher_ctx(conn, &conn->vneg.tx.hp_ctx);
10479 conn->vneg.tx.hp_ctx.native_handle = NULL;
10480
10481 if (conn->vneg.tx.ckm) {
10482 conn_call_delete_crypto_aead_ctx(conn, &conn->vneg.tx.ckm->aead_ctx);
10483 ngtcp2_crypto_km_del(conn->vneg.tx.ckm, conn->mem);
10484 conn->vneg.tx.ckm = NULL;
10485 }
10486
10487 rv = ngtcp2_crypto_km_new(&conn->vneg.rx.ckm, NULL, 0, NULL, rx_iv, ivlen,
10488 conn->mem);
10489 if (rv != 0) {
10490 return rv;
10491 }
10492
10493 rv = ngtcp2_crypto_km_new(&conn->vneg.tx.ckm, NULL, 0, NULL, tx_iv, ivlen,
10494 conn->mem);
10495 if (rv != 0) {
10496 return rv;
10497 }
10498
10499 /* Take owner ship after we are sure that no failure occurs, so that
10500 caller can delete these contexts on failure. */
10501 conn->vneg.rx.ckm->aead_ctx = *rx_aead_ctx;
10502 conn->vneg.rx.hp_ctx = *rx_hp_ctx;
10503 conn->vneg.tx.ckm->aead_ctx = *tx_aead_ctx;
10504 conn->vneg.tx.hp_ctx = *tx_hp_ctx;
10505 conn->vneg.version = version;
10506
10507 return 0;
10508 }
10509
ngtcp2_conn_install_rx_handshake_key(ngtcp2_conn * conn,const ngtcp2_crypto_aead_ctx * aead_ctx,const uint8_t * iv,size_t ivlen,const ngtcp2_crypto_cipher_ctx * hp_ctx)10510 int ngtcp2_conn_install_rx_handshake_key(
10511 ngtcp2_conn *conn, const ngtcp2_crypto_aead_ctx *aead_ctx,
10512 const uint8_t *iv, size_t ivlen, const ngtcp2_crypto_cipher_ctx *hp_ctx) {
10513 ngtcp2_pktns *pktns = conn->hs_pktns;
10514 int rv;
10515
10516 assert(ivlen >= 8);
10517 assert(pktns);
10518 assert(!pktns->crypto.rx.hp_ctx.native_handle);
10519 assert(!pktns->crypto.rx.ckm);
10520
10521 rv = ngtcp2_crypto_km_new(&pktns->crypto.rx.ckm, NULL, 0, aead_ctx, iv, ivlen,
10522 conn->mem);
10523 if (rv != 0) {
10524 return rv;
10525 }
10526
10527 pktns->crypto.rx.hp_ctx = *hp_ctx;
10528
10529 rv = conn_call_recv_rx_key(conn, NGTCP2_CRYPTO_LEVEL_HANDSHAKE);
10530 if (rv != 0) {
10531 ngtcp2_crypto_km_del(pktns->crypto.rx.ckm, conn->mem);
10532 pktns->crypto.rx.ckm = NULL;
10533
10534 memset(&pktns->crypto.rx.hp_ctx, 0, sizeof(pktns->crypto.rx.hp_ctx));
10535
10536 return rv;
10537 }
10538
10539 return 0;
10540 }
10541
ngtcp2_conn_install_tx_handshake_key(ngtcp2_conn * conn,const ngtcp2_crypto_aead_ctx * aead_ctx,const uint8_t * iv,size_t ivlen,const ngtcp2_crypto_cipher_ctx * hp_ctx)10542 int ngtcp2_conn_install_tx_handshake_key(
10543 ngtcp2_conn *conn, const ngtcp2_crypto_aead_ctx *aead_ctx,
10544 const uint8_t *iv, size_t ivlen, const ngtcp2_crypto_cipher_ctx *hp_ctx) {
10545 ngtcp2_pktns *pktns = conn->hs_pktns;
10546 int rv;
10547
10548 assert(ivlen >= 8);
10549 assert(pktns);
10550 assert(!pktns->crypto.tx.hp_ctx.native_handle);
10551 assert(!pktns->crypto.tx.ckm);
10552
10553 rv = ngtcp2_crypto_km_new(&pktns->crypto.tx.ckm, NULL, 0, aead_ctx, iv, ivlen,
10554 conn->mem);
10555 if (rv != 0) {
10556 return rv;
10557 }
10558
10559 pktns->crypto.tx.hp_ctx = *hp_ctx;
10560
10561 if (conn->server) {
10562 rv = ngtcp2_conn_commit_local_transport_params(conn);
10563 if (rv != 0) {
10564 return rv;
10565 }
10566 }
10567
10568 rv = conn_call_recv_tx_key(conn, NGTCP2_CRYPTO_LEVEL_HANDSHAKE);
10569 if (rv != 0) {
10570 ngtcp2_crypto_km_del(pktns->crypto.tx.ckm, conn->mem);
10571 pktns->crypto.tx.ckm = NULL;
10572
10573 memset(&pktns->crypto.tx.hp_ctx, 0, sizeof(pktns->crypto.tx.hp_ctx));
10574
10575 return rv;
10576 }
10577
10578 return 0;
10579 }
10580
ngtcp2_conn_install_early_key(ngtcp2_conn * conn,const ngtcp2_crypto_aead_ctx * aead_ctx,const uint8_t * iv,size_t ivlen,const ngtcp2_crypto_cipher_ctx * hp_ctx)10581 int ngtcp2_conn_install_early_key(ngtcp2_conn *conn,
10582 const ngtcp2_crypto_aead_ctx *aead_ctx,
10583 const uint8_t *iv, size_t ivlen,
10584 const ngtcp2_crypto_cipher_ctx *hp_ctx) {
10585 int rv;
10586
10587 assert(ivlen >= 8);
10588 assert(!conn->early.hp_ctx.native_handle);
10589 assert(!conn->early.ckm);
10590
10591 rv = ngtcp2_crypto_km_new(&conn->early.ckm, NULL, 0, aead_ctx, iv, ivlen,
10592 conn->mem);
10593 if (rv != 0) {
10594 return rv;
10595 }
10596
10597 conn->early.hp_ctx = *hp_ctx;
10598
10599 conn->flags |= NGTCP2_CONN_FLAG_EARLY_KEY_INSTALLED;
10600
10601 if (conn->server) {
10602 rv = conn_call_recv_rx_key(conn, NGTCP2_CRYPTO_LEVEL_EARLY);
10603 } else {
10604 rv = conn_call_recv_tx_key(conn, NGTCP2_CRYPTO_LEVEL_EARLY);
10605 }
10606 if (rv != 0) {
10607 ngtcp2_crypto_km_del(conn->early.ckm, conn->mem);
10608 conn->early.ckm = NULL;
10609
10610 memset(&conn->early.hp_ctx, 0, sizeof(conn->early.hp_ctx));
10611
10612 return rv;
10613 }
10614
10615 return 0;
10616 }
10617
ngtcp2_conn_install_rx_key(ngtcp2_conn * conn,const uint8_t * secret,size_t secretlen,const ngtcp2_crypto_aead_ctx * aead_ctx,const uint8_t * iv,size_t ivlen,const ngtcp2_crypto_cipher_ctx * hp_ctx)10618 int ngtcp2_conn_install_rx_key(ngtcp2_conn *conn, const uint8_t *secret,
10619 size_t secretlen,
10620 const ngtcp2_crypto_aead_ctx *aead_ctx,
10621 const uint8_t *iv, size_t ivlen,
10622 const ngtcp2_crypto_cipher_ctx *hp_ctx) {
10623 ngtcp2_pktns *pktns = &conn->pktns;
10624 int rv;
10625
10626 assert(ivlen >= 8);
10627 assert(!pktns->crypto.rx.hp_ctx.native_handle);
10628 assert(!pktns->crypto.rx.ckm);
10629
10630 rv = ngtcp2_crypto_km_new(&pktns->crypto.rx.ckm, secret, secretlen, aead_ctx,
10631 iv, ivlen, conn->mem);
10632 if (rv != 0) {
10633 return rv;
10634 }
10635
10636 pktns->crypto.rx.hp_ctx = *hp_ctx;
10637
10638 if (!conn->server) {
10639 if (conn->remote.pending_transport_params) {
10640 ngtcp2_transport_params_del(conn->remote.transport_params, conn->mem);
10641
10642 conn->remote.transport_params = conn->remote.pending_transport_params;
10643 conn->remote.pending_transport_params = NULL;
10644 conn_sync_stream_id_limit(conn);
10645 conn->tx.max_offset = conn->remote.transport_params->initial_max_data;
10646 }
10647
10648 if (conn->early.ckm) {
10649 conn_discard_early_key(conn);
10650 }
10651 }
10652
10653 rv = conn_call_recv_rx_key(conn, NGTCP2_CRYPTO_LEVEL_APPLICATION);
10654 if (rv != 0) {
10655 ngtcp2_crypto_km_del(pktns->crypto.rx.ckm, conn->mem);
10656 pktns->crypto.rx.ckm = NULL;
10657
10658 memset(&pktns->crypto.rx.hp_ctx, 0, sizeof(pktns->crypto.rx.hp_ctx));
10659
10660 return rv;
10661 }
10662
10663 return 0;
10664 }
10665
ngtcp2_conn_install_tx_key(ngtcp2_conn * conn,const uint8_t * secret,size_t secretlen,const ngtcp2_crypto_aead_ctx * aead_ctx,const uint8_t * iv,size_t ivlen,const ngtcp2_crypto_cipher_ctx * hp_ctx)10666 int ngtcp2_conn_install_tx_key(ngtcp2_conn *conn, const uint8_t *secret,
10667 size_t secretlen,
10668 const ngtcp2_crypto_aead_ctx *aead_ctx,
10669 const uint8_t *iv, size_t ivlen,
10670 const ngtcp2_crypto_cipher_ctx *hp_ctx) {
10671 ngtcp2_pktns *pktns = &conn->pktns;
10672 int rv;
10673
10674 assert(ivlen >= 8);
10675 assert(!pktns->crypto.tx.hp_ctx.native_handle);
10676 assert(!pktns->crypto.tx.ckm);
10677
10678 rv = ngtcp2_crypto_km_new(&pktns->crypto.tx.ckm, secret, secretlen, aead_ctx,
10679 iv, ivlen, conn->mem);
10680 if (rv != 0) {
10681 return rv;
10682 }
10683
10684 pktns->crypto.tx.hp_ctx = *hp_ctx;
10685
10686 if (conn->server) {
10687 if (conn->remote.pending_transport_params) {
10688 ngtcp2_transport_params_del(conn->remote.transport_params, conn->mem);
10689
10690 conn->remote.transport_params = conn->remote.pending_transport_params;
10691 conn->remote.pending_transport_params = NULL;
10692 conn_sync_stream_id_limit(conn);
10693 conn->tx.max_offset = conn->remote.transport_params->initial_max_data;
10694 }
10695 } else if (conn->early.ckm) {
10696 conn_discard_early_key(conn);
10697 }
10698
10699 rv = conn_call_recv_tx_key(conn, NGTCP2_CRYPTO_LEVEL_APPLICATION);
10700 if (rv != 0) {
10701 ngtcp2_crypto_km_del(pktns->crypto.tx.ckm, conn->mem);
10702 pktns->crypto.tx.ckm = NULL;
10703
10704 memset(&pktns->crypto.tx.hp_ctx, 0, sizeof(pktns->crypto.tx.hp_ctx));
10705
10706 return rv;
10707 }
10708
10709 return 0;
10710 }
10711
ngtcp2_conn_initiate_key_update(ngtcp2_conn * conn,ngtcp2_tstamp ts)10712 int ngtcp2_conn_initiate_key_update(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
10713 ngtcp2_tstamp confirmed_ts = conn->crypto.key_update.confirmed_ts;
10714 ngtcp2_duration pto = conn_compute_pto(conn, &conn->pktns);
10715
10716 assert(conn->state == NGTCP2_CS_POST_HANDSHAKE);
10717
10718 if (!(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED) ||
10719 (conn->flags & NGTCP2_CONN_FLAG_KEY_UPDATE_NOT_CONFIRMED) ||
10720 !conn->crypto.key_update.new_tx_ckm ||
10721 !conn->crypto.key_update.new_rx_ckm ||
10722 (confirmed_ts != UINT64_MAX && confirmed_ts + 3 * pto > ts)) {
10723 return NGTCP2_ERR_INVALID_STATE;
10724 }
10725
10726 conn_rotate_keys(conn, NGTCP2_MAX_PKT_NUM, /* initiator = */ 1);
10727
10728 return 0;
10729 }
10730
10731 /*
10732 * conn_retire_stale_bound_dcid retires stale destination connection
10733 * ID in conn->dcid.bound to keep some unused destination connection
10734 * IDs available.
10735 *
10736 * This function returns 0 if it succeeds, or one of the following
10737 * negative error codes:
10738 *
10739 * NGTCP2_ERR_NOMEM
10740 * Out of memory.
10741 */
conn_retire_stale_bound_dcid(ngtcp2_conn * conn,ngtcp2_duration timeout,ngtcp2_tstamp ts)10742 static int conn_retire_stale_bound_dcid(ngtcp2_conn *conn,
10743 ngtcp2_duration timeout,
10744 ngtcp2_tstamp ts) {
10745 size_t i;
10746 ngtcp2_dcid *dcid, *last;
10747 int rv;
10748
10749 for (i = 0; i < ngtcp2_ringbuf_len(&conn->dcid.bound.rb);) {
10750 dcid = ngtcp2_ringbuf_get(&conn->dcid.bound.rb, i);
10751
10752 assert(dcid->cid.datalen);
10753
10754 if (dcid->bound_ts + timeout > ts) {
10755 ++i;
10756 continue;
10757 }
10758
10759 rv = conn_retire_dcid_seq(conn, dcid->seq);
10760 if (rv != 0) {
10761 return rv;
10762 }
10763
10764 if (i == 0) {
10765 ngtcp2_ringbuf_pop_front(&conn->dcid.bound.rb);
10766 continue;
10767 }
10768
10769 if (i == ngtcp2_ringbuf_len(&conn->dcid.bound.rb) - 1) {
10770 ngtcp2_ringbuf_pop_back(&conn->dcid.bound.rb);
10771 break;
10772 }
10773
10774 last = ngtcp2_ringbuf_get(&conn->dcid.bound.rb,
10775 ngtcp2_ringbuf_len(&conn->dcid.bound.rb) - 1);
10776 ngtcp2_dcid_copy(dcid, last);
10777 ngtcp2_ringbuf_pop_back(&conn->dcid.bound.rb);
10778 }
10779
10780 return 0;
10781 }
10782
ngtcp2_conn_loss_detection_expiry(ngtcp2_conn * conn)10783 ngtcp2_tstamp ngtcp2_conn_loss_detection_expiry(ngtcp2_conn *conn) {
10784 return conn->cstat.loss_detection_timer;
10785 }
10786
ngtcp2_conn_internal_expiry(ngtcp2_conn * conn)10787 ngtcp2_tstamp ngtcp2_conn_internal_expiry(ngtcp2_conn *conn) {
10788 ngtcp2_tstamp res = UINT64_MAX, t;
10789 ngtcp2_duration pto = conn_compute_pto(conn, &conn->pktns);
10790 ngtcp2_scid *scid;
10791 ngtcp2_dcid *dcid;
10792 size_t i, len;
10793
10794 if (conn->pv) {
10795 res = ngtcp2_pv_next_expiry(conn->pv);
10796 }
10797
10798 if (conn->pmtud) {
10799 res = ngtcp2_min(res, conn->pmtud->expiry);
10800 }
10801
10802 if (!ngtcp2_pq_empty(&conn->scid.used)) {
10803 scid = ngtcp2_struct_of(ngtcp2_pq_top(&conn->scid.used), ngtcp2_scid, pe);
10804 if (scid->retired_ts != UINT64_MAX) {
10805 t = scid->retired_ts + pto;
10806 res = ngtcp2_min(res, t);
10807 }
10808 }
10809
10810 if (ngtcp2_ringbuf_len(&conn->dcid.retired.rb)) {
10811 dcid = ngtcp2_ringbuf_get(&conn->dcid.retired.rb, 0);
10812 t = dcid->retired_ts + pto;
10813 res = ngtcp2_min(res, t);
10814 }
10815
10816 if (conn->dcid.current.cid.datalen) {
10817 len = ngtcp2_ringbuf_len(&conn->dcid.bound.rb);
10818 for (i = 0; i < len; ++i) {
10819 dcid = ngtcp2_ringbuf_get(&conn->dcid.bound.rb, i);
10820
10821 assert(dcid->cid.datalen);
10822 assert(dcid->bound_ts != UINT64_MAX);
10823
10824 t = dcid->bound_ts + 3 * pto;
10825 res = ngtcp2_min(res, t);
10826 }
10827 }
10828
10829 if (conn->server && conn->early.ckm &&
10830 conn->early.discard_started_ts != UINT64_MAX) {
10831 t = conn->early.discard_started_ts + 3 * pto;
10832 res = ngtcp2_min(res, t);
10833 }
10834
10835 return res;
10836 }
10837
ngtcp2_conn_ack_delay_expiry(ngtcp2_conn * conn)10838 ngtcp2_tstamp ngtcp2_conn_ack_delay_expiry(ngtcp2_conn *conn) {
10839 ngtcp2_acktr *acktr = &conn->pktns.acktr;
10840
10841 if (!(acktr->flags & NGTCP2_ACKTR_FLAG_CANCEL_TIMER) &&
10842 acktr->first_unacked_ts != UINT64_MAX) {
10843 return acktr->first_unacked_ts + conn_compute_ack_delay(conn);
10844 }
10845 return UINT64_MAX;
10846 }
10847
conn_handshake_expiry(ngtcp2_conn * conn)10848 static ngtcp2_tstamp conn_handshake_expiry(ngtcp2_conn *conn) {
10849 if (conn_is_handshake_completed(conn) ||
10850 conn->local.settings.handshake_timeout == UINT64_MAX) {
10851 return UINT64_MAX;
10852 }
10853
10854 return conn->local.settings.initial_ts +
10855 conn->local.settings.handshake_timeout;
10856 }
10857
ngtcp2_conn_get_expiry(ngtcp2_conn * conn)10858 ngtcp2_tstamp ngtcp2_conn_get_expiry(ngtcp2_conn *conn) {
10859 ngtcp2_tstamp t1 = ngtcp2_conn_loss_detection_expiry(conn);
10860 ngtcp2_tstamp t2 = ngtcp2_conn_ack_delay_expiry(conn);
10861 ngtcp2_tstamp t3 = ngtcp2_conn_internal_expiry(conn);
10862 ngtcp2_tstamp t4 = ngtcp2_conn_lost_pkt_expiry(conn);
10863 ngtcp2_tstamp t5 = conn_keep_alive_expiry(conn);
10864 ngtcp2_tstamp t6 = conn_handshake_expiry(conn);
10865 ngtcp2_tstamp t7 = ngtcp2_conn_get_idle_expiry(conn);
10866 ngtcp2_tstamp res = ngtcp2_min(t1, t2);
10867 res = ngtcp2_min(res, t3);
10868 res = ngtcp2_min(res, t4);
10869 res = ngtcp2_min(res, t5);
10870 res = ngtcp2_min(res, t6);
10871 res = ngtcp2_min(res, t7);
10872 return ngtcp2_min(res, conn->tx.pacing.next_ts);
10873 }
10874
ngtcp2_conn_handle_expiry(ngtcp2_conn * conn,ngtcp2_tstamp ts)10875 int ngtcp2_conn_handle_expiry(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
10876 int rv;
10877 ngtcp2_duration pto = conn_compute_pto(conn, &conn->pktns);
10878
10879 if (ngtcp2_conn_get_idle_expiry(conn) <= ts) {
10880 return NGTCP2_ERR_IDLE_CLOSE;
10881 }
10882
10883 ngtcp2_conn_cancel_expired_ack_delay_timer(conn, ts);
10884
10885 conn_cancel_expired_keep_alive_timer(conn, ts);
10886
10887 conn_cancel_expired_pkt_tx_timer(conn, ts);
10888
10889 ngtcp2_conn_remove_lost_pkt(conn, ts);
10890
10891 if (conn->pv) {
10892 ngtcp2_pv_cancel_expired_timer(conn->pv, ts);
10893 }
10894
10895 if (conn->pmtud) {
10896 ngtcp2_pmtud_handle_expiry(conn->pmtud, ts);
10897 if (ngtcp2_pmtud_finished(conn->pmtud)) {
10898 ngtcp2_conn_stop_pmtud(conn);
10899 }
10900 }
10901
10902 if (ngtcp2_conn_loss_detection_expiry(conn) <= ts) {
10903 rv = ngtcp2_conn_on_loss_detection_timer(conn, ts);
10904 if (rv != 0) {
10905 return rv;
10906 }
10907 }
10908
10909 if (conn->dcid.current.cid.datalen) {
10910 rv = conn_retire_stale_bound_dcid(conn, 3 * pto, ts);
10911 if (rv != 0) {
10912 return rv;
10913 }
10914 }
10915
10916 rv = conn_remove_retired_connection_id(conn, pto, ts);
10917 if (rv != 0) {
10918 return rv;
10919 }
10920
10921 if (conn->server && conn->early.ckm &&
10922 conn->early.discard_started_ts != UINT64_MAX) {
10923 if (conn->early.discard_started_ts + 3 * pto <= ts) {
10924 conn_discard_early_key(conn);
10925 }
10926 }
10927
10928 if (!conn_is_handshake_completed(conn) &&
10929 conn->local.settings.handshake_timeout != UINT64_MAX &&
10930 conn->local.settings.initial_ts +
10931 conn->local.settings.handshake_timeout <=
10932 ts) {
10933 return NGTCP2_ERR_HANDSHAKE_TIMEOUT;
10934 }
10935
10936 return 0;
10937 }
10938
acktr_cancel_expired_ack_delay_timer(ngtcp2_acktr * acktr,ngtcp2_duration max_ack_delay,ngtcp2_tstamp ts)10939 static void acktr_cancel_expired_ack_delay_timer(ngtcp2_acktr *acktr,
10940 ngtcp2_duration max_ack_delay,
10941 ngtcp2_tstamp ts) {
10942 if (!(acktr->flags & NGTCP2_ACKTR_FLAG_CANCEL_TIMER) &&
10943 acktr->first_unacked_ts != UINT64_MAX &&
10944 acktr->first_unacked_ts + max_ack_delay <= ts) {
10945 acktr->flags |= NGTCP2_ACKTR_FLAG_CANCEL_TIMER;
10946 }
10947 }
10948
ngtcp2_conn_cancel_expired_ack_delay_timer(ngtcp2_conn * conn,ngtcp2_tstamp ts)10949 void ngtcp2_conn_cancel_expired_ack_delay_timer(ngtcp2_conn *conn,
10950 ngtcp2_tstamp ts) {
10951 ngtcp2_duration ack_delay = conn_compute_ack_delay(conn);
10952
10953 if (conn->in_pktns) {
10954 acktr_cancel_expired_ack_delay_timer(&conn->in_pktns->acktr, 0, ts);
10955 }
10956 if (conn->hs_pktns) {
10957 acktr_cancel_expired_ack_delay_timer(&conn->hs_pktns->acktr, 0, ts);
10958 }
10959 acktr_cancel_expired_ack_delay_timer(&conn->pktns.acktr, ack_delay, ts);
10960 }
10961
ngtcp2_conn_lost_pkt_expiry(ngtcp2_conn * conn)10962 ngtcp2_tstamp ngtcp2_conn_lost_pkt_expiry(ngtcp2_conn *conn) {
10963 ngtcp2_tstamp res = UINT64_MAX, ts;
10964
10965 if (conn->in_pktns) {
10966 ts = ngtcp2_rtb_lost_pkt_ts(&conn->in_pktns->rtb);
10967 if (ts != UINT64_MAX) {
10968 ts += conn_compute_pto(conn, conn->in_pktns);
10969 res = ngtcp2_min(res, ts);
10970 }
10971 }
10972
10973 if (conn->hs_pktns) {
10974 ts = ngtcp2_rtb_lost_pkt_ts(&conn->hs_pktns->rtb);
10975 if (ts != UINT64_MAX) {
10976 ts += conn_compute_pto(conn, conn->hs_pktns);
10977 res = ngtcp2_min(res, ts);
10978 }
10979 }
10980
10981 ts = ngtcp2_rtb_lost_pkt_ts(&conn->pktns.rtb);
10982 if (ts != UINT64_MAX) {
10983 ts += conn_compute_pto(conn, &conn->pktns);
10984 res = ngtcp2_min(res, ts);
10985 }
10986
10987 return res;
10988 }
10989
ngtcp2_conn_remove_lost_pkt(ngtcp2_conn * conn,ngtcp2_tstamp ts)10990 void ngtcp2_conn_remove_lost_pkt(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
10991 ngtcp2_duration pto;
10992
10993 if (conn->in_pktns) {
10994 pto = conn_compute_pto(conn, conn->in_pktns);
10995 ngtcp2_rtb_remove_expired_lost_pkt(&conn->in_pktns->rtb, pto, ts);
10996 }
10997 if (conn->hs_pktns) {
10998 pto = conn_compute_pto(conn, conn->hs_pktns);
10999 ngtcp2_rtb_remove_expired_lost_pkt(&conn->hs_pktns->rtb, pto, ts);
11000 }
11001 pto = conn_compute_pto(conn, &conn->pktns);
11002 ngtcp2_rtb_remove_expired_lost_pkt(&conn->pktns.rtb, pto, ts);
11003 }
11004
11005 /*
11006 * select_preferred_version selects the most preferred version.
11007 * |fallback_version| is chosen if no preference is made, or
11008 * |preferred_versions| does not include any of |chosen_version| or
11009 * |other_versions|. |chosen_version| is treated as an extra other
11010 * version.
11011 */
select_preferred_version(const uint32_t * preferred_versions,size_t preferred_versionslen,uint32_t chosen_version,const uint8_t * other_versions,size_t other_versionslen,uint32_t fallback_version)11012 static uint32_t select_preferred_version(const uint32_t *preferred_versions,
11013 size_t preferred_versionslen,
11014 uint32_t chosen_version,
11015 const uint8_t *other_versions,
11016 size_t other_versionslen,
11017 uint32_t fallback_version) {
11018 size_t i, j;
11019
11020 if (!preferred_versionslen ||
11021 (!other_versionslen && chosen_version == fallback_version)) {
11022 return fallback_version;
11023 }
11024
11025 for (i = 0; i < preferred_versionslen; ++i) {
11026 if (preferred_versions[i] == chosen_version) {
11027 return chosen_version;
11028 }
11029 for (j = 0; j < other_versionslen; j += sizeof(uint32_t)) {
11030 if (preferred_versions[i] != ngtcp2_get_uint32(&other_versions[j])) {
11031 continue;
11032 }
11033
11034 return preferred_versions[i];
11035 }
11036 }
11037
11038 return fallback_version;
11039 }
11040
11041 /*
11042 * conn_client_validate_transport_params validates |params| as client.
11043 * |params| must be sent with Encrypted Extensions.
11044 *
11045 * This function returns 0 if it succeeds, or one of the following
11046 * negative error codes:
11047 *
11048 * NGTCP2_ERR_TRANSPORT_PARAM
11049 * params contains preferred address but server chose zero-length
11050 * connection ID.
11051 * NGTCP2_ERR_VERSION_NEGOTIATION_FAILURE
11052 * Validation against version negotiation parameters failed.
11053 */
11054 static int
conn_client_validate_transport_params(ngtcp2_conn * conn,const ngtcp2_transport_params * params)11055 conn_client_validate_transport_params(ngtcp2_conn *conn,
11056 const ngtcp2_transport_params *params) {
11057 if (!ngtcp2_cid_eq(&conn->rcid, ¶ms->original_dcid)) {
11058 return NGTCP2_ERR_TRANSPORT_PARAM;
11059 }
11060
11061 if (conn->flags & NGTCP2_CONN_FLAG_RECV_RETRY) {
11062 if (!params->retry_scid_present) {
11063 return NGTCP2_ERR_TRANSPORT_PARAM;
11064 }
11065 if (!ngtcp2_cid_eq(&conn->retry_scid, ¶ms->retry_scid)) {
11066 return NGTCP2_ERR_TRANSPORT_PARAM;
11067 }
11068 } else if (params->retry_scid_present) {
11069 return NGTCP2_ERR_TRANSPORT_PARAM;
11070 }
11071
11072 if (params->preferred_address_present &&
11073 conn->dcid.current.cid.datalen == 0) {
11074 return NGTCP2_ERR_TRANSPORT_PARAM;
11075 }
11076
11077 if (params->version_info_present) {
11078 if (conn->negotiated_version != params->version_info.chosen_version) {
11079 return NGTCP2_ERR_VERSION_NEGOTIATION_FAILURE;
11080 }
11081
11082 assert(vneg_other_versions_includes(conn->vneg.other_versions,
11083 conn->vneg.other_versionslen,
11084 conn->negotiated_version));
11085 } else if (conn->client_chosen_version != conn->negotiated_version ||
11086 conn->client_chosen_version !=
11087 conn->local.settings.original_version) {
11088 return NGTCP2_ERR_VERSION_NEGOTIATION_FAILURE;
11089 }
11090
11091 /* When client reacted upon Version Negotiation */
11092 if (conn->local.settings.original_version != conn->client_chosen_version) {
11093 assert(params->version_info_present);
11094
11095 /* Server choose original version after Version Negotiation.
11096 Draft does not say this particular case, but this smells like
11097 misbehaved server because server should accept original_version
11098 in the original connection. */
11099 if (conn->local.settings.original_version ==
11100 params->version_info.chosen_version) {
11101 return NGTCP2_ERR_VERSION_NEGOTIATION_FAILURE;
11102 }
11103
11104 /* Check version downgrade on incompatible version negotiation. */
11105 if (params->version_info.other_versionslen == 0) {
11106 return NGTCP2_ERR_VERSION_NEGOTIATION_FAILURE;
11107 }
11108
11109 if (conn->client_chosen_version !=
11110 select_preferred_version(conn->vneg.preferred_versions,
11111 conn->vneg.preferred_versionslen,
11112 params->version_info.chosen_version,
11113 params->version_info.other_versions,
11114 params->version_info.other_versionslen,
11115 /* fallback_version = */ 0)) {
11116 return NGTCP2_ERR_VERSION_NEGOTIATION_FAILURE;
11117 }
11118 }
11119
11120 return 0;
11121 }
11122
11123 uint32_t
ngtcp2_conn_server_negotiate_version(ngtcp2_conn * conn,const ngtcp2_version_info * version_info)11124 ngtcp2_conn_server_negotiate_version(ngtcp2_conn *conn,
11125 const ngtcp2_version_info *version_info) {
11126 assert(conn->server);
11127 assert(conn->client_chosen_version == version_info->chosen_version);
11128
11129 return select_preferred_version(
11130 conn->vneg.preferred_versions, conn->vneg.preferred_versionslen,
11131 version_info->chosen_version, version_info->other_versions,
11132 version_info->other_versionslen, version_info->chosen_version);
11133 }
11134
ngtcp2_conn_set_remote_transport_params(ngtcp2_conn * conn,const ngtcp2_transport_params * params)11135 int ngtcp2_conn_set_remote_transport_params(
11136 ngtcp2_conn *conn, const ngtcp2_transport_params *params) {
11137 int rv;
11138
11139 /* We expect this function is called once per QUIC connection, but
11140 GnuTLS server seems to call TLS extension callback twice if it
11141 sends HelloRetryRequest. In practice, same QUIC transport
11142 parameters are sent in the 2nd client flight, just returning 0
11143 would cause no harm. */
11144 if (conn->flags & NGTCP2_CONN_FLAG_TRANSPORT_PARAM_RECVED) {
11145 return 0;
11146 }
11147
11148 /* Assume that ngtcp2_decode_transport_params sets default value if
11149 active_connection_id_limit is omitted. */
11150 if (params->active_connection_id_limit <
11151 NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT) {
11152 return NGTCP2_ERR_TRANSPORT_PARAM;
11153 }
11154
11155 /* We assume that conn->dcid.current.cid is still the initial one.
11156 This requires that transport parameter must be fed into
11157 ngtcp2_conn as early as possible. */
11158 if (!ngtcp2_cid_eq(&conn->dcid.current.cid, ¶ms->initial_scid)) {
11159 return NGTCP2_ERR_TRANSPORT_PARAM;
11160 }
11161
11162 if (params->max_udp_payload_size < NGTCP2_MAX_UDP_PAYLOAD_SIZE) {
11163 return NGTCP2_ERR_TRANSPORT_PARAM;
11164 }
11165
11166 if (conn->server) {
11167 if (params->version_info_present) {
11168 if (params->version_info.chosen_version != conn->client_chosen_version) {
11169 return NGTCP2_ERR_VERSION_NEGOTIATION_FAILURE;
11170 }
11171
11172 conn->negotiated_version =
11173 ngtcp2_conn_server_negotiate_version(conn, ¶ms->version_info);
11174 if (conn->negotiated_version != conn->client_chosen_version) {
11175 rv = conn_call_version_negotiation(conn, conn->negotiated_version,
11176 &conn->rcid);
11177 if (rv != 0) {
11178 return rv;
11179 }
11180 }
11181 } else {
11182 conn->negotiated_version = conn->client_chosen_version;
11183 }
11184
11185 conn->local.transport_params.version_info.chosen_version =
11186 conn->negotiated_version;
11187
11188 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
11189 "the negotiated version is 0x%08x",
11190 conn->negotiated_version);
11191 } else {
11192 rv = conn_client_validate_transport_params(conn, params);
11193 if (rv != 0) {
11194 return rv;
11195 }
11196 }
11197
11198 ngtcp2_log_remote_tp(&conn->log,
11199 conn->server
11200 ? NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO
11201 : NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS,
11202 params);
11203
11204 ngtcp2_qlog_parameters_set_transport_params(&conn->qlog, params, conn->server,
11205 NGTCP2_QLOG_SIDE_REMOTE);
11206
11207 if ((conn->server && conn->pktns.crypto.tx.ckm) ||
11208 (!conn->server && conn->pktns.crypto.rx.ckm)) {
11209 ngtcp2_transport_params_del(conn->remote.transport_params, conn->mem);
11210 conn->remote.transport_params = NULL;
11211
11212 rv = ngtcp2_transport_params_copy_new(&conn->remote.transport_params,
11213 params, conn->mem);
11214 if (rv != 0) {
11215 return rv;
11216 }
11217 conn_sync_stream_id_limit(conn);
11218 conn->tx.max_offset = conn->remote.transport_params->initial_max_data;
11219 } else {
11220 assert(!conn->remote.pending_transport_params);
11221
11222 rv = ngtcp2_transport_params_copy_new(
11223 &conn->remote.pending_transport_params, params, conn->mem);
11224 if (rv != 0) {
11225 return rv;
11226 }
11227 }
11228
11229 conn->flags |= NGTCP2_CONN_FLAG_TRANSPORT_PARAM_RECVED;
11230
11231 return 0;
11232 }
11233
ngtcp2_conn_decode_remote_transport_params(ngtcp2_conn * conn,const uint8_t * data,size_t datalen)11234 int ngtcp2_conn_decode_remote_transport_params(ngtcp2_conn *conn,
11235 const uint8_t *data,
11236 size_t datalen) {
11237 ngtcp2_transport_params params;
11238 int rv;
11239
11240 rv = ngtcp2_decode_transport_params(
11241 ¶ms,
11242 conn->server ? NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO
11243 : NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS,
11244 data, datalen);
11245 if (rv != 0) {
11246 return rv;
11247 }
11248
11249 return ngtcp2_conn_set_remote_transport_params(conn, ¶ms);
11250 }
11251
11252 const ngtcp2_transport_params *
ngtcp2_conn_get_remote_transport_params(ngtcp2_conn * conn)11253 ngtcp2_conn_get_remote_transport_params(ngtcp2_conn *conn) {
11254 if (conn->remote.pending_transport_params) {
11255 return conn->remote.pending_transport_params;
11256 }
11257
11258 return conn->remote.transport_params;
11259 }
11260
ngtcp2_conn_set_early_remote_transport_params_versioned(ngtcp2_conn * conn,int transport_params_version,const ngtcp2_transport_params * params)11261 void ngtcp2_conn_set_early_remote_transport_params_versioned(
11262 ngtcp2_conn *conn, int transport_params_version,
11263 const ngtcp2_transport_params *params) {
11264 ngtcp2_transport_params *p;
11265 (void)transport_params_version;
11266
11267 assert(!conn->server);
11268 assert(!conn->remote.transport_params);
11269
11270 /* Assume that all pointer fields in p are NULL */
11271 p = ngtcp2_mem_calloc(conn->mem, 1, sizeof(*p));
11272
11273 conn->remote.transport_params = p;
11274
11275 p->initial_max_streams_bidi = params->initial_max_streams_bidi;
11276 p->initial_max_streams_uni = params->initial_max_streams_uni;
11277 p->initial_max_stream_data_bidi_local =
11278 params->initial_max_stream_data_bidi_local;
11279 p->initial_max_stream_data_bidi_remote =
11280 params->initial_max_stream_data_bidi_remote;
11281 p->initial_max_stream_data_uni = params->initial_max_stream_data_uni;
11282 p->initial_max_data = params->initial_max_data;
11283 p->active_connection_id_limit =
11284 ngtcp2_max(NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT,
11285 params->active_connection_id_limit);
11286 p->max_idle_timeout = params->max_idle_timeout;
11287 if (!params->max_udp_payload_size) {
11288 p->max_udp_payload_size = NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE;
11289 } else {
11290 p->max_udp_payload_size =
11291 ngtcp2_max(NGTCP2_MAX_UDP_PAYLOAD_SIZE, params->max_udp_payload_size);
11292 }
11293 p->disable_active_migration = params->disable_active_migration;
11294 p->max_datagram_frame_size = params->max_datagram_frame_size;
11295
11296 /* These parameters are treated specially. If server accepts early
11297 data, it must not set values for these parameters that are
11298 smaller than these remembered values. */
11299 conn->early.transport_params.initial_max_streams_bidi =
11300 params->initial_max_streams_bidi;
11301 conn->early.transport_params.initial_max_streams_uni =
11302 params->initial_max_streams_uni;
11303 conn->early.transport_params.initial_max_stream_data_bidi_local =
11304 params->initial_max_stream_data_bidi_local;
11305 conn->early.transport_params.initial_max_stream_data_bidi_remote =
11306 params->initial_max_stream_data_bidi_remote;
11307 conn->early.transport_params.initial_max_stream_data_uni =
11308 params->initial_max_stream_data_uni;
11309 conn->early.transport_params.initial_max_data = params->initial_max_data;
11310 conn->early.transport_params.active_connection_id_limit =
11311 params->active_connection_id_limit;
11312 conn->early.transport_params.max_datagram_frame_size =
11313 params->max_datagram_frame_size;
11314
11315 conn_sync_stream_id_limit(conn);
11316
11317 conn->tx.max_offset = p->initial_max_data;
11318
11319 ngtcp2_qlog_parameters_set_transport_params(&conn->qlog, p, conn->server,
11320 NGTCP2_QLOG_SIDE_REMOTE);
11321 }
11322
ngtcp2_conn_set_local_transport_params_versioned(ngtcp2_conn * conn,int transport_params_version,const ngtcp2_transport_params * params)11323 int ngtcp2_conn_set_local_transport_params_versioned(
11324 ngtcp2_conn *conn, int transport_params_version,
11325 const ngtcp2_transport_params *params) {
11326 (void)transport_params_version;
11327
11328 assert(conn->server);
11329 assert(params->active_connection_id_limit <= NGTCP2_MAX_DCID_POOL_SIZE);
11330
11331 if (conn->hs_pktns == NULL || conn->hs_pktns->crypto.tx.ckm) {
11332 return NGTCP2_ERR_INVALID_STATE;
11333 }
11334
11335 conn_set_local_transport_params(conn, params);
11336
11337 return 0;
11338 }
11339
ngtcp2_conn_commit_local_transport_params(ngtcp2_conn * conn)11340 int ngtcp2_conn_commit_local_transport_params(ngtcp2_conn *conn) {
11341 const ngtcp2_mem *mem = conn->mem;
11342 ngtcp2_transport_params *params = &conn->local.transport_params;
11343 ngtcp2_scid *scident;
11344 int rv;
11345
11346 assert(1 == ngtcp2_ksl_len(&conn->scid.set));
11347
11348 if (params->active_connection_id_limit == 0) {
11349 params->active_connection_id_limit =
11350 NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
11351 }
11352
11353 params->initial_scid = conn->oscid;
11354
11355 if (conn->oscid.datalen == 0) {
11356 params->preferred_address_present = 0;
11357 }
11358
11359 if (conn->server && params->preferred_address_present) {
11360 scident = ngtcp2_mem_malloc(mem, sizeof(*scident));
11361 if (scident == NULL) {
11362 return NGTCP2_ERR_NOMEM;
11363 }
11364
11365 ngtcp2_scid_init(scident, 1, ¶ms->preferred_address.cid);
11366
11367 rv = ngtcp2_ksl_insert(&conn->scid.set, NULL, &scident->cid, scident);
11368 if (rv != 0) {
11369 ngtcp2_mem_free(mem, scident);
11370 return rv;
11371 }
11372
11373 conn->scid.last_seq = 1;
11374 }
11375
11376 conn->rx.window = conn->rx.unsent_max_offset = conn->rx.max_offset =
11377 params->initial_max_data;
11378 conn->remote.bidi.unsent_max_streams = params->initial_max_streams_bidi;
11379 conn->remote.bidi.max_streams = params->initial_max_streams_bidi;
11380 conn->remote.uni.unsent_max_streams = params->initial_max_streams_uni;
11381 conn->remote.uni.max_streams = params->initial_max_streams_uni;
11382
11383 conn->flags |= NGTCP2_CONN_FLAG_LOCAL_TRANSPORT_PARAMS_COMMITTED;
11384
11385 ngtcp2_qlog_parameters_set_transport_params(&conn->qlog, params, conn->server,
11386 NGTCP2_QLOG_SIDE_LOCAL);
11387
11388 return 0;
11389 }
11390
11391 const ngtcp2_transport_params *
ngtcp2_conn_get_local_transport_params(ngtcp2_conn * conn)11392 ngtcp2_conn_get_local_transport_params(ngtcp2_conn *conn) {
11393 return &conn->local.transport_params;
11394 }
11395
ngtcp2_conn_encode_local_transport_params(ngtcp2_conn * conn,uint8_t * dest,size_t destlen)11396 ngtcp2_ssize ngtcp2_conn_encode_local_transport_params(ngtcp2_conn *conn,
11397 uint8_t *dest,
11398 size_t destlen) {
11399 return ngtcp2_encode_transport_params(
11400 dest, destlen,
11401 conn->server ? NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS
11402 : NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO,
11403 &conn->local.transport_params);
11404 }
11405
ngtcp2_conn_open_bidi_stream(ngtcp2_conn * conn,int64_t * pstream_id,void * stream_user_data)11406 int ngtcp2_conn_open_bidi_stream(ngtcp2_conn *conn, int64_t *pstream_id,
11407 void *stream_user_data) {
11408 int rv;
11409 ngtcp2_strm *strm;
11410
11411 if (ngtcp2_conn_get_streams_bidi_left(conn) == 0) {
11412 return NGTCP2_ERR_STREAM_ID_BLOCKED;
11413 }
11414
11415 strm = ngtcp2_objalloc_strm_get(&conn->strm_objalloc);
11416 if (strm == NULL) {
11417 return NGTCP2_ERR_NOMEM;
11418 }
11419
11420 rv = ngtcp2_conn_init_stream(conn, strm, conn->local.bidi.next_stream_id,
11421 stream_user_data);
11422 if (rv != 0) {
11423 ngtcp2_objalloc_strm_release(&conn->strm_objalloc, strm);
11424 return rv;
11425 }
11426
11427 *pstream_id = conn->local.bidi.next_stream_id;
11428 conn->local.bidi.next_stream_id += 4;
11429
11430 return 0;
11431 }
11432
ngtcp2_conn_open_uni_stream(ngtcp2_conn * conn,int64_t * pstream_id,void * stream_user_data)11433 int ngtcp2_conn_open_uni_stream(ngtcp2_conn *conn, int64_t *pstream_id,
11434 void *stream_user_data) {
11435 int rv;
11436 ngtcp2_strm *strm;
11437
11438 if (ngtcp2_conn_get_streams_uni_left(conn) == 0) {
11439 return NGTCP2_ERR_STREAM_ID_BLOCKED;
11440 }
11441
11442 strm = ngtcp2_objalloc_strm_get(&conn->strm_objalloc);
11443 if (strm == NULL) {
11444 return NGTCP2_ERR_NOMEM;
11445 }
11446
11447 rv = ngtcp2_conn_init_stream(conn, strm, conn->local.uni.next_stream_id,
11448 stream_user_data);
11449 if (rv != 0) {
11450 ngtcp2_objalloc_strm_release(&conn->strm_objalloc, strm);
11451 return rv;
11452 }
11453 ngtcp2_strm_shutdown(strm, NGTCP2_STRM_FLAG_SHUT_RD);
11454
11455 *pstream_id = conn->local.uni.next_stream_id;
11456 conn->local.uni.next_stream_id += 4;
11457
11458 return 0;
11459 }
11460
ngtcp2_conn_find_stream(ngtcp2_conn * conn,int64_t stream_id)11461 ngtcp2_strm *ngtcp2_conn_find_stream(ngtcp2_conn *conn, int64_t stream_id) {
11462 return ngtcp2_map_find(&conn->strms, (uint64_t)stream_id);
11463 }
11464
ngtcp2_conn_write_stream_versioned(ngtcp2_conn * conn,ngtcp2_path * path,int pkt_info_version,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,ngtcp2_ssize * pdatalen,uint32_t flags,int64_t stream_id,const uint8_t * data,size_t datalen,ngtcp2_tstamp ts)11465 ngtcp2_ssize ngtcp2_conn_write_stream_versioned(
11466 ngtcp2_conn *conn, ngtcp2_path *path, int pkt_info_version,
11467 ngtcp2_pkt_info *pi, uint8_t *dest, size_t destlen, ngtcp2_ssize *pdatalen,
11468 uint32_t flags, int64_t stream_id, const uint8_t *data, size_t datalen,
11469 ngtcp2_tstamp ts) {
11470 ngtcp2_vec datav;
11471
11472 datav.len = datalen;
11473 datav.base = (uint8_t *)data;
11474
11475 return ngtcp2_conn_writev_stream_versioned(conn, path, pkt_info_version, pi,
11476 dest, destlen, pdatalen, flags,
11477 stream_id, &datav, 1, ts);
11478 }
11479
conn_write_vmsg_wrapper(ngtcp2_conn * conn,ngtcp2_path * path,int pkt_info_version,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,ngtcp2_vmsg * vmsg,ngtcp2_tstamp ts)11480 static ngtcp2_ssize conn_write_vmsg_wrapper(ngtcp2_conn *conn,
11481 ngtcp2_path *path,
11482 int pkt_info_version,
11483 ngtcp2_pkt_info *pi, uint8_t *dest,
11484 size_t destlen, ngtcp2_vmsg *vmsg,
11485 ngtcp2_tstamp ts) {
11486 ngtcp2_conn_stat *cstat = &conn->cstat;
11487 ngtcp2_ssize nwrite;
11488 int undersized;
11489
11490 nwrite = ngtcp2_conn_write_vmsg(conn, path, pkt_info_version, pi, dest,
11491 destlen, vmsg, ts);
11492 if (nwrite < 0) {
11493 return nwrite;
11494 }
11495
11496 if (cstat->bytes_in_flight >= cstat->cwnd) {
11497 conn->rst.is_cwnd_limited = 1;
11498 }
11499
11500 if (vmsg == NULL && cstat->bytes_in_flight < cstat->cwnd &&
11501 conn->tx.strmq_nretrans == 0) {
11502 if (conn->local.settings.no_udp_payload_size_shaping) {
11503 undersized = (size_t)nwrite < conn->local.settings.max_udp_payload_size;
11504 } else {
11505 undersized = (size_t)nwrite < conn->dcid.current.max_udp_payload_size;
11506 }
11507
11508 if (undersized) {
11509 conn->rst.app_limited = conn->rst.delivered + cstat->bytes_in_flight;
11510
11511 if (conn->rst.app_limited == 0) {
11512 conn->rst.app_limited = cstat->max_udp_payload_size;
11513 }
11514 }
11515 }
11516
11517 return nwrite;
11518 }
11519
ngtcp2_conn_writev_stream_versioned(ngtcp2_conn * conn,ngtcp2_path * path,int pkt_info_version,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,ngtcp2_ssize * pdatalen,uint32_t flags,int64_t stream_id,const ngtcp2_vec * datav,size_t datavcnt,ngtcp2_tstamp ts)11520 ngtcp2_ssize ngtcp2_conn_writev_stream_versioned(
11521 ngtcp2_conn *conn, ngtcp2_path *path, int pkt_info_version,
11522 ngtcp2_pkt_info *pi, uint8_t *dest, size_t destlen, ngtcp2_ssize *pdatalen,
11523 uint32_t flags, int64_t stream_id, const ngtcp2_vec *datav, size_t datavcnt,
11524 ngtcp2_tstamp ts) {
11525 ngtcp2_vmsg vmsg, *pvmsg;
11526 ngtcp2_strm *strm;
11527 int64_t datalen;
11528
11529 if (pdatalen) {
11530 *pdatalen = -1;
11531 }
11532
11533 if (stream_id != -1) {
11534 strm = ngtcp2_conn_find_stream(conn, stream_id);
11535 if (strm == NULL) {
11536 return NGTCP2_ERR_STREAM_NOT_FOUND;
11537 }
11538
11539 if (strm->flags & NGTCP2_STRM_FLAG_SHUT_WR) {
11540 return NGTCP2_ERR_STREAM_SHUT_WR;
11541 }
11542
11543 datalen = ngtcp2_vec_len_varint(datav, datavcnt);
11544 if (datalen == -1) {
11545 return NGTCP2_ERR_INVALID_ARGUMENT;
11546 }
11547
11548 if ((uint64_t)datalen > NGTCP2_MAX_VARINT - strm->tx.offset ||
11549 (uint64_t)datalen > NGTCP2_MAX_VARINT - conn->tx.offset) {
11550 return NGTCP2_ERR_INVALID_ARGUMENT;
11551 }
11552
11553 vmsg.type = NGTCP2_VMSG_TYPE_STREAM;
11554 vmsg.stream.strm = strm;
11555 vmsg.stream.flags = flags;
11556 vmsg.stream.data = datav;
11557 vmsg.stream.datacnt = datavcnt;
11558 vmsg.stream.pdatalen = pdatalen;
11559
11560 pvmsg = &vmsg;
11561 } else {
11562 pvmsg = NULL;
11563 }
11564
11565 return conn_write_vmsg_wrapper(conn, path, pkt_info_version, pi, dest,
11566 destlen, pvmsg, ts);
11567 }
11568
ngtcp2_conn_writev_datagram_versioned(ngtcp2_conn * conn,ngtcp2_path * path,int pkt_info_version,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,int * paccepted,uint32_t flags,uint64_t dgram_id,const ngtcp2_vec * datav,size_t datavcnt,ngtcp2_tstamp ts)11569 ngtcp2_ssize ngtcp2_conn_writev_datagram_versioned(
11570 ngtcp2_conn *conn, ngtcp2_path *path, int pkt_info_version,
11571 ngtcp2_pkt_info *pi, uint8_t *dest, size_t destlen, int *paccepted,
11572 uint32_t flags, uint64_t dgram_id, const ngtcp2_vec *datav, size_t datavcnt,
11573 ngtcp2_tstamp ts) {
11574 ngtcp2_vmsg vmsg;
11575 int64_t datalen;
11576
11577 if (paccepted) {
11578 *paccepted = 0;
11579 }
11580
11581 if (conn->remote.transport_params == NULL ||
11582 conn->remote.transport_params->max_datagram_frame_size == 0) {
11583 return NGTCP2_ERR_INVALID_STATE;
11584 }
11585
11586 datalen = ngtcp2_vec_len_varint(datav, datavcnt);
11587 if (datalen == -1 || (uint64_t)datalen > SIZE_MAX) {
11588 return NGTCP2_ERR_INVALID_STATE;
11589 }
11590
11591 if (conn->remote.transport_params->max_datagram_frame_size <
11592 ngtcp2_pkt_datagram_framelen((size_t)datalen)) {
11593 return NGTCP2_ERR_INVALID_ARGUMENT;
11594 }
11595
11596 vmsg.type = NGTCP2_VMSG_TYPE_DATAGRAM;
11597 vmsg.datagram.dgram_id = dgram_id;
11598 vmsg.datagram.flags = flags;
11599 vmsg.datagram.data = datav;
11600 vmsg.datagram.datacnt = datavcnt;
11601 vmsg.datagram.paccepted = paccepted;
11602
11603 return conn_write_vmsg_wrapper(conn, path, pkt_info_version, pi, dest,
11604 destlen, &vmsg, ts);
11605 }
11606
ngtcp2_conn_write_vmsg(ngtcp2_conn * conn,ngtcp2_path * path,int pkt_info_version,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,ngtcp2_vmsg * vmsg,ngtcp2_tstamp ts)11607 ngtcp2_ssize ngtcp2_conn_write_vmsg(ngtcp2_conn *conn, ngtcp2_path *path,
11608 int pkt_info_version, ngtcp2_pkt_info *pi,
11609 uint8_t *dest, size_t destlen,
11610 ngtcp2_vmsg *vmsg, ngtcp2_tstamp ts) {
11611 ngtcp2_ssize nwrite;
11612 size_t origlen;
11613 size_t origdestlen = destlen;
11614 int rv;
11615 uint8_t wflags = NGTCP2_WRITE_PKT_FLAG_NONE;
11616 int ppe_pending = (conn->flags & NGTCP2_CONN_FLAG_PPE_PENDING) != 0;
11617 ngtcp2_conn_stat *cstat = &conn->cstat;
11618 ngtcp2_ssize res = 0;
11619 uint64_t server_tx_left;
11620 uint64_t datalen;
11621 uint64_t write_datalen = 0;
11622 int64_t prev_in_pkt_num = -1;
11623 ngtcp2_ksl_it it;
11624 ngtcp2_rtb_entry *rtbent;
11625 (void)pkt_info_version;
11626
11627 conn->log.last_ts = ts;
11628 conn->qlog.last_ts = ts;
11629
11630 if (path) {
11631 ngtcp2_path_copy(path, &conn->dcid.current.ps.path);
11632 }
11633
11634 origlen = destlen =
11635 conn_shape_udp_payload(conn, &conn->dcid.current, destlen);
11636
11637 if (!ppe_pending && pi) {
11638 pi->ecn = NGTCP2_ECN_NOT_ECT;
11639 }
11640
11641 if (!conn_pacing_pkt_tx_allowed(conn, ts)) {
11642 return 0;
11643 }
11644
11645 switch (conn->state) {
11646 case NGTCP2_CS_CLIENT_INITIAL:
11647 case NGTCP2_CS_CLIENT_WAIT_HANDSHAKE:
11648 case NGTCP2_CS_CLIENT_TLS_HANDSHAKE_FAILED:
11649 nwrite = conn_client_write_handshake(conn, pi, dest, destlen, vmsg, ts);
11650 /* We might be unable to write a packet because of depletion of
11651 congestion window budget, perhaps due to packet loss that
11652 shrinks the window drastically. */
11653 if (nwrite <= 0) {
11654 return nwrite;
11655 }
11656 if (conn->state != NGTCP2_CS_POST_HANDSHAKE) {
11657 return nwrite;
11658 }
11659
11660 assert(nwrite);
11661 assert(dest[0] & NGTCP2_HEADER_FORM_BIT);
11662 assert(conn->negotiated_version);
11663
11664 if (ngtcp2_pkt_get_type_long(conn->negotiated_version, dest[0]) ==
11665 NGTCP2_PKT_INITIAL) {
11666 /* We have added padding already, but in that case, there is no
11667 space left to write 1RTT packet. */
11668 wflags |= NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
11669 }
11670
11671 res = nwrite;
11672 dest += nwrite;
11673 destlen -= (size_t)nwrite;
11674 /* Break here so that we can coalesces 1RTT packet. */
11675 break;
11676 case NGTCP2_CS_SERVER_INITIAL:
11677 case NGTCP2_CS_SERVER_WAIT_HANDSHAKE:
11678 case NGTCP2_CS_SERVER_TLS_HANDSHAKE_FAILED:
11679 if (!ppe_pending) {
11680 if (!(conn->dcid.current.flags & NGTCP2_DCID_FLAG_PATH_VALIDATED)) {
11681 server_tx_left = conn_server_tx_left(conn, &conn->dcid.current);
11682 if (server_tx_left == 0) {
11683 if (cstat->loss_detection_timer != UINT64_MAX) {
11684 ngtcp2_log_info(
11685 &conn->log, NGTCP2_LOG_EVENT_RCV,
11686 "loss detection timer canceled due to amplification limit");
11687 cstat->loss_detection_timer = UINT64_MAX;
11688 }
11689
11690 return 0;
11691 }
11692
11693 destlen = (size_t)ngtcp2_min((uint64_t)destlen, server_tx_left);
11694 }
11695
11696 if (vmsg) {
11697 switch (vmsg->type) {
11698 case NGTCP2_VMSG_TYPE_STREAM:
11699 datalen = ngtcp2_vec_len(vmsg->stream.data, vmsg->stream.datacnt);
11700 if (datalen == 0 || (datalen > 0 &&
11701 (vmsg->stream.strm->tx.max_offset -
11702 vmsg->stream.strm->tx.offset) &&
11703 (conn->tx.max_offset - conn->tx.offset))) {
11704 write_datalen =
11705 conn_enforce_flow_control(conn, vmsg->stream.strm, datalen);
11706 write_datalen =
11707 ngtcp2_min(write_datalen, NGTCP2_MIN_COALESCED_PAYLOADLEN);
11708 write_datalen += NGTCP2_STREAM_OVERHEAD;
11709 }
11710 break;
11711 case NGTCP2_VMSG_TYPE_DATAGRAM:
11712 write_datalen =
11713 ngtcp2_vec_len(vmsg->datagram.data, vmsg->datagram.datacnt) +
11714 NGTCP2_DATAGRAM_OVERHEAD;
11715 break;
11716 default:
11717 assert(0);
11718 }
11719
11720 if (conn->in_pktns && write_datalen > 0) {
11721 it = ngtcp2_rtb_head(&conn->in_pktns->rtb);
11722 if (!ngtcp2_ksl_it_end(&it)) {
11723 rtbent = ngtcp2_ksl_it_get(&it);
11724 prev_in_pkt_num = rtbent->hd.pkt_num;
11725 }
11726 }
11727 }
11728
11729 nwrite = conn_write_handshake(conn, pi, dest, destlen, write_datalen, ts);
11730 if (nwrite < 0) {
11731 return nwrite;
11732 }
11733
11734 res = nwrite;
11735 dest += nwrite;
11736 destlen -= (size_t)nwrite;
11737
11738 if (conn->in_pktns && write_datalen > 0) {
11739 it = ngtcp2_rtb_head(&conn->in_pktns->rtb);
11740 if (!ngtcp2_ksl_it_end(&it)) {
11741 rtbent = ngtcp2_ksl_it_get(&it);
11742 if (rtbent->hd.pkt_num != prev_in_pkt_num &&
11743 (rtbent->flags & NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING)) {
11744 /* We have added padding already, but in that case, there
11745 is no space left to write 1RTT packet. */
11746 wflags |= NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
11747 }
11748 }
11749 }
11750 }
11751 if (conn->state != NGTCP2_CS_POST_HANDSHAKE &&
11752 conn->pktns.crypto.tx.ckm == NULL) {
11753 return res;
11754 }
11755 break;
11756 case NGTCP2_CS_POST_HANDSHAKE:
11757 break;
11758 case NGTCP2_CS_CLOSING:
11759 return NGTCP2_ERR_CLOSING;
11760 case NGTCP2_CS_DRAINING:
11761 return NGTCP2_ERR_DRAINING;
11762 default:
11763 return 0;
11764 }
11765
11766 assert(conn->pktns.crypto.tx.ckm);
11767
11768 if (conn_check_pkt_num_exhausted(conn)) {
11769 return NGTCP2_ERR_PKT_NUM_EXHAUSTED;
11770 }
11771
11772 if (vmsg) {
11773 switch (vmsg->type) {
11774 case NGTCP2_VMSG_TYPE_STREAM:
11775 if (vmsg->stream.flags & NGTCP2_WRITE_STREAM_FLAG_MORE) {
11776 wflags |= NGTCP2_WRITE_PKT_FLAG_MORE;
11777 }
11778 break;
11779 case NGTCP2_VMSG_TYPE_DATAGRAM:
11780 if (vmsg->datagram.flags & NGTCP2_WRITE_DATAGRAM_FLAG_MORE) {
11781 wflags |= NGTCP2_WRITE_PKT_FLAG_MORE;
11782 }
11783 break;
11784 default:
11785 break;
11786 }
11787 }
11788
11789 if (ppe_pending) {
11790 res = conn->pkt.hs_spktlen;
11791 conn->pkt.hs_spktlen = 0;
11792 if (conn->pkt.require_padding) {
11793 wflags |= NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
11794 }
11795 /* dest and destlen have already been adjusted in ppe in the first
11796 run. They are adjusted for probe packet later. */
11797 nwrite = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_1RTT,
11798 wflags, ts);
11799 goto fin;
11800 } else {
11801 conn->pkt.require_padding =
11802 (wflags & NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING);
11803
11804 if (conn->state == NGTCP2_CS_POST_HANDSHAKE) {
11805 rv = conn_prepare_key_update(conn, ts);
11806 if (rv != 0) {
11807 return rv;
11808 }
11809 }
11810
11811 if (!conn->pktns.rtb.probe_pkt_left && conn_cwnd_is_zero(conn)) {
11812 destlen = 0;
11813 } else {
11814 if (res == 0) {
11815 nwrite =
11816 conn_write_path_response(conn, path, pi, dest, origdestlen, ts);
11817 if (nwrite) {
11818 goto fin;
11819 }
11820
11821 if (conn->pv) {
11822 nwrite =
11823 conn_write_path_challenge(conn, path, pi, dest, origdestlen, ts);
11824 if (nwrite) {
11825 goto fin;
11826 }
11827 }
11828
11829 if (conn->pmtud &&
11830 (!conn->hs_pktns ||
11831 ngtcp2_ksl_len(&conn->hs_pktns->crypto.tx.frq) == 0)) {
11832 nwrite = conn_write_pmtud_probe(conn, pi, dest, origdestlen, ts);
11833 if (nwrite) {
11834 goto fin;
11835 }
11836 }
11837 }
11838
11839 if (conn->server &&
11840 !(conn->dcid.current.flags & NGTCP2_DCID_FLAG_PATH_VALIDATED)) {
11841 server_tx_left = conn_server_tx_left(conn, &conn->dcid.current);
11842 origlen = (size_t)ngtcp2_min((uint64_t)origlen, server_tx_left);
11843 destlen = (size_t)ngtcp2_min((uint64_t)destlen, server_tx_left);
11844
11845 if (server_tx_left == 0 &&
11846 conn->cstat.loss_detection_timer != UINT64_MAX) {
11847 ngtcp2_log_info(
11848 &conn->log, NGTCP2_LOG_EVENT_RCV,
11849 "loss detection timer canceled due to amplification limit");
11850 conn->cstat.loss_detection_timer = UINT64_MAX;
11851 }
11852 }
11853 }
11854 }
11855
11856 if (res == 0) {
11857 if (conn_handshake_remnants_left(conn)) {
11858 if (conn_handshake_probe_left(conn)) {
11859 destlen = origlen;
11860 }
11861 nwrite = conn_write_handshake_pkts(conn, pi, dest, destlen,
11862 /* write_datalen = */ 0, ts);
11863 if (nwrite < 0) {
11864 return nwrite;
11865 }
11866 if (nwrite > 0) {
11867 res = nwrite;
11868 dest += nwrite;
11869 destlen -= (size_t)nwrite;
11870 }
11871 }
11872 }
11873
11874 if (conn->pktns.rtb.probe_pkt_left) {
11875 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_CON,
11876 "transmit probe pkt left=%zu",
11877 conn->pktns.rtb.probe_pkt_left);
11878
11879 nwrite = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_1RTT,
11880 wflags, ts);
11881
11882 goto fin;
11883 }
11884
11885 nwrite = conn_write_pkt(conn, pi, dest, destlen, vmsg, NGTCP2_PKT_1RTT,
11886 wflags, ts);
11887 if (nwrite) {
11888 assert(nwrite != NGTCP2_ERR_NOBUF);
11889 goto fin;
11890 }
11891
11892 if (res == 0) {
11893 nwrite = conn_write_ack_pkt(conn, pi, dest, origlen, NGTCP2_PKT_1RTT, ts);
11894 }
11895
11896 fin:
11897 conn->pkt.hs_spktlen = 0;
11898
11899 if (nwrite >= 0) {
11900 res += nwrite;
11901 return res;
11902 }
11903 /* NGTCP2_CONN_FLAG_PPE_PENDING is set in conn_write_pkt above.
11904 ppe_pending cannot be used here. */
11905 if (conn->flags & NGTCP2_CONN_FLAG_PPE_PENDING) {
11906 conn->pkt.hs_spktlen = res;
11907 }
11908
11909 return nwrite;
11910 }
11911
11912 static ngtcp2_ssize
conn_write_connection_close(ngtcp2_conn * conn,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,uint8_t pkt_type,uint64_t error_code,const uint8_t * reason,size_t reasonlen,ngtcp2_tstamp ts)11913 conn_write_connection_close(ngtcp2_conn *conn, ngtcp2_pkt_info *pi,
11914 uint8_t *dest, size_t destlen, uint8_t pkt_type,
11915 uint64_t error_code, const uint8_t *reason,
11916 size_t reasonlen, ngtcp2_tstamp ts) {
11917 ngtcp2_pktns *in_pktns = conn->in_pktns;
11918 ngtcp2_pktns *hs_pktns = conn->hs_pktns;
11919 ngtcp2_ssize res = 0, nwrite;
11920 ngtcp2_frame fr;
11921 uint8_t flags = NGTCP2_WRITE_PKT_FLAG_NONE;
11922
11923 fr.type = NGTCP2_FRAME_CONNECTION_CLOSE;
11924 fr.connection_close.error_code = error_code;
11925 fr.connection_close.frame_type = 0;
11926 fr.connection_close.reasonlen = reasonlen;
11927 fr.connection_close.reason = (uint8_t *)reason;
11928
11929 if (!(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED) &&
11930 pkt_type != NGTCP2_PKT_INITIAL) {
11931 if (in_pktns && conn->server) {
11932 nwrite = ngtcp2_conn_write_single_frame_pkt(
11933 conn, pi, dest, destlen, NGTCP2_PKT_INITIAL,
11934 NGTCP2_WRITE_PKT_FLAG_NONE, &conn->dcid.current.cid, &fr,
11935 NGTCP2_RTB_ENTRY_FLAG_NONE, NULL, ts);
11936 if (nwrite < 0) {
11937 return nwrite;
11938 }
11939
11940 dest += nwrite;
11941 destlen -= (size_t)nwrite;
11942 res += nwrite;
11943 }
11944
11945 if (pkt_type != NGTCP2_PKT_HANDSHAKE && hs_pktns &&
11946 hs_pktns->crypto.tx.ckm) {
11947 nwrite = ngtcp2_conn_write_single_frame_pkt(
11948 conn, pi, dest, destlen, NGTCP2_PKT_HANDSHAKE,
11949 NGTCP2_WRITE_PKT_FLAG_NONE, &conn->dcid.current.cid, &fr,
11950 NGTCP2_RTB_ENTRY_FLAG_NONE, NULL, ts);
11951 if (nwrite < 0) {
11952 return nwrite;
11953 }
11954
11955 dest += nwrite;
11956 destlen -= (size_t)nwrite;
11957 res += nwrite;
11958 }
11959 }
11960
11961 if (!conn->server && pkt_type == NGTCP2_PKT_INITIAL) {
11962 flags = NGTCP2_WRITE_PKT_FLAG_REQUIRE_PADDING;
11963 }
11964
11965 nwrite = ngtcp2_conn_write_single_frame_pkt(
11966 conn, pi, dest, destlen, pkt_type, flags, &conn->dcid.current.cid, &fr,
11967 NGTCP2_RTB_ENTRY_FLAG_NONE, NULL, ts);
11968
11969 if (nwrite < 0) {
11970 return nwrite;
11971 }
11972
11973 res += nwrite;
11974
11975 if (res == 0) {
11976 return NGTCP2_ERR_NOBUF;
11977 }
11978
11979 return res;
11980 }
11981
ngtcp2_conn_write_connection_close_pkt(ngtcp2_conn * conn,ngtcp2_path * path,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,uint64_t error_code,const uint8_t * reason,size_t reasonlen,ngtcp2_tstamp ts)11982 ngtcp2_ssize ngtcp2_conn_write_connection_close_pkt(
11983 ngtcp2_conn *conn, ngtcp2_path *path, ngtcp2_pkt_info *pi, uint8_t *dest,
11984 size_t destlen, uint64_t error_code, const uint8_t *reason,
11985 size_t reasonlen, ngtcp2_tstamp ts) {
11986 ngtcp2_pktns *in_pktns = conn->in_pktns;
11987 ngtcp2_pktns *hs_pktns = conn->hs_pktns;
11988 uint8_t pkt_type;
11989 ngtcp2_ssize nwrite;
11990 uint64_t server_tx_left;
11991
11992 conn->log.last_ts = ts;
11993 conn->qlog.last_ts = ts;
11994
11995 if (conn_check_pkt_num_exhausted(conn)) {
11996 return NGTCP2_ERR_PKT_NUM_EXHAUSTED;
11997 }
11998
11999 switch (conn->state) {
12000 case NGTCP2_CS_CLIENT_INITIAL:
12001 return NGTCP2_ERR_INVALID_STATE;
12002 case NGTCP2_CS_CLOSING:
12003 case NGTCP2_CS_DRAINING:
12004 return 0;
12005 default:
12006 break;
12007 }
12008
12009 if (path) {
12010 ngtcp2_path_copy(path, &conn->dcid.current.ps.path);
12011 }
12012
12013 destlen = conn_shape_udp_payload(conn, &conn->dcid.current, destlen);
12014
12015 if (pi) {
12016 pi->ecn = NGTCP2_ECN_NOT_ECT;
12017 }
12018
12019 if (conn->server) {
12020 server_tx_left = conn_server_tx_left(conn, &conn->dcid.current);
12021 destlen = (size_t)ngtcp2_min((uint64_t)destlen, server_tx_left);
12022 }
12023
12024 if (conn->state == NGTCP2_CS_POST_HANDSHAKE ||
12025 (conn->server && conn->pktns.crypto.tx.ckm)) {
12026 pkt_type = NGTCP2_PKT_1RTT;
12027 } else if (hs_pktns && hs_pktns->crypto.tx.ckm) {
12028 pkt_type = NGTCP2_PKT_HANDSHAKE;
12029 } else if (in_pktns && in_pktns->crypto.tx.ckm) {
12030 pkt_type = NGTCP2_PKT_INITIAL;
12031 } else {
12032 /* This branch is taken if server has not read any Initial packet
12033 from client. */
12034 return NGTCP2_ERR_INVALID_STATE;
12035 }
12036
12037 nwrite = conn_write_connection_close(conn, pi, dest, destlen, pkt_type,
12038 error_code, reason, reasonlen, ts);
12039 if (nwrite < 0) {
12040 return nwrite;
12041 }
12042
12043 conn->state = NGTCP2_CS_CLOSING;
12044
12045 return nwrite;
12046 }
12047
ngtcp2_conn_write_application_close_pkt(ngtcp2_conn * conn,ngtcp2_path * path,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,uint64_t app_error_code,const uint8_t * reason,size_t reasonlen,ngtcp2_tstamp ts)12048 ngtcp2_ssize ngtcp2_conn_write_application_close_pkt(
12049 ngtcp2_conn *conn, ngtcp2_path *path, ngtcp2_pkt_info *pi, uint8_t *dest,
12050 size_t destlen, uint64_t app_error_code, const uint8_t *reason,
12051 size_t reasonlen, ngtcp2_tstamp ts) {
12052 ngtcp2_ssize nwrite;
12053 ngtcp2_ssize res = 0;
12054 ngtcp2_frame fr;
12055 uint64_t server_tx_left;
12056
12057 conn->log.last_ts = ts;
12058 conn->qlog.last_ts = ts;
12059
12060 if (conn_check_pkt_num_exhausted(conn)) {
12061 return NGTCP2_ERR_PKT_NUM_EXHAUSTED;
12062 }
12063
12064 switch (conn->state) {
12065 case NGTCP2_CS_CLIENT_INITIAL:
12066 return NGTCP2_ERR_INVALID_STATE;
12067 case NGTCP2_CS_CLOSING:
12068 case NGTCP2_CS_DRAINING:
12069 return 0;
12070 default:
12071 break;
12072 }
12073
12074 if (path) {
12075 ngtcp2_path_copy(path, &conn->dcid.current.ps.path);
12076 }
12077
12078 destlen = conn_shape_udp_payload(conn, &conn->dcid.current, destlen);
12079
12080 if (pi) {
12081 pi->ecn = NGTCP2_ECN_NOT_ECT;
12082 }
12083
12084 if (conn->server) {
12085 server_tx_left = conn_server_tx_left(conn, &conn->dcid.current);
12086 destlen = (size_t)ngtcp2_min((uint64_t)destlen, server_tx_left);
12087 }
12088
12089 if (!(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED)) {
12090 nwrite = conn_write_connection_close(conn, pi, dest, destlen,
12091 conn->hs_pktns->crypto.tx.ckm
12092 ? NGTCP2_PKT_HANDSHAKE
12093 : NGTCP2_PKT_INITIAL,
12094 NGTCP2_APPLICATION_ERROR, NULL, 0, ts);
12095 if (nwrite < 0) {
12096 return nwrite;
12097 }
12098 res = nwrite;
12099 dest += nwrite;
12100 destlen -= (size_t)nwrite;
12101 }
12102
12103 if (conn->state != NGTCP2_CS_POST_HANDSHAKE) {
12104 assert(res);
12105
12106 if (!conn->server || !conn->pktns.crypto.tx.ckm) {
12107 return res;
12108 }
12109 }
12110
12111 assert(conn->pktns.crypto.tx.ckm);
12112
12113 fr.type = NGTCP2_FRAME_CONNECTION_CLOSE_APP;
12114 fr.connection_close.error_code = app_error_code;
12115 fr.connection_close.frame_type = 0;
12116 fr.connection_close.reasonlen = reasonlen;
12117 fr.connection_close.reason = (uint8_t *)reason;
12118
12119 nwrite = ngtcp2_conn_write_single_frame_pkt(
12120 conn, pi, dest, destlen, NGTCP2_PKT_1RTT, NGTCP2_WRITE_PKT_FLAG_NONE,
12121 &conn->dcid.current.cid, &fr, NGTCP2_RTB_ENTRY_FLAG_NONE, NULL, ts);
12122
12123 if (nwrite < 0) {
12124 return nwrite;
12125 }
12126
12127 res += nwrite;
12128
12129 if (res == 0) {
12130 return NGTCP2_ERR_NOBUF;
12131 }
12132
12133 conn->state = NGTCP2_CS_CLOSING;
12134
12135 return res;
12136 }
12137
12138 static void
connection_close_error_init(ngtcp2_connection_close_error * ccerr,ngtcp2_connection_close_error_code_type type,uint64_t error_code,const uint8_t * reason,size_t reasonlen)12139 connection_close_error_init(ngtcp2_connection_close_error *ccerr,
12140 ngtcp2_connection_close_error_code_type type,
12141 uint64_t error_code, const uint8_t *reason,
12142 size_t reasonlen) {
12143 ccerr->type = type;
12144 ccerr->error_code = error_code;
12145 ccerr->frame_type = 0;
12146 ccerr->reason = (uint8_t *)reason;
12147 ccerr->reasonlen = reasonlen;
12148 }
12149
ngtcp2_connection_close_error_default(ngtcp2_connection_close_error * ccerr)12150 void ngtcp2_connection_close_error_default(
12151 ngtcp2_connection_close_error *ccerr) {
12152 connection_close_error_init(ccerr,
12153 NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT,
12154 NGTCP2_NO_ERROR, NULL, 0);
12155 }
12156
ngtcp2_connection_close_error_set_transport_error(ngtcp2_connection_close_error * ccerr,uint64_t error_code,const uint8_t * reason,size_t reasonlen)12157 void ngtcp2_connection_close_error_set_transport_error(
12158 ngtcp2_connection_close_error *ccerr, uint64_t error_code,
12159 const uint8_t *reason, size_t reasonlen) {
12160 connection_close_error_init(ccerr,
12161 NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT,
12162 error_code, reason, reasonlen);
12163 }
12164
ngtcp2_connection_close_error_set_transport_error_liberr(ngtcp2_connection_close_error * ccerr,int liberr,const uint8_t * reason,size_t reasonlen)12165 void ngtcp2_connection_close_error_set_transport_error_liberr(
12166 ngtcp2_connection_close_error *ccerr, int liberr, const uint8_t *reason,
12167 size_t reasonlen) {
12168 switch (liberr) {
12169 case NGTCP2_ERR_RECV_VERSION_NEGOTIATION:
12170 connection_close_error_init(
12171 ccerr,
12172 NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT_VERSION_NEGOTIATION,
12173 NGTCP2_NO_ERROR, reason, reasonlen);
12174
12175 return;
12176 case NGTCP2_ERR_IDLE_CLOSE:
12177 connection_close_error_init(
12178 ccerr, NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT_IDLE_CLOSE,
12179 NGTCP2_NO_ERROR, reason, reasonlen);
12180
12181 return;
12182 };
12183
12184 ngtcp2_connection_close_error_set_transport_error(
12185 ccerr, ngtcp2_err_infer_quic_transport_error_code(liberr), reason,
12186 reasonlen);
12187 }
12188
ngtcp2_connection_close_error_set_transport_error_tls_alert(ngtcp2_connection_close_error * ccerr,uint8_t tls_alert,const uint8_t * reason,size_t reasonlen)12189 void ngtcp2_connection_close_error_set_transport_error_tls_alert(
12190 ngtcp2_connection_close_error *ccerr, uint8_t tls_alert,
12191 const uint8_t *reason, size_t reasonlen) {
12192 ngtcp2_connection_close_error_set_transport_error(
12193 ccerr, NGTCP2_CRYPTO_ERROR | tls_alert, reason, reasonlen);
12194 }
12195
ngtcp2_connection_close_error_set_application_error(ngtcp2_connection_close_error * ccerr,uint64_t error_code,const uint8_t * reason,size_t reasonlen)12196 void ngtcp2_connection_close_error_set_application_error(
12197 ngtcp2_connection_close_error *ccerr, uint64_t error_code,
12198 const uint8_t *reason, size_t reasonlen) {
12199 connection_close_error_init(
12200 ccerr, NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_APPLICATION, error_code,
12201 reason, reasonlen);
12202 }
12203
ngtcp2_conn_write_connection_close_versioned(ngtcp2_conn * conn,ngtcp2_path * path,int pkt_info_version,ngtcp2_pkt_info * pi,uint8_t * dest,size_t destlen,const ngtcp2_connection_close_error * ccerr,ngtcp2_tstamp ts)12204 ngtcp2_ssize ngtcp2_conn_write_connection_close_versioned(
12205 ngtcp2_conn *conn, ngtcp2_path *path, int pkt_info_version,
12206 ngtcp2_pkt_info *pi, uint8_t *dest, size_t destlen,
12207 const ngtcp2_connection_close_error *ccerr, ngtcp2_tstamp ts) {
12208 (void)pkt_info_version;
12209
12210 switch (ccerr->type) {
12211 case NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT:
12212 return ngtcp2_conn_write_connection_close_pkt(
12213 conn, path, pi, dest, destlen, ccerr->error_code, ccerr->reason,
12214 ccerr->reasonlen, ts);
12215 case NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_APPLICATION:
12216 return ngtcp2_conn_write_application_close_pkt(
12217 conn, path, pi, dest, destlen, ccerr->error_code, ccerr->reason,
12218 ccerr->reasonlen, ts);
12219 default:
12220 return 0;
12221 }
12222 }
12223
ngtcp2_conn_is_in_closing_period(ngtcp2_conn * conn)12224 int ngtcp2_conn_is_in_closing_period(ngtcp2_conn *conn) {
12225 return conn->state == NGTCP2_CS_CLOSING;
12226 }
12227
ngtcp2_conn_is_in_draining_period(ngtcp2_conn * conn)12228 int ngtcp2_conn_is_in_draining_period(ngtcp2_conn *conn) {
12229 return conn->state == NGTCP2_CS_DRAINING;
12230 }
12231
ngtcp2_conn_close_stream(ngtcp2_conn * conn,ngtcp2_strm * strm)12232 int ngtcp2_conn_close_stream(ngtcp2_conn *conn, ngtcp2_strm *strm) {
12233 int rv;
12234
12235 rv = ngtcp2_map_remove(&conn->strms, (ngtcp2_map_key_type)strm->stream_id);
12236 if (rv != 0) {
12237 assert(rv != NGTCP2_ERR_INVALID_ARGUMENT);
12238 return rv;
12239 }
12240
12241 rv = conn_call_stream_close(conn, strm);
12242 if (rv != 0) {
12243 goto fin;
12244 }
12245
12246 if (ngtcp2_strm_is_tx_queued(strm)) {
12247 ngtcp2_pq_remove(&conn->tx.strmq, &strm->pe);
12248 if (!ngtcp2_strm_streamfrq_empty(strm)) {
12249 assert(conn->tx.strmq_nretrans);
12250 --conn->tx.strmq_nretrans;
12251 }
12252 }
12253
12254 fin:
12255 ngtcp2_strm_free(strm);
12256 ngtcp2_objalloc_strm_release(&conn->strm_objalloc, strm);
12257
12258 return rv;
12259 }
12260
ngtcp2_conn_close_stream_if_shut_rdwr(ngtcp2_conn * conn,ngtcp2_strm * strm)12261 int ngtcp2_conn_close_stream_if_shut_rdwr(ngtcp2_conn *conn,
12262 ngtcp2_strm *strm) {
12263 if ((strm->flags & NGTCP2_STRM_FLAG_SHUT_RDWR) ==
12264 NGTCP2_STRM_FLAG_SHUT_RDWR &&
12265 ((strm->flags & NGTCP2_STRM_FLAG_RECV_RST) ||
12266 ngtcp2_strm_rx_offset(strm) == strm->rx.last_offset) &&
12267 (((strm->flags & NGTCP2_STRM_FLAG_SENT_RST) &&
12268 (strm->flags & NGTCP2_STRM_FLAG_RST_ACKED)) ||
12269 ngtcp2_strm_is_all_tx_data_fin_acked(strm))) {
12270 return ngtcp2_conn_close_stream(conn, strm);
12271 }
12272 return 0;
12273 }
12274
12275 /*
12276 * conn_shutdown_stream_write closes send stream with error code
12277 * |app_error_code|. RESET_STREAM frame is scheduled.
12278 *
12279 * This function returns 0 if it succeeds, or one of the following
12280 * negative error codes:
12281 *
12282 * NGTCP2_ERR_NOMEM
12283 * Out of memory.
12284 */
conn_shutdown_stream_write(ngtcp2_conn * conn,ngtcp2_strm * strm,uint64_t app_error_code)12285 static int conn_shutdown_stream_write(ngtcp2_conn *conn, ngtcp2_strm *strm,
12286 uint64_t app_error_code) {
12287 ngtcp2_strm_set_app_error_code(strm, app_error_code);
12288
12289 if ((strm->flags & NGTCP2_STRM_FLAG_SENT_RST) ||
12290 ngtcp2_strm_is_all_tx_data_fin_acked(strm)) {
12291 return 0;
12292 }
12293
12294 /* Set this flag so that we don't accidentally send DATA to this
12295 stream. */
12296 strm->flags |= NGTCP2_STRM_FLAG_SHUT_WR | NGTCP2_STRM_FLAG_SENT_RST;
12297
12298 ngtcp2_strm_streamfrq_clear(strm);
12299
12300 return conn_reset_stream(conn, strm, app_error_code);
12301 }
12302
12303 /*
12304 * conn_shutdown_stream_read closes read stream with error code
12305 * |app_error_code|. STOP_SENDING frame is scheduled.
12306 *
12307 * This function returns 0 if it succeeds, or one of the following
12308 * negative error codes:
12309 *
12310 * NGTCP2_ERR_NOMEM
12311 * Out of memory.
12312 */
conn_shutdown_stream_read(ngtcp2_conn * conn,ngtcp2_strm * strm,uint64_t app_error_code)12313 static int conn_shutdown_stream_read(ngtcp2_conn *conn, ngtcp2_strm *strm,
12314 uint64_t app_error_code) {
12315 if (strm->flags & NGTCP2_STRM_FLAG_STOP_SENDING) {
12316 return 0;
12317 }
12318 if ((strm->flags & NGTCP2_STRM_FLAG_SHUT_RD) &&
12319 ngtcp2_strm_rx_offset(strm) == strm->rx.last_offset) {
12320 return 0;
12321 }
12322
12323 /* Extend connection flow control window for the amount of data
12324 which are not passed to application. */
12325 if (!(strm->flags &
12326 (NGTCP2_STRM_FLAG_STOP_SENDING | NGTCP2_STRM_FLAG_RECV_RST))) {
12327 ngtcp2_conn_extend_max_offset(conn, strm->rx.last_offset -
12328 ngtcp2_strm_rx_offset(strm));
12329 }
12330
12331 strm->flags |= NGTCP2_STRM_FLAG_STOP_SENDING;
12332 ngtcp2_strm_set_app_error_code(strm, app_error_code);
12333
12334 return conn_stop_sending(conn, strm, app_error_code);
12335 }
12336
ngtcp2_conn_shutdown_stream(ngtcp2_conn * conn,int64_t stream_id,uint64_t app_error_code)12337 int ngtcp2_conn_shutdown_stream(ngtcp2_conn *conn, int64_t stream_id,
12338 uint64_t app_error_code) {
12339 int rv;
12340 ngtcp2_strm *strm;
12341
12342 strm = ngtcp2_conn_find_stream(conn, stream_id);
12343 if (strm == NULL) {
12344 return 0;
12345 }
12346
12347 rv = conn_shutdown_stream_read(conn, strm, app_error_code);
12348 if (rv != 0) {
12349 return rv;
12350 }
12351
12352 rv = conn_shutdown_stream_write(conn, strm, app_error_code);
12353 if (rv != 0) {
12354 return rv;
12355 }
12356
12357 return 0;
12358 }
12359
ngtcp2_conn_shutdown_stream_write(ngtcp2_conn * conn,int64_t stream_id,uint64_t app_error_code)12360 int ngtcp2_conn_shutdown_stream_write(ngtcp2_conn *conn, int64_t stream_id,
12361 uint64_t app_error_code) {
12362 ngtcp2_strm *strm;
12363
12364 strm = ngtcp2_conn_find_stream(conn, stream_id);
12365 if (strm == NULL) {
12366 return 0;
12367 }
12368
12369 return conn_shutdown_stream_write(conn, strm, app_error_code);
12370 }
12371
ngtcp2_conn_shutdown_stream_read(ngtcp2_conn * conn,int64_t stream_id,uint64_t app_error_code)12372 int ngtcp2_conn_shutdown_stream_read(ngtcp2_conn *conn, int64_t stream_id,
12373 uint64_t app_error_code) {
12374 ngtcp2_strm *strm;
12375
12376 strm = ngtcp2_conn_find_stream(conn, stream_id);
12377 if (strm == NULL) {
12378 return 0;
12379 }
12380
12381 return conn_shutdown_stream_read(conn, strm, app_error_code);
12382 }
12383
12384 /*
12385 * conn_extend_max_stream_offset extends stream level flow control
12386 * window by |datalen| of the stream denoted by |strm|.
12387 *
12388 * This function returns 0 if it succeeds, or one of the following
12389 * negative error codes:
12390 *
12391 * NGTCP2_ERR_NOMEM
12392 * Out of memory.
12393 */
conn_extend_max_stream_offset(ngtcp2_conn * conn,ngtcp2_strm * strm,uint64_t datalen)12394 static int conn_extend_max_stream_offset(ngtcp2_conn *conn, ngtcp2_strm *strm,
12395 uint64_t datalen) {
12396 ngtcp2_strm *top;
12397
12398 if (datalen > NGTCP2_MAX_VARINT ||
12399 strm->rx.unsent_max_offset > NGTCP2_MAX_VARINT - datalen) {
12400 strm->rx.unsent_max_offset = NGTCP2_MAX_VARINT;
12401 } else {
12402 strm->rx.unsent_max_offset += datalen;
12403 }
12404
12405 if (!(strm->flags &
12406 (NGTCP2_STRM_FLAG_SHUT_RD | NGTCP2_STRM_FLAG_STOP_SENDING)) &&
12407 !ngtcp2_strm_is_tx_queued(strm) &&
12408 conn_should_send_max_stream_data(conn, strm)) {
12409 if (!ngtcp2_pq_empty(&conn->tx.strmq)) {
12410 top = ngtcp2_conn_tx_strmq_top(conn);
12411 strm->cycle = top->cycle;
12412 }
12413 strm->cycle = conn_tx_strmq_first_cycle(conn);
12414 return ngtcp2_conn_tx_strmq_push(conn, strm);
12415 }
12416
12417 return 0;
12418 }
12419
ngtcp2_conn_extend_max_stream_offset(ngtcp2_conn * conn,int64_t stream_id,uint64_t datalen)12420 int ngtcp2_conn_extend_max_stream_offset(ngtcp2_conn *conn, int64_t stream_id,
12421 uint64_t datalen) {
12422 ngtcp2_strm *strm;
12423
12424 strm = ngtcp2_conn_find_stream(conn, stream_id);
12425 if (strm == NULL) {
12426 return 0;
12427 }
12428
12429 return conn_extend_max_stream_offset(conn, strm, datalen);
12430 }
12431
ngtcp2_conn_extend_max_offset(ngtcp2_conn * conn,uint64_t datalen)12432 void ngtcp2_conn_extend_max_offset(ngtcp2_conn *conn, uint64_t datalen) {
12433 if (NGTCP2_MAX_VARINT < datalen ||
12434 conn->rx.unsent_max_offset > NGTCP2_MAX_VARINT - datalen) {
12435 conn->rx.unsent_max_offset = NGTCP2_MAX_VARINT;
12436 return;
12437 }
12438
12439 conn->rx.unsent_max_offset += datalen;
12440 }
12441
ngtcp2_conn_extend_max_streams_bidi(ngtcp2_conn * conn,size_t n)12442 void ngtcp2_conn_extend_max_streams_bidi(ngtcp2_conn *conn, size_t n) {
12443 handle_max_remote_streams_extension(&conn->remote.bidi.unsent_max_streams, n);
12444 }
12445
ngtcp2_conn_extend_max_streams_uni(ngtcp2_conn * conn,size_t n)12446 void ngtcp2_conn_extend_max_streams_uni(ngtcp2_conn *conn, size_t n) {
12447 handle_max_remote_streams_extension(&conn->remote.uni.unsent_max_streams, n);
12448 }
12449
ngtcp2_conn_get_dcid(ngtcp2_conn * conn)12450 const ngtcp2_cid *ngtcp2_conn_get_dcid(ngtcp2_conn *conn) {
12451 return &conn->dcid.current.cid;
12452 }
12453
ngtcp2_conn_get_client_initial_dcid(ngtcp2_conn * conn)12454 const ngtcp2_cid *ngtcp2_conn_get_client_initial_dcid(ngtcp2_conn *conn) {
12455 return &conn->rcid;
12456 }
12457
ngtcp2_conn_get_client_chosen_version(ngtcp2_conn * conn)12458 uint32_t ngtcp2_conn_get_client_chosen_version(ngtcp2_conn *conn) {
12459 return conn->client_chosen_version;
12460 }
12461
ngtcp2_conn_get_negotiated_version(ngtcp2_conn * conn)12462 uint32_t ngtcp2_conn_get_negotiated_version(ngtcp2_conn *conn) {
12463 return conn->negotiated_version;
12464 }
12465
delete_strms_pq_each(void * data,void * ptr)12466 static int delete_strms_pq_each(void *data, void *ptr) {
12467 ngtcp2_conn *conn = ptr;
12468 ngtcp2_strm *s = data;
12469
12470 if (ngtcp2_strm_is_tx_queued(s)) {
12471 ngtcp2_pq_remove(&conn->tx.strmq, &s->pe);
12472 if (!ngtcp2_strm_streamfrq_empty(s)) {
12473 assert(conn->tx.strmq_nretrans);
12474 --conn->tx.strmq_nretrans;
12475 }
12476 }
12477
12478 ngtcp2_strm_free(s);
12479 ngtcp2_objalloc_strm_release(&conn->strm_objalloc, s);
12480
12481 return 0;
12482 }
12483
12484 /*
12485 * conn_discard_early_data_state discards any connection states which
12486 * are altered by any operations during early data transfer.
12487 */
conn_discard_early_data_state(ngtcp2_conn * conn)12488 static void conn_discard_early_data_state(ngtcp2_conn *conn) {
12489 ngtcp2_frame_chain **pfrc, *frc;
12490
12491 ngtcp2_rtb_remove_early_data(&conn->pktns.rtb, &conn->cstat);
12492
12493 ngtcp2_map_each_free(&conn->strms, delete_strms_pq_each, conn);
12494 ngtcp2_map_clear(&conn->strms);
12495
12496 conn->tx.offset = 0;
12497
12498 conn->rx.unsent_max_offset = conn->rx.max_offset =
12499 conn->local.transport_params.initial_max_data;
12500
12501 conn->remote.bidi.unsent_max_streams = conn->remote.bidi.max_streams =
12502 conn->local.transport_params.initial_max_streams_bidi;
12503
12504 conn->remote.uni.unsent_max_streams = conn->remote.uni.max_streams =
12505 conn->local.transport_params.initial_max_streams_uni;
12506
12507 if (conn->server) {
12508 conn->local.bidi.next_stream_id = 1;
12509 conn->local.uni.next_stream_id = 3;
12510 } else {
12511 conn->local.bidi.next_stream_id = 0;
12512 conn->local.uni.next_stream_id = 2;
12513 }
12514
12515 for (pfrc = &conn->pktns.tx.frq; *pfrc;) {
12516 frc = *pfrc;
12517 *pfrc = (*pfrc)->next;
12518 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
12519 }
12520 }
12521
ngtcp2_conn_early_data_rejected(ngtcp2_conn * conn)12522 void ngtcp2_conn_early_data_rejected(ngtcp2_conn *conn) {
12523 if (conn->flags & NGTCP2_CONN_FLAG_EARLY_DATA_REJECTED) {
12524 return;
12525 }
12526
12527 conn->flags |= NGTCP2_CONN_FLAG_EARLY_DATA_REJECTED;
12528
12529 conn_discard_early_data_state(conn);
12530 }
12531
ngtcp2_conn_update_rtt(ngtcp2_conn * conn,ngtcp2_duration rtt,ngtcp2_duration ack_delay,ngtcp2_tstamp ts)12532 int ngtcp2_conn_update_rtt(ngtcp2_conn *conn, ngtcp2_duration rtt,
12533 ngtcp2_duration ack_delay, ngtcp2_tstamp ts) {
12534 ngtcp2_conn_stat *cstat = &conn->cstat;
12535
12536 if (cstat->min_rtt == UINT64_MAX) {
12537 cstat->latest_rtt = rtt;
12538 cstat->min_rtt = rtt;
12539 cstat->smoothed_rtt = rtt;
12540 cstat->rttvar = rtt / 2;
12541 cstat->first_rtt_sample_ts = ts;
12542 } else {
12543 if (conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED) {
12544 assert(conn->remote.transport_params);
12545
12546 ack_delay =
12547 ngtcp2_min(ack_delay, conn->remote.transport_params->max_ack_delay);
12548 } else if (ack_delay > 0 && rtt >= cstat->min_rtt &&
12549 rtt < cstat->min_rtt + ack_delay) {
12550 /* Ignore RTT sample if adjusting ack_delay causes the sample
12551 less than min_rtt before handshake confirmation. */
12552 ngtcp2_log_info(
12553 &conn->log, NGTCP2_LOG_EVENT_RCV,
12554 "ignore rtt sample because ack_delay is too large latest_rtt=%" PRIu64
12555 " min_rtt=%" PRIu64 " ack_delay=%" PRIu64,
12556 rtt / NGTCP2_MILLISECONDS, cstat->min_rtt / NGTCP2_MILLISECONDS,
12557 ack_delay / NGTCP2_MILLISECONDS);
12558 return NGTCP2_ERR_INVALID_ARGUMENT;
12559 }
12560
12561 cstat->latest_rtt = rtt;
12562 cstat->min_rtt = ngtcp2_min(cstat->min_rtt, rtt);
12563
12564 if (rtt >= cstat->min_rtt + ack_delay) {
12565 rtt -= ack_delay;
12566 }
12567
12568 cstat->rttvar = (cstat->rttvar * 3 + (cstat->smoothed_rtt < rtt
12569 ? rtt - cstat->smoothed_rtt
12570 : cstat->smoothed_rtt - rtt)) /
12571 4;
12572 cstat->smoothed_rtt = (cstat->smoothed_rtt * 7 + rtt) / 8;
12573 }
12574
12575 ngtcp2_log_info(
12576 &conn->log, NGTCP2_LOG_EVENT_RCV,
12577 "latest_rtt=%" PRIu64 " min_rtt=%" PRIu64 " smoothed_rtt=%" PRIu64
12578 " rttvar=%" PRIu64 " ack_delay=%" PRIu64,
12579 cstat->latest_rtt / NGTCP2_MILLISECONDS,
12580 cstat->min_rtt / NGTCP2_MILLISECONDS,
12581 cstat->smoothed_rtt / NGTCP2_MILLISECONDS,
12582 cstat->rttvar / NGTCP2_MILLISECONDS, ack_delay / NGTCP2_MILLISECONDS);
12583
12584 return 0;
12585 }
12586
ngtcp2_conn_get_conn_stat_versioned(ngtcp2_conn * conn,int conn_stat_version,ngtcp2_conn_stat * cstat)12587 void ngtcp2_conn_get_conn_stat_versioned(ngtcp2_conn *conn,
12588 int conn_stat_version,
12589 ngtcp2_conn_stat *cstat) {
12590 (void)conn_stat_version;
12591
12592 *cstat = conn->cstat;
12593 }
12594
conn_get_loss_time_and_pktns(ngtcp2_conn * conn,ngtcp2_tstamp * ploss_time,ngtcp2_pktns ** ppktns)12595 static void conn_get_loss_time_and_pktns(ngtcp2_conn *conn,
12596 ngtcp2_tstamp *ploss_time,
12597 ngtcp2_pktns **ppktns) {
12598 ngtcp2_pktns *const ns[] = {conn->hs_pktns, &conn->pktns};
12599 ngtcp2_conn_stat *cstat = &conn->cstat;
12600 ngtcp2_duration *loss_time = cstat->loss_time;
12601 ngtcp2_tstamp earliest_loss_time = loss_time[NGTCP2_PKTNS_ID_INITIAL];
12602 ngtcp2_pktns *pktns = conn->in_pktns;
12603 size_t i;
12604
12605 for (i = 0; i < sizeof(ns) / sizeof(ns[0]); ++i) {
12606 if (ns[i] == NULL || ns[i]->rtb.num_pto_eliciting == 0 ||
12607 loss_time[i] >= earliest_loss_time) {
12608 continue;
12609 }
12610
12611 earliest_loss_time = loss_time[i];
12612 pktns = ns[i];
12613 }
12614
12615 if (ploss_time) {
12616 *ploss_time = earliest_loss_time;
12617 }
12618 if (ppktns) {
12619 *ppktns = pktns;
12620 }
12621 }
12622
conn_get_earliest_pto_expiry(ngtcp2_conn * conn,ngtcp2_tstamp ts)12623 static ngtcp2_tstamp conn_get_earliest_pto_expiry(ngtcp2_conn *conn,
12624 ngtcp2_tstamp ts) {
12625 ngtcp2_pktns *ns[] = {conn->in_pktns, conn->hs_pktns, &conn->pktns};
12626 size_t i;
12627 ngtcp2_tstamp earliest_ts = UINT64_MAX, t;
12628 ngtcp2_conn_stat *cstat = &conn->cstat;
12629 ngtcp2_tstamp *times = cstat->last_tx_pkt_ts;
12630 ngtcp2_duration duration =
12631 compute_pto(cstat->smoothed_rtt, cstat->rttvar, /* max_ack_delay = */ 0) *
12632 (1ULL << cstat->pto_count);
12633
12634 for (i = NGTCP2_PKTNS_ID_INITIAL; i < NGTCP2_PKTNS_ID_MAX; ++i) {
12635 if (ns[i] == NULL || ns[i]->rtb.num_pto_eliciting == 0 ||
12636 (times[i] == UINT64_MAX ||
12637 (i == NGTCP2_PKTNS_ID_APPLICATION &&
12638 !(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED)))) {
12639 continue;
12640 }
12641
12642 t = times[i] + duration;
12643
12644 if (i == NGTCP2_PKTNS_ID_APPLICATION) {
12645 assert(conn->remote.transport_params);
12646 t += conn->remote.transport_params->max_ack_delay *
12647 (1ULL << cstat->pto_count);
12648 }
12649
12650 if (t < earliest_ts) {
12651 earliest_ts = t;
12652 }
12653 }
12654
12655 if (earliest_ts == UINT64_MAX) {
12656 return ts + duration;
12657 }
12658
12659 return earliest_ts;
12660 }
12661
ngtcp2_conn_set_loss_detection_timer(ngtcp2_conn * conn,ngtcp2_tstamp ts)12662 void ngtcp2_conn_set_loss_detection_timer(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
12663 ngtcp2_conn_stat *cstat = &conn->cstat;
12664 ngtcp2_duration timeout;
12665 ngtcp2_pktns *in_pktns = conn->in_pktns;
12666 ngtcp2_pktns *hs_pktns = conn->hs_pktns;
12667 ngtcp2_pktns *pktns = &conn->pktns;
12668 ngtcp2_tstamp earliest_loss_time;
12669
12670 conn_get_loss_time_and_pktns(conn, &earliest_loss_time, NULL);
12671
12672 if (earliest_loss_time != UINT64_MAX) {
12673 cstat->loss_detection_timer = earliest_loss_time;
12674
12675 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_RCV,
12676 "loss_detection_timer=%" PRIu64 " nonzero crypto loss time",
12677 cstat->loss_detection_timer);
12678 return;
12679 }
12680
12681 if ((!in_pktns || in_pktns->rtb.num_pto_eliciting == 0) &&
12682 (!hs_pktns || hs_pktns->rtb.num_pto_eliciting == 0) &&
12683 (pktns->rtb.num_pto_eliciting == 0 ||
12684 !(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED)) &&
12685 (conn->server ||
12686 (conn->flags & (NGTCP2_CONN_FLAG_SERVER_ADDR_VERIFIED |
12687 NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED)))) {
12688 if (cstat->loss_detection_timer != UINT64_MAX) {
12689 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_RCV,
12690 "loss detection timer canceled");
12691 cstat->loss_detection_timer = UINT64_MAX;
12692 cstat->pto_count = 0;
12693 }
12694 return;
12695 }
12696
12697 cstat->loss_detection_timer = conn_get_earliest_pto_expiry(conn, ts);
12698
12699 timeout =
12700 cstat->loss_detection_timer > ts ? cstat->loss_detection_timer - ts : 0;
12701
12702 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_RCV,
12703 "loss_detection_timer=%" PRIu64 " timeout=%" PRIu64,
12704 cstat->loss_detection_timer, timeout / NGTCP2_MILLISECONDS);
12705 }
12706
ngtcp2_conn_on_loss_detection_timer(ngtcp2_conn * conn,ngtcp2_tstamp ts)12707 int ngtcp2_conn_on_loss_detection_timer(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
12708 ngtcp2_conn_stat *cstat = &conn->cstat;
12709 int rv;
12710 ngtcp2_pktns *in_pktns = conn->in_pktns;
12711 ngtcp2_pktns *hs_pktns = conn->hs_pktns;
12712 ngtcp2_tstamp earliest_loss_time;
12713 ngtcp2_pktns *loss_pktns = NULL;
12714
12715 conn->log.last_ts = ts;
12716 conn->qlog.last_ts = ts;
12717
12718 switch (conn->state) {
12719 case NGTCP2_CS_CLOSING:
12720 case NGTCP2_CS_DRAINING:
12721 cstat->loss_detection_timer = UINT64_MAX;
12722 cstat->pto_count = 0;
12723 return 0;
12724 default:
12725 break;
12726 }
12727
12728 if (cstat->loss_detection_timer == UINT64_MAX) {
12729 return 0;
12730 }
12731
12732 conn_get_loss_time_and_pktns(conn, &earliest_loss_time, &loss_pktns);
12733
12734 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_RCV,
12735 "loss detection timer fired");
12736
12737 if (earliest_loss_time != UINT64_MAX) {
12738 assert(loss_pktns);
12739
12740 rv = ngtcp2_conn_detect_lost_pkt(conn, loss_pktns, cstat, ts);
12741 if (rv != 0) {
12742 return rv;
12743 }
12744 ngtcp2_conn_set_loss_detection_timer(conn, ts);
12745 return 0;
12746 }
12747
12748 if (!conn->server && !conn_is_handshake_completed(conn)) {
12749 if (hs_pktns->crypto.tx.ckm) {
12750 hs_pktns->rtb.probe_pkt_left = 1;
12751 } else {
12752 in_pktns->rtb.probe_pkt_left = 1;
12753 }
12754 } else {
12755 if (in_pktns && in_pktns->rtb.num_pto_eliciting) {
12756 in_pktns->rtb.probe_pkt_left = 1;
12757
12758 assert(hs_pktns);
12759
12760 if (conn->server && hs_pktns->rtb.num_pto_eliciting) {
12761 /* let server coalesce packets */
12762 hs_pktns->rtb.probe_pkt_left = 1;
12763 }
12764 } else if (hs_pktns && hs_pktns->rtb.num_pto_eliciting) {
12765 hs_pktns->rtb.probe_pkt_left = 1;
12766 } else {
12767 conn->pktns.rtb.probe_pkt_left = 2;
12768 }
12769 }
12770
12771 ++cstat->pto_count;
12772
12773 ngtcp2_log_info(&conn->log, NGTCP2_LOG_EVENT_RCV, "pto_count=%zu",
12774 cstat->pto_count);
12775
12776 ngtcp2_conn_set_loss_detection_timer(conn, ts);
12777
12778 return 0;
12779 }
12780
conn_buffer_crypto_data(ngtcp2_conn * conn,const uint8_t ** pdata,ngtcp2_pktns * pktns,const uint8_t * data,size_t datalen)12781 static int conn_buffer_crypto_data(ngtcp2_conn *conn, const uint8_t **pdata,
12782 ngtcp2_pktns *pktns, const uint8_t *data,
12783 size_t datalen) {
12784 int rv;
12785 ngtcp2_buf_chain **pbufchain = &pktns->crypto.tx.data;
12786
12787 if (*pbufchain) {
12788 for (; (*pbufchain)->next; pbufchain = &(*pbufchain)->next)
12789 ;
12790
12791 if (ngtcp2_buf_left(&(*pbufchain)->buf) < datalen) {
12792 pbufchain = &(*pbufchain)->next;
12793 }
12794 }
12795
12796 if (!*pbufchain) {
12797 rv = ngtcp2_buf_chain_new(pbufchain, ngtcp2_max(1024, datalen), conn->mem);
12798 if (rv != 0) {
12799 return rv;
12800 }
12801 }
12802
12803 *pdata = (*pbufchain)->buf.last;
12804 (*pbufchain)->buf.last = ngtcp2_cpymem((*pbufchain)->buf.last, data, datalen);
12805
12806 return 0;
12807 }
12808
ngtcp2_conn_submit_crypto_data(ngtcp2_conn * conn,ngtcp2_crypto_level crypto_level,const uint8_t * data,const size_t datalen)12809 int ngtcp2_conn_submit_crypto_data(ngtcp2_conn *conn,
12810 ngtcp2_crypto_level crypto_level,
12811 const uint8_t *data, const size_t datalen) {
12812 ngtcp2_pktns *pktns;
12813 ngtcp2_frame_chain *frc;
12814 ngtcp2_crypto *fr;
12815 int rv;
12816
12817 if (datalen == 0) {
12818 return 0;
12819 }
12820
12821 switch (crypto_level) {
12822 case NGTCP2_CRYPTO_LEVEL_INITIAL:
12823 assert(conn->in_pktns);
12824 pktns = conn->in_pktns;
12825 break;
12826 case NGTCP2_CRYPTO_LEVEL_HANDSHAKE:
12827 assert(conn->hs_pktns);
12828 pktns = conn->hs_pktns;
12829 break;
12830 case NGTCP2_CRYPTO_LEVEL_APPLICATION:
12831 pktns = &conn->pktns;
12832 break;
12833 default:
12834 return NGTCP2_ERR_INVALID_ARGUMENT;
12835 }
12836
12837 rv = conn_buffer_crypto_data(conn, &data, pktns, data, datalen);
12838 if (rv != 0) {
12839 return rv;
12840 }
12841
12842 rv = ngtcp2_frame_chain_objalloc_new(&frc, &conn->frc_objalloc);
12843 if (rv != 0) {
12844 return rv;
12845 }
12846
12847 fr = &frc->fr.crypto;
12848
12849 fr->type = NGTCP2_FRAME_CRYPTO;
12850 fr->offset = pktns->crypto.tx.offset;
12851 fr->datacnt = 1;
12852 fr->data[0].len = datalen;
12853 fr->data[0].base = (uint8_t *)data;
12854
12855 rv = ngtcp2_ksl_insert(&pktns->crypto.tx.frq, NULL, &fr->offset, frc);
12856 if (rv != 0) {
12857 ngtcp2_frame_chain_objalloc_del(frc, &conn->frc_objalloc, conn->mem);
12858 return rv;
12859 }
12860
12861 pktns->crypto.strm.tx.offset += datalen;
12862 pktns->crypto.tx.offset += datalen;
12863
12864 return 0;
12865 }
12866
ngtcp2_conn_submit_new_token(ngtcp2_conn * conn,const uint8_t * token,size_t tokenlen)12867 int ngtcp2_conn_submit_new_token(ngtcp2_conn *conn, const uint8_t *token,
12868 size_t tokenlen) {
12869 int rv;
12870 ngtcp2_frame_chain *nfrc;
12871 ngtcp2_vec tokenv = {(uint8_t *)token, tokenlen};
12872
12873 assert(conn->server);
12874 assert(token);
12875 assert(tokenlen);
12876
12877 rv = ngtcp2_frame_chain_new_token_objalloc_new(
12878 &nfrc, &tokenv, &conn->frc_objalloc, conn->mem);
12879 if (rv != 0) {
12880 return rv;
12881 }
12882
12883 nfrc->next = conn->pktns.tx.frq;
12884 conn->pktns.tx.frq = nfrc;
12885
12886 return 0;
12887 }
12888
ngtcp2_conn_tx_strmq_top(ngtcp2_conn * conn)12889 ngtcp2_strm *ngtcp2_conn_tx_strmq_top(ngtcp2_conn *conn) {
12890 assert(!ngtcp2_pq_empty(&conn->tx.strmq));
12891 return ngtcp2_struct_of(ngtcp2_pq_top(&conn->tx.strmq), ngtcp2_strm, pe);
12892 }
12893
ngtcp2_conn_tx_strmq_pop(ngtcp2_conn * conn)12894 void ngtcp2_conn_tx_strmq_pop(ngtcp2_conn *conn) {
12895 ngtcp2_strm *strm = ngtcp2_conn_tx_strmq_top(conn);
12896 assert(strm);
12897 ngtcp2_pq_pop(&conn->tx.strmq);
12898 strm->pe.index = NGTCP2_PQ_BAD_INDEX;
12899 }
12900
ngtcp2_conn_tx_strmq_push(ngtcp2_conn * conn,ngtcp2_strm * strm)12901 int ngtcp2_conn_tx_strmq_push(ngtcp2_conn *conn, ngtcp2_strm *strm) {
12902 return ngtcp2_pq_push(&conn->tx.strmq, &strm->pe);
12903 }
12904
conn_has_uncommited_preferred_address_cid(ngtcp2_conn * conn)12905 static int conn_has_uncommited_preferred_address_cid(ngtcp2_conn *conn) {
12906 return conn->server &&
12907 !(conn->flags & NGTCP2_CONN_FLAG_LOCAL_TRANSPORT_PARAMS_COMMITTED) &&
12908 conn->oscid.datalen &&
12909 conn->local.transport_params.preferred_address_present;
12910 }
12911
ngtcp2_conn_get_num_scid(ngtcp2_conn * conn)12912 size_t ngtcp2_conn_get_num_scid(ngtcp2_conn *conn) {
12913 return ngtcp2_ksl_len(&conn->scid.set) +
12914 (size_t)conn_has_uncommited_preferred_address_cid(conn);
12915 }
12916
ngtcp2_conn_get_scid(ngtcp2_conn * conn,ngtcp2_cid * dest)12917 size_t ngtcp2_conn_get_scid(ngtcp2_conn *conn, ngtcp2_cid *dest) {
12918 ngtcp2_cid *origdest = dest;
12919 ngtcp2_ksl_it it;
12920 ngtcp2_scid *scid;
12921
12922 for (it = ngtcp2_ksl_begin(&conn->scid.set); !ngtcp2_ksl_it_end(&it);
12923 ngtcp2_ksl_it_next(&it)) {
12924 scid = ngtcp2_ksl_it_get(&it);
12925 *dest++ = scid->cid;
12926 }
12927
12928 if (conn_has_uncommited_preferred_address_cid(conn)) {
12929 *dest++ = conn->local.transport_params.preferred_address.cid;
12930 }
12931
12932 return (size_t)(dest - origdest);
12933 }
12934
ngtcp2_conn_get_num_active_dcid(ngtcp2_conn * conn)12935 size_t ngtcp2_conn_get_num_active_dcid(ngtcp2_conn *conn) {
12936 size_t n = 1; /* for conn->dcid.current */
12937 ngtcp2_pv *pv = conn->pv;
12938
12939 if (!(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_COMPLETED_HANDLED)) {
12940 return 0;
12941 }
12942
12943 if (pv) {
12944 if (pv->dcid.seq != conn->dcid.current.seq) {
12945 ++n;
12946 }
12947 if ((pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) &&
12948 pv->fallback_dcid.seq != conn->dcid.current.seq &&
12949 pv->fallback_dcid.seq != pv->dcid.seq) {
12950 ++n;
12951 }
12952 }
12953
12954 n += ngtcp2_ringbuf_len(&conn->dcid.retired.rb);
12955
12956 return n;
12957 }
12958
copy_dcid_to_cid_token(ngtcp2_cid_token * dest,const ngtcp2_dcid * src)12959 static void copy_dcid_to_cid_token(ngtcp2_cid_token *dest,
12960 const ngtcp2_dcid *src) {
12961 dest->seq = src->seq;
12962 dest->cid = src->cid;
12963 ngtcp2_path_storage_init2(&dest->ps, &src->ps.path);
12964 if ((dest->token_present =
12965 (src->flags & NGTCP2_DCID_FLAG_TOKEN_PRESENT) != 0)) {
12966 memcpy(dest->token, src->token, NGTCP2_STATELESS_RESET_TOKENLEN);
12967 }
12968 }
12969
ngtcp2_conn_get_active_dcid(ngtcp2_conn * conn,ngtcp2_cid_token * dest)12970 size_t ngtcp2_conn_get_active_dcid(ngtcp2_conn *conn, ngtcp2_cid_token *dest) {
12971 ngtcp2_pv *pv = conn->pv;
12972 ngtcp2_cid_token *orig = dest;
12973 ngtcp2_dcid *dcid;
12974 size_t len, i;
12975
12976 if (!(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_COMPLETED_HANDLED)) {
12977 return 0;
12978 }
12979
12980 copy_dcid_to_cid_token(dest, &conn->dcid.current);
12981 ++dest;
12982
12983 if (pv) {
12984 if (pv->dcid.seq != conn->dcid.current.seq) {
12985 copy_dcid_to_cid_token(dest, &pv->dcid);
12986 ++dest;
12987 }
12988 if ((pv->flags & NGTCP2_PV_FLAG_FALLBACK_ON_FAILURE) &&
12989 pv->fallback_dcid.seq != conn->dcid.current.seq &&
12990 pv->fallback_dcid.seq != pv->dcid.seq) {
12991 copy_dcid_to_cid_token(dest, &pv->fallback_dcid);
12992 ++dest;
12993 }
12994 }
12995
12996 len = ngtcp2_ringbuf_len(&conn->dcid.retired.rb);
12997 for (i = 0; i < len; ++i) {
12998 dcid = ngtcp2_ringbuf_get(&conn->dcid.retired.rb, i);
12999 copy_dcid_to_cid_token(dest, dcid);
13000 ++dest;
13001 }
13002
13003 return (size_t)(dest - orig);
13004 }
13005
ngtcp2_conn_set_local_addr(ngtcp2_conn * conn,const ngtcp2_addr * addr)13006 void ngtcp2_conn_set_local_addr(ngtcp2_conn *conn, const ngtcp2_addr *addr) {
13007 ngtcp2_addr *dest = &conn->dcid.current.ps.path.local;
13008
13009 assert(addr->addrlen <=
13010 (ngtcp2_socklen)sizeof(conn->dcid.current.ps.local_addrbuf));
13011 ngtcp2_addr_copy(dest, addr);
13012 }
13013
ngtcp2_conn_set_path_user_data(ngtcp2_conn * conn,void * path_user_data)13014 void ngtcp2_conn_set_path_user_data(ngtcp2_conn *conn, void *path_user_data) {
13015 conn->dcid.current.ps.path.user_data = path_user_data;
13016 }
13017
ngtcp2_conn_get_path(ngtcp2_conn * conn)13018 const ngtcp2_path *ngtcp2_conn_get_path(ngtcp2_conn *conn) {
13019 return &conn->dcid.current.ps.path;
13020 }
13021
ngtcp2_conn_get_max_udp_payload_size(ngtcp2_conn * conn)13022 size_t ngtcp2_conn_get_max_udp_payload_size(ngtcp2_conn *conn) {
13023 return conn->local.settings.max_udp_payload_size;
13024 }
13025
ngtcp2_conn_get_path_max_udp_payload_size(ngtcp2_conn * conn)13026 size_t ngtcp2_conn_get_path_max_udp_payload_size(ngtcp2_conn *conn) {
13027 if (conn->local.settings.no_udp_payload_size_shaping) {
13028 return ngtcp2_conn_get_max_udp_payload_size(conn);
13029 }
13030
13031 return conn->dcid.current.max_udp_payload_size;
13032 }
13033
conn_initiate_migration_precheck(ngtcp2_conn * conn,const ngtcp2_addr * local_addr)13034 static int conn_initiate_migration_precheck(ngtcp2_conn *conn,
13035 const ngtcp2_addr *local_addr) {
13036 if (!(conn->flags & NGTCP2_CONN_FLAG_HANDSHAKE_CONFIRMED) ||
13037 conn->remote.transport_params->disable_active_migration ||
13038 conn->dcid.current.cid.datalen == 0 ||
13039 (conn->pv && (conn->pv->flags & NGTCP2_PV_FLAG_PREFERRED_ADDR))) {
13040 return NGTCP2_ERR_INVALID_STATE;
13041 }
13042
13043 if (ngtcp2_ringbuf_len(&conn->dcid.unused.rb) == 0) {
13044 return NGTCP2_ERR_CONN_ID_BLOCKED;
13045 }
13046
13047 if (ngtcp2_addr_eq(&conn->dcid.current.ps.path.local, local_addr)) {
13048 return NGTCP2_ERR_INVALID_ARGUMENT;
13049 }
13050
13051 return 0;
13052 }
13053
ngtcp2_conn_initiate_immediate_migration(ngtcp2_conn * conn,const ngtcp2_path * path,ngtcp2_tstamp ts)13054 int ngtcp2_conn_initiate_immediate_migration(ngtcp2_conn *conn,
13055 const ngtcp2_path *path,
13056 ngtcp2_tstamp ts) {
13057 int rv;
13058 ngtcp2_dcid *dcid;
13059
13060 assert(!conn->server);
13061
13062 conn->log.last_ts = ts;
13063 conn->qlog.last_ts = ts;
13064
13065 rv = conn_initiate_migration_precheck(conn, &path->local);
13066 if (rv != 0) {
13067 return rv;
13068 }
13069
13070 ngtcp2_conn_stop_pmtud(conn);
13071
13072 if (conn->pv) {
13073 rv = conn_abort_pv(conn, ts);
13074 if (rv != 0) {
13075 return rv;
13076 }
13077 }
13078
13079 rv = conn_retire_dcid(conn, &conn->dcid.current, ts);
13080 if (rv != 0) {
13081 return rv;
13082 }
13083
13084 dcid = ngtcp2_ringbuf_get(&conn->dcid.unused.rb, 0);
13085 ngtcp2_dcid_set_path(dcid, path);
13086
13087 ngtcp2_dcid_copy(&conn->dcid.current, dcid);
13088 ngtcp2_ringbuf_pop_front(&conn->dcid.unused.rb);
13089
13090 rv = conn_call_activate_dcid(conn, &conn->dcid.current);
13091 if (rv != 0) {
13092 return rv;
13093 }
13094
13095 conn_reset_congestion_state(conn, ts);
13096 conn_reset_ecn_validation_state(conn);
13097
13098 if (!conn->local.settings.no_pmtud) {
13099 rv = conn_start_pmtud(conn);
13100 if (rv != 0) {
13101 return rv;
13102 }
13103 }
13104
13105 return 0;
13106 }
13107
ngtcp2_conn_initiate_migration(ngtcp2_conn * conn,const ngtcp2_path * path,ngtcp2_tstamp ts)13108 int ngtcp2_conn_initiate_migration(ngtcp2_conn *conn, const ngtcp2_path *path,
13109 ngtcp2_tstamp ts) {
13110 int rv;
13111 ngtcp2_dcid *dcid;
13112 ngtcp2_duration pto, initial_pto, timeout;
13113 ngtcp2_pv *pv;
13114
13115 assert(!conn->server);
13116
13117 conn->log.last_ts = ts;
13118 conn->qlog.last_ts = ts;
13119
13120 rv = conn_initiate_migration_precheck(conn, &path->local);
13121 if (rv != 0) {
13122 return rv;
13123 }
13124
13125 if (conn->pv) {
13126 rv = conn_abort_pv(conn, ts);
13127 if (rv != 0) {
13128 return rv;
13129 }
13130 }
13131
13132 dcid = ngtcp2_ringbuf_get(&conn->dcid.unused.rb, 0);
13133 ngtcp2_dcid_set_path(dcid, path);
13134
13135 pto = conn_compute_pto(conn, &conn->pktns);
13136 initial_pto = conn_compute_initial_pto(conn, &conn->pktns);
13137 timeout = 3 * ngtcp2_max(pto, initial_pto);
13138
13139 rv = ngtcp2_pv_new(&pv, dcid, timeout, NGTCP2_PV_FLAG_NONE, &conn->log,
13140 conn->mem);
13141 if (rv != 0) {
13142 return rv;
13143 }
13144
13145 ngtcp2_ringbuf_pop_front(&conn->dcid.unused.rb);
13146 conn->pv = pv;
13147
13148 return conn_call_activate_dcid(conn, &pv->dcid);
13149 }
13150
ngtcp2_conn_get_max_local_streams_uni(ngtcp2_conn * conn)13151 uint64_t ngtcp2_conn_get_max_local_streams_uni(ngtcp2_conn *conn) {
13152 return conn->local.uni.max_streams;
13153 }
13154
ngtcp2_conn_get_max_data_left(ngtcp2_conn * conn)13155 uint64_t ngtcp2_conn_get_max_data_left(ngtcp2_conn *conn) {
13156 return conn->tx.max_offset - conn->tx.offset;
13157 }
13158
ngtcp2_conn_get_max_stream_data_left(ngtcp2_conn * conn,int64_t stream_id)13159 uint64_t ngtcp2_conn_get_max_stream_data_left(ngtcp2_conn *conn,
13160 int64_t stream_id) {
13161 ngtcp2_strm *strm = ngtcp2_conn_find_stream(conn, stream_id);
13162
13163 if (strm == NULL) {
13164 return 0;
13165 }
13166
13167 return strm->tx.max_offset - strm->tx.offset;
13168 }
13169
ngtcp2_conn_get_streams_bidi_left(ngtcp2_conn * conn)13170 uint64_t ngtcp2_conn_get_streams_bidi_left(ngtcp2_conn *conn) {
13171 uint64_t n = ngtcp2_ord_stream_id(conn->local.bidi.next_stream_id);
13172
13173 return n > conn->local.bidi.max_streams
13174 ? 0
13175 : conn->local.bidi.max_streams - n + 1;
13176 }
13177
ngtcp2_conn_get_streams_uni_left(ngtcp2_conn * conn)13178 uint64_t ngtcp2_conn_get_streams_uni_left(ngtcp2_conn *conn) {
13179 uint64_t n = ngtcp2_ord_stream_id(conn->local.uni.next_stream_id);
13180
13181 return n > conn->local.uni.max_streams ? 0
13182 : conn->local.uni.max_streams - n + 1;
13183 }
13184
ngtcp2_conn_get_cwnd_left(ngtcp2_conn * conn)13185 uint64_t ngtcp2_conn_get_cwnd_left(ngtcp2_conn *conn) {
13186 uint64_t bytes_in_flight = conn->cstat.bytes_in_flight;
13187 uint64_t cwnd = conn_get_cwnd(conn);
13188
13189 if (cwnd > bytes_in_flight) {
13190 return cwnd - bytes_in_flight;
13191 }
13192
13193 return 0;
13194 }
13195
ngtcp2_conn_get_idle_expiry(ngtcp2_conn * conn)13196 ngtcp2_tstamp ngtcp2_conn_get_idle_expiry(ngtcp2_conn *conn) {
13197 ngtcp2_duration trpto;
13198 ngtcp2_duration idle_timeout;
13199
13200 /* TODO Remote max_idle_timeout becomes effective after handshake
13201 completion. */
13202
13203 if (!conn_is_handshake_completed(conn) ||
13204 conn->remote.transport_params->max_idle_timeout == 0 ||
13205 (conn->local.transport_params.max_idle_timeout &&
13206 conn->local.transport_params.max_idle_timeout <
13207 conn->remote.transport_params->max_idle_timeout)) {
13208 idle_timeout = conn->local.transport_params.max_idle_timeout;
13209 } else {
13210 idle_timeout = conn->remote.transport_params->max_idle_timeout;
13211 }
13212
13213 if (idle_timeout == 0) {
13214 return UINT64_MAX;
13215 }
13216
13217 trpto = 3 * conn_compute_pto(conn, conn_is_handshake_completed(conn)
13218 ? &conn->pktns
13219 : conn->hs_pktns);
13220
13221 return conn->idle_ts + ngtcp2_max(idle_timeout, trpto);
13222 }
13223
ngtcp2_conn_get_pto(ngtcp2_conn * conn)13224 ngtcp2_duration ngtcp2_conn_get_pto(ngtcp2_conn *conn) {
13225 return conn_compute_pto(
13226 conn, conn_is_handshake_completed(conn) ? &conn->pktns : conn->hs_pktns);
13227 }
13228
ngtcp2_conn_set_initial_crypto_ctx(ngtcp2_conn * conn,const ngtcp2_crypto_ctx * ctx)13229 void ngtcp2_conn_set_initial_crypto_ctx(ngtcp2_conn *conn,
13230 const ngtcp2_crypto_ctx *ctx) {
13231 assert(conn->in_pktns);
13232 conn->in_pktns->crypto.ctx = *ctx;
13233 }
13234
ngtcp2_conn_get_initial_crypto_ctx(ngtcp2_conn * conn)13235 const ngtcp2_crypto_ctx *ngtcp2_conn_get_initial_crypto_ctx(ngtcp2_conn *conn) {
13236 assert(conn->in_pktns);
13237 return &conn->in_pktns->crypto.ctx;
13238 }
13239
ngtcp2_conn_set_retry_aead(ngtcp2_conn * conn,const ngtcp2_crypto_aead * aead,const ngtcp2_crypto_aead_ctx * aead_ctx)13240 void ngtcp2_conn_set_retry_aead(ngtcp2_conn *conn,
13241 const ngtcp2_crypto_aead *aead,
13242 const ngtcp2_crypto_aead_ctx *aead_ctx) {
13243 assert(!conn->crypto.retry_aead_ctx.native_handle);
13244
13245 conn->crypto.retry_aead = *aead;
13246 conn->crypto.retry_aead_ctx = *aead_ctx;
13247 }
13248
ngtcp2_conn_set_crypto_ctx(ngtcp2_conn * conn,const ngtcp2_crypto_ctx * ctx)13249 void ngtcp2_conn_set_crypto_ctx(ngtcp2_conn *conn,
13250 const ngtcp2_crypto_ctx *ctx) {
13251 assert(conn->hs_pktns);
13252 conn->hs_pktns->crypto.ctx = *ctx;
13253 conn->pktns.crypto.ctx = *ctx;
13254 }
13255
ngtcp2_conn_get_crypto_ctx(ngtcp2_conn * conn)13256 const ngtcp2_crypto_ctx *ngtcp2_conn_get_crypto_ctx(ngtcp2_conn *conn) {
13257 return &conn->pktns.crypto.ctx;
13258 }
13259
ngtcp2_conn_set_early_crypto_ctx(ngtcp2_conn * conn,const ngtcp2_crypto_ctx * ctx)13260 void ngtcp2_conn_set_early_crypto_ctx(ngtcp2_conn *conn,
13261 const ngtcp2_crypto_ctx *ctx) {
13262 conn->early.ctx = *ctx;
13263 }
13264
ngtcp2_conn_get_early_crypto_ctx(ngtcp2_conn * conn)13265 const ngtcp2_crypto_ctx *ngtcp2_conn_get_early_crypto_ctx(ngtcp2_conn *conn) {
13266 return &conn->early.ctx;
13267 }
13268
ngtcp2_conn_get_tls_native_handle(ngtcp2_conn * conn)13269 void *ngtcp2_conn_get_tls_native_handle(ngtcp2_conn *conn) {
13270 return conn->crypto.tls_native_handle;
13271 }
13272
ngtcp2_conn_set_tls_native_handle(ngtcp2_conn * conn,void * tls_native_handle)13273 void ngtcp2_conn_set_tls_native_handle(ngtcp2_conn *conn,
13274 void *tls_native_handle) {
13275 conn->crypto.tls_native_handle = tls_native_handle;
13276 }
13277
ngtcp2_conn_get_connection_close_error(ngtcp2_conn * conn,ngtcp2_connection_close_error * ccerr)13278 void ngtcp2_conn_get_connection_close_error(
13279 ngtcp2_conn *conn, ngtcp2_connection_close_error *ccerr) {
13280 *ccerr = conn->rx.ccerr;
13281 }
13282
ngtcp2_conn_set_tls_error(ngtcp2_conn * conn,int liberr)13283 void ngtcp2_conn_set_tls_error(ngtcp2_conn *conn, int liberr) {
13284 conn->crypto.tls_error = liberr;
13285 }
13286
ngtcp2_conn_get_tls_error(ngtcp2_conn * conn)13287 int ngtcp2_conn_get_tls_error(ngtcp2_conn *conn) {
13288 return conn->crypto.tls_error;
13289 }
13290
ngtcp2_conn_set_tls_alert(ngtcp2_conn * conn,uint8_t alert)13291 void ngtcp2_conn_set_tls_alert(ngtcp2_conn *conn, uint8_t alert) {
13292 conn->crypto.tls_alert = alert;
13293 }
13294
ngtcp2_conn_get_tls_alert(ngtcp2_conn * conn)13295 uint8_t ngtcp2_conn_get_tls_alert(ngtcp2_conn *conn) {
13296 return conn->crypto.tls_alert;
13297 }
13298
ngtcp2_conn_is_local_stream(ngtcp2_conn * conn,int64_t stream_id)13299 int ngtcp2_conn_is_local_stream(ngtcp2_conn *conn, int64_t stream_id) {
13300 return conn_local_stream(conn, stream_id);
13301 }
13302
ngtcp2_conn_is_server(ngtcp2_conn * conn)13303 int ngtcp2_conn_is_server(ngtcp2_conn *conn) { return conn->server; }
13304
ngtcp2_conn_after_retry(ngtcp2_conn * conn)13305 int ngtcp2_conn_after_retry(ngtcp2_conn *conn) {
13306 return (conn->flags & NGTCP2_CONN_FLAG_RECV_RETRY) != 0;
13307 }
13308
ngtcp2_conn_set_stream_user_data(ngtcp2_conn * conn,int64_t stream_id,void * stream_user_data)13309 int ngtcp2_conn_set_stream_user_data(ngtcp2_conn *conn, int64_t stream_id,
13310 void *stream_user_data) {
13311 ngtcp2_strm *strm = ngtcp2_conn_find_stream(conn, stream_id);
13312
13313 if (strm == NULL) {
13314 return NGTCP2_ERR_STREAM_NOT_FOUND;
13315 }
13316
13317 strm->stream_user_data = stream_user_data;
13318
13319 return 0;
13320 }
13321
ngtcp2_conn_update_pkt_tx_time(ngtcp2_conn * conn,ngtcp2_tstamp ts)13322 void ngtcp2_conn_update_pkt_tx_time(ngtcp2_conn *conn, ngtcp2_tstamp ts) {
13323 if (!(conn->cstat.pacing_rate > 0) || conn->tx.pacing.pktlen == 0) {
13324 return;
13325 }
13326
13327 conn->tx.pacing.next_ts =
13328 ts + (ngtcp2_duration)((double)conn->tx.pacing.pktlen /
13329 conn->cstat.pacing_rate);
13330 conn->tx.pacing.pktlen = 0;
13331 }
13332
ngtcp2_conn_get_send_quantum(ngtcp2_conn * conn)13333 size_t ngtcp2_conn_get_send_quantum(ngtcp2_conn *conn) {
13334 return conn->cstat.send_quantum;
13335 }
13336
ngtcp2_conn_track_retired_dcid_seq(ngtcp2_conn * conn,uint64_t seq)13337 int ngtcp2_conn_track_retired_dcid_seq(ngtcp2_conn *conn, uint64_t seq) {
13338 size_t i;
13339
13340 if (conn->dcid.retire_unacked.len >=
13341 sizeof(conn->dcid.retire_unacked.seqs) /
13342 sizeof(conn->dcid.retire_unacked.seqs[0])) {
13343 return NGTCP2_ERR_CONNECTION_ID_LIMIT;
13344 }
13345
13346 /* Make sure that we do not have a duplicate */
13347 for (i = 0; i < conn->dcid.retire_unacked.len; ++i) {
13348 if (conn->dcid.retire_unacked.seqs[i] == seq) {
13349 assert(0);
13350 }
13351 }
13352
13353 conn->dcid.retire_unacked.seqs[conn->dcid.retire_unacked.len++] = seq;
13354
13355 return 0;
13356 }
13357
ngtcp2_conn_untrack_retired_dcid_seq(ngtcp2_conn * conn,uint64_t seq)13358 void ngtcp2_conn_untrack_retired_dcid_seq(ngtcp2_conn *conn, uint64_t seq) {
13359 size_t i;
13360
13361 for (i = 0; i < conn->dcid.retire_unacked.len; ++i) {
13362 if (conn->dcid.retire_unacked.seqs[i] != seq) {
13363 continue;
13364 }
13365
13366 if (i != conn->dcid.retire_unacked.len - 1) {
13367 conn->dcid.retire_unacked.seqs[i] =
13368 conn->dcid.retire_unacked.seqs[conn->dcid.retire_unacked.len - 1];
13369 }
13370
13371 --conn->dcid.retire_unacked.len;
13372
13373 return;
13374 }
13375 }
13376
ngtcp2_conn_get_stream_loss_count(ngtcp2_conn * conn,int64_t stream_id)13377 size_t ngtcp2_conn_get_stream_loss_count(ngtcp2_conn *conn, int64_t stream_id) {
13378 ngtcp2_strm *strm = ngtcp2_conn_find_stream(conn, stream_id);
13379
13380 if (strm == NULL) {
13381 return 0;
13382 }
13383
13384 return strm->tx.loss_count;
13385 }
13386
ngtcp2_path_challenge_entry_init(ngtcp2_path_challenge_entry * pcent,const ngtcp2_path * path,const uint8_t * data)13387 void ngtcp2_path_challenge_entry_init(ngtcp2_path_challenge_entry *pcent,
13388 const ngtcp2_path *path,
13389 const uint8_t *data) {
13390 ngtcp2_path_storage_init2(&pcent->ps, path);
13391 memcpy(pcent->data, data, sizeof(pcent->data));
13392 }
13393
ngtcp2_settings_default_versioned(int settings_version,ngtcp2_settings * settings)13394 void ngtcp2_settings_default_versioned(int settings_version,
13395 ngtcp2_settings *settings) {
13396 (void)settings_version;
13397
13398 memset(settings, 0, sizeof(*settings));
13399 settings->cc_algo = NGTCP2_CC_ALGO_CUBIC;
13400 settings->initial_rtt = NGTCP2_DEFAULT_INITIAL_RTT;
13401 settings->ack_thresh = 2;
13402 settings->max_udp_payload_size = 1500 - 48;
13403 settings->handshake_timeout = NGTCP2_DEFAULT_HANDSHAKE_TIMEOUT;
13404 }
13405
ngtcp2_transport_params_default_versioned(int transport_params_version,ngtcp2_transport_params * params)13406 void ngtcp2_transport_params_default_versioned(
13407 int transport_params_version, ngtcp2_transport_params *params) {
13408 (void)transport_params_version;
13409
13410 memset(params, 0, sizeof(*params));
13411 params->max_udp_payload_size = NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE;
13412 params->ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT;
13413 params->max_ack_delay = NGTCP2_DEFAULT_MAX_ACK_DELAY;
13414 params->active_connection_id_limit =
13415 NGTCP2_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
13416 }
13417
13418 /* The functions prefixed with ngtcp2_pkt_ are usually put inside
13419 ngtcp2_pkt.c. This function uses encryption construct and uses
13420 test data defined only in ngtcp2_conn_test.c, so it is written
13421 here. */
ngtcp2_pkt_write_connection_close(uint8_t * dest,size_t destlen,uint32_t version,const ngtcp2_cid * dcid,const ngtcp2_cid * scid,uint64_t error_code,const uint8_t * reason,size_t reasonlen,ngtcp2_encrypt encrypt,const ngtcp2_crypto_aead * aead,const ngtcp2_crypto_aead_ctx * aead_ctx,const uint8_t * iv,ngtcp2_hp_mask hp_mask,const ngtcp2_crypto_cipher * hp,const ngtcp2_crypto_cipher_ctx * hp_ctx)13422 ngtcp2_ssize ngtcp2_pkt_write_connection_close(
13423 uint8_t *dest, size_t destlen, uint32_t version, const ngtcp2_cid *dcid,
13424 const ngtcp2_cid *scid, uint64_t error_code, const uint8_t *reason,
13425 size_t reasonlen, ngtcp2_encrypt encrypt, const ngtcp2_crypto_aead *aead,
13426 const ngtcp2_crypto_aead_ctx *aead_ctx, const uint8_t *iv,
13427 ngtcp2_hp_mask hp_mask, const ngtcp2_crypto_cipher *hp,
13428 const ngtcp2_crypto_cipher_ctx *hp_ctx) {
13429 ngtcp2_pkt_hd hd;
13430 ngtcp2_crypto_km ckm;
13431 ngtcp2_crypto_cc cc;
13432 ngtcp2_ppe ppe;
13433 ngtcp2_frame fr = {0};
13434 int rv;
13435
13436 ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_LONG_FORM, NGTCP2_PKT_INITIAL, dcid,
13437 scid, /* pkt_num = */ 0, /* pkt_numlen = */ 1, version,
13438 /* len = */ 0);
13439
13440 ngtcp2_vec_init(&ckm.secret, NULL, 0);
13441 ngtcp2_vec_init(&ckm.iv, iv, 12);
13442 ckm.aead_ctx = *aead_ctx;
13443 ckm.pkt_num = 0;
13444 ckm.flags = NGTCP2_CRYPTO_KM_FLAG_NONE;
13445
13446 cc.aead = *aead;
13447 cc.hp = *hp;
13448 cc.ckm = &ckm;
13449 cc.hp_ctx = *hp_ctx;
13450 cc.encrypt = encrypt;
13451 cc.hp_mask = hp_mask;
13452
13453 ngtcp2_ppe_init(&ppe, dest, destlen, &cc);
13454
13455 rv = ngtcp2_ppe_encode_hd(&ppe, &hd);
13456 if (rv != 0) {
13457 assert(NGTCP2_ERR_NOBUF == rv);
13458 return rv;
13459 }
13460
13461 if (!ngtcp2_ppe_ensure_hp_sample(&ppe)) {
13462 return NGTCP2_ERR_NOBUF;
13463 }
13464
13465 fr.type = NGTCP2_FRAME_CONNECTION_CLOSE;
13466 fr.connection_close.error_code = error_code;
13467 fr.connection_close.reasonlen = reasonlen;
13468 fr.connection_close.reason = (uint8_t *)reason;
13469
13470 rv = ngtcp2_ppe_encode_frame(&ppe, &fr);
13471 if (rv != 0) {
13472 assert(NGTCP2_ERR_NOBUF == rv);
13473 return rv;
13474 }
13475
13476 return ngtcp2_ppe_final(&ppe, NULL);
13477 }
13478
ngtcp2_is_bidi_stream(int64_t stream_id)13479 int ngtcp2_is_bidi_stream(int64_t stream_id) { return bidi_stream(stream_id); }
13480
ngtcp2_select_version(const uint32_t * preferred_versions,size_t preferred_versionslen,const uint32_t * offered_versions,size_t offered_versionslen)13481 uint32_t ngtcp2_select_version(const uint32_t *preferred_versions,
13482 size_t preferred_versionslen,
13483 const uint32_t *offered_versions,
13484 size_t offered_versionslen) {
13485 size_t i, j;
13486
13487 if (!preferred_versionslen || !offered_versionslen) {
13488 return 0;
13489 }
13490
13491 for (i = 0; i < preferred_versionslen; ++i) {
13492 assert(ngtcp2_is_supported_version(preferred_versions[i]));
13493
13494 for (j = 0; j < offered_versionslen; ++j) {
13495 if (preferred_versions[i] == offered_versions[j]) {
13496 return preferred_versions[i];
13497 }
13498 }
13499 }
13500
13501 return 0;
13502 }
13503