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