refactor NodeInfo

This commit is contained in:
yuzuki999
2023-08-19 20:06:42 +08:00
parent 42e86bf94c
commit 42407d5c62
13 changed files with 333 additions and 391 deletions

View File

@@ -6,11 +6,11 @@ import (
)
type AddUsersParams struct {
Tag string
Config *conf.Options
UserInfo []panel.UserInfo
NodeInfo *panel.NodeInfo
Tag string
Users []panel.UserInfo
*panel.NodeInfo
}
type Core interface {
Start() error
Close() error

View File

@@ -5,7 +5,6 @@ import (
"crypto/rand"
"encoding/base64"
"fmt"
"github.com/google/uuid"
"net/netip"
"net/url"
"strconv"
@@ -33,7 +32,7 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
}
listen := option.ListenOptions{
Listen: (*option.ListenAddress)(&addr),
ListenPort: uint16(info.Port),
ListenPort: uint16(info.Common.ServerPort),
ProxyProtocol: c.SingOptions.EnableProxyProtocol,
TCPFastOpen: c.SingOptions.TCPFastOpen,
InboundOptions: option.InboundOptions{
@@ -42,83 +41,56 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
},
}
var tls option.InboundTLSOptions
if info.Tls || info.Type == "hysteria" {
switch info.Security {
case panel.Tls:
if c.CertConfig == nil {
return option.Inbound{}, fmt.Errorf("the CertConfig is not vail")
}
tls.Enabled = true
tls.Insecure = true
tls.ServerName = info.ServerName
switch c.CertConfig.CertMode {
case "none", "":
break // disable
case "reality":
if c.CertConfig.RealityConfig == nil {
return option.Inbound{}, fmt.Errorf("RealityConfig is not valid")
}
rc := c.CertConfig.RealityConfig
tls.ServerName = rc.ServerNames[0]
if len(rc.ShortIds) == 0 {
rc.ShortIds = []string{""}
}
dest, _ := strconv.Atoi(rc.Dest)
mtd, _ := strconv.Atoi(strconv.FormatUint(rc.MaxTimeDiff, 10))
tls.Reality = &option.InboundRealityOptions{
Enabled: true,
ShortID: rc.ShortIds,
PrivateKey: rc.PrivateKey,
MaxTimeDifference: option.Duration(time.Duration(mtd) * time.Second),
Handshake: option.InboundRealityHandshakeOptions{
ServerOptions: option.ServerOptions{
Server: rc.ServerNames[0],
ServerPort: uint16(dest),
},
},
}
case "remote":
if info.ExtraConfig.EnableReality == "true" {
if c.CertConfig.RealityConfig == nil {
return option.Inbound{}, fmt.Errorf("RealityConfig is not valid")
}
rc := info.ExtraConfig.RealityConfig
if len(rc.ShortIds) == 0 {
rc.ShortIds = []string{""}
}
dest, _ := strconv.Atoi(rc.Dest)
mtd, _ := strconv.Atoi(rc.MaxTimeDiff)
tls.Reality = &option.InboundRealityOptions{
Enabled: true,
ShortID: rc.ShortIds,
PrivateKey: rc.PrivateKey,
MaxTimeDifference: option.Duration(time.Duration(mtd) * time.Second),
Handshake: option.InboundRealityHandshakeOptions{
ServerOptions: option.ServerOptions{
Server: rc.ServerNames[0],
ServerPort: uint16(dest),
},
},
}
}
default:
tls.Enabled = true
tls.CertificatePath = c.CertConfig.CertFile
tls.KeyPath = c.CertConfig.KeyFile
}
case panel.Reality:
tls.Enabled = true
v := info.VAllss
tls.ServerName = v.TlsSettings.PrivateKey
if len(v.TlsSettings.ShortIds) == 0 {
v.TlsSettings.ShortIds = []string{""}
}
dest, _ := strconv.Atoi(v.TlsSettings.ServerPort)
mtd, _ := strconv.Atoi(strconv.FormatUint(v.RealityConfig.MaxTimeDiff, 10))
tls.Reality = &option.InboundRealityOptions{
Enabled: true,
ShortID: v.TlsSettings.ShortIds,
PrivateKey: v.TlsSettings.PrivateKey,
MaxTimeDifference: option.Duration(time.Duration(mtd) * time.Second),
Handshake: option.InboundRealityHandshakeOptions{
ServerOptions: option.ServerOptions{
Server: v.TlsSettings.ServerName[0],
ServerPort: uint16(dest),
},
},
}
}
in := option.Inbound{
Tag: tag,
}
switch info.Type {
case "v2ray":
case "vmess", "vless":
n := info.VAllss
t := option.V2RayTransportOptions{
Type: info.Network,
Type: n.Network,
}
switch info.Network {
switch n.Network {
case "tcp":
t.Type = ""
case "ws":
network := WsNetworkConfig{}
err := json.Unmarshal(info.NetworkSettings, &network)
err := json.Unmarshal(n.NetworkSettings, &network)
if err != nil {
return option.Inbound{}, fmt.Errorf("decode NetworkSettings error: %s", err)
}
@@ -141,12 +113,13 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
Headers: h,
}
case "grpc":
err := json.Unmarshal(info.NetworkSettings, &t.GRPCOptions)
err := json.Unmarshal(n.NetworkSettings, &t.GRPCOptions)
if err != nil {
return option.Inbound{}, fmt.Errorf("decode NetworkSettings error: %s", err)
}
}
if info.ExtraConfig.EnableVless == "true" {
tls.ServerName = n.ServerName
if info.Type == "vless" {
in.Type = "vless"
in.VLESSOptions = option.VLESSInboundOptions{
ListenOptions: listen,
@@ -163,8 +136,9 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
}
case "shadowsocks":
in.Type = "shadowsocks"
n := info.Shadowsocks
var keyLength int
switch info.Cipher {
switch n.Cipher {
case "2022-blake3-aes-128-gcm":
keyLength = 16
case "2022-blake3-aes-256-gcm":
@@ -174,13 +148,13 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
}
in.ShadowsocksOptions = option.ShadowsocksInboundOptions{
ListenOptions: listen,
Method: info.Cipher,
Method: n.Cipher,
}
p := make([]byte, keyLength)
_, _ = rand.Read(p)
randomPasswd := string(p)
if strings.Contains(info.Cipher, "2022") {
in.ShadowsocksOptions.Password = info.ServerKey
if strings.Contains(n.Cipher, "2022") {
in.ShadowsocksOptions.Password = n.ServerKey
randomPasswd = base64.StdEncoding.EncodeToString([]byte(randomPasswd))
}
in.ShadowsocksOptions.Users = []option.ShadowsocksUser{{
@@ -188,27 +162,9 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
}}
case "trojan":
in.Type = "trojan"
t := option.V2RayTransportOptions{
Type: info.Network,
}
switch info.Network {
case "tcp":
t.Type = ""
case "grpc":
err := json.Unmarshal(info.NetworkSettings, &t.GRPCOptions)
if err != nil {
return option.Inbound{}, fmt.Errorf("decode NetworkSettings error: %s", err)
}
}
randomPasswd := uuid.New().String()
in.TrojanOptions = option.TrojanInboundOptions{
ListenOptions: listen,
Users: []option.TrojanUser{{
Name: randomPasswd,
Password: randomPasswd,
}},
TLS: &tls,
Transport: &t,
TLS: &tls,
}
if c.SingOptions.FallBackConfigs != nil {
// fallback handling
@@ -230,9 +186,9 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
in.Type = "hysteria"
in.HysteriaOptions = option.HysteriaInboundOptions{
ListenOptions: listen,
UpMbps: info.UpMbps,
DownMbps: info.DownMbps,
Obfs: info.HyObfs,
UpMbps: info.Hysteria.UpMbps,
DownMbps: info.Hysteria.DownMbps,
Obfs: info.Hysteria.Obfs,
TLS: &tls,
}
}

View File

@@ -264,7 +264,8 @@ func (b *Box) Router() adapter.Router {
func (b *Box) Protocols() []string {
return []string{
"v2ray",
"vmess",
"vless",
"shadowsocks",
"trojan",
"hysteria",

View File

@@ -13,58 +13,58 @@ import (
func (b *Box) AddUsers(p *core.AddUsersParams) (added int, err error) {
switch p.NodeInfo.Type {
case "v2ray":
if p.NodeInfo.ExtraConfig.EnableVless == "true" {
us := make([]option.VLESSUser, len(p.UserInfo))
for i := range p.UserInfo {
case "vmess", "vless":
if p.NodeInfo.Type == "vless" {
us := make([]option.VLESSUser, len(p.Users))
for i := range p.Users {
us[i] = option.VLESSUser{
Name: p.UserInfo[i].Uuid,
Flow: p.NodeInfo.ExtraConfig.VlessFlow,
UUID: p.UserInfo[i].Uuid,
Name: p.Users[i].Uuid,
Flow: p.VAllss.Flow,
UUID: p.Users[i].Uuid,
}
}
err = b.inbounds[p.Tag].(*inbound.VLESS).AddUsers(us)
} else {
us := make([]option.VMessUser, len(p.UserInfo))
for i := range p.UserInfo {
us := make([]option.VMessUser, len(p.Users))
for i := range p.Users {
us[i] = option.VMessUser{
Name: p.UserInfo[i].Uuid,
UUID: p.UserInfo[i].Uuid,
Name: p.Users[i].Uuid,
UUID: p.Users[i].Uuid,
}
}
err = b.inbounds[p.Tag].(*inbound.VMess).AddUsers(us)
}
case "shadowsocks":
us := make([]option.ShadowsocksUser, len(p.UserInfo))
for i := range p.UserInfo {
var password = p.UserInfo[i].Uuid
switch p.NodeInfo.Cipher {
us := make([]option.ShadowsocksUser, len(p.Users))
for i := range p.Users {
var password = p.Users[i].Uuid
switch p.Shadowsocks.Cipher {
case "2022-blake3-aes-128-gcm":
password = base64.StdEncoding.EncodeToString([]byte(password[:16]))
case "2022-blake3-aes-256-gcm":
password = base64.StdEncoding.EncodeToString([]byte(password[:32]))
}
us[i] = option.ShadowsocksUser{
Name: p.UserInfo[i].Uuid,
Name: p.Users[i].Uuid,
Password: password,
}
}
err = b.inbounds[p.Tag].(*inbound.ShadowsocksMulti).AddUsers(us)
case "trojan":
us := make([]option.TrojanUser, len(p.UserInfo))
for i := range p.UserInfo {
us := make([]option.TrojanUser, len(p.Users))
for i := range p.Users {
us[i] = option.TrojanUser{
Name: p.UserInfo[i].Uuid,
Password: p.UserInfo[i].Uuid,
Name: p.Users[i].Uuid,
Password: p.Users[i].Uuid,
}
}
err = b.inbounds[p.Tag].(*inbound.Trojan).AddUsers(us)
case "hysteria":
us := make([]option.HysteriaUser, len(p.UserInfo))
for i := range p.UserInfo {
us := make([]option.HysteriaUser, len(p.Users))
for i := range p.Users {
us[i] = option.HysteriaUser{
Name: p.UserInfo[i].Uuid,
AuthString: p.UserInfo[i].Uuid,
Name: p.Users[i].Uuid,
AuthString: p.Users[i].Uuid,
}
}
err = b.inbounds[p.Tag].(*inbound.Hysteria).AddUsers(us)
@@ -72,7 +72,7 @@ func (b *Box) AddUsers(p *core.AddUsersParams) (added int, err error) {
if err != nil {
return 0, err
}
return len(p.UserInfo), err
return len(p.Users), err
}
func (b *Box) GetUserTraffic(tag, uuid string, reset bool) (up int64, down int64) {

View File

@@ -6,8 +6,6 @@ import (
"encoding/hex"
"errors"
"fmt"
"strconv"
"github.com/InazumaV/V2bX/api/panel"
"github.com/InazumaV/V2bX/conf"
"github.com/goccy/go-json"
@@ -17,141 +15,121 @@ import (
)
// BuildInbound build Inbound config for different protocol
func buildInbound(config *conf.Options, nodeInfo *panel.NodeInfo, tag string) (*core.InboundHandlerConfig, error) {
func buildInbound(option *conf.Options, nodeInfo *panel.NodeInfo, tag string) (*core.InboundHandlerConfig, error) {
in := &coreConf.InboundDetourConfig{}
// Set network protocol
t := coreConf.TransportProtocol(nodeInfo.Network)
in.StreamSetting = &coreConf.StreamConfig{Network: &t}
var err error
var network string
switch nodeInfo.Type {
case "v2ray":
err = buildV2ray(config, nodeInfo, in)
err = buildV2ray(option, nodeInfo, in)
network = nodeInfo.VAllss.Network
case "trojan":
err = buildTrojan(config, in)
err = buildTrojan(option, in)
case "shadowsocks":
err = buildShadowsocks(config, nodeInfo, in)
err = buildShadowsocks(option, nodeInfo, in)
default:
return nil, fmt.Errorf("unsupported node type: %s, Only support: V2ray, Trojan, Shadowsocks", nodeInfo.Type)
}
if err != nil {
return nil, err
}
// Set network protocol
t := coreConf.TransportProtocol(network)
in.StreamSetting = &coreConf.StreamConfig{Network: &t}
// Set server port
in.PortList = &coreConf.PortList{
Range: []coreConf.PortRange{{From: uint32(nodeInfo.Port), To: uint32(nodeInfo.Port)}},
Range: []coreConf.PortRange{
{
From: uint32(nodeInfo.Common.ServerPort),
To: uint32(nodeInfo.Common.ServerPort),
}},
}
// Set Listen IP address
ipAddress := net.ParseAddress(config.ListenIP)
ipAddress := net.ParseAddress(option.ListenIP)
in.ListenOn = &coreConf.Address{Address: ipAddress}
// Set SniffingConfig
sniffingConfig := &coreConf.SniffingConfig{
Enabled: true,
DestOverride: &coreConf.StringList{"http", "tls"},
}
if config.XrayOptions.DisableSniffing {
if option.XrayOptions.DisableSniffing {
sniffingConfig.Enabled = false
}
in.SniffingConfig = sniffingConfig
if *in.StreamSetting.Network == "tcp" {
switch network {
case "tcp":
if in.StreamSetting.TCPSettings != nil {
in.StreamSetting.TCPSettings.AcceptProxyProtocol = config.XrayOptions.EnableProxyProtocol
in.StreamSetting.TCPSettings.AcceptProxyProtocol = option.XrayOptions.EnableProxyProtocol
} else {
tcpSetting := &coreConf.TCPConfig{
AcceptProxyProtocol: config.XrayOptions.EnableProxyProtocol,
AcceptProxyProtocol: option.XrayOptions.EnableProxyProtocol,
} //Enable proxy protocol
in.StreamSetting.TCPSettings = tcpSetting
}
} else if *in.StreamSetting.Network == "ws" {
case "ws":
in.StreamSetting.WSSettings = &coreConf.WebSocketConfig{
AcceptProxyProtocol: config.XrayOptions.EnableProxyProtocol} //Enable proxy protocol
}
// Set TLS or Reality settings
if nodeInfo.Tls {
if config.CertConfig == nil {
return nil, errors.New("the CertConfig is not vail")
}
switch config.CertConfig.CertMode {
case "none", "":
break // disable
case "reality":
// Reality
in.StreamSetting.Security = "reality"
d, err := json.Marshal(config.CertConfig.RealityConfig.Dest)
if err != nil {
return nil, fmt.Errorf("marshal reality dest error: %s", err)
}
if len(config.CertConfig.RealityConfig.ShortIds) == 0 {
config.CertConfig.RealityConfig.ShortIds = []string{""}
}
in.StreamSetting.REALITYSettings = &coreConf.REALITYConfig{
Dest: d,
Xver: config.CertConfig.RealityConfig.Xver,
ServerNames: config.CertConfig.RealityConfig.ServerNames,
PrivateKey: config.CertConfig.RealityConfig.PrivateKey,
MinClientVer: config.CertConfig.RealityConfig.MinClientVer,
MaxClientVer: config.CertConfig.RealityConfig.MaxClientVer,
MaxTimeDiff: config.CertConfig.RealityConfig.MaxTimeDiff,
ShortIds: config.CertConfig.RealityConfig.ShortIds,
}
break
case "remote":
if nodeInfo.ExtraConfig.EnableReality == "true" {
rc := nodeInfo.ExtraConfig.RealityConfig
in.StreamSetting.Security = "reality"
d, err := json.Marshal(rc.Dest)
if err != nil {
return nil, fmt.Errorf("marshal reality dest error: %s", err)
}
if len(rc.ShortIds) == 0 {
rc.ShortIds = []string{""}
}
Xver, _ := strconv.ParseUint(rc.Xver, 10, 64)
MaxTimeDiff, _ := strconv.ParseUint(rc.Xver, 10, 64)
in.StreamSetting.REALITYSettings = &coreConf.REALITYConfig{
Dest: d,
Xver: Xver,
ServerNames: rc.ServerNames,
PrivateKey: rc.PrivateKey,
MinClientVer: rc.MinClientVer,
MaxClientVer: rc.MaxClientVer,
MaxTimeDiff: MaxTimeDiff,
ShortIds: rc.ShortIds,
}
break
}
default:
{
// Normal tls
in.StreamSetting.Security = "tls"
in.StreamSetting.TLSSettings = &coreConf.TLSConfig{
Certs: []*coreConf.TLSCertConfig{
{
CertFile: config.CertConfig.CertFile,
KeyFile: config.CertConfig.KeyFile,
OcspStapling: 3600,
},
},
RejectUnknownSNI: config.CertConfig.RejectUnknownSni,
}
}
}
}
// Support ProxyProtocol for any transport protocol
if *in.StreamSetting.Network != "tcp" &&
*in.StreamSetting.Network != "ws" &&
config.XrayOptions.EnableProxyProtocol {
AcceptProxyProtocol: option.XrayOptions.EnableProxyProtocol} //Enable proxy protocol
default:
socketConfig := &coreConf.SocketConfig{
AcceptProxyProtocol: config.XrayOptions.EnableProxyProtocol,
TFO: config.XrayOptions.EnableTFO,
AcceptProxyProtocol: option.XrayOptions.EnableProxyProtocol,
TFO: option.XrayOptions.EnableTFO,
} //Enable proxy protocol
in.StreamSetting.SocketSettings = socketConfig
}
// Set TLS or Reality settings
switch nodeInfo.Security {
case panel.Tls:
// Normal tls
if option.CertConfig == nil {
return nil, errors.New("the CertConfig is not vail")
}
switch option.CertConfig.CertMode {
case "none", "":
break // disable
default:
in.StreamSetting.Security = "tls"
in.StreamSetting.TLSSettings = &coreConf.TLSConfig{
Certs: []*coreConf.TLSCertConfig{
{
CertFile: option.CertConfig.CertFile,
KeyFile: option.CertConfig.KeyFile,
OcspStapling: 3600,
},
},
RejectUnknownSNI: option.CertConfig.RejectUnknownSni,
}
}
case panel.Reality:
// Reality
in.StreamSetting.Security = "reality"
v := nodeInfo.VAllss
d, err := json.Marshal(v.RealityConfig.Dest)
if err != nil {
return nil, fmt.Errorf("marshal reality dest error: %s", err)
}
short := nodeInfo.VAllss.TlsSettings.ShortIds
if len(short) == 0 {
short = []string{""}
}
in.StreamSetting.REALITYSettings = &coreConf.REALITYConfig{
Dest: d,
Xver: v.RealityConfig.Xver,
ServerNames: v.TlsSettings.ServerName,
PrivateKey: v.TlsSettings.PrivateKey,
MinClientVer: v.RealityConfig.MinClientVer,
MaxClientVer: v.RealityConfig.MaxClientVer,
MaxTimeDiff: v.RealityConfig.MaxTimeDiff,
ShortIds: short,
}
break
}
in.Tag = tag
return in.Build()
}
func buildV2ray(config *conf.Options, nodeInfo *panel.NodeInfo, inbound *coreConf.InboundDetourConfig) error {
if nodeInfo.ExtraConfig.EnableVless == "true" {
v := nodeInfo.VAllss
if nodeInfo.Type == "vless" {
//Set vless
inbound.Protocol = "vless"
if config.XrayOptions.EnableFallback {
@@ -188,22 +166,22 @@ func buildV2ray(config *conf.Options, nodeInfo *panel.NodeInfo, inbound *coreCon
}
inbound.Settings = (*json.RawMessage)(&s)
}
if len(nodeInfo.NetworkSettings) == 0 {
if len(v.NetworkSettings) == 0 {
return nil
}
switch nodeInfo.Network {
switch v.Network {
case "tcp":
err := json.Unmarshal(nodeInfo.NetworkSettings, &inbound.StreamSetting.TCPSettings)
err := json.Unmarshal(v.NetworkSettings, &inbound.StreamSetting.TCPSettings)
if err != nil {
return fmt.Errorf("unmarshal tcp settings error: %s", err)
}
case "ws":
err := json.Unmarshal(nodeInfo.NetworkSettings, &inbound.StreamSetting.WSSettings)
err := json.Unmarshal(v.NetworkSettings, &inbound.StreamSetting.WSSettings)
if err != nil {
return fmt.Errorf("unmarshal ws settings error: %s", err)
}
case "grpc":
err := json.Unmarshal(nodeInfo.NetworkSettings, &inbound.StreamSetting.GRPCConfig)
err := json.Unmarshal(v.NetworkSettings, &inbound.StreamSetting.GRPCConfig)
if err != nil {
return fmt.Errorf("unmarshal grpc settings error: %s", err)
}
@@ -239,8 +217,9 @@ func buildTrojan(config *conf.Options, inbound *coreConf.InboundDetourConfig) er
func buildShadowsocks(config *conf.Options, nodeInfo *panel.NodeInfo, inbound *coreConf.InboundDetourConfig) error {
inbound.Protocol = "shadowsocks"
s := nodeInfo.Shadowsocks
settings := &coreConf.ShadowsocksServerConfig{
Cipher: nodeInfo.Cipher,
Cipher: s.Cipher,
}
p := make([]byte, 32)
_, err := rand.Read(p)
@@ -248,9 +227,9 @@ func buildShadowsocks(config *conf.Options, nodeInfo *panel.NodeInfo, inbound *c
return fmt.Errorf("generate random password error: %s", err)
}
randomPasswd := hex.EncodeToString(p)
cipher := nodeInfo.Cipher
if nodeInfo.ServerKey != "" {
settings.Password = nodeInfo.ServerKey
cipher := s.Cipher
if s.ServerKey != "" {
settings.Password = s.ServerKey
randomPasswd = base64.StdEncoding.EncodeToString([]byte(randomPasswd))
cipher = ""
}
@@ -266,8 +245,8 @@ func buildShadowsocks(config *conf.Options, nodeInfo *panel.NodeInfo, inbound *c
}
t := coreConf.TransportProtocol("tcp")
inbound.StreamSetting = &coreConf.StreamConfig{Network: &t}
s, err := json.Marshal(settings)
inbound.Settings = (*json.RawMessage)(&s)
sets, err := json.Marshal(settings)
inbound.Settings = (*json.RawMessage)(&sets)
if err != nil {
return fmt.Errorf("marshal shadowsocks settings error: %s", err)
}

View File

@@ -71,21 +71,19 @@ func (c *Core) GetUserTraffic(tag, uuid string, reset bool) (up int64, down int6
}
func (c *Core) AddUsers(p *vCore.AddUsersParams) (added int, err error) {
users := make([]*protocol.User, 0, len(p.UserInfo))
users := make([]*protocol.User, 0, len(p.Users))
switch p.NodeInfo.Type {
case "v2ray":
if p.NodeInfo.ExtraConfig.EnableVless == "true" {
users = buildVlessUsers(p.Tag, p.UserInfo, p.NodeInfo.ExtraConfig.VlessFlow)
} else {
users = buildVmessUsers(p.Tag, p.UserInfo)
}
case "vmess":
users = buildVmessUsers(p.Tag, p.Users)
case "vless":
users = buildVlessUsers(p.Tag, p.Users, p.VAllss.Flow)
case "trojan":
users = buildTrojanUsers(p.Tag, p.UserInfo)
users = buildTrojanUsers(p.Tag, p.Users)
case "shadowsocks":
users = buildSSUsers(p.Tag,
p.UserInfo,
p.NodeInfo.Cipher,
p.NodeInfo.ServerKey)
p.Users,
p.Shadowsocks.Cipher,
p.Shadowsocks.ServerKey)
default:
return 0, fmt.Errorf("unsupported node type: %s", p.NodeInfo.Type)
}

View File

@@ -188,7 +188,8 @@ func (c *Core) Close() error {
func (c *Core) Protocols() []string {
return []string{
"v2ray",
"vmess",
"vless",
"shadowsocks",
"trojan",
}