Bug Summary

File:out/../deps/ngtcp2/ngtcp2/lib/ngtcp2_conn.c
Warning:line 3449, column 13
Access to field 'type' results in a dereference of a null pointer (loaded from variable 'vmsg')

Annotated Source Code

Press '?' to see keyboard shortcuts

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