lsquic_senhist.h revision 5392f7a3
1229fce07SDmitri Tikhonov/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */ 250aadb33SDmitri Tikhonov/* 350aadb33SDmitri Tikhonov * lsquic_senhist.h -- History sent packets. 450aadb33SDmitri Tikhonov * 516a9b66aSDmitri Tikhonov * We need to keep track of packet numbers in order to verify ACKs. To 616a9b66aSDmitri Tikhonov * speed up processing, we make sure that there is never a gap in the 716a9b66aSDmitri Tikhonov * packet number sequence we generate. 850aadb33SDmitri Tikhonov */ 950aadb33SDmitri Tikhonov 1050aadb33SDmitri Tikhonov#ifndef LSQUIC_SENHIST_H 1150aadb33SDmitri Tikhonov#define LSQUIC_SENHIST_H 1 1250aadb33SDmitri Tikhonov 1316a9b66aSDmitri Tikhonov#ifndef LSQUIC_SENHIST_FATAL 1416a9b66aSDmitri Tikhonov# define LSQUIC_SENHIST_FATAL 0 1516a9b66aSDmitri Tikhonov#endif 1650aadb33SDmitri Tikhonov 1750aadb33SDmitri Tikhonovtypedef struct lsquic_senhist { 1816a9b66aSDmitri Tikhonov lsquic_packno_t sh_last_sent; 1916a9b66aSDmitri Tikhonov enum { 205392f7a3SLiteSpeed Tech#if !LSQUIC_SENHIST_FATAL 2116a9b66aSDmitri Tikhonov SH_WARNED = 1 << 0, /* Warn once */ 2216a9b66aSDmitri Tikhonov#endif 235392f7a3SLiteSpeed Tech SH_GAP_OK = 1 << 1, /* Before connection is just about to close */ 245392f7a3SLiteSpeed Tech } sh_flags; 2550aadb33SDmitri Tikhonov} lsquic_senhist_t; 2650aadb33SDmitri Tikhonov 275392f7a3SLiteSpeed Tech#define lsquic_senhist_init(hist, is_ietf) do { \ 285392f7a3SLiteSpeed Tech if (is_ietf) \ 295392f7a3SLiteSpeed Tech (hist)->sh_last_sent = ~0ull; \ 305392f7a3SLiteSpeed Tech else \ 315392f7a3SLiteSpeed Tech (hist)->sh_last_sent = 0; \ 3216a9b66aSDmitri Tikhonov} while (0) 3316a9b66aSDmitri Tikhonov 3416a9b66aSDmitri Tikhonov#define lsquic_senhist_cleanup(hist) 3516a9b66aSDmitri Tikhonov 3616a9b66aSDmitri Tikhonov#if LSQUIC_SENHIST_FATAL 3716a9b66aSDmitri Tikhonov#define lsquic_senhist_add(hist, packno) do { \ 385392f7a3SLiteSpeed Tech if (!((hist)->sh_flags & SH_GAP_OK)) \ 395392f7a3SLiteSpeed Tech assert((hist)->sh_last_sent == packno - 1); \ 405392f7a3SLiteSpeed Tech if ((int64_t) (packno) > (int64_t) (hist)->sh_last_sent) \ 415392f7a3SLiteSpeed Tech (hist)->sh_last_sent = packno; \ 4216a9b66aSDmitri Tikhonov} while (0) 4316a9b66aSDmitri Tikhonov#else 4416a9b66aSDmitri Tikhonov#define lsquic_senhist_add(hist, packno) do { \ 455392f7a3SLiteSpeed Tech if ((hist)->sh_last_sent != packno - 1) \ 4616a9b66aSDmitri Tikhonov { \ 475392f7a3SLiteSpeed Tech if (!((hist)->sh_flags & (SH_WARNED|SH_GAP_OK))) \ 4816a9b66aSDmitri Tikhonov { \ 4916a9b66aSDmitri Tikhonov LSQ_WARN("send history gap %"PRIu64" - %"PRIu64, \ 5016a9b66aSDmitri Tikhonov (hist)->sh_last_sent, packno); \ 5116a9b66aSDmitri Tikhonov (hist)->sh_flags |= SH_WARNED; \ 5216a9b66aSDmitri Tikhonov } \ 5316a9b66aSDmitri Tikhonov } \ 545392f7a3SLiteSpeed Tech if ((int64_t) (packno) > (int64_t) (hist)->sh_last_sent) \ 555392f7a3SLiteSpeed Tech (hist)->sh_last_sent = packno; \ 5616a9b66aSDmitri Tikhonov} while (0) 5716a9b66aSDmitri Tikhonov#endif 5850aadb33SDmitri Tikhonov 5950aadb33SDmitri Tikhonov/* Returns 0 if no packets have been sent yet */ 6016a9b66aSDmitri Tikhonov#define lsquic_senhist_largest(hist) (+(hist)->sh_last_sent) 6150aadb33SDmitri Tikhonov 6250aadb33SDmitri Tikhonovvoid 6350aadb33SDmitri Tikhonovlsquic_senhist_tostr (lsquic_senhist_t *hist, char *buf, size_t bufsz); 6450aadb33SDmitri Tikhonov 6516a9b66aSDmitri Tikhonov#define lsquic_senhist_mem_used(hist) (sizeof(*(hist))) 66c51ce338SDmitri Tikhonov 6750aadb33SDmitri Tikhonov#endif 68