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