Proxy: Add Hysteria 2 inbound & transport (supports listening port range, Salamander finalmask) (#5679)

https://github.com/XTLS/Xray-core/pull/5679#issuecomment-3888548778

Closes https://github.com/XTLS/Xray-core/issues/5605
This commit is contained in:
LjhAUMEM
2026-02-12 22:56:06 +08:00
committed by GitHub
parent 7abad3fac0
commit 6a909b2507
20 changed files with 1341 additions and 85 deletions

View File

@@ -3,7 +3,9 @@ package conf
import (
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/proxy/hysteria"
"github.com/xtls/xray-core/proxy/hysteria/account"
"google.golang.org/protobuf/proto"
)
@@ -27,3 +29,33 @@ func (c *HysteriaClientConfig) Build() (proto.Message, error) {
return config, nil
}
type HysteriaUserConfig struct {
Auth string `json:"auth"`
Level uint32 `json:"level"`
Email string `json:"email"`
}
type HysteriaServerConfig struct {
Version int32 `json:"version"`
Users []*HysteriaUserConfig `json:"clients"`
}
func (c *HysteriaServerConfig) Build() (proto.Message, error) {
config := new(hysteria.ServerConfig)
if c.Users != nil {
for _, user := range c.Users {
account := &account.Account{
Auth: user.Auth,
}
config.Users = append(config.Users, &protocol.User{
Email: user.Email,
Level: user.Level,
Account: serial.ToTypedMessage(account),
})
}
}
return config, nil
}

View File

@@ -508,6 +508,20 @@ type UdpHop struct {
Interval *Int32Range `json:"interval"`
}
type Masquerade struct {
Type string `json:"type"`
Dir string `json:"dir"`
Url string `json:"url"`
RewriteHost bool `json:"rewriteHost"`
Insecure bool `json:"insecure"`
Content string `json:"content"`
Headers map[string]string `json:"headers"`
StatusCode int32 `json:"statusCode"`
}
type HysteriaConfig struct {
Version int32 `json:"version"`
Auth string `json:"auth"`
@@ -523,6 +537,10 @@ type HysteriaConfig struct {
MaxIdleTimeout int64 `json:"maxIdleTimeout"`
KeepAlivePeriod int64 `json:"keepAlivePeriod"`
DisablePathMTUDiscovery bool `json:"disablePathMTUDiscovery"`
MaxIncomingStreams int64 `json:"maxIncomingStreams"`
UdpIdleTimeout int64 `json:"udpIdleTimeout"`
Masquerade Masquerade `json:"masquerade"`
}
func (c *HysteriaConfig) Build() (proto.Message, error) {
@@ -556,10 +574,10 @@ func (c *HysteriaConfig) Build() (proto.Message, error) {
}
if up > 0 && up < 65536 {
return nil, errors.New("Up must be at least 65536 Bps")
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 Bps")
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")
@@ -583,6 +601,12 @@ func (c *HysteriaConfig) Build() (proto.Message, error) {
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")
}
config := &hysteria.Config{}
config.Version = c.Version
@@ -600,6 +624,16 @@ func (c *HysteriaConfig) Build() (proto.Message, error) {
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
config.MasqUrl = c.Masquerade.Url
config.MasqUrlRewriteHost = c.Masquerade.RewriteHost
config.MasqUrlInsecure = c.Masquerade.Insecure
config.MasqString = c.Masquerade.Content
config.MasqStringHeaders = c.Masquerade.Headers
config.MasqStringStatusCode = c.Masquerade.StatusCode
if config.InitStreamReceiveWindow == 0 {
config.InitStreamReceiveWindow = 8388608
@@ -619,6 +653,12 @@ func (c *HysteriaConfig) Build() (proto.Message, error) {
// if config.KeepAlivePeriod == 0 {
// config.KeepAlivePeriod = 10
// }
if config.MaxIncomingStreams == 0 {
config.MaxIncomingStreams = 1024
}
if config.UdpIdleTimeout == 0 {
config.UdpIdleTimeout = 60
}
return config, nil
}

View File

@@ -33,6 +33,7 @@ var (
"vmess": func() interface{} { return new(VMessInboundConfig) },
"trojan": func() interface{} { return new(TrojanServerConfig) },
"wireguard": func() interface{} { return &WireGuardConfig{IsClient: false} },
"hysteria": func() interface{} { return new(HysteriaServerConfig) },
"tun": func() interface{} { return new(TunConfig) },
}, "protocol", "settings")