Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ SET(QUICLY_LIBRARY_FILES
lib/remote_cid.c
lib/retire_cid.c
lib/sendstate.c
lib/ss-rfc2001.c
lib/ss-hybla.c
lib/ss-hystart.c
lib/ss-search.c
lib/sentmap.c
lib/streambuf.c
${CMAKE_CURRENT_BINARY_DIR}/quicly-tracer.h)
Expand Down
5 changes: 5 additions & 0 deletions include/quicly.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ extern "C" {
#include "quicly/local_cid.h"
#include "quicly/linklist.h"
#include "quicly/loss.h"
#include "quicly/ss.h"
#include "quicly/cc.h"
#include "quicly/rate.h"
#include "quicly/recvstate.h"
Expand Down Expand Up @@ -392,6 +393,10 @@ struct st_quicly_context_t {
* initializes a congestion controller for given connection.
*/
quicly_init_cc_t *init_cc;
/**
* set the slowstart function for the connection
*/
quicly_ss_type_t *cc_slowstart;
/**
* optional refcount callback
*/
Expand Down
49 changes: 49 additions & 0 deletions include/quicly/cc.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ extern "C" {
#define QUICLY_MIN_CWND 2
#define QUICLY_RENO_BETA 0.7

#define SEARCH20_DELV_BIN_COUNT 10
Comment thread
parvit marked this conversation as resolved.
Outdated
#define SEARCH20_SENT_BIN_COUNT 25 // 10 + 15 extra bins
#define SEARCH20_WINDOW_MULTIPLIER (3.5)
#define SEARCH20_THRESH (0.35)

#define QUICLY_HYBLA_RTT0 (25)
Comment thread
parvit marked this conversation as resolved.
Outdated
#define QUICLY_HYBLA_RHO_LIM (16)

// #define SEARCH_EXIT

/**
* Holds pointers to concrete congestion control implementation functions.
*/
Expand All @@ -58,6 +68,41 @@ typedef struct st_quicly_cc_t {
* Current slow start threshold.
*/
uint32_t ssthresh;
/**
* Slow-start specific data storage
*/
union {
struct {
double rho;
} hybla;
struct {
uint8_t found;
Comment thread
parvit marked this conversation as resolved.
Outdated
int64_t round_start;
int64_t last_ack;
int64_t end_seq;
uint32_t min_round_rtt;
uint8_t samples;
} hystart;
struct {
/**
* Bins for the byte count sent and the byte count delivered (instantiated on init)
*/
uint64_t delv_bins[SEARCH20_SENT_BIN_COUNT];
/**
* Maintains the end time of the current bin
*/
int64_t bin_end;
/**
* Holds the size of each bin (based on the handshake RTT)
*/
uint32_t bin_time;
/**
* Counts the number of times that the bin has been incremented, so we know when to
* start trying to watch for congestion
*/
uint32_t bin_rounds;
} search;
} ss_state;
/**
* Packet number indicating end of recovery period, if in recovery.
*/
Expand Down Expand Up @@ -202,6 +247,10 @@ struct st_quicly_cc_type_t {
* Switches the underlying algorithm of `cc` to that of `cc_switch`, returning a boolean if the operation was successful.
*/
int (*cc_switch)(quicly_cc_t *cc);
/*
* Defines a variable slowstart callback
*/
struct st_quicly_variable_ss *cc_slowstart;
/**
*
*/
Expand Down
1 change: 1 addition & 0 deletions include/quicly/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ extern quicly_crypto_engine_t quicly_default_crypto_engine;

#define quicly_default_cc quicly_cc_type_reno
#define quicly_default_init_cc quicly_cc_reno_init
#define quicly_default_ss quicly_ss_type_rfc2001

#ifdef __cplusplus
}
Expand Down
69 changes: 69 additions & 0 deletions include/quicly/ss.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2024 Viasat Inc.
* Authors: Amber Cronin, Jae Won Chung, Mike Foxworthy, Feng Li, Mark Claypool
Comment thread
parvit marked this conversation as resolved.
Outdated
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

#ifndef quicly_ss_h
#define quicly_ss_h

#ifdef __cplusplus
extern "C" {
#endif

#include "quicly/cc.h"
#include "quicly/constants.h"
#include <stdint.h>
#include <stdbool.h>

extern bool search_exit;

#define MIN(x,y) ((x > y) ? (y) : (x))
#define MAX(x,y) ((x < y) ? (y) : (x))
Comment thread
parvit marked this conversation as resolved.
Outdated

/**
* Holds pointers to concrete congestion control implementation functions.
*/
typedef const struct st_quicly_ss_type_t quicly_ss_type_t;

struct st_quicly_ss_type_t {
const char* name;
void (*ss)(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t bytes, uint64_t largest_acked, uint32_t inflight,
uint64_t next_pn, int64_t now, uint32_t max_udp_payload_size);
};

extern quicly_ss_type_t quicly_ss_type_rfc2001, quicly_ss_type_hybla, quicly_ss_type_hystart, quicly_ss_type_search;

extern quicly_ss_type_t* quicly_ss_all_types[];

void ss_rfc2001(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t bytes, uint64_t largest_acked, uint32_t inflight,
uint64_t next_pn, int64_t now, uint32_t max_udp_payload_size);

struct st_quicly_variable_ss {
Comment thread
parvit marked this conversation as resolved.
Outdated
quicly_ss_type_t* slowstart;
};

extern struct st_quicly_variable_ss active_slowstart;

#ifdef __cplusplus
}
#endif

#endif
14 changes: 8 additions & 6 deletions lib/cc-cubic.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
*/
#include <math.h>
#include "quicly/cc.h"
#include "quicly/defaults.h"
#include "quicly.h"
#include "quicly/pacer.h"
#include "quicly/ss.h"

#define QUICLY_MIN_CWND 2

Expand Down Expand Up @@ -73,13 +75,11 @@ static void cubic_on_acked(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t

quicly_cc_jumpstart_on_acked(cc, 0, bytes, largest_acked, inflight, next_pn);

/* TODO: respect cc_limited */

/* Slow start. */
if (cc->cwnd < cc->ssthresh) {
cc->cwnd += bytes;
if (cc->cwnd_maximum < cc->cwnd)
cc->cwnd_maximum = cc->cwnd;
if (cc_limited) {
cc->type->cc_slowstart->slowstart->ss(cc, loss, bytes, largest_acked, inflight, next_pn, now, max_udp_payload_size);
}
return;
}

Expand Down Expand Up @@ -206,7 +206,9 @@ static void cubic_init(quicly_init_cc_t *self, quicly_cc_t *cc, uint32_t initcwn
cubic_reset(cc, initcwnd);
}

struct st_quicly_variable_ss cubic_active_slowstart = {&quicly_default_ss};

quicly_cc_type_t quicly_cc_type_cubic = {"cubic", &quicly_cc_cubic_init, cubic_on_acked,
cubic_on_lost, cubic_on_persistent_congestion, cubic_on_sent,
cubic_on_switch, quicly_cc_jumpstart_enter};
cubic_on_switch, &cubic_active_slowstart, quicly_cc_jumpstart_enter};
quicly_init_cc_t quicly_cc_cubic_init = {cubic_init};
3 changes: 2 additions & 1 deletion lib/cc-pico.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,5 +194,6 @@ static void pico_init(quicly_init_cc_t *self, quicly_cc_t *cc, uint32_t initcwnd

quicly_cc_type_t quicly_cc_type_pico = {"pico", &quicly_cc_pico_init, pico_on_acked,
pico_on_lost, pico_on_persistent_congestion, pico_on_sent,
pico_on_switch, quicly_cc_jumpstart_enter};
pico_on_switch, NULL /* no slow start exists for this CCA*/,
Comment thread
parvit marked this conversation as resolved.
Outdated
quicly_cc_jumpstart_enter};
quicly_init_cc_t quicly_cc_pico_init = {pico_init};
8 changes: 5 additions & 3 deletions lib/cc-reno.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* IN THE SOFTWARE.
*/
#include "quicly/cc.h"
#include "quicly/defaults.h"
#include "quicly.h"

/* TODO: Avoid increase if sender was application limited. */
Expand All @@ -39,9 +40,7 @@ static void reno_on_acked(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t b
/* Slow start. */
if (cc->cwnd < cc->ssthresh) {
if (cc_limited) {
cc->cwnd += bytes;
if (cc->cwnd_maximum < cc->cwnd)
cc->cwnd_maximum = cc->cwnd;
cc->type->cc_slowstart->slowstart->ss(cc, loss, bytes, largest_acked, inflight, next_pn, now, max_udp_payload_size);
}
return;
}
Expand Down Expand Up @@ -136,13 +135,16 @@ static void reno_init(quicly_init_cc_t *self, quicly_cc_t *cc, uint32_t initcwnd
reno_reset(cc, initcwnd);
}

struct st_quicly_variable_ss reno_active_slowstart = {&quicly_default_ss};

quicly_cc_type_t quicly_cc_type_reno = {"reno",
&quicly_cc_reno_init,
reno_on_acked,
quicly_cc_reno_on_lost,
quicly_cc_reno_on_persistent_congestion,
quicly_cc_reno_on_sent,
reno_on_switch,
&reno_active_slowstart,
quicly_cc_jumpstart_enter};
quicly_init_cc_t quicly_cc_reno_init = {reno_init};

Expand Down
6 changes: 4 additions & 2 deletions lib/defaults.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ const quicly_context_t quicly_spec_context = {NULL,
NULL,
NULL,
&quicly_default_crypto_engine,
&quicly_default_init_cc};
&quicly_default_init_cc,
&quicly_default_ss};
Comment thread
parvit marked this conversation as resolved.

/* profile with a focus on reducing latency for the HTTP use case */
const quicly_context_t quicly_performant_context = {NULL, /* tls */
Expand Down Expand Up @@ -99,7 +100,8 @@ const quicly_context_t quicly_performant_context = {NULL,
NULL,
NULL,
&quicly_default_crypto_engine,
&quicly_default_init_cc};
&quicly_default_init_cc,
&quicly_default_ss};

/**
* The context of the default CID encryptor. All the contexts being used here are ECB ciphers and therefore stateless - they can be
Expand Down
4 changes: 4 additions & 0 deletions lib/quicly.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "quicly/sentmap.h"
#include "quicly/pacer.h"
#include "quicly/frame.h"
#include "quicly/ss.h"
#include "quicly/streambuf.h"
#include "quicly/cc.h"
#if QUICLY_USE_DTRACE
Expand Down Expand Up @@ -2259,6 +2260,9 @@ static quicly_conn_t *create_connection(quicly_context_t *ctx, uint32_t protocol
conn->egress.ack_frequency.update_at = INT64_MAX;
conn->egress.send_ack_at = INT64_MAX;
conn->super.ctx->init_cc->cb(conn->super.ctx->init_cc, &conn->egress.cc, initcwnd, conn->stash.now);
if (conn->egress.cc.type->cc_slowstart != NULL) {
Comment thread
parvit marked this conversation as resolved.
Outdated
conn->egress.cc.type->cc_slowstart->slowstart = conn->super.ctx->cc_slowstart;
}
if (pacer != NULL) {
conn->egress.pacer = pacer;
quicly_pacer_reset(conn->egress.pacer);
Expand Down
50 changes: 50 additions & 0 deletions lib/ss-hybla.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2024 Viasat Inc.
* Authors: Amber Cronin, Jae Won Chung, Mike Foxworthy, Feng Li, Mark Claypool
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

#include "quicly/ss.h"
#include <stdint.h>
#include <math.h>

static void recalc_rho(quicly_cc_t *cc, const quicly_loss_t *loss) {
// RTT in msec
// Linux here uses us instead of ms for their rho calculations, which gives them more accurate information about
// the bandwidth of the connection. Here, we only have ms level measurements from loss, and so all of our
// measurements are only up to that level of precision. It cleans the code up a little bit though from the kernel.
// we have changed this to use doubles for more accuracy and ease of writing code.
double rho = (double) loss->rtt.minimum / QUICLY_HYBLA_RTT0;
// don't allow the ratio to be less than one for faster connections than reference.
cc->ss_state.hybla.rho = MAX(rho, 1);
}

void ss_hybla(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t bytes, uint64_t largest_acked, uint32_t inflight,
Comment thread
parvit marked this conversation as resolved.
Outdated
uint64_t next_pn, int64_t now, uint32_t max_udp_payload_size)
{
recalc_rho(cc, loss);

cc->cwnd += (uint32_t)round(pow(2, MIN(cc->ss_state.hybla.rho, QUICLY_HYBLA_RHO_LIM)));

if (cc->cwnd_maximum < cc->cwnd)
cc->cwnd_maximum = cc->cwnd;
}

quicly_ss_type_t quicly_ss_type_hybla = { "hybla", ss_hybla };
Loading