Skip to content

Commit 8ef10d3

Browse files
authored
Copa support & Fix several bugs (#258)
* [~] unified interfaces of win_filter * [+] add a new congestion controller, Copa (NSDI'18) * [~] unified MSS definition * [~] disable additive increase of cwnd in BBR * [~] bug fix for rate sampling * [+] calculate MSS according to settings * [~] bug fix for cubic * [~] add copa in the document of testing
1 parent 00f6228 commit 8ef10d3

28 files changed

+917
-189
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
build/
22
bss/
33
*.swp
4+
third_party/

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ set(
225225
CONGESTION_CONTROL_SOURCES
226226
"src/congestion_control/xqc_cubic.c"
227227
"src/congestion_control/xqc_bbr.c"
228+
"src/congestion_control/xqc_copa.c"
228229
"src/congestion_control/xqc_window_filter.c"
229230
"src/congestion_control/xqc_sample.c"
230231
)

cmake/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ set(
226226
CONGESTION_CONTROL_SOURCES
227227
"src/congestion_control/xqc_cubic.c"
228228
"src/congestion_control/xqc_bbr.c"
229+
"src/congestion_control/xqc_copa.c"
229230
"src/congestion_control/xqc_window_filter.c"
230231
"src/congestion_control/xqc_sample.c"
231232
)

docs/docs-zh/Testing-zh.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ openssl req -newkey rsa:2048 -x509 -nodes -keyout "$keyfile" -new -out "$certfil
3535
| -p | Server port. |
3636
| -P | Number of Parallel requests per single connection. Default 1. |
3737
| -n | Total number of requests to send. Defaults 1. |
38-
| -c | Congestion Control Algorithm. r:reno b:bbr c:cubic B:bbr2 bbr+ bbr2+ |
38+
| -c | Congestion Control Algorithm. r:reno b:bbr c:cubic B:bbr2 bbr+ bbr2+ P:Copa |
39+
| -A | Copa: the addtive increasing coefficient of 1/delta, default:1.0 |
40+
| -D | Copa: the delta paramter, default:0.05 |
3941
| -C | Pacing on. |
4042
| -t | Connection timeout. Default 3 seconds. |
4143
| -T | Transport layer. No HTTP3. |
@@ -63,7 +65,9 @@ openssl req -newkey rsa:2048 -x509 -nodes -keyout "$keyfile" -new -out "$certfil
6365
| :----: | ---- |
6466
| -p | Server port. |
6567
| -e | Echo. Send received body. |
66-
| -c | Congestion Control Algorithm. r:reno b:bbr c:cubic B:bbr2 bbr+ bbr2+ |
68+
| -c | Congestion Control Algorithm. r:reno b:bbr c:cubic B:bbr2 bbr+ bbr2+ P:Copa |
69+
| -A | Copa: the addtive increasing coefficient of 1/delta, default:1.0 |
70+
| -D | Copa: the delta paramter, default:0.05 |
6771
| -C | Pacing on. |
6872
| -s | Body size to send. |
6973
| -w | Write received body to file. |

include/xquic/xquic.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,15 @@ typedef struct xqc_cc_params_s {
627627
uint32_t expect_bw;
628628
uint32_t max_expect_bw;
629629
uint32_t cc_optimization_flags;
630+
/* 0 < delta <= delta_max, default 0.05, ->0 = more throughput-oriented */
631+
double copa_delta_base;
632+
/* 0 < delta_max <= 1.0, default 0.5 */
633+
double copa_delta_max;
634+
/*
635+
* 1.0 <= delta_ai_unit, default 1.0, greater values mean more aggressive
636+
* when Copa competes with loss-based CCAs.
637+
*/
638+
double copa_delta_ai_unit;
630639
} xqc_cc_params_t;
631640

632641
typedef struct xqc_congestion_control_callback_s {
@@ -657,8 +666,8 @@ typedef struct xqc_congestion_control_callback_s {
657666
/* This function is used by BBR and Cubic*/
658667
void (*xqc_cong_ctl_restart_from_idle)(void *cong_ctl, uint64_t arg);
659668

660-
/* For BBR */
661-
void (*xqc_cong_ctl_bbr)(void *cong_ctl, xqc_sample_t *sampler);
669+
/* For BBR & Copa */
670+
void (*xqc_cong_ctl_on_ack_multiple_pkts)(void *cong_ctl, xqc_sample_t *sampler);
662671

663672
/* initialize bbr */
664673
void (*xqc_cong_ctl_init_bbr)(void *cong_ctl, xqc_sample_t *sampler, xqc_cc_params_t cc_params);
@@ -680,6 +689,7 @@ XQC_EXPORT_PUBLIC_API XQC_EXTERN const xqc_cong_ctrl_callback_t xqc_bbr2_cb;
680689
#endif
681690
XQC_EXPORT_PUBLIC_API XQC_EXTERN const xqc_cong_ctrl_callback_t xqc_bbr_cb;
682691
XQC_EXPORT_PUBLIC_API XQC_EXTERN const xqc_cong_ctrl_callback_t xqc_cubic_cb;
692+
XQC_EXPORT_PUBLIC_API XQC_EXTERN const xqc_cong_ctrl_callback_t xqc_copa_cb;
683693

684694

685695
/**

scripts/case_test.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,32 @@ else
786786
fi
787787

788788

789+
clear_log
790+
echo -e "Copa with default parameters (delta=0.05, ai_unit=1.0) ...\c"
791+
result=`./test_client -s 10240000 -l e -t 1 -E -c P|grep ">>>>>>>> pass"`
792+
errlog=`grep_err_log`
793+
echo "$result"
794+
if [ -z "$errlog" ] && [ "$result" == ">>>>>>>> pass:1" ]; then
795+
case_print_result "copa_with_default_parameters" "pass"
796+
else
797+
case_print_result "copa_with_default_parameters" "fail"
798+
echo "$errlog"
799+
fi
800+
801+
clear_log
802+
echo -e "Copa with customized parameters (delta=0.5, ai_unit=5.0) ...\c"
803+
result=`./test_client -s 10240000 -l e -t 1 -E -c P -A 5.0 -D 0.5|grep ">>>>>>>> pass"`
804+
errlog=`grep_err_log`
805+
echo "$result"
806+
if [ -z "$errlog" ] && [ "$result" == ">>>>>>>> pass:1" ]; then
807+
case_print_result "copa_with_customized_parameters" "pass"
808+
else
809+
case_print_result "copa_with_customized_parameters" "fail"
810+
echo "$errlog"
811+
fi
812+
813+
814+
789815
clear_log
790816
result=`./test_client -s 10240000 -l e -t 1 -E -x 26|grep ">>>>>>>> pass"`
791817
errlog=`grep_err_log`

scripts/xquic.lds

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ XQUIC_VERS_1.0 {
5454
xqc_bbr2_cb;
5555
xqc_reno_cb;
5656
xqc_cubic_cb;
57+
xqc_copa_cb;
5758
xqc_conn_is_ready_to_send_early_data;
5859
xqc_h3_conn_send_ping;
5960
xqc_conn_send_ping;

src/congestion_control/xqc_bbr.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "src/transport/xqc_send_ctl.h"
2121
#include "src/transport/xqc_packet.h"
2222

23-
#define XQC_BBR_MAX_DATAGRAMSIZE XQC_QUIC_MSS
23+
#define XQC_BBR_MAX_DATAGRAMSIZE XQC_MSS
2424
#define XQC_BBR_MIN_WINDOW (4 * XQC_BBR_MAX_DATAGRAMSIZE)
2525
#define XQC_BBR_MAX_WINDOW (100 * XQC_BBR_MAX_DATAGRAMSIZE)
2626
/* The RECOMMENDED value is the minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)) */
@@ -147,10 +147,12 @@ xqc_bbr_init(void *cong_ctl, xqc_sample_t *sampler, xqc_cc_params_t cc_params)
147147
bbr->rttvar_compensation_on = 1;
148148
}
149149
#endif
150+
#ifndef XQC_BBR_DISABLE_CWND_AI
150151
bbr->beyond_target_cwnd = 0;
151152
bbr->snd_cwnd_cnt_bytes = 0;
152153
bbr->ai_scale = 1;
153154
bbr->ai_scale_accumulated_bytes = 0;
155+
#endif
154156
bbr->min_rtt = sampler->srtt ? sampler->srtt : XQC_BBR_INF;
155157
bbr->min_rtt_stamp = now;
156158
bbr->probe_rtt_min_us = sampler->srtt ? sampler->srtt : XQC_BBR_INF;
@@ -266,7 +268,7 @@ static uint32_t
266268
xqc_bbr_compensate_cwnd_for_rttvar(xqc_bbr_t *bbr, xqc_sample_t *sampler)
267269
{
268270
xqc_usec_t srtt = sampler->srtt;
269-
xqc_usec_t recent_max_rtt = xqc_win_filter_get_u64(&bbr->max_rtt);
271+
xqc_usec_t recent_max_rtt = xqc_win_filter_get(&bbr->max_rtt);
270272
xqc_usec_t compensation_thresh = (1 + bbr->rtt_compensation_thresh) *
271273
bbr->min_rtt;
272274
uint32_t cwnd_addition = 0;
@@ -546,6 +548,8 @@ xqc_bbr_update_min_rtt(xqc_bbr_t *bbr, xqc_sample_t *sampler)
546548
xqc_log(sampler->send_ctl->ctl_conn->log, XQC_LOG_DEBUG, "|minrtt expire|rtt:%ui, old_rtt:%ui|",
547549
bbr->probe_rtt_min_us,
548550
bbr->min_rtt);
551+
552+
#ifndef XQC_BBR_DISABLE_CWND_AI
549553
if (bbr->probe_rtt_min_us_stamp != bbr->min_rtt_stamp
550554
|| min_rtt_expired)
551555
{
@@ -562,6 +566,8 @@ xqc_bbr_update_min_rtt(xqc_bbr_t *bbr, xqc_sample_t *sampler)
562566
bbr->ai_scale_accumulated_bytes = 0;
563567
}
564568
}
569+
#endif
570+
565571
bbr->min_rtt = bbr->probe_rtt_min_us;
566572
bbr->min_rtt_stamp = bbr->probe_rtt_min_us_stamp;
567573
}
@@ -712,14 +718,16 @@ xqc_bbr_reset_cwnd(void *cong_ctl)
712718
}
713719
/* reset recovery start time in any case */
714720
bbr->recovery_start_time = 0;
721+
#ifndef XQC_BBR_DISABLE_CWND_AI
715722
/* If losses happened, we do not increase cwnd beyond target_cwnd. */
716723
bbr->snd_cwnd_cnt_bytes = 0;
717724
bbr->beyond_target_cwnd = 0;
718725
bbr->ai_scale = 1;
719726
bbr->ai_scale_accumulated_bytes = 0;
727+
#endif
720728
}
721729

722-
730+
#ifndef XQC_BBR_DISABLE_CWND_AI
723731
static void
724732
xqc_bbr_cong_avoid_ai(xqc_bbr_t *bbr, uint32_t cwnd, uint32_t acked)
725733
{
@@ -744,6 +752,7 @@ xqc_bbr_cong_avoid_ai(xqc_bbr_t *bbr, uint32_t cwnd, uint32_t acked)
744752
bbr->ai_scale_accumulated_bytes -= delta * cwnd_thresh;
745753
}
746754
}
755+
#endif
747756

748757
static void
749758
xqc_bbr_set_cwnd(xqc_bbr_t *bbr, xqc_sample_t *sampler)
@@ -772,6 +781,7 @@ xqc_bbr_set_cwnd(xqc_bbr_t *bbr, xqc_sample_t *sampler)
772781
xqc_bbr_modulate_cwnd_for_recovery(bbr, sampler);
773782
if (!bbr->packet_conservation) {
774783
if (bbr->full_bandwidth_reached) {
784+
#ifndef XQC_BBR_DISABLE_CWND_AI
775785
if ((bbr->congestion_window + sampler->acked
776786
>= (target_cwnd + bbr->beyond_target_cwnd))
777787
&& sampler->send_ctl->ctl_is_cwnd_limited)
@@ -789,6 +799,7 @@ xqc_bbr_set_cwnd(xqc_bbr_t *bbr, xqc_sample_t *sampler)
789799
sampler->acked,
790800
bbr->snd_cwnd_cnt_bytes,
791801
bbr->beyond_target_cwnd);
802+
#endif
792803
bbr->congestion_window = xqc_min(target_cwnd,
793804
bbr->congestion_window +
794805
sampler->acked);
@@ -820,11 +831,13 @@ xqc_bbr_on_lost(void *cong_ctl, xqc_usec_t lost_sent_time)
820831
*/
821832
xqc_bbr_save_cwnd(bbr);
822833
bbr->recovery_start_time = xqc_monotonic_timestamp();
834+
#ifndef XQC_BBR_DISABLE_CWND_AI
823835
/* If losses happened, we do not increase cwnd beyond target_cwnd. */
824836
bbr->snd_cwnd_cnt_bytes = 0;
825837
bbr->beyond_target_cwnd = 0;
826838
bbr->ai_scale = 1;
827839
bbr->ai_scale_accumulated_bytes = 0;
840+
#endif
828841
}
829842

830843
static void
@@ -870,14 +883,14 @@ xqc_bbr_on_ack(void *cong_ctl, xqc_sample_t *sampler)
870883
/* maintain windowed max rtt here */
871884
if (bbr->rttvar_compensation_on) {
872885
if (sampler->rtt >= 0) {
873-
xqc_usec_t last_max_rtt = xqc_win_filter_get_u64(&bbr->max_rtt);
874-
xqc_win_filter_max_u64(&bbr->max_rtt, bbr->max_rtt_win_len,
886+
xqc_usec_t last_max_rtt = xqc_win_filter_get(&bbr->max_rtt);
887+
xqc_win_filter_max(&bbr->max_rtt, bbr->max_rtt_win_len,
875888
bbr->round_cnt, sampler->rtt);
876889
xqc_log(sampler->send_ctl->ctl_conn->log, XQC_LOG_DEBUG,
877890
"|rttvar_compensation|windowed max rtt info|"
878891
"rtt %ui, last_max %ui, max %ui|",
879892
sampler->rtt, last_max_rtt,
880-
xqc_win_filter_get_u64(&bbr->max_rtt));
893+
xqc_win_filter_get(&bbr->max_rtt));
881894
}
882895
}
883896
#endif
@@ -1034,7 +1047,7 @@ static xqc_bbr_info_interface_t xqc_bbr_info_cb = {
10341047
const xqc_cong_ctrl_callback_t xqc_bbr_cb = {
10351048
.xqc_cong_ctl_size = xqc_bbr_size,
10361049
.xqc_cong_ctl_init_bbr = xqc_bbr_init,
1037-
.xqc_cong_ctl_bbr = xqc_bbr_on_ack,
1050+
.xqc_cong_ctl_on_ack_multiple_pkts = xqc_bbr_on_ack,
10381051
.xqc_cong_ctl_get_cwnd = xqc_bbr_get_cwnd,
10391052
.xqc_cong_ctl_get_pacing_rate = xqc_bbr_get_pacing_rate,
10401053
.xqc_cong_ctl_get_bandwidth_estimate = xqc_bbr_get_bandwidth,

src/congestion_control/xqc_bbr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ typedef char bool;
1515
#define TRUE 1
1616
#define FALSE 0
1717
#define MSEC2SEC 1000000
18+
#define XQC_BBR_DISABLE_CWND_AI
1819

1920
typedef enum {
2021
/* Start phase quickly to fill pipe */
@@ -127,10 +128,12 @@ typedef struct xqc_bbr_s {
127128
uint64_t probe_rtt_min_us;
128129
uint64_t probe_rtt_min_us_stamp;
129130

131+
#ifndef XQC_BBR_DISABLE_CWND_AI
130132
uint32_t snd_cwnd_cnt_bytes; /* For AI */
131133
uint32_t beyond_target_cwnd; /* To compete with buffer fillers */
132134
uint32_t ai_scale_accumulated_bytes;
133135
uint32_t ai_scale;
136+
#endif
134137

135138
#if XQC_BBR_RTTVAR_COMPENSATION_ENABLED
136139
/* CWND compensation for RTT variation+ */

src/congestion_control/xqc_bbr2.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "src/transport/xqc_send_ctl.h"
1313
#include "src/transport/xqc_packet.h"
1414

15-
#define XQC_BBR2_MAX_DATAGRAM_SIZE XQC_QUIC_MSS
15+
#define XQC_BBR2_MAX_DATAGRAM_SIZE XQC_MSS
1616
#define XQC_BBR2_MIN_WINDOW (4 * XQC_BBR2_MAX_DATAGRAM_SIZE)
1717
/* The RECOMMENDED value is the minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)). */
1818
#define XQC_BBR2_INITIAL_WINDOW (32 * XQC_BBR2_MAX_DATAGRAM_SIZE)
@@ -151,7 +151,7 @@ xqc_bbr2_init(void *cong_ctl, xqc_sample_t *sampler, xqc_cc_params_t cc_params)
151151
memset(bbr2, 0, sizeof(*bbr2));
152152

153153
#if XQC_BBR2_PLUS_ENABLED
154-
xqc_win_filter_reset_u64(&bbr2->max_rtt, 0, 0);
154+
xqc_win_filter_reset(&bbr2->max_rtt, 0, 0);
155155
bbr2->max_rtt_win_len = xqc_bbr2_windowed_max_rtt_win_size;
156156
if (cc_params.cc_optimization_flags & XQC_BBR2_FLAG_RTTVAR_COMPENSATION) {
157157
bbr2->rtt_compensation_on = 1;
@@ -1102,7 +1102,7 @@ static uint32_t
11021102
xqc_bbr2_compensate_cwnd_for_rttvar(xqc_bbr2_t *bbr2, xqc_sample_t *sampler)
11031103
{
11041104
xqc_usec_t srtt = sampler->srtt;
1105-
xqc_usec_t recent_max_rtt = xqc_win_filter_get_u64(&bbr2->max_rtt);
1105+
xqc_usec_t recent_max_rtt = xqc_win_filter_get(&bbr2->max_rtt);
11061106
xqc_usec_t compensation_thresh = (1 + bbr2->rtt_compensation_thresh) *
11071107
bbr2->min_rtt;
11081108
uint32_t cwnd_addition = 0;
@@ -1422,14 +1422,14 @@ xqc_bbr2_on_ack(void *cong_ctl, xqc_sample_t *sampler)
14221422
/* maintain windowed max rtt here */
14231423
if (bbr2->rtt_compensation_on) {
14241424
if (sampler->rtt >= 0) {
1425-
xqc_usec_t last_max_rtt = xqc_win_filter_get_u64(&bbr2->max_rtt);
1426-
xqc_win_filter_max_u64(&bbr2->max_rtt, bbr2->max_rtt_win_len,
1425+
xqc_usec_t last_max_rtt = xqc_win_filter_get(&bbr2->max_rtt);
1426+
xqc_win_filter_max(&bbr2->max_rtt, bbr2->max_rtt_win_len,
14271427
bbr2->round_cnt, sampler->rtt);
14281428
xqc_log(sampler->send_ctl->ctl_conn->log, XQC_LOG_DEBUG,
14291429
"|BBRv2 Plus|windowed max rtt info: rtt %ui, "
14301430
"last_max %ui, max %ui|",
14311431
sampler->rtt, last_max_rtt,
1432-
xqc_win_filter_get_u64(&bbr2->max_rtt));
1432+
xqc_win_filter_get(&bbr2->max_rtt));
14331433
}
14341434
}
14351435
#endif
@@ -1611,7 +1611,7 @@ static xqc_bbr_info_interface_t xqc_bbr2_info_cb = {
16111611
const xqc_cong_ctrl_callback_t xqc_bbr2_cb = {
16121612
.xqc_cong_ctl_size = xqc_bbr2_size,
16131613
.xqc_cong_ctl_init_bbr = xqc_bbr2_init,
1614-
.xqc_cong_ctl_bbr = xqc_bbr2_on_ack,
1614+
.xqc_cong_ctl_on_ack_multiple_pkts = xqc_bbr2_on_ack,
16151615
.xqc_cong_ctl_get_cwnd = xqc_bbr2_get_cwnd,
16161616
.xqc_cong_ctl_get_pacing_rate = xqc_bbr2_get_pacing_rate,
16171617
.xqc_cong_ctl_get_bandwidth_estimate = xqc_bbr2_get_bandwidth,

0 commit comments

Comments
 (0)