Add BBR-Copilot to improve BBR bandwidth estimation under application-limited traffic#662
Add BBR-Copilot to improve BBR bandwidth estimation under application-limited traffic#662litonglab wants to merge 14 commits into
Conversation
dtikhonov
left a comment
There was a problem hiding this comment.
This is a great start, but I would not merge it as-is. There are a few correctness issues and one structural issue that should be addressed first.
Main Structural Suggestion
The packet-filling loop should live in the send controller, not in lsquic_full_conn.c.
A better shape would be:
lsquic_send_ctl_maybe_app_limited()decides whether the connection is about to become app-limited.- If BBR-Copilot is enabled, the send controller asks congestion control whether probe-fill is wanted.
- The full connection supplies a callback/function to generate one ack-eliciting padded packet, since GQUIC and IETF frame generation differ.
- The send controller owns the common loop and accounting.
This keeps the on/off logic in one place, avoids duplicating the filling loop between GQUIC and IETF paths, and keeps connection code from knowing BBR-Copilot send-controller details.
Correctness Issues
1. Extra packets appear to overwrite their PING frame
In src/liblsquic/lsquic_full_conn.c, the new code calls pf_gen_ping_frame() but does not advance packet_out->po_data_sz before calling lsquic_packet_out_zero_pad().
Existing PING generation calls lsquic_send_ctl_incr_pack_sz() or otherwise increments po_data_sz after writing the frame. As written, the extra packet is marked as PING|PADDING, but the PING bytes are likely overwritten by zero padding, leaving a padding-only packet on the wire.
That is a blocker because padding-only packets are not reliably ack-eliciting, which defeats the purpose of BBR-Copilot.
2. The feature is only wired into the GQUIC full connection path
The engine setting is public and generic, but packet injection is only added to lsquic_full_conn.c.
lsquic_full_conn_ietf.c still only calls lsquic_send_ctl_maybe_app_limited(), so HTTP/3/IETF QUIC does not use the feature.
3. Adaptive congestion control does not forward the new BBR query
Adaptive CC is the default. The new congestion-control hook is implemented by BBR, but lsquic_adaptive_cc.c does not forward it.
That means the option will not activate under the default CC setting, even if adaptive CC selected BBR. Users would have to force BBRv1 explicitly.
API and Style Issues
- The new names are too long. For example,
cci_need_send_extra_data_to_probe_bwis much longer than typical LSQUIC internal names. - The command-line option should match the engine setting name without the
es_prefix. Other-ooptions follow that convention, sosend_extrawould besend_extra_data_to_probe_bw(or a shorter version if the engine setting is renamed). PO_SEND_EXTRA = (1 << 31)is not portable C because it shifts a signedintinto the sign bit. Let's do1u << 31.- Please fix the Windows compilation failures.
Summary
This PR introduces BBR-Copilot, a lightweight auxiliary mechanism that helps improve BBR's bandwidth estimation under application-limited traffic, especially in live-streaming scenarios.
BBR estimates bottleneck bandwidth using delivery-rate samples. Under application-limited traffic, the sender frequently has no data to transmit because the application generates data periodically. This results in inaccurate bandwidth samples, which may prevent BBR from exiting the Startup phase and delay bandwidth adaptation during ProbeBW.
BBR-Copilot addresses this issue by generating auxiliary padding packets only when they are needed, specifically when:
pacing_gain > 1).The generated packets are used only for bandwidth probing and are not retransmitted after loss, keeping the additional overhead low.
Main Changes
Reference
The design of BBR-Copilot is described in our paper When BBR Meets Live Streaming:
https://arxiv.org/abs/2606.03468