11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci * ngtcp2 31cb0ef41Sopenharmony_ci * 41cb0ef41Sopenharmony_ci * Copyright (c) 2017 ngtcp2 contributors 51cb0ef41Sopenharmony_ci * 61cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 71cb0ef41Sopenharmony_ci * a copy of this software and associated documentation files (the 81cb0ef41Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 91cb0ef41Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 101cb0ef41Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 111cb0ef41Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 121cb0ef41Sopenharmony_ci * the following conditions: 131cb0ef41Sopenharmony_ci * 141cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be 151cb0ef41Sopenharmony_ci * included in all copies or substantial portions of the Software. 161cb0ef41Sopenharmony_ci * 171cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 181cb0ef41Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 191cb0ef41Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 201cb0ef41Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 211cb0ef41Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 221cb0ef41Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 231cb0ef41Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 241cb0ef41Sopenharmony_ci */ 251cb0ef41Sopenharmony_ci#ifndef NGTCP2_RTB_H 261cb0ef41Sopenharmony_ci#define NGTCP2_RTB_H 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci#ifdef HAVE_CONFIG_H 291cb0ef41Sopenharmony_ci# include <config.h> 301cb0ef41Sopenharmony_ci#endif /* HAVE_CONFIG_H */ 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci#include <ngtcp2/ngtcp2.h> 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci#include "ngtcp2_pkt.h" 351cb0ef41Sopenharmony_ci#include "ngtcp2_ksl.h" 361cb0ef41Sopenharmony_ci#include "ngtcp2_pq.h" 371cb0ef41Sopenharmony_ci#include "ngtcp2_objalloc.h" 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_citypedef struct ngtcp2_conn ngtcp2_conn; 401cb0ef41Sopenharmony_citypedef struct ngtcp2_pktns ngtcp2_pktns; 411cb0ef41Sopenharmony_citypedef struct ngtcp2_log ngtcp2_log; 421cb0ef41Sopenharmony_citypedef struct ngtcp2_qlog ngtcp2_qlog; 431cb0ef41Sopenharmony_citypedef struct ngtcp2_strm ngtcp2_strm; 441cb0ef41Sopenharmony_citypedef struct ngtcp2_rst ngtcp2_rst; 451cb0ef41Sopenharmony_citypedef struct ngtcp2_cc ngtcp2_cc; 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci/* NGTCP2_FRAME_CHAIN_BINDER_FLAG_NONE indicates that no flag is 481cb0ef41Sopenharmony_ci set. */ 491cb0ef41Sopenharmony_ci#define NGTCP2_FRAME_CHAIN_BINDER_FLAG_NONE 0x00u 501cb0ef41Sopenharmony_ci/* NGTCP2_FRAME_CHAIN_BINDER_FLAG_ACK indicates that an information 511cb0ef41Sopenharmony_ci which a frame carries has been acknowledged. */ 521cb0ef41Sopenharmony_ci#define NGTCP2_FRAME_CHAIN_BINDER_FLAG_ACK 0x01u 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci/* 551cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_binder binds 2 or more of ngtcp2_frame_chain to 561cb0ef41Sopenharmony_ci * share the acknowledgement state. In general, all 571cb0ef41Sopenharmony_ci * ngtcp2_frame_chains bound to the same binder must have the same 581cb0ef41Sopenharmony_ci * information. 591cb0ef41Sopenharmony_ci */ 601cb0ef41Sopenharmony_citypedef struct ngtcp2_frame_chain_binder { 611cb0ef41Sopenharmony_ci size_t refcount; 621cb0ef41Sopenharmony_ci /* flags is bitwise OR of zero or more of 631cb0ef41Sopenharmony_ci NGTCP2_FRAME_CHAIN_BINDER_FLAG_*. */ 641cb0ef41Sopenharmony_ci uint32_t flags; 651cb0ef41Sopenharmony_ci} ngtcp2_frame_chain_binder; 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ciint ngtcp2_frame_chain_binder_new(ngtcp2_frame_chain_binder **pbinder, 681cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_citypedef struct ngtcp2_frame_chain ngtcp2_frame_chain; 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci/* 731cb0ef41Sopenharmony_ci * ngtcp2_frame_chain chains frames in a single packet. 741cb0ef41Sopenharmony_ci */ 751cb0ef41Sopenharmony_cistruct ngtcp2_frame_chain { 761cb0ef41Sopenharmony_ci union { 771cb0ef41Sopenharmony_ci struct { 781cb0ef41Sopenharmony_ci ngtcp2_frame_chain *next; 791cb0ef41Sopenharmony_ci ngtcp2_frame_chain_binder *binder; 801cb0ef41Sopenharmony_ci ngtcp2_frame fr; 811cb0ef41Sopenharmony_ci }; 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci ngtcp2_opl_entry oplent; 841cb0ef41Sopenharmony_ci }; 851cb0ef41Sopenharmony_ci}; 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_cingtcp2_objalloc_def(frame_chain, ngtcp2_frame_chain, oplent); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci/* 901cb0ef41Sopenharmony_ci * ngtcp2_bind_frame_chains binds two frame chains |a| and |b| using 911cb0ef41Sopenharmony_ci * new or existing ngtcp2_frame_chain_binder. |a| might have non-NULL 921cb0ef41Sopenharmony_ci * a->binder. |b| must not have non-NULL b->binder. 931cb0ef41Sopenharmony_ci * 941cb0ef41Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 951cb0ef41Sopenharmony_ci * negative error codes: 961cb0ef41Sopenharmony_ci * 971cb0ef41Sopenharmony_ci * NGTCP2_ERR_NOMEM 981cb0ef41Sopenharmony_ci * Out of memory 991cb0ef41Sopenharmony_ci */ 1001cb0ef41Sopenharmony_ciint ngtcp2_bind_frame_chains(ngtcp2_frame_chain *a, ngtcp2_frame_chain *b, 1011cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci/* NGTCP2_MAX_STREAM_DATACNT is the maximum number of ngtcp2_vec that 1041cb0ef41Sopenharmony_ci a ngtcp2_stream can include. */ 1051cb0ef41Sopenharmony_ci#define NGTCP2_MAX_STREAM_DATACNT 256 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci/* NGTCP2_MAX_CRYPTO_DATACNT is the maximum number of ngtcp2_vec that 1081cb0ef41Sopenharmony_ci a ngtcp2_crypto can include. */ 1091cb0ef41Sopenharmony_ci#define NGTCP2_MAX_CRYPTO_DATACNT 8 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci/* 1121cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_new allocates ngtcp2_frame_chain object and 1131cb0ef41Sopenharmony_ci * assigns its pointer to |*pfrc|. 1141cb0ef41Sopenharmony_ci * 1151cb0ef41Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 1161cb0ef41Sopenharmony_ci * negative error codes: 1171cb0ef41Sopenharmony_ci * 1181cb0ef41Sopenharmony_ci * NGTCP2_ERR_NOMEM 1191cb0ef41Sopenharmony_ci * Out of memory. 1201cb0ef41Sopenharmony_ci */ 1211cb0ef41Sopenharmony_ciint ngtcp2_frame_chain_new(ngtcp2_frame_chain **pfrc, const ngtcp2_mem *mem); 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci/* 1241cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_objalloc_new behaves like 1251cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_new, but it uses |objalloc| to allocate the object. 1261cb0ef41Sopenharmony_ci */ 1271cb0ef41Sopenharmony_ciint ngtcp2_frame_chain_objalloc_new(ngtcp2_frame_chain **pfrc, 1281cb0ef41Sopenharmony_ci ngtcp2_objalloc *objalloc); 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci/* 1311cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_extralen_new works like ngtcp2_frame_chain_new, 1321cb0ef41Sopenharmony_ci * but it allocates extra memory |extralen| in order to extend 1331cb0ef41Sopenharmony_ci * ngtcp2_frame. 1341cb0ef41Sopenharmony_ci */ 1351cb0ef41Sopenharmony_ciint ngtcp2_frame_chain_extralen_new(ngtcp2_frame_chain **pfrc, size_t extralen, 1361cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci/* 1391cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_stream_datacnt_objalloc_new works like 1401cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_new, but it allocates enough data to store 1411cb0ef41Sopenharmony_ci * additional |datacnt| - 1 ngtcp2_vec object after ngtcp2_stream 1421cb0ef41Sopenharmony_ci * object. If no additional space is required, 1431cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_objalloc_new is called internally. 1441cb0ef41Sopenharmony_ci */ 1451cb0ef41Sopenharmony_ciint ngtcp2_frame_chain_stream_datacnt_objalloc_new(ngtcp2_frame_chain **pfrc, 1461cb0ef41Sopenharmony_ci size_t datacnt, 1471cb0ef41Sopenharmony_ci ngtcp2_objalloc *objalloc, 1481cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci/* 1511cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_crypto_datacnt_objalloc_new works like 1521cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_new, but it allocates enough data to store 1531cb0ef41Sopenharmony_ci * additional |datacnt| - 1 ngtcp2_vec object after ngtcp2_crypto 1541cb0ef41Sopenharmony_ci * object. If no additional space is required, 1551cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_objalloc_new is called internally. 1561cb0ef41Sopenharmony_ci */ 1571cb0ef41Sopenharmony_ciint ngtcp2_frame_chain_crypto_datacnt_objalloc_new(ngtcp2_frame_chain **pfrc, 1581cb0ef41Sopenharmony_ci size_t datacnt, 1591cb0ef41Sopenharmony_ci ngtcp2_objalloc *objalloc, 1601cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ciint ngtcp2_frame_chain_new_token_objalloc_new(ngtcp2_frame_chain **pfrc, 1631cb0ef41Sopenharmony_ci const ngtcp2_vec *token, 1641cb0ef41Sopenharmony_ci ngtcp2_objalloc *objalloc, 1651cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci/* 1681cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_del deallocates |frc|. It also deallocates the 1691cb0ef41Sopenharmony_ci * memory pointed by |frc|. 1701cb0ef41Sopenharmony_ci */ 1711cb0ef41Sopenharmony_civoid ngtcp2_frame_chain_del(ngtcp2_frame_chain *frc, const ngtcp2_mem *mem); 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci/* 1741cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_objalloc_del adds |frc| to |objalloc| for reuse. 1751cb0ef41Sopenharmony_ci * It might just delete |frc| depending on the frame type and the size 1761cb0ef41Sopenharmony_ci * of |frc|. 1771cb0ef41Sopenharmony_ci */ 1781cb0ef41Sopenharmony_civoid ngtcp2_frame_chain_objalloc_del(ngtcp2_frame_chain *frc, 1791cb0ef41Sopenharmony_ci ngtcp2_objalloc *objalloc, 1801cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci/* 1831cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_init initializes |frc|. 1841cb0ef41Sopenharmony_ci */ 1851cb0ef41Sopenharmony_civoid ngtcp2_frame_chain_init(ngtcp2_frame_chain *frc); 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci/* 1881cb0ef41Sopenharmony_ci * ngtcp2_frame_chain_list_objalloc_del adds all ngtcp2_frame_chain 1891cb0ef41Sopenharmony_ci * linked from |frc| to |objalloc| for reuse. Depending on the frame type 1901cb0ef41Sopenharmony_ci * and its size, ngtcp2_frame_chain might be deleted instead. 1911cb0ef41Sopenharmony_ci */ 1921cb0ef41Sopenharmony_civoid ngtcp2_frame_chain_list_objalloc_del(ngtcp2_frame_chain *frc, 1931cb0ef41Sopenharmony_ci ngtcp2_objalloc *objalloc, 1941cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 1951cb0ef41Sopenharmony_ci 1961cb0ef41Sopenharmony_ci/* NGTCP2_RTB_ENTRY_FLAG_NONE indicates that no flag is set. */ 1971cb0ef41Sopenharmony_ci#define NGTCP2_RTB_ENTRY_FLAG_NONE 0x00u 1981cb0ef41Sopenharmony_ci/* NGTCP2_RTB_ENTRY_FLAG_PROBE indicates that the entry includes a 1991cb0ef41Sopenharmony_ci probe packet. */ 2001cb0ef41Sopenharmony_ci#define NGTCP2_RTB_ENTRY_FLAG_PROBE 0x01u 2011cb0ef41Sopenharmony_ci/* NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE indicates that the entry 2021cb0ef41Sopenharmony_ci includes a frame which must be retransmitted until it is 2031cb0ef41Sopenharmony_ci acknowledged. In most cases, this flag is used along with 2041cb0ef41Sopenharmony_ci NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING and 2051cb0ef41Sopenharmony_ci NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING. */ 2061cb0ef41Sopenharmony_ci#define NGTCP2_RTB_ENTRY_FLAG_RETRANSMITTABLE 0x02u 2071cb0ef41Sopenharmony_ci/* NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING indicates that the entry 2081cb0ef41Sopenharmony_ci elicits acknowledgement. */ 2091cb0ef41Sopenharmony_ci#define NGTCP2_RTB_ENTRY_FLAG_ACK_ELICITING 0x04u 2101cb0ef41Sopenharmony_ci/* NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED indicates that the packet has 2111cb0ef41Sopenharmony_ci been reclaimed on PTO. It is not marked lost yet and still 2121cb0ef41Sopenharmony_ci consumes congestion window. */ 2131cb0ef41Sopenharmony_ci#define NGTCP2_RTB_ENTRY_FLAG_PTO_RECLAIMED 0x08u 2141cb0ef41Sopenharmony_ci/* NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED indicates that the entry 2151cb0ef41Sopenharmony_ci has been marked lost and, optionally, scheduled to retransmit. */ 2161cb0ef41Sopenharmony_ci#define NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED 0x10u 2171cb0ef41Sopenharmony_ci/* NGTCP2_RTB_ENTRY_FLAG_ECN indicates that the entry is included in a 2181cb0ef41Sopenharmony_ci UDP datagram with ECN marking. */ 2191cb0ef41Sopenharmony_ci#define NGTCP2_RTB_ENTRY_FLAG_ECN 0x20u 2201cb0ef41Sopenharmony_ci/* NGTCP2_RTB_ENTRY_FLAG_DATAGRAM indicates that the entry includes 2211cb0ef41Sopenharmony_ci DATAGRAM frame. */ 2221cb0ef41Sopenharmony_ci#define NGTCP2_RTB_ENTRY_FLAG_DATAGRAM 0x40u 2231cb0ef41Sopenharmony_ci/* NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE indicates that the entry includes 2241cb0ef41Sopenharmony_ci a PMTUD probe packet. */ 2251cb0ef41Sopenharmony_ci#define NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE 0x80u 2261cb0ef41Sopenharmony_ci/* NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING indicates that the entry 2271cb0ef41Sopenharmony_ci includes a packet which elicits PTO probe packets. */ 2281cb0ef41Sopenharmony_ci#define NGTCP2_RTB_ENTRY_FLAG_PTO_ELICITING 0x100u 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_citypedef struct ngtcp2_rtb_entry ngtcp2_rtb_entry; 2311cb0ef41Sopenharmony_ci 2321cb0ef41Sopenharmony_ci/* 2331cb0ef41Sopenharmony_ci * ngtcp2_rtb_entry is an object stored in ngtcp2_rtb. It corresponds 2341cb0ef41Sopenharmony_ci * to the one packet which is waiting for its ACK. 2351cb0ef41Sopenharmony_ci */ 2361cb0ef41Sopenharmony_cistruct ngtcp2_rtb_entry { 2371cb0ef41Sopenharmony_ci union { 2381cb0ef41Sopenharmony_ci struct { 2391cb0ef41Sopenharmony_ci ngtcp2_rtb_entry *next; 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_ci struct { 2421cb0ef41Sopenharmony_ci int64_t pkt_num; 2431cb0ef41Sopenharmony_ci uint8_t type; 2441cb0ef41Sopenharmony_ci uint8_t flags; 2451cb0ef41Sopenharmony_ci } hd; 2461cb0ef41Sopenharmony_ci ngtcp2_frame_chain *frc; 2471cb0ef41Sopenharmony_ci /* ts is the time point when a packet included in this entry is sent 2481cb0ef41Sopenharmony_ci to a peer. */ 2491cb0ef41Sopenharmony_ci ngtcp2_tstamp ts; 2501cb0ef41Sopenharmony_ci /* lost_ts is the time when this entry is marked lost. */ 2511cb0ef41Sopenharmony_ci ngtcp2_tstamp lost_ts; 2521cb0ef41Sopenharmony_ci /* pktlen is the length of QUIC packet */ 2531cb0ef41Sopenharmony_ci size_t pktlen; 2541cb0ef41Sopenharmony_ci struct { 2551cb0ef41Sopenharmony_ci uint64_t delivered; 2561cb0ef41Sopenharmony_ci ngtcp2_tstamp delivered_ts; 2571cb0ef41Sopenharmony_ci ngtcp2_tstamp first_sent_ts; 2581cb0ef41Sopenharmony_ci uint64_t tx_in_flight; 2591cb0ef41Sopenharmony_ci uint64_t lost; 2601cb0ef41Sopenharmony_ci int is_app_limited; 2611cb0ef41Sopenharmony_ci } rst; 2621cb0ef41Sopenharmony_ci /* flags is bitwise-OR of zero or more of 2631cb0ef41Sopenharmony_ci NGTCP2_RTB_ENTRY_FLAG_*. */ 2641cb0ef41Sopenharmony_ci uint16_t flags; 2651cb0ef41Sopenharmony_ci }; 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci ngtcp2_opl_entry oplent; 2681cb0ef41Sopenharmony_ci }; 2691cb0ef41Sopenharmony_ci}; 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_cingtcp2_objalloc_def(rtb_entry, ngtcp2_rtb_entry, oplent); 2721cb0ef41Sopenharmony_ci 2731cb0ef41Sopenharmony_ci/* 2741cb0ef41Sopenharmony_ci * ngtcp2_rtb_entry_new allocates ngtcp2_rtb_entry object, and assigns 2751cb0ef41Sopenharmony_ci * its pointer to |*pent|. 2761cb0ef41Sopenharmony_ci */ 2771cb0ef41Sopenharmony_ciint ngtcp2_rtb_entry_objalloc_new(ngtcp2_rtb_entry **pent, 2781cb0ef41Sopenharmony_ci const ngtcp2_pkt_hd *hd, 2791cb0ef41Sopenharmony_ci ngtcp2_frame_chain *frc, ngtcp2_tstamp ts, 2801cb0ef41Sopenharmony_ci size_t pktlen, uint16_t flags, 2811cb0ef41Sopenharmony_ci ngtcp2_objalloc *objalloc); 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci/* 2841cb0ef41Sopenharmony_ci * ngtcp2_rtb_entry_objalloc_del adds |ent| to |objalloc| for reuse. 2851cb0ef41Sopenharmony_ci * ngtcp2_frame_chain linked from ent->frc are also added to 2861cb0ef41Sopenharmony_ci * |frc_objalloc| depending on their frame type and size. 2871cb0ef41Sopenharmony_ci */ 2881cb0ef41Sopenharmony_civoid ngtcp2_rtb_entry_objalloc_del(ngtcp2_rtb_entry *ent, 2891cb0ef41Sopenharmony_ci ngtcp2_objalloc *objalloc, 2901cb0ef41Sopenharmony_ci ngtcp2_objalloc *frc_objalloc, 2911cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_ci/* 2941cb0ef41Sopenharmony_ci * ngtcp2_rtb tracks sent packets, and its ACK timeout for 2951cb0ef41Sopenharmony_ci * retransmission. 2961cb0ef41Sopenharmony_ci */ 2971cb0ef41Sopenharmony_citypedef struct ngtcp2_rtb { 2981cb0ef41Sopenharmony_ci ngtcp2_objalloc *frc_objalloc; 2991cb0ef41Sopenharmony_ci ngtcp2_objalloc *rtb_entry_objalloc; 3001cb0ef41Sopenharmony_ci /* ents includes ngtcp2_rtb_entry sorted by decreasing order of 3011cb0ef41Sopenharmony_ci packet number. */ 3021cb0ef41Sopenharmony_ci ngtcp2_ksl ents; 3031cb0ef41Sopenharmony_ci /* crypto is CRYPTO stream. */ 3041cb0ef41Sopenharmony_ci ngtcp2_strm *crypto; 3051cb0ef41Sopenharmony_ci ngtcp2_rst *rst; 3061cb0ef41Sopenharmony_ci ngtcp2_cc *cc; 3071cb0ef41Sopenharmony_ci ngtcp2_log *log; 3081cb0ef41Sopenharmony_ci ngtcp2_qlog *qlog; 3091cb0ef41Sopenharmony_ci const ngtcp2_mem *mem; 3101cb0ef41Sopenharmony_ci /* largest_acked_tx_pkt_num is the largest packet number 3111cb0ef41Sopenharmony_ci acknowledged by the peer. */ 3121cb0ef41Sopenharmony_ci int64_t largest_acked_tx_pkt_num; 3131cb0ef41Sopenharmony_ci /* num_ack_eliciting is the number of ACK eliciting entries. */ 3141cb0ef41Sopenharmony_ci size_t num_ack_eliciting; 3151cb0ef41Sopenharmony_ci /* num_retransmittable is the number of packets which contain frames 3161cb0ef41Sopenharmony_ci that must be retransmitted on loss. */ 3171cb0ef41Sopenharmony_ci size_t num_retransmittable; 3181cb0ef41Sopenharmony_ci /* num_pto_eliciting is the number of packets that elicit PTO probe 3191cb0ef41Sopenharmony_ci packets. */ 3201cb0ef41Sopenharmony_ci size_t num_pto_eliciting; 3211cb0ef41Sopenharmony_ci /* probe_pkt_left is the number of probe packet to send */ 3221cb0ef41Sopenharmony_ci size_t probe_pkt_left; 3231cb0ef41Sopenharmony_ci /* pktns_id is the identifier of packet number space. */ 3241cb0ef41Sopenharmony_ci ngtcp2_pktns_id pktns_id; 3251cb0ef41Sopenharmony_ci /* cc_pkt_num is the smallest packet number that is contributed to 3261cb0ef41Sopenharmony_ci ngtcp2_conn_stat.bytes_in_flight. */ 3271cb0ef41Sopenharmony_ci int64_t cc_pkt_num; 3281cb0ef41Sopenharmony_ci /* cc_bytes_in_flight is the number of in-flight bytes that is 3291cb0ef41Sopenharmony_ci contributed to ngtcp2_conn_stat.bytes_in_flight. It only 3301cb0ef41Sopenharmony_ci includes the bytes after congestion state is reset. */ 3311cb0ef41Sopenharmony_ci uint64_t cc_bytes_in_flight; 3321cb0ef41Sopenharmony_ci /* persistent_congestion_start_ts is the time when persistent 3331cb0ef41Sopenharmony_ci congestion evaluation is started. It happens roughly after 3341cb0ef41Sopenharmony_ci handshake is confirmed. */ 3351cb0ef41Sopenharmony_ci ngtcp2_tstamp persistent_congestion_start_ts; 3361cb0ef41Sopenharmony_ci /* num_lost_pkts is the number entries in ents which has 3371cb0ef41Sopenharmony_ci NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED flag set. */ 3381cb0ef41Sopenharmony_ci size_t num_lost_pkts; 3391cb0ef41Sopenharmony_ci /* num_lost_pmtud_pkts is the number of entries in ents which have 3401cb0ef41Sopenharmony_ci both NGTCP2_RTB_ENTRY_FLAG_LOST_RETRANSMITTED and 3411cb0ef41Sopenharmony_ci NGTCP2_RTB_ENTRY_FLAG_PMTUD_PROBE flags set. */ 3421cb0ef41Sopenharmony_ci size_t num_lost_pmtud_pkts; 3431cb0ef41Sopenharmony_ci} ngtcp2_rtb; 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_ci/* 3461cb0ef41Sopenharmony_ci * ngtcp2_rtb_init initializes |rtb|. 3471cb0ef41Sopenharmony_ci */ 3481cb0ef41Sopenharmony_civoid ngtcp2_rtb_init(ngtcp2_rtb *rtb, ngtcp2_pktns_id pktns_id, 3491cb0ef41Sopenharmony_ci ngtcp2_strm *crypto, ngtcp2_rst *rst, ngtcp2_cc *cc, 3501cb0ef41Sopenharmony_ci ngtcp2_log *log, ngtcp2_qlog *qlog, 3511cb0ef41Sopenharmony_ci ngtcp2_objalloc *rtb_entry_objalloc, 3521cb0ef41Sopenharmony_ci ngtcp2_objalloc *frc_objalloc, const ngtcp2_mem *mem); 3531cb0ef41Sopenharmony_ci 3541cb0ef41Sopenharmony_ci/* 3551cb0ef41Sopenharmony_ci * ngtcp2_rtb_free deallocates resources allocated for |rtb|. 3561cb0ef41Sopenharmony_ci */ 3571cb0ef41Sopenharmony_civoid ngtcp2_rtb_free(ngtcp2_rtb *rtb); 3581cb0ef41Sopenharmony_ci 3591cb0ef41Sopenharmony_ci/* 3601cb0ef41Sopenharmony_ci * ngtcp2_rtb_add adds |ent| to |rtb|. 3611cb0ef41Sopenharmony_ci * 3621cb0ef41Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 3631cb0ef41Sopenharmony_ci * negative error codes: 3641cb0ef41Sopenharmony_ci * 3651cb0ef41Sopenharmony_ci * NGTCP2_ERR_NOMEM 3661cb0ef41Sopenharmony_ci * Out of memory 3671cb0ef41Sopenharmony_ci */ 3681cb0ef41Sopenharmony_ciint ngtcp2_rtb_add(ngtcp2_rtb *rtb, ngtcp2_rtb_entry *ent, 3691cb0ef41Sopenharmony_ci ngtcp2_conn_stat *cstat); 3701cb0ef41Sopenharmony_ci 3711cb0ef41Sopenharmony_ci/* 3721cb0ef41Sopenharmony_ci * ngtcp2_rtb_head returns the iterator which points to the entry 3731cb0ef41Sopenharmony_ci * which has the largest packet number. If there is no entry, 3741cb0ef41Sopenharmony_ci * returned value satisfies ngtcp2_ksl_it_end(&it) != 0. 3751cb0ef41Sopenharmony_ci */ 3761cb0ef41Sopenharmony_cingtcp2_ksl_it ngtcp2_rtb_head(ngtcp2_rtb *rtb); 3771cb0ef41Sopenharmony_ci 3781cb0ef41Sopenharmony_ci/* 3791cb0ef41Sopenharmony_ci * ngtcp2_rtb_recv_ack removes acked ngtcp2_rtb_entry from |rtb|. 3801cb0ef41Sopenharmony_ci * |pkt_num| is a packet number which includes |fr|. |pkt_ts| is the 3811cb0ef41Sopenharmony_ci * timestamp when packet is received. |ts| should be the current 3821cb0ef41Sopenharmony_ci * time. Usually they are the same, but for buffered packets, 3831cb0ef41Sopenharmony_ci * |pkt_ts| would be earlier than |ts|. 3841cb0ef41Sopenharmony_ci * 3851cb0ef41Sopenharmony_ci * This function returns the number of newly acknowledged packets if 3861cb0ef41Sopenharmony_ci * it succeeds, or one of the following negative error codes: 3871cb0ef41Sopenharmony_ci * 3881cb0ef41Sopenharmony_ci * NGTCP2_ERR_CALLBACK_FAILURE 3891cb0ef41Sopenharmony_ci * User callback failed 3901cb0ef41Sopenharmony_ci * NGTCP2_ERR_NOMEM 3911cb0ef41Sopenharmony_ci * Out of memory 3921cb0ef41Sopenharmony_ci */ 3931cb0ef41Sopenharmony_cingtcp2_ssize ngtcp2_rtb_recv_ack(ngtcp2_rtb *rtb, const ngtcp2_ack *fr, 3941cb0ef41Sopenharmony_ci ngtcp2_conn_stat *cstat, ngtcp2_conn *conn, 3951cb0ef41Sopenharmony_ci ngtcp2_pktns *pktns, ngtcp2_tstamp pkt_ts, 3961cb0ef41Sopenharmony_ci ngtcp2_tstamp ts); 3971cb0ef41Sopenharmony_ci 3981cb0ef41Sopenharmony_ci/* 3991cb0ef41Sopenharmony_ci * ngtcp2_rtb_detect_lost_pkt detects lost packets and prepends the 4001cb0ef41Sopenharmony_ci * frames contained them to |*pfrc|. Even when this function fails, 4011cb0ef41Sopenharmony_ci * some frames might be prepended to |*pfrc| and the caller should 4021cb0ef41Sopenharmony_ci * handle them. 4031cb0ef41Sopenharmony_ci */ 4041cb0ef41Sopenharmony_ciint ngtcp2_rtb_detect_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_conn *conn, 4051cb0ef41Sopenharmony_ci ngtcp2_pktns *pktns, ngtcp2_conn_stat *cstat, 4061cb0ef41Sopenharmony_ci ngtcp2_tstamp ts); 4071cb0ef41Sopenharmony_ci 4081cb0ef41Sopenharmony_ci/* 4091cb0ef41Sopenharmony_ci * ngtcp2_rtb_remove_expired_lost_pkt removes expired lost packet. 4101cb0ef41Sopenharmony_ci */ 4111cb0ef41Sopenharmony_civoid ngtcp2_rtb_remove_expired_lost_pkt(ngtcp2_rtb *rtb, ngtcp2_duration pto, 4121cb0ef41Sopenharmony_ci ngtcp2_tstamp ts); 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci/* 4151cb0ef41Sopenharmony_ci * ngtcp2_rtb_lost_pkt_ts returns the earliest time when the still 4161cb0ef41Sopenharmony_ci * retained packet was lost. It returns UINT64_MAX if no such packet 4171cb0ef41Sopenharmony_ci * exists. 4181cb0ef41Sopenharmony_ci */ 4191cb0ef41Sopenharmony_cingtcp2_tstamp ngtcp2_rtb_lost_pkt_ts(ngtcp2_rtb *rtb); 4201cb0ef41Sopenharmony_ci 4211cb0ef41Sopenharmony_ci/* 4221cb0ef41Sopenharmony_ci * ngtcp2_rtb_remove_all removes all packets from |rtb| and prepends 4231cb0ef41Sopenharmony_ci * all frames to |*pfrc|. Even when this function fails, some frames 4241cb0ef41Sopenharmony_ci * might be prepended to |*pfrc| and the caller should handle them. 4251cb0ef41Sopenharmony_ci */ 4261cb0ef41Sopenharmony_ciint ngtcp2_rtb_remove_all(ngtcp2_rtb *rtb, ngtcp2_conn *conn, 4271cb0ef41Sopenharmony_ci ngtcp2_pktns *pktns, ngtcp2_conn_stat *cstat); 4281cb0ef41Sopenharmony_ci 4291cb0ef41Sopenharmony_ci/* 4301cb0ef41Sopenharmony_ci * ngtcp2_rtb_remove_early_data removes all entries for 0RTT packets. 4311cb0ef41Sopenharmony_ci */ 4321cb0ef41Sopenharmony_civoid ngtcp2_rtb_remove_early_data(ngtcp2_rtb *rtb, ngtcp2_conn_stat *cstat); 4331cb0ef41Sopenharmony_ci 4341cb0ef41Sopenharmony_ci/* 4351cb0ef41Sopenharmony_ci * ngtcp2_rtb_empty returns nonzero if |rtb| have no entry. 4361cb0ef41Sopenharmony_ci */ 4371cb0ef41Sopenharmony_ciint ngtcp2_rtb_empty(ngtcp2_rtb *rtb); 4381cb0ef41Sopenharmony_ci 4391cb0ef41Sopenharmony_ci/* 4401cb0ef41Sopenharmony_ci * ngtcp2_rtb_reset_cc_state resets congestion state in |rtb|. 4411cb0ef41Sopenharmony_ci * |cc_pkt_num| is the next outbound packet number which is sent under 4421cb0ef41Sopenharmony_ci * new congestion state. 4431cb0ef41Sopenharmony_ci */ 4441cb0ef41Sopenharmony_civoid ngtcp2_rtb_reset_cc_state(ngtcp2_rtb *rtb, int64_t cc_pkt_num); 4451cb0ef41Sopenharmony_ci 4461cb0ef41Sopenharmony_ci/* 4471cb0ef41Sopenharmony_ci * ngtcp2_rtb_remove_expired_lost_pkt ensures that the number of lost 4481cb0ef41Sopenharmony_ci * packets at most |n|. 4491cb0ef41Sopenharmony_ci */ 4501cb0ef41Sopenharmony_civoid ngtcp2_rtb_remove_excessive_lost_pkt(ngtcp2_rtb *rtb, size_t n); 4511cb0ef41Sopenharmony_ci 4521cb0ef41Sopenharmony_ci/* 4531cb0ef41Sopenharmony_ci * ngtcp2_rtb_reclaim_on_pto reclaims up to |num_pkts| packets which 4541cb0ef41Sopenharmony_ci * are in-flight and not marked lost to send them in PTO probe. The 4551cb0ef41Sopenharmony_ci * reclaimed frames are chained to |*pfrc|. 4561cb0ef41Sopenharmony_ci * 4571cb0ef41Sopenharmony_ci * This function returns the number of packets reclaimed if it 4581cb0ef41Sopenharmony_ci * succeeds, or one of the following negative error codes: 4591cb0ef41Sopenharmony_ci * 4601cb0ef41Sopenharmony_ci * NGTCP2_ERR_NOMEM 4611cb0ef41Sopenharmony_ci * Out of memory 4621cb0ef41Sopenharmony_ci */ 4631cb0ef41Sopenharmony_cingtcp2_ssize ngtcp2_rtb_reclaim_on_pto(ngtcp2_rtb *rtb, ngtcp2_conn *conn, 4641cb0ef41Sopenharmony_ci ngtcp2_pktns *pktns, size_t num_pkts); 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_ci#endif /* NGTCP2_RTB_H */ 467