lsquic_conn_flow.h revision 50aadb33
150aadb33SDmitri Tikhonov/* Copyright (c) 2017 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_tosend;         /* Number of bytes scheduled to be sent
2750aadb33SDmitri Tikhonov                                 * accross all streams.
2850aadb33SDmitri Tikhonov                                 */
2950aadb33SDmitri Tikhonov    uint64_t cc_blocked;        /* Last blocked offset used */
3050aadb33SDmitri Tikhonov};
3150aadb33SDmitri Tikhonov
3250aadb33SDmitri Tikhonov
3350aadb33SDmitri Tikhonov#define lsquic_conn_cap_init(cc, max) do {                          \
3450aadb33SDmitri Tikhonov    (cc)->cc_sent = 0;                                              \
3550aadb33SDmitri Tikhonov    (cc)->cc_tosend = 0;                                            \
3650aadb33SDmitri Tikhonov    (cc)->cc_max = max;                                             \
3750aadb33SDmitri Tikhonov} while (0)
3850aadb33SDmitri Tikhonov
3950aadb33SDmitri Tikhonov
4050aadb33SDmitri Tikhonov#define lsquic_conn_cap_avail(cap) (                                \
4150aadb33SDmitri Tikhonov    ((cap)->cc_sent + (cap)->cc_tosend <= (cap)->cc_max)            \
4250aadb33SDmitri Tikhonov    ?                                                               \
4350aadb33SDmitri Tikhonov        ((cap)->cc_max - (cap)->cc_sent - (cap)->cc_tosend)         \
4450aadb33SDmitri Tikhonov    :                                                               \
4550aadb33SDmitri Tikhonov        0                                                           \
4650aadb33SDmitri Tikhonov)
4750aadb33SDmitri Tikhonov
4850aadb33SDmitri Tikhonov
4950aadb33SDmitri Tikhonovvoid
5050aadb33SDmitri Tikhonovlsquic_cfcw_init (lsquic_cfcw_t *, struct lsquic_conn_public *,
5150aadb33SDmitri Tikhonov                                        unsigned initial_max_recv_window);
5250aadb33SDmitri Tikhonov
5350aadb33SDmitri Tikhonov/* If update is to be sent, updates max_recv_off and returns true.  Note
5450aadb33SDmitri Tikhonov * that if you call this function twice, the second call will return false.
5550aadb33SDmitri Tikhonov */
5650aadb33SDmitri Tikhonovint
5750aadb33SDmitri Tikhonovlsquic_cfcw_fc_offsets_changed (lsquic_cfcw_t *);
5850aadb33SDmitri Tikhonov
5950aadb33SDmitri Tikhonov#define lsquic_cfcw_get_fc_recv_off(fc) (+(fc)->cf_recv_off)
6050aadb33SDmitri Tikhonov
6150aadb33SDmitri Tikhonov#define lsquic_cfcw_get_max_recv_off(fc) (+(fc)->cf_max_recv_off)
6250aadb33SDmitri Tikhonov
6350aadb33SDmitri Tikhonov#define lsquic_cfcw_get_max_recv_window(fc) (+(fc)->cf_max_recv_win)
6450aadb33SDmitri Tikhonov
6550aadb33SDmitri Tikhonov/* Returns false if flow control violation is encountered */
6650aadb33SDmitri Tikhonovint
6750aadb33SDmitri Tikhonovlsquic_cfcw_incr_max_recv_off (lsquic_cfcw_t *, uint64_t);
6850aadb33SDmitri Tikhonov
6950aadb33SDmitri Tikhonov/* Void because we do not expect the caller to make a mistake.
7050aadb33SDmitri Tikhonov */
7150aadb33SDmitri Tikhonovvoid
7250aadb33SDmitri Tikhonovlsquic_cfcw_incr_read_off (lsquic_cfcw_t *, uint64_t);
7350aadb33SDmitri Tikhonov
7450aadb33SDmitri Tikhonov#endif
75