|
7 | 7 | "github.com/apernet/hysteria/core/v2/internal/congestion/bbr" |
8 | 8 | "github.com/apernet/hysteria/core/v2/internal/congestion/brutal" |
9 | 9 | "github.com/apernet/quic-go" |
| 10 | + "github.com/apernet/quic-go/congestion" |
10 | 11 | ) |
11 | 12 |
|
12 | 13 | const ( |
@@ -36,11 +37,27 @@ func NormalizeBBRProfile(profile string) (string, error) { |
36 | 37 | func UseBBR(conn *quic.Conn, profile bbr.Profile) { |
37 | 38 | conn.SetCongestionControl(bbr.NewBbrSender( |
38 | 39 | bbr.DefaultClock{}, |
39 | | - bbr.GetInitialPacketSize(conn.RemoteAddr()), |
| 40 | + seedPacketSize(conn.InitialPacketSize(), bbr.GetInitialPacketSize(conn.RemoteAddr())), |
40 | 41 | profile, |
41 | 42 | )) |
42 | 43 | } |
43 | 44 |
|
| 45 | +// seedPacketSize picks the datagram size to seed a replacement congestion |
| 46 | +// controller with, given the size QUIC itself starts at and the guess derived |
| 47 | +// from the remote address. |
| 48 | +// |
| 49 | +// The seed must not exceed what QUIC actually starts at. If it does, the first |
| 50 | +// path MTU probe can land between the two: QUIC sees an increase and reports |
| 51 | +// it, but the controller sees a decrease, which it cannot represent. Taking the |
| 52 | +// smaller of the two keeps the address-based guess as a floor for connections |
| 53 | +// whose path we can't reason about, while never seeding above QUIC. |
| 54 | +func seedPacketSize(quicSize, byAddr congestion.ByteCount) congestion.ByteCount { |
| 55 | + if quicSize <= 0 { |
| 56 | + return byAddr |
| 57 | + } |
| 58 | + return min(quicSize, byAddr) |
| 59 | +} |
| 60 | + |
44 | 61 | func UseBrutal(conn *quic.Conn, tx uint64, disableLossCompensation bool) { |
45 | 62 | conn.SetCongestionControl(brutal.NewBrutalSender(tx, disableLossCompensation)) |
46 | 63 | } |
|
0 commit comments