123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- /*
- * ngtcp2
- *
- * Copyright (c) 2017 ngtcp2 contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- #ifndef NGTCP2_ACKTR_H
- #define NGTCP2_ACKTR_H
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif /* defined(HAVE_CONFIG_H) */
- #include <ngtcp2/ngtcp2.h>
- #include "ngtcp2_mem.h"
- #include "ngtcp2_ringbuf.h"
- #include "ngtcp2_ksl.h"
- #include "ngtcp2_pkt.h"
- #include "ngtcp2_objalloc.h"
- /* NGTCP2_ACKTR_MAX_ENT is the maximum number of ngtcp2_acktr_entry
- which ngtcp2_acktr stores. */
- #define NGTCP2_ACKTR_MAX_ENT (NGTCP2_MAX_ACK_RANGES + 1)
- typedef struct ngtcp2_log ngtcp2_log;
- /*
- * ngtcp2_acktr_entry is a range of packets which need to be acked.
- */
- typedef struct ngtcp2_acktr_entry {
- union {
- struct {
- /* pkt_num is the largest packet number to acknowledge in this
- range. */
- int64_t pkt_num;
- /* len is the consecutive packets started from pkt_num which
- includes pkt_num itself counting in decreasing order. So pkt_num
- = 987 and len = 2, this entry includes packet 987 and 986. */
- size_t len;
- /* tstamp is the timestamp when a packet denoted by pkt_num is
- received. */
- ngtcp2_tstamp tstamp;
- };
- ngtcp2_opl_entry oplent;
- };
- } ngtcp2_acktr_entry;
- ngtcp2_objalloc_decl(acktr_entry, ngtcp2_acktr_entry, oplent)
- /*
- * ngtcp2_acktr_entry_objalloc_new allocates memory for ent, and
- * initializes it with the given parameters. The pointer to the
- * allocated object is stored to |*ent|.
- *
- * This function returns 0 if it succeeds, or one of the following
- * negative error codes:
- *
- * NGTCP2_ERR_NOMEM
- * Out of memory.
- */
- int ngtcp2_acktr_entry_objalloc_new(ngtcp2_acktr_entry **ent, int64_t pkt_num,
- ngtcp2_tstamp tstamp,
- ngtcp2_objalloc *objalloc);
- /*
- * ngtcp2_acktr_entry_objalloc_del deallocates memory allocated for
- * |ent|.
- */
- void ngtcp2_acktr_entry_objalloc_del(ngtcp2_acktr_entry *ent,
- ngtcp2_objalloc *objalloc);
- typedef struct ngtcp2_acktr_ack_entry {
- /* largest_ack is the largest packet number in outgoing ACK frame */
- int64_t largest_ack;
- /* pkt_num is the packet number that ACK frame is included. */
- int64_t pkt_num;
- } ngtcp2_acktr_ack_entry;
- /* NGTCP2_ACKTR_FLAG_NONE indicates that no flag set. */
- #define NGTCP2_ACKTR_FLAG_NONE 0x00u
- /* NGTCP2_ACKTR_FLAG_IMMEDIATE_ACK indicates that immediate
- acknowledgement is required. */
- #define NGTCP2_ACKTR_FLAG_IMMEDIATE_ACK 0x01u
- /* NGTCP2_ACKTR_FLAG_ACTIVE_ACK indicates that there are pending
- protected packet to be acknowledged. */
- #define NGTCP2_ACKTR_FLAG_ACTIVE_ACK 0x02u
- /* NGTCP2_ACKTR_FLAG_CANCEL_TIMER is set when ACK delay timer is
- expired and canceled. */
- #define NGTCP2_ACKTR_FLAG_CANCEL_TIMER 0x0100u
- ngtcp2_static_ringbuf_def(acks, 32, sizeof(ngtcp2_acktr_ack_entry))
- /*
- * ngtcp2_acktr tracks received packets which we have to send ack.
- */
- typedef struct ngtcp2_acktr {
- ngtcp2_objalloc objalloc;
- ngtcp2_static_ringbuf_acks acks;
- /* ents includes ngtcp2_acktr_entry sorted by decreasing order of
- packet number. */
- ngtcp2_ksl ents;
- ngtcp2_log *log;
- /* flags is bitwise OR of zero, or more of NGTCP2_ACKTR_FLAG_*. */
- uint16_t flags;
- /* first_unacked_ts is timestamp when ngtcp2_acktr_entry is added
- first time after the last outgoing ACK frame. */
- ngtcp2_tstamp first_unacked_ts;
- /* rx_npkt is the number of ACK eliciting packets received without
- sending ACK. */
- size_t rx_npkt;
- } ngtcp2_acktr;
- /*
- * ngtcp2_acktr_init initializes |acktr|.
- */
- void ngtcp2_acktr_init(ngtcp2_acktr *acktr, ngtcp2_log *log,
- const ngtcp2_mem *mem);
- /*
- * ngtcp2_acktr_free frees resources allocated for |acktr|. It frees
- * any ngtcp2_acktr_entry added to |acktr|.
- */
- void ngtcp2_acktr_free(ngtcp2_acktr *acktr);
- /*
- * ngtcp2_acktr_add adds packet number |pkt_num| to |acktr|.
- * |active_ack| is nonzero if |pkt_num| is retransmittable packet.
- *
- * This function assumes that |acktr| does not contain |pkt_num|.
- *
- * This function returns 0 if it succeeds, or one of the following
- * negative error codes:
- *
- * NGTCP2_ERR_NOMEM
- * OUt of memory.
- */
- int ngtcp2_acktr_add(ngtcp2_acktr *acktr, int64_t pkt_num, int active_ack,
- ngtcp2_tstamp ts);
- /*
- * ngtcp2_acktr_forget removes all entries which have the packet
- * number that is equal to or less than ent->pkt_num. This function
- * assumes that |acktr| includes |ent|.
- */
- void ngtcp2_acktr_forget(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent);
- /*
- * ngtcp2_acktr_get returns the pointer to pointer to the entry which
- * has the largest packet number to be acked. If there is no entry,
- * returned value satisfies ngtcp2_ksl_it_end(&it) != 0.
- */
- ngtcp2_ksl_it ngtcp2_acktr_get(const ngtcp2_acktr *acktr);
- /*
- * ngtcp2_acktr_empty returns nonzero if it has no packet to
- * acknowledge.
- */
- int ngtcp2_acktr_empty(const ngtcp2_acktr *acktr);
- /*
- * ngtcp2_acktr_add_ack records outgoing ACK frame whose largest
- * acknowledged packet number is |largest_ack|. |pkt_num| is the
- * packet number of a packet in which ACK frame is included. This
- * function returns a pointer to the object it adds.
- */
- ngtcp2_acktr_ack_entry *
- ngtcp2_acktr_add_ack(ngtcp2_acktr *acktr, int64_t pkt_num, int64_t largest_ack);
- /*
- * ngtcp2_acktr_recv_ack processes the incoming ACK frame |fr|.
- * |pkt_num| is a packet number which includes |fr|. If we receive
- * ACK which acknowledges the ACKs added by ngtcp2_acktr_add_ack,
- * ngtcp2_acktr_entry which the outgoing ACK acknowledges is removed.
- */
- void ngtcp2_acktr_recv_ack(ngtcp2_acktr *acktr, const ngtcp2_ack *fr);
- /*
- * ngtcp2_acktr_commit_ack tells |acktr| that ACK frame is generated.
- */
- void ngtcp2_acktr_commit_ack(ngtcp2_acktr *acktr);
- /*
- * ngtcp2_acktr_require_active_ack returns nonzero if ACK frame should
- * be generated actively.
- */
- int ngtcp2_acktr_require_active_ack(const ngtcp2_acktr *acktr,
- ngtcp2_duration max_ack_delay,
- ngtcp2_tstamp ts);
- /*
- * ngtcp2_acktr_immediate_ack tells |acktr| that immediate
- * acknowledgement is required.
- */
- void ngtcp2_acktr_immediate_ack(ngtcp2_acktr *acktr);
- #endif /* !defined(NGTCP2_ACKTR_H) */
|