1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov/*
350aadb33SDmitri Tikhonov * lsquic_rechist.h -- History of received packets.
450aadb33SDmitri Tikhonov *
550aadb33SDmitri Tikhonov * The purpose of received packet history is to generate ACK frames.
650aadb33SDmitri Tikhonov */
750aadb33SDmitri Tikhonov
850aadb33SDmitri Tikhonov#ifndef LSQUIC_RECHIST_H
950aadb33SDmitri Tikhonov#define LSQUIC_RECHIST_H 1
1050aadb33SDmitri Tikhonov
11f198a02dSDmitri Tikhonov#ifndef LSQUIC_TEST
12f198a02dSDmitri Tikhonov#define LSQUIC_TEST 0
13f198a02dSDmitri Tikhonov#endif
145392f7a3SLiteSpeed Tech
15b62ec17fSDmitri Tikhonov/* Structure is exposed to facilitate some manipulations in unit tests. */
16b62ec17fSDmitri Tikhonovstruct rechist_elem {
17b62ec17fSDmitri Tikhonov    lsquic_packno_t     re_low;
18b62ec17fSDmitri Tikhonov    unsigned            re_count;
19b62ec17fSDmitri Tikhonov    unsigned            re_next;    /* UINT_MAX means no next element */
20b62ec17fSDmitri Tikhonov};
21b62ec17fSDmitri Tikhonov
2250aadb33SDmitri Tikhonov
2350aadb33SDmitri Tikhonovstruct lsquic_rechist {
24b62ec17fSDmitri Tikhonov    /* elems and masks are allocated in contiguous memory */
25b62ec17fSDmitri Tikhonov    struct rechist_elem            *rh_elems;
26b62ec17fSDmitri Tikhonov    uintptr_t                      *rh_masks;
2750aadb33SDmitri Tikhonov    lsquic_packno_t                 rh_cutoff;
2850aadb33SDmitri Tikhonov    lsquic_time_t                   rh_largest_acked_received;
29b62ec17fSDmitri Tikhonov    unsigned                        rh_n_masks;
30b62ec17fSDmitri Tikhonov    unsigned                        rh_n_alloced;
31b62ec17fSDmitri Tikhonov    unsigned                        rh_n_used;
32b62ec17fSDmitri Tikhonov    unsigned                        rh_head;
33f38b395aSDmitri Tikhonov    unsigned                        rh_max_ranges;
3450aadb33SDmitri Tikhonov    enum {
3550aadb33SDmitri Tikhonov        RH_CUTOFF_SET   = (1 << 0),
3650aadb33SDmitri Tikhonov    }                               rh_flags;
37b62ec17fSDmitri Tikhonov    struct
38b62ec17fSDmitri Tikhonov    {
39b62ec17fSDmitri Tikhonov        struct lsquic_packno_range      range;
40b62ec17fSDmitri Tikhonov        unsigned                        next;
41b62ec17fSDmitri Tikhonov    }                               rh_iter;
42b62ec17fSDmitri Tikhonov#if LSQUIC_TEST
43b62ec17fSDmitri Tikhonov    unsigned                        rh_n_ops;
44de46bf2fSDmitri Tikhonov#endif
4550aadb33SDmitri Tikhonov};
4650aadb33SDmitri Tikhonov
4750aadb33SDmitri Tikhonovtypedef struct lsquic_rechist lsquic_rechist_t;
4850aadb33SDmitri Tikhonov
4950aadb33SDmitri Tikhonovvoid
50f38b395aSDmitri Tikhonovlsquic_rechist_init (struct lsquic_rechist *, int is_ietf, unsigned max_ranges);
5150aadb33SDmitri Tikhonov
5250aadb33SDmitri Tikhonovvoid
5350aadb33SDmitri Tikhonovlsquic_rechist_cleanup (struct lsquic_rechist *);
5450aadb33SDmitri Tikhonov
5550aadb33SDmitri Tikhonovenum received_st {
5650aadb33SDmitri Tikhonov    REC_ST_OK,
5750aadb33SDmitri Tikhonov    REC_ST_DUP,
5850aadb33SDmitri Tikhonov    REC_ST_ERR,
5950aadb33SDmitri Tikhonov};
6050aadb33SDmitri Tikhonov
6150aadb33SDmitri Tikhonovenum received_st
6250aadb33SDmitri Tikhonovlsquic_rechist_received (lsquic_rechist_t *, lsquic_packno_t,
6350aadb33SDmitri Tikhonov                         lsquic_time_t now);
6450aadb33SDmitri Tikhonov
6550aadb33SDmitri Tikhonovvoid
6650aadb33SDmitri Tikhonovlsquic_rechist_stop_wait (lsquic_rechist_t *, lsquic_packno_t);
6750aadb33SDmitri Tikhonov
6850aadb33SDmitri Tikhonovconst struct lsquic_packno_range *
6950aadb33SDmitri Tikhonovlsquic_rechist_first (lsquic_rechist_t *);
7050aadb33SDmitri Tikhonov
7150aadb33SDmitri Tikhonovconst struct lsquic_packno_range *
7250aadb33SDmitri Tikhonovlsquic_rechist_next (lsquic_rechist_t *);
7350aadb33SDmitri Tikhonov
7450aadb33SDmitri Tikhonovlsquic_packno_t
7550aadb33SDmitri Tikhonovlsquic_rechist_largest_packno (const lsquic_rechist_t *);
7650aadb33SDmitri Tikhonov
7750aadb33SDmitri Tikhonovlsquic_packno_t
7850aadb33SDmitri Tikhonovlsquic_rechist_cutoff (const lsquic_rechist_t *);
7950aadb33SDmitri Tikhonov
8050aadb33SDmitri Tikhonovlsquic_time_t
8150aadb33SDmitri Tikhonovlsquic_rechist_largest_recv (const lsquic_rechist_t *);
8250aadb33SDmitri Tikhonov
83c51ce338SDmitri Tikhonovsize_t
84c51ce338SDmitri Tikhonovlsquic_rechist_mem_used (const struct lsquic_rechist *);
85c51ce338SDmitri Tikhonov
86b1a7c3f9SDmitri Tikhonovconst struct lsquic_packno_range *
87b62ec17fSDmitri Tikhonovlsquic_rechist_peek (struct lsquic_rechist *);
88b1a7c3f9SDmitri Tikhonov
89b62ec17fSDmitri Tikhonov#define lsquic_rechist_is_empty(rechist_) ((rechist_)->rh_n_used == 0)
90b1a7c3f9SDmitri Tikhonov
91fbc6cc04SDmitri Tikhonovint
92fbc6cc04SDmitri Tikhonovlsquic_rechist_copy_ranges (struct lsquic_rechist *, void *rechist_ctx,
93fbc6cc04SDmitri Tikhonov    const struct lsquic_packno_range * (*first) (void *),
94fbc6cc04SDmitri Tikhonov    const struct lsquic_packno_range * (*next) (void *));
95fbc6cc04SDmitri Tikhonov
9650aadb33SDmitri Tikhonov#endif
97