How to Configure BBRv2 Congestion Control in XQUIC: Build and Runtime Guide
Enable BBRv2 in XQUIC by compiling with -DXQC_ENABLE_BBR2=ON and passing the --conn_options B2ON flag at runtime to activate the algorithm via the internal option tag system.
XQUIC is Alibaba's open-source QUIC protocol implementation that provides a pluggable congestion control framework supporting multiple algorithms including BBRv2. To configure BBRv2 congestion control in XQUIC, you must enable the algorithm at compile time using CMake flags and then activate it through connection option strings or command-line arguments when initializing connections.
Build-Time Configuration: Enabling BBRv2 in CMake
BBRv2 support is conditionally compiled via the XQC_ENABLE_BBR2 macro. The implementation resides in src/congestion_control/xqc_bbr2.c and src/congestion_control/xqc_bbr2.h, which are only included in the build when the CMake flag is set.
To compile XQUIC with BBRv2 support, add -DXQC_ENABLE_BBR2=ON to your CMake configuration:
cd xquic
mkdir -p build && cd build
cmake -DXQC_ENABLE_BBR2=ON \
-DXQC_ENABLE_RENO=ON \
-DSSL_TYPE=boringssl \
-DSSL_PATH=/path/to/boringssl \
-DCMAKE_BUILD_TYPE=Release ..
make -j
The XQC_ENABLE_BBR2 flag activates the BBRv2 state machine, bandwidth probing, and pacing logic implemented in src/congestion_control/xqc_bbr2.c. As documented in the repository's README.md (lines 95-99), this is the required first step before any runtime configuration can take effect.
Runtime Configuration: Activating BBRv2 with Connection Options
XQUIC uses a four-character option tag system to enable specific connection features at runtime. The BBRv2 algorithm is controlled by the XQC_CO_B2ON tag, defined in include/xquic/xquic_typedef.h (line 278) as:
#define XQC_CO_B2ON XQC_CO_TAG('B','2','O','N') // Enable BBRv2
Command-Line Activation
Both the test client (tests/test_client.c) and test server (tests/test_server.c) accept the --conn_options argument. The parsing logic in src/transport/xqc_conn.c (around line 545) processes this string and stores the corresponding tags in the connection's conn_options[] array.
To enable BBRv2 via command line:
# Client side
./xquic_client -c bbr2 --conn_options B2ON -s 1024 -l d -t 1 -E
# Server side (optional, for server-initiated congestion control)
./xquic_server --conn_options B2ON -s 1024 -l d -t 1
The -c bbr2 switch selects the congestion control algorithm, while --conn_options B2ON passes the specific option tag that activates the BBRv2 variant within the connection structure defined in src/transport/xqc_conn.h.
Advanced Configuration: Enabling BBRv2+ Mode
XQUIC ships with an experimental "BBRv2+" mode that modifies the pacing-gain cycle for specific performance characteristics. This feature requires additional compile-time and runtime configuration.
Compile-Time Setup
Enable the plus variant by setting XQC_BBR2_PLUS_ENABLED to 1 in your CMake command:
cmake -DXQC_ENABLE_BBR2=ON -DXQC_BBR2_PLUS_ENABLED=1 ..
This macro is defined in include/xquic/xquic_typedef.h (line 164) and guards the extended pacing logic within the BBRv2 implementation.
Runtime Selection
When running the test client, use the bbr2+ or bbr+ algorithm identifier with the -c switch. The parsing logic in tests/test_client.c (lines 13-22) automatically sets the internal c_cong_plus flag when these strings are detected:
./xquic_client -c bbr2+ --conn_options B2ON -s 1024 -l d -t 1 -E
This activates the enhanced BBRv2 variant with modified probe bandwidth behavior while maintaining compatibility with the standard BBRv2 state machine in xqc_bbr2.c.
Programmatic Configuration via C API
For applications integrating XQUIC as a library, configure BBRv2 through the xqc_conn_settings_t structure before creating a connection.
Basic BBRv2 Activation
#include <xquic/xquic.h>
int main() {
xqc_engine_t *engine = xqc_engine_create(&engine_config, NULL);
if (!engine) return -1;
xqc_conn_settings_t settings = XQC_DEFAULT_CONN_SETTINGS;
/* Enable BBRv2 via the connection option string */
strncpy(settings.conn_option_str, "B2ON", XQC_CO_STR_MAX_LEN);
xqc_connection_t *conn = xqc_conn_create(engine, &dcid, &scid,
&settings, NULL,
XQC_CONN_TYPE_CLIENT);
if (!conn) return -1;
xqc_engine_connect(engine, conn, server_addr, server_port);
/* ... run event loop ... */
return 0;
}
The conn_option_str field mirrors the command-line --conn_options B2ON behavior, causing the connection logic in src/transport/xqc_conn.c to populate the conn_options[] array with the XQC_CO_B2ON tag.
BBRv2+ via API
When the library is compiled with XQC_BBR2_PLUS_ENABLED=1, you can activate the plus mode by combining the option string with algorithm selection flags:
strncpy(settings.conn_option_str, "B2ON", XQC_CO_STR_MAX_LEN);
settings.cong_ctl_flags |= XQC_CO_B2ON; // Explicit tag setting
settings.c_cong_plus = 1; // Enable plus mode
Note that c_cong_plus is typically managed internally by the algorithm selection logic when using -c bbr2+ in the test harness.
Summary
- Compile with
-DXQC_ENABLE_BBR2=ONto include the BBRv2 implementation files (src/congestion_control/xqc_bbr2.c) in the build. - Pass the
B2ONoption tag via--conn_options B2ONat runtime or setconn_option_strto"B2ON"in the C API to activate the algorithm. - Use
-DXQC_BBR2_PLUS_ENABLED=1and thebbr2+algorithm identifier to enable experimental BBRv2+ features. - Reference implementation resides in
src/congestion_control/xqc_bbr2.cwith parsing logic insrc/transport/xqc_conn.cand option definitions ininclude/xquic/xquic_typedef.h.
Frequently Asked Questions
What is the difference between BBRv2 and BBRv2+ in XQUIC?
BBRv2+ is an experimental variant that modifies the pacing-gain cycle within the standard BBRv2 state machine. While standard BBRv2 uses the default probe bandwidth behavior defined in the IETF draft, BBRv2+ (enabled via -DXQC_BBR2_PLUS_ENABLED=1 and -c bbr2+) applies custom pacing parameters for specific high-throughput scenarios. Both implementations share the core state machine in src/congestion_control/xqc_bbr2.c but diverge in the gain cycle calculations.
Can I use BBRv2 on both client and server sides simultaneously?
Yes, BBRv2 operates independently on each peer. Pass --conn_options B2ON to both the client (tests/test_client.c) and server (tests/test_server.c) binaries, or set the option string in both connection settings when using the C API. Each endpoint maintains its own congestion control state in xqc_send_ctl.c, allowing asymmetric configurations where one peer uses BBRv2 and the other uses a different algorithm like Reno or Cubic.
Why does XQUIC require both -c bbr2 and --conn_options B2ON?
The -c switch selects the algorithm module, while --conn_options passes specific feature flags to that module. The -c bbr2 argument loads the callbacks defined in xqc_bbr2.c (such as xqc_cong_ctl_get_cwnd and xqc_cong_ctl_on_ack), whereas the B2ON tag in conn_options[] triggers internal initialization paths specific to BBRv2's startup behavior. Omitting the option tag may result in the connection defaulting to basic congestion control behavior even when the BBRv2 module is loaded.
Does enabling BBRv2 affect connection performance compared to Reno?
BBRv2 generally provides higher throughput and lower latency on high-BDP (bandwidth-delay product) networks by using a model-based approach rather than loss-based signals. According to the implementation in src/congestion_control/xqc_bbr2.c, BBRv2 maintains separate pacing and bandwidth estimation loops compared to the loss-based Reno algorithm in src/congestion_control/xqc_reno.c. However, BBRv2 may exhibit different behavior during the startup phase and under extreme packet loss conditions, making the B2ON option tag essential for proper initialization tuning.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →