diff --git a/infra/conf/shadowsocks.go b/infra/conf/shadowsocks.go index 19dd035f..32e4bb9d 100644 --- a/infra/conf/shadowsocks.go +++ b/infra/conf/shadowsocks.go @@ -4,9 +4,12 @@ import ( "strings" "github.com/golang/protobuf/proto" + C "github.com/sagernet/sing/common" + "github.com/sagernet/sing/protocol/shadowsocks/shadowaead_2022" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/proxy/shadowsocks" + "github.com/xtls/xray-core/proxy/shadowsocks_2022" ) func cipherFromString(c string) shadowsocks.CipherType { @@ -44,6 +47,17 @@ type ShadowsocksServerConfig struct { } func (v *ShadowsocksServerConfig) Build() (proto.Message, error) { + if C.Contains(shadowaead_2022.List, v.Cipher) { + config := new(shadowsocks_2022.ServerConfig) + config.Method = v.Cipher + config.Key = v.Password + config.Network = v.NetworkList.Build() + if len(v.Users) == 0 { + return nil, newError("shadowsocks 2022 ciphers accept no users.") + } + return config, nil + } + config := new(shadowsocks.ServerConfig) config.Network = v.NetworkList.Build() @@ -104,14 +118,38 @@ type ShadowsocksClientConfig struct { } func (v *ShadowsocksClientConfig) Build() (proto.Message, error) { - config := new(shadowsocks.ClientConfig) - if len(v.Servers) == 0 { return nil, newError("0 Shadowsocks server configured.") } + if len(v.Servers) == 1 { + server := v.Servers[0] + if C.Contains(shadowaead_2022.List, server.Cipher) { + if server.Address == nil { + return nil, newError("Shadowsocks server address is not set.") + } + if server.Port == 0 { + return nil, newError("Invalid Shadowsocks port.") + } + if server.Password == "" { + return nil, newError("Shadowsocks password is not specified.") + } + + config := new(shadowsocks_2022.ClientConfig) + config.Address = server.Address.Build() + config.Port = uint32(server.Port) + config.Method = server.Cipher + config.Key = server.Password + return config, nil + } + } + + config := new(shadowsocks.ClientConfig) serverSpecs := make([]*protocol.ServerEndpoint, len(v.Servers)) for idx, server := range v.Servers { + if C.Contains(shadowaead_2022.List, server.Cipher) { + return nil, newError("Shadowsocks 2022 accept no multi servers") + } if server.Address == nil { return nil, newError("Shadowsocks server address is not set.") } diff --git a/infra/conf/shadowsocks_2022.go b/infra/conf/shadowsocks_2022.go deleted file mode 100644 index 594e2af9..00000000 --- a/infra/conf/shadowsocks_2022.go +++ /dev/null @@ -1,46 +0,0 @@ -package conf - -import ( - "github.com/golang/protobuf/proto" - "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/proxy/shadowsocks_2022" -) - -type Shadowsocks2022ServerConfig struct { - Cipher string `json:"method"` - Key string `json:"key"` - NetworkList *NetworkList `json:"network"` -} - -func (v *Shadowsocks2022ServerConfig) Build() (proto.Message, error) { - var network []net.Network - if v.NetworkList != nil { - network = v.NetworkList.Build() - } - return &shadowsocks_2022.ServerConfig{ - Method: v.Cipher, - Key: v.Key, - Network: network, - }, nil -} - -type Shadowsocks2022ClientConfig struct { - Address *Address `json:"address"` - Port uint16 `json:"port"` - Cipher string `json:"method"` - Key string `json:"key"` - ReducedIvHeadEntropy bool `json:"reducedIvHeadEntropy"` -} - -func (v *Shadowsocks2022ClientConfig) Build() (proto.Message, error) { - if v.Address == nil { - return nil, newError("shadowsocks 2022: missing server address") - } - return &shadowsocks_2022.ClientConfig{ - Address: v.Address.Build(), - Port: uint32(v.Port), - Method: v.Cipher, - Key: v.Key, - ReducedIvHeadEntropy: v.ReducedIvHeadEntropy, - }, nil -} diff --git a/infra/conf/xray.go b/infra/conf/xray.go index a47d59ba..76f00804 100644 --- a/infra/conf/xray.go +++ b/infra/conf/xray.go @@ -18,30 +18,28 @@ import ( var ( inboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{ - "dokodemo-door": func() interface{} { return new(DokodemoConfig) }, - "http": func() interface{} { return new(HTTPServerConfig) }, - "shadowsocks": func() interface{} { return new(ShadowsocksServerConfig) }, - "socks": func() interface{} { return new(SocksServerConfig) }, - "vless": func() interface{} { return new(VLessInboundConfig) }, - "vmess": func() interface{} { return new(VMessInboundConfig) }, - "trojan": func() interface{} { return new(TrojanServerConfig) }, - "mtproto": func() interface{} { return new(MTProtoServerConfig) }, - "shadowsocks-2022": func() interface{} { return new(Shadowsocks2022ServerConfig) }, + "dokodemo-door": func() interface{} { return new(DokodemoConfig) }, + "http": func() interface{} { return new(HTTPServerConfig) }, + "shadowsocks": func() interface{} { return new(ShadowsocksServerConfig) }, + "socks": func() interface{} { return new(SocksServerConfig) }, + "vless": func() interface{} { return new(VLessInboundConfig) }, + "vmess": func() interface{} { return new(VMessInboundConfig) }, + "trojan": func() interface{} { return new(TrojanServerConfig) }, + "mtproto": func() interface{} { return new(MTProtoServerConfig) }, }, "protocol", "settings") outboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{ - "blackhole": func() interface{} { return new(BlackholeConfig) }, - "loopback": func() interface{} { return new(LoopbackConfig) }, - "freedom": func() interface{} { return new(FreedomConfig) }, - "http": func() interface{} { return new(HTTPClientConfig) }, - "shadowsocks": func() interface{} { return new(ShadowsocksClientConfig) }, - "socks": func() interface{} { return new(SocksClientConfig) }, - "vless": func() interface{} { return new(VLessOutboundConfig) }, - "vmess": func() interface{} { return new(VMessOutboundConfig) }, - "trojan": func() interface{} { return new(TrojanClientConfig) }, - "mtproto": func() interface{} { return new(MTProtoClientConfig) }, - "dns": func() interface{} { return new(DNSOutboundConfig) }, - "shadowsocks-2022": func() interface{} { return new(Shadowsocks2022ClientConfig) }, + "blackhole": func() interface{} { return new(BlackholeConfig) }, + "loopback": func() interface{} { return new(LoopbackConfig) }, + "freedom": func() interface{} { return new(FreedomConfig) }, + "http": func() interface{} { return new(HTTPClientConfig) }, + "shadowsocks": func() interface{} { return new(ShadowsocksClientConfig) }, + "socks": func() interface{} { return new(SocksClientConfig) }, + "vless": func() interface{} { return new(VLessOutboundConfig) }, + "vmess": func() interface{} { return new(VMessOutboundConfig) }, + "trojan": func() interface{} { return new(TrojanClientConfig) }, + "mtproto": func() interface{} { return new(MTProtoClientConfig) }, + "dns": func() interface{} { return new(DNSOutboundConfig) }, }, "protocol", "settings") ctllog = log.New(os.Stderr, "xctl> ", 0)