lsquic_senhist.h revision 5392f7a3
1/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_senhist.h -- History sent packets.
4 *
5 * We need to keep track of packet numbers in order to verify ACKs.  To
6 * speed up processing, we make sure that there is never a gap in the
7 * packet number sequence we generate.
8 */
9
10#ifndef LSQUIC_SENHIST_H
11#define LSQUIC_SENHIST_H 1
12
13#ifndef LSQUIC_SENHIST_FATAL
14#   define LSQUIC_SENHIST_FATAL 0
15#endif
16
17typedef struct lsquic_senhist {
18    lsquic_packno_t             sh_last_sent;
19    enum {
20#if !LSQUIC_SENHIST_FATAL
21        SH_WARNED   = 1 << 0,   /* Warn once */
22#endif
23        SH_GAP_OK   = 1 << 1,   /* Before connection is just about to close */
24    }                           sh_flags;
25} lsquic_senhist_t;
26
27#define lsquic_senhist_init(hist, is_ietf) do {                         \
28    if (is_ietf)                                                        \
29        (hist)->sh_last_sent = ~0ull;                                   \
30    else                                                                \
31        (hist)->sh_last_sent = 0;                                       \
32} while (0)
33
34#define lsquic_senhist_cleanup(hist)
35
36#if LSQUIC_SENHIST_FATAL
37#define lsquic_senhist_add(hist, packno) do {                           \
38    if (!((hist)->sh_flags & SH_GAP_OK))                                \
39        assert((hist)->sh_last_sent == packno - 1);                     \
40    if ((int64_t) (packno) > (int64_t) (hist)->sh_last_sent)            \
41        (hist)->sh_last_sent = packno;                                  \
42} while (0)
43#else
44#define lsquic_senhist_add(hist, packno) do {                           \
45    if ((hist)->sh_last_sent != packno - 1)                             \
46    {                                                                   \
47        if (!((hist)->sh_flags & (SH_WARNED|SH_GAP_OK)))                \
48        {                                                               \
49            LSQ_WARN("send history gap %"PRIu64" - %"PRIu64,            \
50                (hist)->sh_last_sent, packno);                          \
51            (hist)->sh_flags |= SH_WARNED;                              \
52        }                                                               \
53    }                                                                   \
54    if ((int64_t) (packno) > (int64_t) (hist)->sh_last_sent)            \
55        (hist)->sh_last_sent = packno;                                  \
56} while (0)
57#endif
58
59/* Returns 0 if no packets have been sent yet */
60#define lsquic_senhist_largest(hist) (+(hist)->sh_last_sent)
61
62void
63lsquic_senhist_tostr (lsquic_senhist_t *hist, char *buf, size_t bufsz);
64
65#define lsquic_senhist_mem_used(hist) (sizeof(*(hist)))
66
67#endif
68