Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SplitHTTP client: Add xmux (multiplex controller) for H3 & H2 #3613

Merged
merged 13 commits into from
Sep 16, 2024
22 changes: 22 additions & 0 deletions infra/conf/transport_internet.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,14 @@ type SplitHTTPConfig struct {
ScMinPostsIntervalMs *Int32Range `json:"scMinPostsIntervalMs"`
NoSSEHeader bool `json:"noSSEHeader"`
XPaddingBytes *Int32Range `json:"xPaddingBytes"`
Xmux Xmux `json:"xmux"`
}

type Xmux struct {
maxConnections *Int32Range `json:"maxConnections"`
maxConcurrency *Int32Range `json:"maxConcurrency"`
cMaxReuseTimes *Int32Range `json:"cMaxReuseTimes"`
cMaxLifetimeMs *Int32Range `json:"cMaxLifetimeMs"`
}

func splithttpNewRandRangeConfig(input *Int32Range) *splithttp.RandRangeConfig {
Expand All @@ -254,6 +262,19 @@ func (c *SplitHTTPConfig) Build() (proto.Message, error) {
} else if c.Host == "" && c.Headers["Host"] != "" {
c.Host = c.Headers["Host"]
}

if c.Xmux.maxConnections != nil && c.Xmux.maxConcurrency != nil {
return nil, errors.New("maxConnections cannot be specified together with maxConcurrency")
}

// Multiplexing config
muxProtobuf := splithttp.Multiplexing{
MaxConnections: splithttpNewRandRangeConfig(c.Xmux.maxConnections),
MaxConcurrency: splithttpNewRandRangeConfig(c.Xmux.maxConcurrency),
CMaxReuseTimes: splithttpNewRandRangeConfig(c.Xmux.cMaxReuseTimes),
CMaxLifetimeMs: splithttpNewRandRangeConfig(c.Xmux.cMaxLifetimeMs),
}

config := &splithttp.Config{
Path: c.Path,
Host: c.Host,
Expand All @@ -263,6 +284,7 @@ func (c *SplitHTTPConfig) Build() (proto.Message, error) {
ScMinPostsIntervalMs: splithttpNewRandRangeConfig(c.ScMinPostsIntervalMs),
NoSSEHeader: c.NoSSEHeader,
XPaddingBytes: splithttpNewRandRangeConfig(c.XPaddingBytes),
Xmux: &muxProtobuf,
}
return config, nil
}
Expand Down
7 changes: 3 additions & 4 deletions transport/internet/splithttp/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ type DialerClient interface {
// implements splithttp.DialerClient in terms of direct network connections
type DefaultDialerClient struct {
transportConfig *Config
download *http.Client
upload *http.Client
client *http.Client
isH2 bool
isH3 bool
// pool of net.Conn, created using dialUploadConn
Expand Down Expand Up @@ -79,7 +78,7 @@ func (c *DefaultDialerClient) OpenDownload(ctx context.Context, baseURL string)

req.Header = c.transportConfig.GetRequestHeader()

response, err := c.download.Do(req)
response, err := c.client.Do(req)
gotConn.Close()
if err != nil {
errors.LogInfoInner(ctx, err, "failed to send download http request")
Expand Down Expand Up @@ -137,7 +136,7 @@ func (c *DefaultDialerClient) SendUploadRequest(ctx context.Context, url string,
req.Header = c.transportConfig.GetRequestHeader()

if c.isH2 || c.isH3 {
resp, err := c.upload.Do(req)
resp, err := c.client.Do(req)
if err != nil {
return err
}
Expand Down
43 changes: 43 additions & 0 deletions transport/internet/splithttp/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,49 @@ func (c *Config) GetNormalizedXPaddingBytes() RandRangeConfig {
return *c.XPaddingBytes
}

func (m *Multiplexing) GetNormalizedCMaxReuseTimes() RandRangeConfig {
if m.CMaxReuseTimes == nil {
return RandRangeConfig{
From: 0,
To: 0,
}
}

return *m.CMaxReuseTimes
}

func (m *Multiplexing) GetNormalizedCMaxLifetimeMs() RandRangeConfig {
if m.CMaxLifetimeMs == nil || m.CMaxLifetimeMs.To == 0 {
return RandRangeConfig{
From: 0,
To: 0,
}
}
return *m.CMaxLifetimeMs
}

func (m *Multiplexing) GetNormalizedMaxConnections() RandRangeConfig {
if m.MaxConnections == nil {
return RandRangeConfig{
From: 0,
To: 0,
}
}

return *m.MaxConnections
}

func (m *Multiplexing) GetNormalizedMaxConcurrency() RandRangeConfig {
if m.MaxConcurrency == nil {
return RandRangeConfig{
From: 0,
To: 0,
}
}

return *m.MaxConcurrency
}

func init() {
common.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {
return new(Config)
Expand Down
187 changes: 156 additions & 31 deletions transport/internet/splithttp/config.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions transport/internet/splithttp/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@ message Config {
RandRangeConfig scMinPostsIntervalMs = 6;
bool noSSEHeader = 7;
RandRangeConfig xPaddingBytes = 8;
Multiplexing xmux = 9;
}

message RandRangeConfig {
ll11l1lIllIl1lll marked this conversation as resolved.
Show resolved Hide resolved
int32 from = 1;
int32 to = 2;
}

message Multiplexing {
RandRangeConfig maxConnections = 1;
RandRangeConfig maxConcurrency = 2;
RandRangeConfig cMaxReuseTimes = 3;
RandRangeConfig cMaxLifetimeMs = 4;
}
Loading