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