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_adaptive_cc.c
/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
/* lsquic_adaptive_cc.c -- adaptive congestion controller */
#include <inttypes.h>
#include <math.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic_int_types.h"
#include "lsquic_types.h"
#include "lsquic_hash.h"
#include "lsquic_util.h"
#include "lsquic_cong_ctl.h"
#include "lsquic_sfcw.h"
#include "lsquic_conn_flow.h"
#include "lsquic_varint.h"
#include "lsquic_hq.h"
#include "lsquic_stream.h"
#include "lsquic_rtt.h"
#include "lsquic_conn_public.h"
#include "lsquic_packet_common.h"
#include "lsquic_packet_out.h"
#include "lsquic_bw_sampler.h"
#include "lsquic_minmax.h"
#include "lsquic_bbr.h"
#include "lsquic_cubic.h"
#include "lsquic_adaptive_cc.h"
#define LSQUIC_LOGGER_MODULE LSQLM_ADAPTIVE_CC
#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(acc->acc_cubic.cu_conn)
#include "lsquic_logger.h"
#define CALL_BOTH(method, ...) do { \
lsquic_cong_bbr_if.method(&acc->acc_bbr, __VA_ARGS__); \
lsquic_cong_cubic_if.method(&acc->acc_cubic, __VA_ARGS__); \
} while (0)
#define CALL_BOTH_MAYBE(method, ...) do { \
if (lsquic_cong_bbr_if.method) \
lsquic_cong_bbr_if.method(&acc->acc_bbr, __VA_ARGS__); \
if (lsquic_cong_cubic_if.method) \
lsquic_cong_cubic_if.method(&acc->acc_cubic, __VA_ARGS__); \
} while (0)
#define CALL_BOTH0(method) do { \
lsquic_cong_bbr_if.method(&acc->acc_bbr); \
lsquic_cong_cubic_if.method(&acc->acc_cubic); \
} while (0)
static void
adaptive_cc_init (void *cong_ctl, const struct lsquic_conn_public *conn_pub,
enum quic_ft_bit retx_frames)
{
struct adaptive_cc *const acc = cong_ctl;
CALL_BOTH(cci_init, conn_pub, retx_frames);
LSQ_DEBUG("initialized");
}
static void
adaptive_cc_reinit (void *cong_ctl)
{
struct adaptive_cc *const acc = cong_ctl;
CALL_BOTH0(cci_reinit);
}
static void
adaptive_cc_ack (void *cong_ctl, struct lsquic_packet_out *packet_out,
unsigned packet_sz, lsquic_time_t now, int app_limited)
{
struct adaptive_cc *const acc = cong_ctl;
CALL_BOTH(cci_ack, packet_out, packet_sz, now, app_limited);
}
static void
adaptive_cc_loss (void *cong_ctl)
{
struct adaptive_cc *const acc = cong_ctl;
CALL_BOTH0(cci_loss);
}
static void
adaptive_cc_begin_ack (void *cong_ctl, lsquic_time_t ack_time,
uint64_t in_flight)
{
struct adaptive_cc *const acc = cong_ctl;
CALL_BOTH_MAYBE(cci_begin_ack, ack_time, in_flight);
}
static void
adaptive_cc_end_ack (void *cong_ctl, uint64_t in_flight)
{
struct adaptive_cc *const acc = cong_ctl;
CALL_BOTH_MAYBE(cci_end_ack, in_flight);
}
static void
adaptive_cc_sent (void *cong_ctl, struct lsquic_packet_out *packet_out,
uint64_t in_flight, int app_limited)
{
struct adaptive_cc *const acc = cong_ctl;
CALL_BOTH_MAYBE(cci_sent, packet_out, in_flight, app_limited);
}
static void
adaptive_cc_lost (void *cong_ctl, struct lsquic_packet_out *packet_out,
unsigned packet_sz)
{
struct adaptive_cc *const acc = cong_ctl;
CALL_BOTH_MAYBE(cci_lost, packet_out, packet_sz);
}
static void
adaptive_cc_timeout (void *cong_ctl)
{
struct adaptive_cc *const acc = cong_ctl;
CALL_BOTH0(cci_timeout);
}
static void
adaptive_cc_was_quiet (void *cong_ctl, lsquic_time_t now, uint64_t in_flight)
{
struct adaptive_cc *const acc = cong_ctl;
CALL_BOTH(cci_was_quiet, now, in_flight);
}
static uint64_t
adaptive_cc_get_cwnd (void *cong_ctl)
{
struct adaptive_cc *const acc = cong_ctl;
uint64_t rv[2];
rv[0] = lsquic_cong_cubic_if.cci_get_cwnd(&acc->acc_cubic);
rv[1] = lsquic_cong_bbr_if.cci_get_cwnd(&acc->acc_bbr);
if (acc->acc_flags & ACC_CUBIC)
return rv[0];
else
return rv[1];
}
static uint64_t
adaptive_cc_pacing_rate (void *cong_ctl, int in_recovery)
{
struct adaptive_cc *const acc = cong_ctl;
uint64_t rv[2];
rv[0] = lsquic_cong_cubic_if.cci_pacing_rate(&acc->acc_cubic, in_recovery);
rv[1] = lsquic_cong_bbr_if.cci_pacing_rate(&acc->acc_bbr, in_recovery);
if (acc->acc_flags & ACC_CUBIC)
return rv[0];
else
return rv[1];
}
static void
adaptive_cc_cleanup (void *cong_ctl)
{
struct adaptive_cc *const acc = cong_ctl;
CALL_BOTH0(cci_cleanup);
LSQ_DEBUG("cleanup");
}
const struct cong_ctl_if lsquic_cong_adaptive_if =
{
.cci_ack = adaptive_cc_ack,
.cci_begin_ack = adaptive_cc_begin_ack,
.cci_end_ack = adaptive_cc_end_ack,
.cci_cleanup = adaptive_cc_cleanup,
.cci_get_cwnd = adaptive_cc_get_cwnd,
.cci_init = adaptive_cc_init,
.cci_pacing_rate = adaptive_cc_pacing_rate,
.cci_loss = adaptive_cc_loss,
.cci_lost = adaptive_cc_lost,
.cci_reinit = adaptive_cc_reinit,
.cci_timeout = adaptive_cc_timeout,
.cci_sent = adaptive_cc_sent,
.cci_was_quiet = adaptive_cc_was_quiet,
};