mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-05-08 14:13:22 +00:00
Hysteria & XHTTP/3: Unified Finalmask's quicParams to set congestion, brutalUp, brutalDown, udpHop (ports & interval), etc. (#5772)
https://github.com/XTLS/Xray-core/pull/5772#issuecomment-4023006179
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"encoding/json"
|
||||
"math"
|
||||
"net/url"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -500,7 +501,7 @@ func (b Bandwidth) Bps() (uint64, error) {
|
||||
}
|
||||
|
||||
type UdpHop struct {
|
||||
PortList json.RawMessage `json:"port"`
|
||||
PortList json.RawMessage `json:"ports"`
|
||||
Interval *Int32Range `json:"interval"`
|
||||
}
|
||||
|
||||
@@ -519,21 +520,13 @@ type Masquerade struct {
|
||||
}
|
||||
|
||||
type HysteriaConfig struct {
|
||||
Version int32 `json:"version"`
|
||||
Auth string `json:"auth"`
|
||||
Congestion string `json:"congestion"`
|
||||
Up Bandwidth `json:"up"`
|
||||
Down Bandwidth `json:"down"`
|
||||
UdpHop UdpHop `json:"udphop"`
|
||||
Version int32 `json:"version"`
|
||||
Auth string `json:"auth"`
|
||||
|
||||
InitStreamReceiveWindow uint64 `json:"initStreamReceiveWindow"`
|
||||
MaxStreamReceiveWindow uint64 `json:"maxStreamReceiveWindow"`
|
||||
InitConnectionReceiveWindow uint64 `json:"initConnectionReceiveWindow"`
|
||||
MaxConnectionReceiveWindow uint64 `json:"maxConnectionReceiveWindow"`
|
||||
MaxIdleTimeout int64 `json:"maxIdleTimeout"`
|
||||
KeepAlivePeriod int64 `json:"keepAlivePeriod"`
|
||||
DisablePathMTUDiscovery bool `json:"disablePathMTUDiscovery"`
|
||||
MaxIncomingStreams int64 `json:"maxIncomingStreams"`
|
||||
Congestion *string `json:"congestion"`
|
||||
Up *Bandwidth `json:"up"`
|
||||
Down *Bandwidth `json:"down"`
|
||||
UdpHop *UdpHop `json:"udphop"`
|
||||
|
||||
UdpIdleTimeout int64 `json:"udpIdleTimeout"`
|
||||
Masquerade Masquerade `json:"masquerade"`
|
||||
@@ -544,62 +537,10 @@ func (c *HysteriaConfig) Build() (proto.Message, error) {
|
||||
return nil, errors.New("version != 2")
|
||||
}
|
||||
|
||||
up, err := c.Up.Bps()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
down, err := c.Down.Bps()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if c.Congestion != nil || c.Up != nil || c.Down != nil || c.UdpHop != nil {
|
||||
errors.LogWarning(context.Background(), "congestion & up & down & udphop move to finalmask/quicParams")
|
||||
}
|
||||
|
||||
c.Congestion = strings.ToLower(c.Congestion)
|
||||
if c.Congestion == "force-brutal" && up == 0 {
|
||||
return nil, errors.New("force-brutal require up")
|
||||
}
|
||||
|
||||
var hop *PortList
|
||||
if err := json.Unmarshal(c.UdpHop.PortList, &hop); err != nil {
|
||||
hop = &PortList{}
|
||||
}
|
||||
|
||||
var inertvalMin, inertvalMax int64
|
||||
if c.UdpHop.Interval != nil {
|
||||
inertvalMin = int64(c.UdpHop.Interval.From)
|
||||
inertvalMax = int64(c.UdpHop.Interval.To)
|
||||
}
|
||||
|
||||
if up > 0 && up < 65536 {
|
||||
return nil, errors.New("Up must be at least 65536 bytes per second")
|
||||
}
|
||||
if down > 0 && down < 65536 {
|
||||
return nil, errors.New("Down must be at least 65536 bytes per second")
|
||||
}
|
||||
if (inertvalMin != 0 && inertvalMin < 5) || (inertvalMax != 0 && inertvalMax < 5) {
|
||||
return nil, errors.New("Interval must be at least 5")
|
||||
}
|
||||
|
||||
if c.InitStreamReceiveWindow > 0 && c.InitStreamReceiveWindow < 16384 {
|
||||
return nil, errors.New("InitStreamReceiveWindow must be at least 16384")
|
||||
}
|
||||
if c.MaxStreamReceiveWindow > 0 && c.MaxStreamReceiveWindow < 16384 {
|
||||
return nil, errors.New("MaxStreamReceiveWindow must be at least 16384")
|
||||
}
|
||||
if c.InitConnectionReceiveWindow > 0 && c.InitConnectionReceiveWindow < 16384 {
|
||||
return nil, errors.New("InitConnectionReceiveWindow must be at least 16384")
|
||||
}
|
||||
if c.MaxConnectionReceiveWindow > 0 && c.MaxConnectionReceiveWindow < 16384 {
|
||||
return nil, errors.New("MaxConnectionReceiveWindow must be at least 16384")
|
||||
}
|
||||
if c.MaxIdleTimeout != 0 && (c.MaxIdleTimeout < 4 || c.MaxIdleTimeout > 120) {
|
||||
return nil, errors.New("MaxIdleTimeout must be between 4 and 120")
|
||||
}
|
||||
if c.KeepAlivePeriod != 0 && (c.KeepAlivePeriod < 2 || c.KeepAlivePeriod > 60) {
|
||||
return nil, errors.New("KeepAlivePeriod must be between 2 and 60")
|
||||
}
|
||||
if c.MaxIncomingStreams != 0 && c.MaxIncomingStreams < 8 {
|
||||
return nil, errors.New("MaxIncomingStreams must be at least 8")
|
||||
}
|
||||
if c.UdpIdleTimeout != 0 && (c.UdpIdleTimeout < 2 || c.UdpIdleTimeout > 600) {
|
||||
return nil, errors.New("UdpIdleTimeout must be between 2 and 600")
|
||||
}
|
||||
@@ -607,20 +548,6 @@ func (c *HysteriaConfig) Build() (proto.Message, error) {
|
||||
config := &hysteria.Config{}
|
||||
config.Version = c.Version
|
||||
config.Auth = c.Auth
|
||||
config.Congestion = c.Congestion
|
||||
config.Up = up
|
||||
config.Down = down
|
||||
config.Ports = hop.Build().Ports()
|
||||
config.IntervalMin = inertvalMin
|
||||
config.IntervalMax = inertvalMax
|
||||
config.InitStreamReceiveWindow = c.InitStreamReceiveWindow
|
||||
config.MaxStreamReceiveWindow = c.MaxStreamReceiveWindow
|
||||
config.InitConnReceiveWindow = c.InitConnectionReceiveWindow
|
||||
config.MaxConnReceiveWindow = c.MaxConnectionReceiveWindow
|
||||
config.MaxIdleTimeout = c.MaxIdleTimeout
|
||||
config.KeepAlivePeriod = c.KeepAlivePeriod
|
||||
config.DisablePathMtuDiscovery = c.DisablePathMTUDiscovery
|
||||
config.MaxIncomingStreams = c.MaxIncomingStreams
|
||||
config.UdpIdleTimeout = c.UdpIdleTimeout
|
||||
config.MasqType = c.Masquerade.Type
|
||||
config.MasqFile = c.Masquerade.Dir
|
||||
@@ -631,27 +558,6 @@ func (c *HysteriaConfig) Build() (proto.Message, error) {
|
||||
config.MasqStringHeaders = c.Masquerade.Headers
|
||||
config.MasqStringStatusCode = c.Masquerade.StatusCode
|
||||
|
||||
if config.InitStreamReceiveWindow == 0 {
|
||||
config.InitStreamReceiveWindow = 8388608
|
||||
}
|
||||
if config.MaxStreamReceiveWindow == 0 {
|
||||
config.MaxStreamReceiveWindow = 8388608
|
||||
}
|
||||
if config.InitConnReceiveWindow == 0 {
|
||||
config.InitConnReceiveWindow = 8388608 * 5 / 2
|
||||
}
|
||||
if config.MaxConnReceiveWindow == 0 {
|
||||
config.MaxConnReceiveWindow = 8388608 * 5 / 2
|
||||
}
|
||||
if config.MaxIdleTimeout == 0 {
|
||||
config.MaxIdleTimeout = 30
|
||||
}
|
||||
// if config.KeepAlivePeriod == 0 {
|
||||
// config.KeepAlivePeriod = 10
|
||||
// }
|
||||
if config.MaxIncomingStreams == 0 {
|
||||
config.MaxIncomingStreams = 1024
|
||||
}
|
||||
if config.UdpIdleTimeout == 0 {
|
||||
config.UdpIdleTimeout = 60
|
||||
}
|
||||
@@ -722,8 +628,19 @@ func (c *TLSCertConfig) Build() (*tls.Certificate, error) {
|
||||
}
|
||||
|
||||
type QuicParamsConfig struct {
|
||||
Congestion string `json:"congestion"`
|
||||
Up Bandwidth `json:"up"`
|
||||
Congestion string `json:"congestion"`
|
||||
Debug bool `json:"debug"`
|
||||
BrutalUp Bandwidth `json:"brutalUp"`
|
||||
BrutalDown Bandwidth `json:"brutalDown"`
|
||||
UdpHop UdpHop `json:"udpHop"`
|
||||
InitStreamReceiveWindow uint64 `json:"initStreamReceiveWindow"`
|
||||
MaxStreamReceiveWindow uint64 `json:"maxStreamReceiveWindow"`
|
||||
InitConnectionReceiveWindow uint64 `json:"initConnectionReceiveWindow"`
|
||||
MaxConnectionReceiveWindow uint64 `json:"maxConnectionReceiveWindow"`
|
||||
MaxIdleTimeout int64 `json:"maxIdleTimeout"`
|
||||
KeepAlivePeriod int64 `json:"keepAlivePeriod"`
|
||||
DisablePathMTUDiscovery bool `json:"disablePathMTUDiscovery"`
|
||||
MaxIncomingStreams int64 `json:"maxIncomingStreams"`
|
||||
}
|
||||
|
||||
type TLSConfig struct {
|
||||
@@ -1918,25 +1835,92 @@ func (c *StreamConfig) Build() (*internet.StreamConfig, error) {
|
||||
config.Udpmasks = append(config.Udpmasks, serial.ToTypedMessage(u))
|
||||
}
|
||||
if c.FinalMask.QuicParams != nil {
|
||||
up, err := c.FinalMask.QuicParams.Up.Bps()
|
||||
up, err := c.FinalMask.QuicParams.BrutalUp.Bps()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if up > 0 && up < 65536 {
|
||||
return nil, errors.New("Up must be at least 65536 bytes per second")
|
||||
down, err := c.FinalMask.QuicParams.BrutalDown.Bps()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if up > 0 && up < 65536 {
|
||||
return nil, errors.New("BrutalUp must be at least 65536 bytes per second")
|
||||
}
|
||||
if down > 0 && down < 65536 {
|
||||
return nil, errors.New("BrutalDown must be at least 65536 bytes per second")
|
||||
}
|
||||
|
||||
c.FinalMask.QuicParams.Congestion = strings.ToLower(c.FinalMask.QuicParams.Congestion)
|
||||
switch c.FinalMask.QuicParams.Congestion {
|
||||
case "", "bbr", "reno":
|
||||
case "", "brutal", "reno", "bbr":
|
||||
case "force-brutal":
|
||||
if up == 0 {
|
||||
return nil, errors.New("force-brutal requires up")
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("unknown congestion control: ", c.FinalMask.QuicParams.Congestion, ", valid values: bbr, reno, force-brutal")
|
||||
return nil, errors.New("unknown congestion control: ", c.FinalMask.QuicParams.Congestion, ", valid values: reno, bbr, brutal, force-brutal")
|
||||
}
|
||||
|
||||
var hop *PortList
|
||||
if err := json.Unmarshal(c.FinalMask.QuicParams.UdpHop.PortList, &hop); err != nil {
|
||||
hop = &PortList{}
|
||||
}
|
||||
|
||||
var inertvalMin, inertvalMax int64
|
||||
if c.FinalMask.QuicParams.UdpHop.Interval != nil {
|
||||
inertvalMin = int64(c.FinalMask.QuicParams.UdpHop.Interval.From)
|
||||
inertvalMax = int64(c.FinalMask.QuicParams.UdpHop.Interval.To)
|
||||
}
|
||||
|
||||
if (inertvalMin != 0 && inertvalMin < 5) || (inertvalMax != 0 && inertvalMax < 5) {
|
||||
return nil, errors.New("Interval must be at least 5")
|
||||
}
|
||||
|
||||
if c.FinalMask.QuicParams.InitStreamReceiveWindow > 0 && c.FinalMask.QuicParams.InitStreamReceiveWindow < 16384 {
|
||||
return nil, errors.New("InitStreamReceiveWindow must be at least 16384")
|
||||
}
|
||||
if c.FinalMask.QuicParams.MaxStreamReceiveWindow > 0 && c.FinalMask.QuicParams.MaxStreamReceiveWindow < 16384 {
|
||||
return nil, errors.New("MaxStreamReceiveWindow must be at least 16384")
|
||||
}
|
||||
if c.FinalMask.QuicParams.InitConnectionReceiveWindow > 0 && c.FinalMask.QuicParams.InitConnectionReceiveWindow < 16384 {
|
||||
return nil, errors.New("InitConnectionReceiveWindow must be at least 16384")
|
||||
}
|
||||
if c.FinalMask.QuicParams.MaxConnectionReceiveWindow > 0 && c.FinalMask.QuicParams.MaxConnectionReceiveWindow < 16384 {
|
||||
return nil, errors.New("MaxConnectionReceiveWindow must be at least 16384")
|
||||
}
|
||||
if c.FinalMask.QuicParams.MaxIdleTimeout != 0 && (c.FinalMask.QuicParams.MaxIdleTimeout < 4 || c.FinalMask.QuicParams.MaxIdleTimeout > 120) {
|
||||
return nil, errors.New("MaxIdleTimeout must be between 4 and 120")
|
||||
}
|
||||
if c.FinalMask.QuicParams.KeepAlivePeriod != 0 && (c.FinalMask.QuicParams.KeepAlivePeriod < 2 || c.FinalMask.QuicParams.KeepAlivePeriod > 60) {
|
||||
return nil, errors.New("KeepAlivePeriod must be between 2 and 60")
|
||||
}
|
||||
if c.FinalMask.QuicParams.MaxIncomingStreams != 0 && c.FinalMask.QuicParams.MaxIncomingStreams < 8 {
|
||||
return nil, errors.New("MaxIncomingStreams must be at least 8")
|
||||
}
|
||||
|
||||
if c.FinalMask.QuicParams.Debug {
|
||||
os.Setenv("HYSTERIA_BBR_DEBUG", "true")
|
||||
os.Setenv("HYSTERIA_BRUTAL_DEBUG", "true")
|
||||
}
|
||||
|
||||
config.QuicParams = &internet.QuicParams{
|
||||
Congestion: c.FinalMask.QuicParams.Congestion,
|
||||
Up: up,
|
||||
BrutalUp: up,
|
||||
BrutalDown: down,
|
||||
UdpHop: &internet.UdpHop{
|
||||
Ports: hop.Build().Ports(),
|
||||
IntervalMin: inertvalMin,
|
||||
IntervalMax: inertvalMax,
|
||||
},
|
||||
InitStreamReceiveWindow: c.FinalMask.QuicParams.InitStreamReceiveWindow,
|
||||
MaxStreamReceiveWindow: c.FinalMask.QuicParams.MaxStreamReceiveWindow,
|
||||
InitConnReceiveWindow: c.FinalMask.QuicParams.InitConnectionReceiveWindow,
|
||||
MaxConnReceiveWindow: c.FinalMask.QuicParams.MaxConnectionReceiveWindow,
|
||||
MaxIdleTimeout: c.FinalMask.QuicParams.MaxIdleTimeout,
|
||||
KeepAlivePeriod: c.FinalMask.QuicParams.KeepAlivePeriod,
|
||||
DisablePathMtuDiscovery: c.FinalMask.QuicParams.DisablePathMTUDiscovery,
|
||||
MaxIncomingStreams: c.FinalMask.QuicParams.MaxIncomingStreams,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user