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