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