Packages
hackney
2.0.0
4.7.2
4.7.1
4.7.0
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.5
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
3.2.1
3.2.0
3.1.2
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
retired
2.0.1
2.0.0
2.0.0-beta.1
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.1
1.20.0
1.19.1
1.19.0
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.0
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.0
1.13.0
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.0
1.7.1
1.7.0
1.6.6
retired
1.6.5
1.6.4
retired
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.6
1.0.5
1.0.2
1.0.1
0.15.2
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
Simple HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
c_src/lsquic/src/liblsquic/lsquic_cfcw.c
/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
#include <inttypes.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#include "lsquic.h"
#include "lsquic_types.h"
#include "lsquic_int_types.h"
#include "lsquic_rtt.h"
#include "lsquic_conn_flow.h"
#include "lsquic_sfcw.h"
#include "lsquic_varint.h"
#include "lsquic_hq.h"
#include "lsquic_hash.h"
#include "lsquic_stream.h"
#include "lsquic_conn_public.h"
#include "lsquic_mm.h"
#include "lsquic_engine_public.h"
#include "lsquic_util.h"
#include "lsquic_conn.h"
#include "lsquic_ev_log.h"
#define LSQUIC_LOGGER_MODULE LSQLM_CFCW
#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(fc->cf_conn_pub->lconn)
#include "lsquic_logger.h"
void
lsquic_cfcw_init (struct lsquic_cfcw *fc, struct lsquic_conn_public *cpub,
unsigned max_recv_window)
{
memset(fc, 0, sizeof(*fc));
fc->cf_max_recv_win = max_recv_window;
fc->cf_conn_pub = cpub;
(void) lsquic_cfcw_fc_offsets_changed(fc);
}
static void
cfcw_maybe_increase_max_window (struct lsquic_cfcw *fc)
{
unsigned new_max_window;
new_max_window = fc->cf_max_recv_win * 2;
/* Do not increase past explicitly specified maximum */
if (new_max_window > fc->cf_conn_pub->enpub->enp_settings.es_max_cfcw)
new_max_window = fc->cf_conn_pub->enpub->enp_settings.es_max_cfcw;
if (new_max_window > fc->cf_max_recv_win)
{
LSQ_DEBUG("max window increase %u -> %u", fc->cf_max_recv_win,
new_max_window);
EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID,
"max CFCW increase %u -> %u", fc->cf_max_recv_win,
new_max_window);
fc->cf_max_recv_win = new_max_window;
}
else
LSQ_DEBUG("max window could use an increase, but we're stuck "
"at %u", fc->cf_max_recv_win);
}
int
lsquic_cfcw_fc_offsets_changed (struct lsquic_cfcw *fc)
{
lsquic_time_t now, since_last_update, srtt;
if (fc->cf_recv_off - fc->cf_read_off >= fc->cf_max_recv_win / 2)
return 0;
now = lsquic_time_now();
since_last_update = now - fc->cf_last_updated;
fc->cf_last_updated = now;
srtt = lsquic_rtt_stats_get_srtt(&fc->cf_conn_pub->rtt_stats);
if (since_last_update < srtt * 2)
cfcw_maybe_increase_max_window(fc);
fc->cf_recv_off = fc->cf_read_off + fc->cf_max_recv_win;
LSQ_DEBUG("recv_off changed: read_off: %"PRIu64"; recv_off: %"
PRIu64"", fc->cf_read_off, fc->cf_recv_off);
return 1;
}
int
lsquic_cfcw_incr_max_recv_off (struct lsquic_cfcw *fc, uint64_t incr)
{
if (fc->cf_max_recv_off + incr <= fc->cf_recv_off)
{
fc->cf_max_recv_off += incr;
LSQ_DEBUG("max_recv_off goes from %"PRIu64" to %"PRIu64"",
fc->cf_max_recv_off - incr, fc->cf_max_recv_off);
return 1;
}
else
{
LSQ_INFO("flow control violation: received at offset %"PRIu64", while "
"flow control receive offset is %"PRIu64,
fc->cf_max_recv_off + incr, fc->cf_recv_off);
return 0;
}
}
void
lsquic_cfcw_incr_read_off (struct lsquic_cfcw *fc, uint64_t incr)
{
fc->cf_read_off += incr;
LSQ_DEBUG("read_off goes from %"PRIu64" to %"PRIu64,
fc->cf_read_off - incr, fc->cf_read_off);
}