Merge branch 'dev' of https://github.com/Dreamacro/clash into Alpha
This commit is contained in:
@ -36,6 +36,7 @@ import (
|
||||
"github.com/Dreamacro/clash/log"
|
||||
T "github.com/Dreamacro/clash/tunnel"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@ -68,8 +69,6 @@ type Inbound struct {
|
||||
MixedPort int `json:"mixed-port"`
|
||||
ShadowSocksConfig string `json:"ss-config"`
|
||||
VmessConfig string `json:"vmess-config"`
|
||||
TcpTunConfig string `json:"tcptun-config"`
|
||||
UdpTunConfig string `json:"udptun-config"`
|
||||
Authentication []string `json:"authentication"`
|
||||
AllowLan bool `json:"allow-lan"`
|
||||
BindAddress string `json:"bind-address"`
|
||||
@ -247,6 +246,7 @@ type Config struct {
|
||||
Proxies map[string]C.Proxy
|
||||
Providers map[string]providerTypes.ProxyProvider
|
||||
RuleProviders map[string]providerTypes.RuleProvider
|
||||
Tunnels []Tunnel
|
||||
Sniffer *Sniffer
|
||||
}
|
||||
|
||||
@ -314,6 +314,64 @@ type RawTuicServer struct {
|
||||
MaxUdpRelayPacketSize int `yaml:"max-udp-relay-packet-size" json:"max-udp-relay-packet-size,omitempty"`
|
||||
}
|
||||
|
||||
type tunnel struct {
|
||||
Network []string `yaml:"network"`
|
||||
Address string `yaml:"address"`
|
||||
Target string `yaml:"target"`
|
||||
Proxy string `yaml:"proxy"`
|
||||
}
|
||||
|
||||
type Tunnel tunnel
|
||||
|
||||
// UnmarshalYAML implements yaml.Unmarshaler
|
||||
func (t *Tunnel) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
var tp string
|
||||
if err := unmarshal(&tp); err != nil {
|
||||
var inner tunnel
|
||||
if err := unmarshal(&inner); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*t = Tunnel(inner)
|
||||
return nil
|
||||
}
|
||||
|
||||
// parse udp/tcp,address,target,proxy
|
||||
parts := lo.Map(strings.Split(tp, ","), func(s string, _ int) string {
|
||||
return strings.TrimSpace(s)
|
||||
})
|
||||
if len(parts) != 4 {
|
||||
return fmt.Errorf("invalid tunnel config %s", tp)
|
||||
}
|
||||
network := strings.Split(parts[0], "/")
|
||||
|
||||
// validate network
|
||||
for _, n := range network {
|
||||
switch n {
|
||||
case "tcp", "udp":
|
||||
default:
|
||||
return fmt.Errorf("invalid tunnel network %s", n)
|
||||
}
|
||||
}
|
||||
|
||||
// validate address and target
|
||||
address := parts[1]
|
||||
target := parts[2]
|
||||
for _, addr := range []string{address, target} {
|
||||
if _, _, err := net.SplitHostPort(addr); err != nil {
|
||||
return fmt.Errorf("invalid tunnel target or address %s", addr)
|
||||
}
|
||||
}
|
||||
|
||||
*t = Tunnel(tunnel{
|
||||
Network: network,
|
||||
Address: address,
|
||||
Target: target,
|
||||
Proxy: parts[3],
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
type RawConfig struct {
|
||||
Port int `yaml:"port"`
|
||||
SocksPort int `yaml:"socks-port"`
|
||||
@ -322,8 +380,6 @@ type RawConfig struct {
|
||||
MixedPort int `yaml:"mixed-port"`
|
||||
ShadowSocksConfig string `yaml:"ss-config"`
|
||||
VmessConfig string `yaml:"vmess-config"`
|
||||
TcpTunConfig string `yaml:"tcptun-config"`
|
||||
UdpTunConfig string `yaml:"udptun-config"`
|
||||
InboundTfo bool `yaml:"inbound-tfo"`
|
||||
Authentication []string `yaml:"authentication"`
|
||||
AllowLan bool `yaml:"allow-lan"`
|
||||
@ -337,6 +393,7 @@ type RawConfig struct {
|
||||
Secret string `yaml:"secret"`
|
||||
Interface string `yaml:"interface-name"`
|
||||
RoutingMark int `yaml:"routing-mark"`
|
||||
Tunnels []Tunnel `yaml:"tunnels"`
|
||||
GeodataMode bool `yaml:"geodata-mode"`
|
||||
GeodataLoader string `yaml:"geodata-loader"`
|
||||
TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"`
|
||||
@ -560,6 +617,14 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
||||
|
||||
config.Users = parseAuthentication(rawCfg.Authentication)
|
||||
|
||||
config.Tunnels = rawCfg.Tunnels
|
||||
// verify tunnels
|
||||
for _, t := range config.Tunnels {
|
||||
if _, ok := config.Proxies[t.Proxy]; !ok {
|
||||
return nil, fmt.Errorf("tunnel proxy %s not found", t.Proxy)
|
||||
}
|
||||
}
|
||||
|
||||
config.Sniffer, err = parseSniffer(rawCfg.Sniffer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -567,6 +632,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
||||
|
||||
elapsedTime := time.Since(startTime) / time.Millisecond // duration in ms
|
||||
log.Infoln("Initial configuration complete, total time: %dms", elapsedTime) //Segment finished in xxm
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
@ -591,8 +657,6 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
||||
MixedPort: cfg.MixedPort,
|
||||
ShadowSocksConfig: cfg.ShadowSocksConfig,
|
||||
VmessConfig: cfg.VmessConfig,
|
||||
TcpTunConfig: cfg.TcpTunConfig,
|
||||
UdpTunConfig: cfg.UdpTunConfig,
|
||||
AllowLan: cfg.AllowLan,
|
||||
BindAddress: cfg.BindAddress,
|
||||
InboundTfo: cfg.InboundTfo,
|
||||
|
Reference in New Issue
Block a user