1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov/*
350aadb33SDmitri Tikhonov * lsquic_conn_flow.h -- Connection flow control-related functions
450aadb33SDmitri Tikhonov */
550aadb33SDmitri Tikhonov
650aadb33SDmitri Tikhonov#ifndef LSQUIC_CONN_FLOW_H
750aadb33SDmitri Tikhonov#define LSQUIC_CONN_FLOW_H 1
850aadb33SDmitri Tikhonov
950aadb33SDmitri Tikhonovstruct lsquic_conn_public;
1050aadb33SDmitri Tikhonov
1150aadb33SDmitri Tikhonovtypedef struct lsquic_cfcw {
1250aadb33SDmitri Tikhonov    struct lsquic_conn_public
1350aadb33SDmitri Tikhonov                 *cf_conn_pub;
1450aadb33SDmitri Tikhonov    uint64_t      cf_max_recv_off;  /* Largest offset observed (cumulative) */
1550aadb33SDmitri Tikhonov    uint64_t      cf_recv_off;      /* Flow control receive offset */
1650aadb33SDmitri Tikhonov    uint64_t      cf_read_off;      /* Number of bytes consumed (cumulative) */
1750aadb33SDmitri Tikhonov    lsquic_time_t cf_last_updated;
1850aadb33SDmitri Tikhonov    unsigned      cf_max_recv_win;  /* Maximum receive window */
1950aadb33SDmitri Tikhonov} lsquic_cfcw_t;
2050aadb33SDmitri Tikhonov
2150aadb33SDmitri Tikhonovstruct lsquic_conn_cap {
2250aadb33SDmitri Tikhonov    uint64_t cc_sent;           /* Number of bytes sent on connection */
2350aadb33SDmitri Tikhonov    uint64_t cc_max;            /* Maximum cumulative number of bytes allowed
2450aadb33SDmitri Tikhonov                                 * to be sent on this connection.
2550aadb33SDmitri Tikhonov                                 */
2650aadb33SDmitri Tikhonov    uint64_t cc_blocked;        /* Last blocked offset used */
2750aadb33SDmitri Tikhonov};
2850aadb33SDmitri Tikhonov
2950aadb33SDmitri Tikhonov
3050aadb33SDmitri Tikhonov#define lsquic_conn_cap_init(cc, max) do {                          \
3150aadb33SDmitri Tikhonov    (cc)->cc_sent = 0;                                              \
3250aadb33SDmitri Tikhonov    (cc)->cc_max = max;                                             \
3350aadb33SDmitri Tikhonov} while (0)
3450aadb33SDmitri Tikhonov
3550aadb33SDmitri Tikhonov
3650aadb33SDmitri Tikhonov#define lsquic_conn_cap_avail(cap) (                                \
37c51ce338SDmitri Tikhonov    (assert((cap)->cc_max >= (cap)->cc_sent)),                      \
38c51ce338SDmitri Tikhonov        (cap)->cc_max - (cap)->cc_sent)
3950aadb33SDmitri Tikhonov
4050aadb33SDmitri Tikhonov
4150aadb33SDmitri Tikhonovvoid
4250aadb33SDmitri Tikhonovlsquic_cfcw_init (lsquic_cfcw_t *, struct lsquic_conn_public *,
4350aadb33SDmitri Tikhonov                                        unsigned initial_max_recv_window);
4450aadb33SDmitri Tikhonov
4550aadb33SDmitri Tikhonov/* If update is to be sent, updates max_recv_off and returns true.  Note
4650aadb33SDmitri Tikhonov * that if you call this function twice, the second call will return false.
4750aadb33SDmitri Tikhonov */
4850aadb33SDmitri Tikhonovint
4950aadb33SDmitri Tikhonovlsquic_cfcw_fc_offsets_changed (lsquic_cfcw_t *);
5050aadb33SDmitri Tikhonov
5150aadb33SDmitri Tikhonov#define lsquic_cfcw_get_fc_recv_off(fc) (+(fc)->cf_recv_off)
5250aadb33SDmitri Tikhonov
5350aadb33SDmitri Tikhonov#define lsquic_cfcw_get_max_recv_off(fc) (+(fc)->cf_max_recv_off)
5450aadb33SDmitri Tikhonov
5550aadb33SDmitri Tikhonov#define lsquic_cfcw_get_max_recv_window(fc) (+(fc)->cf_max_recv_win)
5650aadb33SDmitri Tikhonov
5750aadb33SDmitri Tikhonov/* Returns false if flow control violation is encountered */
5850aadb33SDmitri Tikhonovint
5950aadb33SDmitri Tikhonovlsquic_cfcw_incr_max_recv_off (lsquic_cfcw_t *, uint64_t);
6050aadb33SDmitri Tikhonov
6150aadb33SDmitri Tikhonov/* Void because we do not expect the caller to make a mistake.
6250aadb33SDmitri Tikhonov */
6350aadb33SDmitri Tikhonovvoid
6450aadb33SDmitri Tikhonovlsquic_cfcw_incr_read_off (lsquic_cfcw_t *, uint64_t);
6550aadb33SDmitri Tikhonov
6650aadb33SDmitri Tikhonov#endif
67