From 99effb051bbe79dc708943f71fd2ba3dc7056cf2 Mon Sep 17 00:00:00 2001 From: Skyxim Date: Sun, 28 Aug 2022 13:41:19 +0800 Subject: [PATCH 01/22] feat: add ip-version param --- adapter/outbound/base.go | 42 ++++++--- adapter/outbound/direct.go | 14 +-- adapter/outbound/http.go | 11 ++- adapter/outbound/hysteria.go | 29 ++++-- adapter/outbound/reject.go | 14 +-- adapter/outbound/shadowsocks.go | 15 +-- adapter/outbound/shadowsocksr.go | 15 +-- adapter/outbound/snell.go | 13 +-- adapter/outbound/socks5.go | 13 +-- adapter/outbound/trojan.go | 13 +-- adapter/outbound/util.go | 54 +++++++++++ adapter/outbound/vless.go | 11 ++- adapter/outbound/vmess.go | 13 +-- component/dialer/dialer.go | 121 +++++++++++++++++++------ component/dialer/options.go | 28 +++++- component/resolver/resolver.go | 48 +--------- constant/dns.go | 43 +++++++++ dns/resolver.go | 2 +- docs/config.yaml | 97 +++++++++++--------- transport/hysteria/transport/client.go | 18 +--- 20 files changed, 398 insertions(+), 216 deletions(-) diff --git a/adapter/outbound/base.go b/adapter/outbound/base.go index 0666d306..1112732e 100644 --- a/adapter/outbound/base.go +++ b/adapter/outbound/base.go @@ -13,13 +13,14 @@ import ( ) type Base struct { - name string - addr string - iface string - tp C.AdapterType - udp bool - rmark int - id string + name string + addr string + iface string + tp C.AdapterType + udp bool + rmark int + id string + prefer C.DNSPrefer } // Name implements C.ProxyAdapter @@ -103,12 +104,25 @@ func (b *Base) DialOptions(opts ...dialer.Option) []dialer.Option { opts = append(opts, dialer.WithRoutingMark(b.rmark)) } + switch b.prefer { + case C.IPv4Only: + opts = append(opts, dialer.WithOnlySingleStack(true)) + case C.IPv6Only: + opts = append(opts, dialer.WithOnlySingleStack(false)) + case C.IPv4Prefer: + opts = append(opts, dialer.WithPreferIPv4()) + case C.IPv6Prefer: + opts = append(opts, dialer.WithPreferIPv6()) + default: + } + return opts } type BasicOption struct { Interface string `proxy:"interface-name,omitempty" group:"interface-name,omitempty"` RoutingMark int `proxy:"routing-mark,omitempty" group:"routing-mark,omitempty"` + IPVersion string `proxy:"ip-version,omitempty" group:"ip-version,omitempty"` } type BaseOption struct { @@ -118,16 +132,18 @@ type BaseOption struct { UDP bool Interface string RoutingMark int + Prefer C.DNSPrefer } func NewBase(opt BaseOption) *Base { return &Base{ - name: opt.Name, - addr: opt.Addr, - tp: opt.Type, - udp: opt.UDP, - iface: opt.Interface, - rmark: opt.RoutingMark, + name: opt.Name, + addr: opt.Addr, + tp: opt.Type, + udp: opt.UDP, + iface: opt.Interface, + rmark: opt.RoutingMark, + prefer: opt.Prefer, } } diff --git a/adapter/outbound/direct.go b/adapter/outbound/direct.go index f7c88124..fdbbcb62 100644 --- a/adapter/outbound/direct.go +++ b/adapter/outbound/direct.go @@ -40,9 +40,10 @@ type directPacketConn struct { func NewDirect() *Direct { return &Direct{ Base: &Base{ - name: "DIRECT", - tp: C.Direct, - udp: true, + name: "DIRECT", + tp: C.Direct, + udp: true, + prefer: C.DualStack, }, } } @@ -50,9 +51,10 @@ func NewDirect() *Direct { func NewCompatible() *Direct { return &Direct{ Base: &Base{ - name: "COMPATIBLE", - tp: C.Compatible, - udp: true, + name: "COMPATIBLE", + tp: C.Compatible, + udp: true, + prefer: C.DualStack, }, } } diff --git a/adapter/outbound/http.go b/adapter/outbound/http.go index e8ff3e96..ae4fd75b 100644 --- a/adapter/outbound/http.go +++ b/adapter/outbound/http.go @@ -153,11 +153,12 @@ func NewHttp(option HttpOption) (*Http, error) { return &Http{ Base: &Base{ - name: option.Name, - addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)), - tp: C.Http, - iface: option.Interface, - rmark: option.RoutingMark, + name: option.Name, + addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)), + tp: C.Http, + iface: option.Interface, + rmark: option.RoutingMark, + prefer: C.NewDNSPrefer(option.IPVersion), }, user: option.UserName, pass: option.Password, diff --git a/adapter/outbound/hysteria.go b/adapter/outbound/hysteria.go index 5485d2b4..adc904a2 100644 --- a/adapter/outbound/hysteria.go +++ b/adapter/outbound/hysteria.go @@ -53,6 +53,9 @@ func (h *Hysteria) DialContext(ctx context.Context, metadata *C.Metadata, opts . hyDialer: func() (net.PacketConn, error) { return dialer.ListenPacket(ctx, "udp", "", h.Base.DialOptions(opts...)...) }, + remoteAddr: func(addr string) (net.Addr, error) { + return resolveUDPAddrWithPrefer("udp", addr, h.prefer) + }, } tcpConn, err := h.client.DialTCP(metadata.RemoteAddress(), &hdc) @@ -184,11 +187,11 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) { option.Protocol = DefaultProtocol } if option.ReceiveWindowConn == 0 { - quicConfig.InitialStreamReceiveWindow = DefaultStreamReceiveWindow + quicConfig.InitialStreamReceiveWindow = DefaultStreamReceiveWindow / 10 quicConfig.MaxStreamReceiveWindow = DefaultStreamReceiveWindow } if option.ReceiveWindow == 0 { - quicConfig.InitialConnectionReceiveWindow = DefaultConnectionReceiveWindow + quicConfig.InitialConnectionReceiveWindow = DefaultConnectionReceiveWindow / 10 quicConfig.MaxConnectionReceiveWindow = DefaultConnectionReceiveWindow } if !quicConfig.DisablePathMTUDiscovery && pmtud_fix.DisablePathMTUDiscovery { @@ -216,12 +219,13 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) { } return &Hysteria{ Base: &Base{ - name: option.Name, - addr: addr, - tp: C.Hysteria, - udp: true, - iface: option.Interface, - rmark: option.RoutingMark, + name: option.Name, + addr: addr, + tp: C.Hysteria, + udp: true, + iface: option.Interface, + rmark: option.RoutingMark, + prefer: C.NewDNSPrefer(option.IPVersion), }, client: client, }, nil @@ -287,8 +291,9 @@ func (c *hyPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { } type hyDialerWithContext struct { - hyDialer func() (net.PacketConn, error) - ctx context.Context + hyDialer func() (net.PacketConn, error) + ctx context.Context + remoteAddr func(host string) (net.Addr, error) } func (h *hyDialerWithContext) ListenPacket() (net.PacketConn, error) { @@ -298,3 +303,7 @@ func (h *hyDialerWithContext) ListenPacket() (net.PacketConn, error) { func (h *hyDialerWithContext) Context() context.Context { return h.ctx } + +func (h *hyDialerWithContext) RemoteAddr(host string) (net.Addr, error) { + return h.remoteAddr(host) +} diff --git a/adapter/outbound/reject.go b/adapter/outbound/reject.go index 30ca75ee..43833238 100644 --- a/adapter/outbound/reject.go +++ b/adapter/outbound/reject.go @@ -27,9 +27,10 @@ func (r *Reject) ListenPacketContext(ctx context.Context, metadata *C.Metadata, func NewReject() *Reject { return &Reject{ Base: &Base{ - name: "REJECT", - tp: C.Reject, - udp: true, + name: "REJECT", + tp: C.Reject, + udp: true, + prefer: C.DualStack, }, } } @@ -37,9 +38,10 @@ func NewReject() *Reject { func NewPass() *Reject { return &Reject{ Base: &Base{ - name: "PASS", - tp: C.Pass, - udp: true, + name: "PASS", + tp: C.Pass, + udp: true, + prefer: C.DualStack, }, } } diff --git a/adapter/outbound/shadowsocks.go b/adapter/outbound/shadowsocks.go index fc872835..b26f8802 100644 --- a/adapter/outbound/shadowsocks.go +++ b/adapter/outbound/shadowsocks.go @@ -116,7 +116,7 @@ func (ss *ShadowSocks) ListenPacketContext(ctx context.Context, metadata *C.Meta return nil, err } - addr, err := resolveUDPAddr("udp", ss.addr) + addr, err := resolveUDPAddrWithPrefer("udp", ss.addr, ss.prefer) if err != nil { pc.Close() return nil, err @@ -186,12 +186,13 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) { return &ShadowSocks{ Base: &Base{ - name: option.Name, - addr: addr, - tp: C.Shadowsocks, - udp: option.UDP, - iface: option.Interface, - rmark: option.RoutingMark, + name: option.Name, + addr: addr, + tp: C.Shadowsocks, + udp: option.UDP, + iface: option.Interface, + rmark: option.RoutingMark, + prefer: C.NewDNSPrefer(option.IPVersion), }, method: method, diff --git a/adapter/outbound/shadowsocksr.go b/adapter/outbound/shadowsocksr.go index 57ef5604..6b6b9a98 100644 --- a/adapter/outbound/shadowsocksr.go +++ b/adapter/outbound/shadowsocksr.go @@ -79,7 +79,7 @@ func (ssr *ShadowSocksR) ListenPacketContext(ctx context.Context, metadata *C.Me return nil, err } - addr, err := resolveUDPAddr("udp", ssr.addr) + addr, err := resolveUDPAddrWithPrefer("udp", ssr.addr, ssr.prefer) if err != nil { pc.Close() return nil, err @@ -143,12 +143,13 @@ func NewShadowSocksR(option ShadowSocksROption) (*ShadowSocksR, error) { return &ShadowSocksR{ Base: &Base{ - name: option.Name, - addr: addr, - tp: C.ShadowsocksR, - udp: option.UDP, - iface: option.Interface, - rmark: option.RoutingMark, + name: option.Name, + addr: addr, + tp: C.ShadowsocksR, + udp: option.UDP, + iface: option.Interface, + rmark: option.RoutingMark, + prefer: C.NewDNSPrefer(option.IPVersion), }, cipher: coreCiph, obfs: obfs, diff --git a/adapter/outbound/snell.go b/adapter/outbound/snell.go index 7b272d5d..0aadb1c8 100644 --- a/adapter/outbound/snell.go +++ b/adapter/outbound/snell.go @@ -152,12 +152,13 @@ func NewSnell(option SnellOption) (*Snell, error) { s := &Snell{ Base: &Base{ - name: option.Name, - addr: addr, - tp: C.Snell, - udp: option.UDP, - iface: option.Interface, - rmark: option.RoutingMark, + name: option.Name, + addr: addr, + tp: C.Snell, + udp: option.UDP, + iface: option.Interface, + rmark: option.RoutingMark, + prefer: C.NewDNSPrefer(option.IPVersion), }, psk: psk, obfsOption: obfsOption, diff --git a/adapter/outbound/socks5.go b/adapter/outbound/socks5.go index 4e79d6a9..43900b1e 100644 --- a/adapter/outbound/socks5.go +++ b/adapter/outbound/socks5.go @@ -160,12 +160,13 @@ func NewSocks5(option Socks5Option) (*Socks5, error) { return &Socks5{ Base: &Base{ - name: option.Name, - addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)), - tp: C.Socks5, - udp: option.UDP, - iface: option.Interface, - rmark: option.RoutingMark, + name: option.Name, + addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)), + tp: C.Socks5, + udp: option.UDP, + iface: option.Interface, + rmark: option.RoutingMark, + prefer: C.NewDNSPrefer(option.IPVersion), }, user: option.UserName, pass: option.Password, diff --git a/adapter/outbound/trojan.go b/adapter/outbound/trojan.go index 88c87e22..946a0101 100644 --- a/adapter/outbound/trojan.go +++ b/adapter/outbound/trojan.go @@ -209,12 +209,13 @@ func NewTrojan(option TrojanOption) (*Trojan, error) { t := &Trojan{ Base: &Base{ - name: option.Name, - addr: addr, - tp: C.Trojan, - udp: option.UDP, - iface: option.Interface, - rmark: option.RoutingMark, + name: option.Name, + addr: addr, + tp: C.Trojan, + udp: option.UDP, + iface: option.Interface, + rmark: option.RoutingMark, + prefer: C.NewDNSPrefer(option.IPVersion), }, instance: trojan.New(tOption), option: &option, diff --git a/adapter/outbound/util.go b/adapter/outbound/util.go index 071052a6..de9287bd 100644 --- a/adapter/outbound/util.go +++ b/adapter/outbound/util.go @@ -5,6 +5,7 @@ import ( "crypto/tls" xtls "github.com/xtls/go" "net" + "net/netip" "strconv" "sync" "time" @@ -74,6 +75,59 @@ func resolveUDPAddr(network, address string) (*net.UDPAddr, error) { return net.ResolveUDPAddr(network, net.JoinHostPort(ip.String(), port)) } +func resolveUDPAddrWithPrefer(network, address string, prefer C.DNSPrefer) (*net.UDPAddr, error) { + host, port, err := net.SplitHostPort(address) + if err != nil { + return nil, err + } + var ip netip.Addr + switch prefer { + case C.IPv4Only: + ip, err = resolver.ResolveIPv4ProxyServerHost(host) + case C.IPv6Only: + ip, err = resolver.ResolveIPv6ProxyServerHost(host) + case C.IPv6Prefer: + var ips []netip.Addr + ips, err = resolver.ResolveAllIPProxyServerHost(host) + var fallback netip.Addr + if err == nil { + for _, addr := range ips { + if addr.Is6() { + ip = addr + break + } else { + if !fallback.IsValid() { + fallback = addr + } + } + } + ip = fallback + } + case C.IPv4Prefer | C.DualStack: + var ips []netip.Addr + ips, err = resolver.ResolveAllIPProxyServerHost(host) + var fallback netip.Addr + if err == nil { + for _, addr := range ips { + if addr.Is4() { + ip = addr + break + } else { + if !fallback.IsValid() { + fallback = addr + } + } + } + ip = fallback + } + } + + if err != nil { + return nil, err + } + return net.ResolveUDPAddr(network, net.JoinHostPort(ip.String(), port)) +} + func safeConnClose(c net.Conn, err error) { if err != nil { _ = c.Close() diff --git a/adapter/outbound/vless.go b/adapter/outbound/vless.go index 7c30c0a9..4811de0f 100644 --- a/adapter/outbound/vless.go +++ b/adapter/outbound/vless.go @@ -418,11 +418,12 @@ func NewVless(option VlessOption) (*Vless, error) { v := &Vless{ Base: &Base{ - name: option.Name, - addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)), - tp: C.Vless, - udp: option.UDP, - iface: option.Interface, + name: option.Name, + addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)), + tp: C.Vless, + udp: option.UDP, + iface: option.Interface, + prefer: C.NewDNSPrefer(option.IPVersion), }, client: client, option: &option, diff --git a/adapter/outbound/vmess.go b/adapter/outbound/vmess.go index cf7814f1..fc8e1e87 100644 --- a/adapter/outbound/vmess.go +++ b/adapter/outbound/vmess.go @@ -316,12 +316,13 @@ func NewVmess(option VmessOption) (*Vmess, error) { v := &Vmess{ Base: &Base{ - name: option.Name, - addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)), - tp: C.Vmess, - udp: option.UDP, - iface: option.Interface, - rmark: option.RoutingMark, + name: option.Name, + addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)), + tp: C.Vmess, + udp: option.UDP, + iface: option.Interface, + rmark: option.RoutingMark, + prefer: C.NewDNSPrefer(option.IPVersion), }, client: client, option: &option, diff --git a/component/dialer/dialer.go b/component/dialer/dialer.go index 521479b0..48cc1ce7 100644 --- a/component/dialer/dialer.go +++ b/component/dialer/dialer.go @@ -5,8 +5,10 @@ import ( "errors" "fmt" "github.com/Dreamacro/clash/component/resolver" + "go.uber.org/atomic" "net" "net/netip" + "strings" "sync" ) @@ -16,6 +18,8 @@ var ( actualDualStackDialContext = dualStackDialContext tcpConcurrent = false DisableIPv6 = false + ErrorInvalidedNetworkStack = errors.New("invalided network stack") + ErrorDisableIPv6 = errors.New("IPv6 is disabled, dialer cancel") ) func DialContext(ctx context.Context, network, address string, options ...Option) (net.Conn, error) { @@ -32,13 +36,23 @@ func DialContext(ctx context.Context, network, address string, options ...Option o(opt) } + if opt.network == 4 || opt.network == 6 { + if strings.Contains(network, "tcp") { + network = "tcp" + } else { + network = "udp" + } + + network = fmt.Sprintf("%s%d", network, opt.network) + } + switch network { case "tcp4", "tcp6", "udp4", "udp6": return actualSingleDialContext(ctx, network, address, opt) case "tcp", "udp": return actualDualStackDialContext(ctx, network, address, opt) default: - return nil, errors.New("network invalid") + return nil, ErrorInvalidedNetworkStack } } @@ -56,10 +70,6 @@ func ListenPacket(ctx context.Context, network, address string, options ...Optio o(cfg) } - if DisableIPv6 { - network = "udp4" - } - lc := &net.ListenConfig{} if cfg.interfaceName != "" { addr, err := bindIfaceToListenConfig(cfg.interfaceName, lc, network, address) @@ -108,7 +118,7 @@ func dialContext(ctx context.Context, network string, destination netip.Addr, po } if DisableIPv6 && destination.Is6() { - return nil, fmt.Errorf("IPv6 is diabled, dialer cancel") + return nil, ErrorDisableIPv6 } return dialer.DialContext(ctx, network, net.JoinHostPort(destination.String(), port)) @@ -230,29 +240,49 @@ func concurrentDialContext(ctx context.Context, network string, ips []netip.Addr ip netip.Addr net.Conn error - resolved bool + isPrimary bool + done bool } + preferCount := atomic.NewInt32(0) results := make(chan dialResult) tcpRacer := func(ctx context.Context, ip netip.Addr) { - result := dialResult{ip: ip} + result := dialResult{ip: ip, done: true} defer func() { select { case results <- result: case <-returned: if result.Conn != nil { - result.Conn.Close() + _ = result.Conn.Close() } } }() - - v := "4" - if ip.Is6() { - v = "6" + if strings.Contains(network, "tcp") { + network = "tcp" + } else { + network = "udp" } - result.Conn, result.error = dialContext(ctx, network+v, ip, port, opt) + if ip.Is6() { + network += "6" + if opt.prefer != 4 { + result.isPrimary = true + } + } + + if ip.Is4() { + network += "4" + if opt.prefer != 6 { + result.isPrimary = true + } + } + + if result.isPrimary { + preferCount.Add(1) + } + + result.Conn, result.error = dialContext(ctx, network, ip, port, opt) } for _, ip := range ips { @@ -260,13 +290,28 @@ func concurrentDialContext(ctx context.Context, network string, ips []netip.Addr } connCount := len(ips) + var fallback dialResult for i := 0; i < connCount; i++ { select { case res := <-results: if res.error == nil { - return res.Conn, nil + if res.isPrimary { + return res.Conn, nil + } else { + fallback = res + } + } else { + if res.isPrimary { + preferCount.Add(-1) + if preferCount.Load() == 0 && fallback.done { + return fallback.Conn, nil + } + } } case <-ctx.Done(): + if fallback.done { + return fallback.Conn, nil + } break } } @@ -303,25 +348,45 @@ func singleDialContext(ctx context.Context, network string, address string, opt } func concurrentSingleDialContext(ctx context.Context, network string, address string, opt *option) (net.Conn, error) { + switch network { + case "tcp4", "udp4": + return concurrentIPv4DialContext(ctx, network, address, opt) + default: + return concurrentIPv6DialContext(ctx, network, address, opt) + } +} + +func concurrentIPv4DialContext(ctx context.Context, network, address string, opt *option) (net.Conn, error) { host, port, err := net.SplitHostPort(address) if err != nil { return nil, err } var ips []netip.Addr - switch network { - case "tcp4", "udp4": - if !opt.direct { - ips, err = resolver.ResolveAllIPv4ProxyServerHost(host) - } else { - ips, err = resolver.ResolveAllIPv4(host) - } - default: - if !opt.direct { - ips, err = resolver.ResolveAllIPv6ProxyServerHost(host) - } else { - ips, err = resolver.ResolveAllIPv6(host) - } + if !opt.direct { + ips, err = resolver.ResolveAllIPv4ProxyServerHost(host) + } else { + ips, err = resolver.ResolveAllIPv4(host) + } + + if err != nil { + return nil, err + } + + return concurrentDialContext(ctx, network, ips, port, opt) +} + +func concurrentIPv6DialContext(ctx context.Context, network, address string, opt *option) (net.Conn, error) { + host, port, err := net.SplitHostPort(address) + if err != nil { + return nil, err + } + + var ips []netip.Addr + if !opt.direct { + ips, err = resolver.ResolveAllIPv6ProxyServerHost(host) + } else { + ips, err = resolver.ResolveAllIPv6(host) } if err != nil { diff --git a/component/dialer/options.go b/component/dialer/options.go index 2985dc7b..ce911035 100644 --- a/component/dialer/options.go +++ b/component/dialer/options.go @@ -1,6 +1,8 @@ package dialer -import "go.uber.org/atomic" +import ( + "go.uber.org/atomic" +) var ( DefaultOptions []Option @@ -13,6 +15,8 @@ type option struct { addrReuse bool routingMark int direct bool + network int + prefer int } type Option func(opt *option) @@ -40,3 +44,25 @@ func WithDirect() Option { opt.direct = true } } + +func WithPreferIPv4() Option { + return func(opt *option) { + opt.prefer = 4 + } +} + +func WithPreferIPv6() Option { + return func(opt *option) { + opt.prefer = 6 + } +} + +func WithOnlySingleStack(isIPv4 bool) Option { + return func(opt *option) { + if isIPv4 { + opt.network = 4 + } else { + opt.network = 6 + } + } +} diff --git a/component/resolver/resolver.go b/component/resolver/resolver.go index 23725c7c..abb45564 100644 --- a/component/resolver/resolver.go +++ b/component/resolver/resolver.go @@ -41,7 +41,6 @@ type Resolver interface { ResolveIPv4(host string) (ip netip.Addr, err error) ResolveIPv6(host string) (ip netip.Addr, err error) ResolveAllIP(host string) (ip []netip.Addr, err error) - ResolveAllIPPrimaryIPv4(host string) (ips []netip.Addr, err error) ResolveAllIPv4(host string) (ips []netip.Addr, err error) ResolveAllIPv6(host string) (ips []netip.Addr, err error) } @@ -74,10 +73,10 @@ func ResolveIPv6WithResolver(host string, r Resolver) (netip.Addr, error) { // ResolveIPWithResolver same as ResolveIP, but with a resolver func ResolveIPWithResolver(host string, r Resolver) (netip.Addr, error) { - if ips, err := ResolveAllIPPrimaryIPv4WithResolver(host, r); err == nil { - return ips[rand.Intn(len(ips))], nil + if ip, err := ResolveIPv4WithResolver(host, r); err == nil { + return ip, nil } else { - return netip.Addr{}, err + return ResolveIPv6WithResolver(host, r) } } @@ -95,7 +94,6 @@ func ResolveIPv4ProxyServerHost(host string) (netip.Addr, error) { return ip, nil } } - return ResolveIPv4(host) } @@ -108,7 +106,6 @@ func ResolveIPv6ProxyServerHost(host string) (netip.Addr, error) { return ip, nil } } - return ResolveIPv6(host) } @@ -121,7 +118,6 @@ func ResolveProxyServerHost(host string) (netip.Addr, error) { return ip, err } } - return ResolveIP(host) } @@ -160,7 +156,6 @@ func ResolveAllIPv6WithResolver(host string, r Resolver) ([]netip.Addr, error) { return []netip.Addr{netip.AddrFrom16(*(*[16]byte)(ipAddrs[rand.Intn(len(ipAddrs))]))}, nil } - return []netip.Addr{}, ErrIPNotFound } @@ -200,7 +195,6 @@ func ResolveAllIPv4WithResolver(host string, r Resolver) ([]netip.Addr, error) { return []netip.Addr{netip.AddrFrom4(*(*[4]byte)(ip))}, nil } - return []netip.Addr{}, ErrIPNotFound } @@ -232,39 +226,6 @@ func ResolveAllIPWithResolver(host string, r Resolver) ([]netip.Addr, error) { return []netip.Addr{nnip.IpToAddr(ipAddr.IP)}, nil } - - return []netip.Addr{}, ErrIPNotFound -} - -func ResolveAllIPPrimaryIPv4WithResolver(host string, r Resolver) ([]netip.Addr, error) { - if node := DefaultHosts.Search(host); node != nil { - return []netip.Addr{node.Data}, nil - } - - ip, err := netip.ParseAddr(host) - if err == nil { - return []netip.Addr{ip}, nil - } - - if r != nil { - if DisableIPv6 { - return r.ResolveAllIPv4(host) - } - - return r.ResolveAllIPPrimaryIPv4(host) - } else if DisableIPv6 { - return ResolveAllIPv4(host) - } - - if DefaultResolver == nil { - ipAddr, err := net.ResolveIPAddr("ip", host) - if err != nil { - return []netip.Addr{}, err - } - - return []netip.Addr{nnip.IpToAddr(ipAddr.IP)}, nil - } - return []netip.Addr{}, ErrIPNotFound } @@ -284,7 +245,6 @@ func ResolveAllIPv6ProxyServerHost(host string) ([]netip.Addr, error) { if ProxyServerHostResolver != nil { return ResolveAllIPv6WithResolver(host, ProxyServerHostResolver) } - return ResolveAllIPv6(host) } @@ -292,7 +252,6 @@ func ResolveAllIPv4ProxyServerHost(host string) ([]netip.Addr, error) { if ProxyServerHostResolver != nil { return ResolveAllIPv4WithResolver(host, ProxyServerHostResolver) } - return ResolveAllIPv4(host) } @@ -300,6 +259,5 @@ func ResolveAllIPProxyServerHost(host string) ([]netip.Addr, error) { if ProxyServerHostResolver != nil { return ResolveAllIPWithResolver(host, ProxyServerHostResolver) } - return ResolveAllIP(host) } diff --git a/constant/dns.go b/constant/dns.go index eee98e5d..4d94ad6d 100644 --- a/constant/dns.go +++ b/constant/dns.go @@ -68,3 +68,46 @@ func (e DNSMode) String() string { return "unknown" } } + +type DNSPrefer int + +const ( + DualStack DNSPrefer = iota + IPv4Only + IPv6Only + IPv4Prefer + IPv6Prefer +) + +var dnsPreferMap = map[string]DNSPrefer{ + DualStack.String(): DualStack, + IPv4Only.String(): IPv4Only, + IPv6Only.String(): IPv6Only, + IPv4Prefer.String(): IPv4Prefer, + IPv6Prefer.String(): IPv6Prefer, +} + +func (d DNSPrefer) String() string { + switch d { + case DualStack: + return "dual" + case IPv4Only: + return "ipv4" + case IPv6Only: + return "ipv6" + case IPv4Prefer: + return "ipv4-prefer" + case IPv6Prefer: + return "ipv6-prefer" + default: + return "dual" + } +} + +func NewDNSPrefer(prefer string) DNSPrefer { + if p, ok := dnsPreferMap[prefer]; ok { + return p + } else { + return DualStack + } +} diff --git a/dns/resolver.go b/dns/resolver.go index b576fe36..aac22cc8 100644 --- a/dns/resolver.go +++ b/dns/resolver.go @@ -88,7 +88,7 @@ func (r *Resolver) ResolveAllIP(host string) (ips []netip.Addr, err error) { return nil, resolver.ErrIPNotFound } ips = append(ips, ipv6s...) - case <-time.After(1 * time.Millisecond): + case <-time.After(30 * time.Millisecond): // wait ipv6 result } diff --git a/docs/config.yaml b/docs/config.yaml index 2f77a53b..9240bf96 100644 --- a/docs/config.yaml +++ b/docs/config.yaml @@ -1,19 +1,19 @@ # port: 7890 # HTTP(S) 代理服务器端口 # socks-port: 7891 # SOCKS5 代理端口 mixed-port: 10801 # HTTP(S) 和 SOCKS 代理混合端口 -# redir-port: 7892 # 透明代理端口 用于Linux和 +# redir-port: 7892 # 透明代理端口,用于 Linux 和 MacOS # Transparent proxy server port for Linux (TProxy TCP and TProxy UDP) # tproxy-port: 7893 allow-lan: true # 允许局域网连接 -bind-address: "*" # 绑定IP地址,仅作用于 allow-lan 为true, '*'表示所有地址 +bind-address: "*" # 绑定IP地址,仅作用于 allow-lan 为 true,'*'表示所有地址 mode: rule -log-level: debug #日志等级 silent/error/warning/info/debug +log-level: debug # 日志等级 silent/error/warning/info/debug -ipv6: true #开启IPv6总开关 关闭阻断所有IPv6和屏蔽DNS请求AAAA记录 +ipv6: true # 开启 IPv6 总开关,关闭阻断所有 IPv6 链接和屏蔽 DNS 请求 AAAA 记录 external-controller: 0.0.0.0:9093 # RESTful API 监听地址 @@ -24,33 +24,33 @@ external-ui: /path/to/ui/folder # 配置WEB UI目录,使用http://{{external-c # interface-name: en0 # 设置出口网卡 -# routing-mark: 6666 # 配置fwmark 仅用于Linux +# routing-mark: 6666 # 配置 fwmark 仅用于Linux experimental: # 具体配置待定 # 证书指纹,SHA256格式,补充校验TLS证书 # 可使用 openssl x509 -noout -fingerprint -sha256 -inform pem -in yourcert.pem 获取 fingerprints: - "8F111FA9AD3CD8E917A118522CAC39EA33741B3BBE73F91CECE548D5CCB0E5E8" # 忽略大小写 -# 类似于/etc/hosts, 仅支持配置单个IP +# 类似于 /etc/hosts, 仅支持配置单个 IP hosts: # '*.clash.dev': 127.0.0.1 # '.dev': 127.0.0.1 # 'alpha.clash.dev': '::1' -# Tun配置 +# Tun 配置 tun: enable: false stack: system # gvisor dns-hijack: - - 198.18.0.2:53 # 需要劫持的DNS - # auto-detect-interface: true # 自动识别interface - # auto-route: true # 配置 + - 198.18.0.2:53 # 需要劫持的 DNS + # auto-detect-interface: true # 自动识别出口网卡 + # auto-route: true # 配置路由表 #ebpf配置 ebpf: - auto-redir: #redirect模式,仅支持TCP + auto-redir: # redirect 模式,仅支持 TCP - eth0 - redirect-to-tun: #UDP+TCP,使用该功能请勿启用auto-route + redirect-to-tun: # UDP+TCP 使用该功能请勿启用 auto-route - eth0 # 嗅探域名 可选配置 @@ -63,7 +63,7 @@ sniffer: # 强制对此域名进行嗅探 force-domain: - +.v2ex.com - # 仅对白名单中的端口进行嗅探,默认为0-65535,推荐只对需要嗅探写的的常见端口嗅探 + # 仅对白名单中的端口进行嗅探,默认为 443,80 port-whitelist: - "80" - "443" @@ -78,12 +78,12 @@ profile: # DNS配置 dns: - enable: false # 关闭将使用系统DNS - listen: 0.0.0.0:53 # 开启DNS服务器监听 - # ipv6: false # false将返回AAAA的空结果 + enable: false # 关闭将使用系统 DNS + listen: 0.0.0.0:53 # 开启 DNS 服务器监听 + # ipv6: false # false 将返回 AAAA 的空结果 - # 用于解析nameserver,fallbacky以及其他DNS服务器配置的,DNS服务域名 - # 只能使用纯IP地址,可使用加密DNS + # 用于解析 nameserver,fallback 以及其他DNS服务器配置的,DNS 服务域名 + # 只能使用纯 IP 地址,可使用加密 DNS default-nameserver: - 114.114.114.114 - 8.8.8.8 @@ -93,7 +93,7 @@ dns: fake-ip-range: 198.18.0.1/16 # fake-ip 池设置 - # use-hosts: true # 查询hosts + # use-hosts: true # 查询 hosts # 配置不使用fake-ip的域名 # fake-ip-filter: @@ -101,40 +101,40 @@ dns: # - localhost.ptlogin2.qq.com # DNS主要域名配置 - # 支持 UDP,TCP,DoT,DoH,DoQ - # 这部分为主要DNS配置,影响所有直连,确保使用对大陆解析精准的DNS + # 支持 UDP,TCP,DoT,DoH,DoQ + # 这部分为主要 DNS 配置,影响所有直连,确保使用对大陆解析精准的 DNS nameserver: - 114.114.114.114 # default value - 8.8.8.8 # default value - tls://223.5.5.5:853 # DNS over TLS - https://doh.pub/dns-query # DNS over HTTPS - https://dns.alidns.com/dns-query#h3=true # 强制HTTP/3 - - https://mozilla.cloudflare-dns.com/dns-query#DNS&h3=true # 指定策略组和使用HTTP/3 + - https://mozilla.cloudflare-dns.com/dns-query#DNS&h3=true # 指定策略组和使用 HTTP/3 - dhcp://en0 # dns from dhcp - quic://dns.adguard.com:784 # DNS over QUIC # - '8.8.8.8#en0' # 兼容指定DNS出口网卡 - # 当配置fallback时,会查询nameserver中返回的IP是否为CN,非必要配置 - # 当不是CN,则使用fallback中的DNS查询结果 - # 确保配置fallback时能够正常查询 + # 当配置 fallback 时,会查询 nameserver 中返回的 IP 是否为 CN,非必要配置 + # 当不是 CN,则使用 fallback 中的 DNS 查询结果 + # 确保配置 fallback 时能够正常查询 # fallback: # - tcp://1.1.1.1 - # - 'tcp://1.1.1.1#ProxyGroupName' # 指定DNS过代理查询,ProxyGroupName为策略组名或节点名,过代理配置优先于配置出口网卡,当找不到策略组或节点名则设置为出口网卡 + # - 'tcp://1.1.1.1#ProxyGroupName' # 指定 DNS 过代理查询,ProxyGroupName 为策略组名或节点名,过代理配置优先于配置出口网卡,当找不到策略组或节点名则设置为出口网卡 - # 专用于节点域名解析的DNS服务器,非必要配置项 - # 配置服务器若查询失败将使用nameserver,非并发查询 + # 专用于节点域名解析的 DNS 服务器,非必要配置项 + # 配置服务器若查询失败将使用 nameserver,非并发查询 # proxy-server-nameserver: # - https://dns.google/dns-query # - tls://one.one.one.one - # 配置fallback使用条件 + # 配置 fallback 使用条件 # fallback-filter: - # geoip: true # 配置是否使用geoip - # geoip-code: CN # 当nameserver域名的IP查询geoip库为CN时,不使用fallback - # 配置强制fallback,优先于IP判断,具体分类自行查看geosite库 + # geoip: true # 配置是否使用 geoip + # geoip-code: CN # 当 nameserver 域名的 IP 查询 geoip 库为 CN 时,不使用 fallback 中的 DNS 查询结果 + # 配置强制 fallback,优先于 IP 判断,具体分类自行查看 geosite 库 # geosite: # - gfw - # 配置不需要使用fallback的IP CIDR + # 配置不需要使用 fallback 的 IP CIDR # ipcidr: # - 240.0.0.0/4 # domain: @@ -142,7 +142,7 @@ dns: # - '+.facebook.com' # - '+.youtube.com' - # 配置查询域名使用的DNS服务器 + # 配置查询域名使用的 DNS 服务器 # nameserver-policy: # 'www.baidu.com': '114.114.114.114' # '+.internal.crop.com': '10.0.0.1' @@ -164,7 +164,12 @@ proxies: password: "password" # udp: true # udp-over-tcp: false - + # ip-version: ipv4 # 设置节点使用 IP 版本,可选:dual,ipv4,ipv6,ipv4-prefer,ipv6-prefer。默认使用 dual + # ipv4:仅使用 IPv4 ipv6:仅使用 IPv6 + # ipv4-prefer:优先使用 IPv4 对于 TCP 会进行双栈解析,并发链接但是优先使用 IPv4 链接, + # UDP 则为双栈解析,获取结果中的第一个 IPv4 + # ipv6-prefer 同 ipv4-prefer + # 现有协议都支持此参数 - name: "ss2" type: ss server: server @@ -249,6 +254,7 @@ proxies: # # headers: # # Connection: # # - keep-alive + # ip-version: ipv4 # 设置使用 IP 类型偏好,可选:ipv4,ipv6,dual,默认值:dual - name: vmess-grpc server: server @@ -264,6 +270,7 @@ proxies: # skip-cert-verify: true grpc-opts: grpc-service-name: "example" + # ip-version: ipv4 # socks5 - name: "socks" @@ -276,6 +283,7 @@ proxies: # fingerprint: xxxx # skip-cert-verify: true # udp: true + # ip-version: ipv6 # http - name: "http" @@ -288,6 +296,7 @@ proxies: # skip-cert-verify: true # sni: custom.com # fingerprint: xxxx # 同 experimental.fingerprints 使用 sha256 指纹,配置协议独立的指纹,将忽略 experimental.fingerprints + # ip-version: dual # Snell # Beware that there's currently no UDP support yet @@ -389,9 +398,9 @@ proxies: auth_str: yourpassword # obfs: obfs_str # alpn: h3 - protocol: udp #支持udp/wechat-video/faketcp - up: "30 Mbps" #若不写单位,默认为Mbps - down: "200 Mbps" #若不写单位,默认为Mbps + protocol: udp # 支持 udp/wechat-video/faketcp + up: "30 Mbps" # 若不写单位,默认为 Mbps + down: "200 Mbps" # 若不写单位,默认为 Mbps #sni: server.com #skip-cert-verify: false #recv_window_conn: 12582912 @@ -422,7 +431,7 @@ proxies: # udp: true proxy-groups: - # 代理链,若落地协议支持UDP over TCP则可支持UDP + # 代理链,若落地协议支持 UDP over TCP 则可支持 UDP # Traffic: clash <-> http <-> vmess <-> ss1 <-> ss2 <-> Internet - name: "relay" type: relay @@ -432,7 +441,7 @@ proxy-groups: - ss1 - ss2 - # url-test 将按照url测试结果使用延迟最低节点 + # url-test 将按照 url 测试结果使用延迟最低节点 - name: "auto" type: url-test proxies: @@ -444,7 +453,7 @@ proxy-groups: url: "http://www.gstatic.com/generate_204" interval: 300 - # fallback 将按照url测试结果按照节点顺序选择 + # fallback 将按照 url 测试结果按照节点顺序选择 - name: "fallback-auto" type: fallback proxies: @@ -475,7 +484,7 @@ proxy-groups: - vmess1 - auto - # 配置指定interface-name和fwmark的DIRECT + # 配置指定 interface-name 和 fwmark 的 DIRECT - name: en1 type: select interface-name: en1 @@ -485,14 +494,14 @@ proxy-groups: - name: UseProvider type: select - filter: "HK|TW" # 正则表达式,过滤provider1中节点名包含HK或TW + filter: "HK|TW" # 正则表达式,过滤 provider1 中节点名包含 HK 或 TW use: - provider1 proxies: - Proxy - DIRECT -# Clash格式的节点或支持*ray的分享格式 +# Clash 格式的节点或支持 *ray 的分享格式 proxy-providers: provider1: type: http diff --git a/transport/hysteria/transport/client.go b/transport/hysteria/transport/client.go index 9d0158e5..d350b4ad 100644 --- a/transport/hysteria/transport/client.go +++ b/transport/hysteria/transport/client.go @@ -4,12 +4,10 @@ import ( "context" "crypto/tls" "fmt" - "github.com/Dreamacro/clash/component/resolver" "github.com/Dreamacro/clash/transport/hysteria/conns/faketcp" "github.com/Dreamacro/clash/transport/hysteria/conns/udp" "github.com/Dreamacro/clash/transport/hysteria/conns/wechat" "github.com/Dreamacro/clash/transport/hysteria/obfs" - "github.com/Dreamacro/clash/transport/hysteria/utils" "github.com/lucas-clemente/quic-go" "net" ) @@ -61,29 +59,21 @@ func (ct *ClientTransport) quicPacketConn(proto string, server string, obfs obfs type PacketDialer interface { ListenPacket() (net.PacketConn, error) Context() context.Context + RemoteAddr(host string) (net.Addr, error) } func (ct *ClientTransport) QUICDial(proto string, server string, tlsConfig *tls.Config, quicConfig *quic.Config, obfs obfs.Obfuscator, dialer PacketDialer) (quic.Connection, error) { - ipStr, port, err := utils.SplitHostPort(server) + serverUDPAddr, err := dialer.RemoteAddr(server) if err != nil { return nil, err } - ip, err := resolver.ResolveProxyServerHost(ipStr) - if err != nil { - return nil, err - } - - serverUDPAddr := net.UDPAddr{ - IP: net.ParseIP(ip.String()), - Port: int(port), - } - pktConn, err := ct.quicPacketConn(proto, serverUDPAddr.String(), obfs, dialer) if err != nil { return nil, err } - qs, err := quic.DialContext(dialer.Context(), pktConn, &serverUDPAddr, server, tlsConfig, quicConfig) + + qs, err := quic.DialContext(dialer.Context(), pktConn, serverUDPAddr, server, tlsConfig, quicConfig) if err != nil { _ = pktConn.Close() return nil, err From db94dc76b48ccf90ec5d58480d7914f7639d6afd Mon Sep 17 00:00:00 2001 From: Skyxim Date: Sun, 28 Aug 2022 15:57:10 +0800 Subject: [PATCH 02/22] fix: udp default resolve ip --- adapter/outbound/util.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adapter/outbound/util.go b/adapter/outbound/util.go index de9287bd..0b859630 100644 --- a/adapter/outbound/util.go +++ b/adapter/outbound/util.go @@ -103,7 +103,8 @@ func resolveUDPAddrWithPrefer(network, address string, prefer C.DNSPrefer) (*net } ip = fallback } - case C.IPv4Prefer | C.DualStack: + default: + // C.IPv4Prefer, C.DualStack and other var ips []netip.Addr ips, err = resolver.ResolveAllIPProxyServerHost(host) var fallback netip.Addr From af97922e9446be97b6af11e1a9f4f3a3d3f3da37 Mon Sep 17 00:00:00 2001 From: Skyxim Date: Sun, 28 Aug 2022 20:26:13 +0800 Subject: [PATCH 03/22] fix: no main result conn, will fail --- component/dialer/dialer.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/component/dialer/dialer.go b/component/dialer/dialer.go index 48cc1ce7..fa1b17a2 100644 --- a/component/dialer/dialer.go +++ b/component/dialer/dialer.go @@ -218,7 +218,6 @@ func concurrentDualStackDialContext(ctx context.Context, network, address string } var ips []netip.Addr - if opt.direct { ips, err = resolver.ResolveAllIP(host) } else { @@ -298,24 +297,30 @@ func concurrentDialContext(ctx context.Context, network string, ips []netip.Addr if res.isPrimary { return res.Conn, nil } else { - fallback = res + if !fallback.done || fallback.error != nil { + fallback = res + } } } else { if res.isPrimary { preferCount.Add(-1) - if preferCount.Load() == 0 && fallback.done { + if preferCount.Load() == 0 && fallback.done && fallback.error == nil { return fallback.Conn, nil } } } case <-ctx.Done(): - if fallback.done { + if fallback.done && fallback.error == nil { return fallback.Conn, nil } break } } + if fallback.done && fallback.error == nil { + return fallback.Conn, nil + } + return nil, fmt.Errorf("all ips %v tcp shake hands failed", ips) } From 7f197ede5157754f1aa3b703d911c1f0dad524da Mon Sep 17 00:00:00 2001 From: Skyxim Date: Mon, 29 Aug 2022 12:10:46 +0800 Subject: [PATCH 04/22] fix: hysteria udp crash --- adapter/outbound/hysteria.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/adapter/outbound/hysteria.go b/adapter/outbound/hysteria.go index adc904a2..9446cf93 100644 --- a/adapter/outbound/hysteria.go +++ b/adapter/outbound/hysteria.go @@ -72,6 +72,9 @@ func (h *Hysteria) ListenPacketContext(ctx context.Context, metadata *C.Metadata hyDialer: func() (net.PacketConn, error) { return dialer.ListenPacket(ctx, "udp", "", h.Base.DialOptions(opts...)...) }, + remoteAddr: func(addr string) (net.Addr, error) { + return resolveUDPAddrWithPrefer("udp", addr, h.prefer) + }, } udpConn, err := h.client.DialUDP(&hdc) if err != nil { From d69e0bce4a065ea72c27fdd82b48da25b442adea Mon Sep 17 00:00:00 2001 From: Skyxim Date: Mon, 29 Aug 2022 13:04:48 +0800 Subject: [PATCH 05/22] fix: resolve ip of udp proxy error --- adapter/outbound/util.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/adapter/outbound/util.go b/adapter/outbound/util.go index 0b859630..d5219131 100644 --- a/adapter/outbound/util.go +++ b/adapter/outbound/util.go @@ -104,7 +104,7 @@ func resolveUDPAddrWithPrefer(network, address string, prefer C.DNSPrefer) (*net ip = fallback } default: - // C.IPv4Prefer, C.DualStack and other + // C.IPv4Prefer, C.DualStack and other var ips []netip.Addr ips, err = resolver.ResolveAllIPProxyServerHost(host) var fallback netip.Addr @@ -119,7 +119,10 @@ func resolveUDPAddrWithPrefer(network, address string, prefer C.DNSPrefer) (*net } } } - ip = fallback + + if !ip.IsValid() && fallback.IsValid() { + ip = fallback + } } } From d823dde43c537f8fdcb77c6a06af58a73046b2e8 Mon Sep 17 00:00:00 2001 From: Skyxim Date: Mon, 29 Aug 2022 13:07:38 +0800 Subject: [PATCH 06/22] chore: update doc --- docs/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.yaml b/docs/config.yaml index 9240bf96..53ed7416 100644 --- a/docs/config.yaml +++ b/docs/config.yaml @@ -169,7 +169,7 @@ proxies: # ipv4-prefer:优先使用 IPv4 对于 TCP 会进行双栈解析,并发链接但是优先使用 IPv4 链接, # UDP 则为双栈解析,获取结果中的第一个 IPv4 # ipv6-prefer 同 ipv4-prefer - # 现有协议都支持此参数 + # 现有协议都支持此参数,TCP 效果仅在开启 tcp-concurrent 生效 - name: "ss2" type: ss server: server From a9694fcdc0aa394a75e1d20123231febaae24c5b Mon Sep 17 00:00:00 2001 From: Skyxim Date: Tue, 30 Aug 2022 15:59:52 +0800 Subject: [PATCH 07/22] chore: update doc --- docs/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.yaml b/docs/config.yaml index 53ed7416..94c93137 100644 --- a/docs/config.yaml +++ b/docs/config.yaml @@ -134,7 +134,7 @@ dns: # 配置强制 fallback,优先于 IP 判断,具体分类自行查看 geosite 库 # geosite: # - gfw - # 配置不需要使用 fallback 的 IP CIDR + # 如果不匹配 ipcidr 则使用 nameservers 中的结果 # ipcidr: # - 240.0.0.0/4 # domain: From 9b89ff9f2dca997668a28d35bb8596df120a1dd1 Mon Sep 17 00:00:00 2001 From: adlyq Date: Tue, 6 Sep 2022 17:30:35 +0800 Subject: [PATCH 08/22] feat: support sub-rule, eg. rules: - SUB-RULE,(AND,((NETWORK,TCP),(DOMAIN-KEYWORD,google))),TEST2 - SUB-RULE,(GEOIP,!CN),TEST1 - MATCH,DIRECT sub-rules: TEST2: - MATCH,Proxy TEST1: - RULE-SET,Local,DIRECT,no-resolve - GEOSITE,CN,Domestic - GEOIP,CN,Domestic - MATCH,Proxy --- config/config.go | 130 ++++++++++++++++++++++++--- constant/rule.go | 5 +- rules/common/base.go | 2 +- rules/common/domain.go | 8 +- rules/common/domain_keyword.go | 8 +- rules/common/domain_suffix.go | 8 +- rules/common/final.go | 6 +- rules/common/geoip.go | 12 +-- rules/common/geosite.go | 8 +- rules/common/in_type.go | 6 +- rules/common/ipcidr.go | 6 +- rules/common/ipsuffix.go | 10 +-- rules/common/network_type.go | 4 +- rules/common/port.go | 6 +- rules/common/process.go | 6 +- rules/common/uid.go | 10 +-- rules/logic/and.go | 12 +-- rules/logic/common.go | 10 +-- rules/logic/logic_test.go | 23 +++-- rules/logic/not.go | 16 +++- rules/logic/or.go | 12 +-- rules/parser.go | 7 +- rules/provider/classical_strategy.go | 8 +- rules/provider/parse.go | 2 +- rules/provider/provider.go | 4 +- rules/provider/rule_set.go | 6 +- rules/sub_rule/sub_rules.go | 91 +++++++++++++++++++ tunnel/tunnel.go | 4 +- 28 files changed, 325 insertions(+), 105 deletions(-) create mode 100644 rules/sub_rule/sub_rules.go diff --git a/config/config.go b/config/config.go index 59d493c2..7daf1549 100644 --- a/config/config.go +++ b/config/config.go @@ -153,6 +153,7 @@ type Config struct { Hosts *trie.DomainTrie[netip.Addr] Profile *Profile Rules []C.Rule + SubRules *map[string][]C.Rule Users []auth.AuthUser Proxies map[string]C.Proxy Providers map[string]providerTypes.ProxyProvider @@ -233,6 +234,7 @@ type RawConfig struct { Proxy []map[string]any `yaml:"proxies"` ProxyGroup []map[string]any `yaml:"proxy-groups"` Rule []string `yaml:"rules"` + SubRules map[string][]string `yaml:"sub-rules"` } type RawGeoXUrl struct { @@ -381,12 +383,18 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) { config.Proxies = proxies config.Providers = providers - rules, ruleProviders, err := parseRules(rawCfg, proxies) + subRules, ruleProviders, err := parseSubRules(rawCfg, proxies) + if err != nil { + return nil, err + } + config.SubRules = subRules + config.RuleProviders = ruleProviders + + rules, err := parseRules(rawCfg, proxies, subRules) if err != nil { return nil, err } config.Rules = rules - config.RuleProviders = ruleProviders hosts, err := parseHosts(rawCfg) if err != nil { @@ -563,8 +571,9 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[ return proxies, providersMap, nil } -func parseRules(cfg *RawConfig, proxies map[string]C.Proxy) ([]C.Rule, map[string]providerTypes.RuleProvider, error) { - ruleProviders := map[string]providerTypes.RuleProvider{} +func parseSubRules(cfg *RawConfig, proxies map[string]C.Proxy) (subRules *map[string][]C.Rule, ruleProviders map[string]providerTypes.RuleProvider, err error) { + ruleProviders = map[string]providerTypes.RuleProvider{} + subRules = &map[string][]C.Rule{} log.Infoln("Geodata Loader mode: %s", geodata.LoaderName()) // parse rule provider for name, mapping := range cfg.RuleProvider { @@ -577,6 +586,102 @@ func parseRules(cfg *RawConfig, proxies map[string]C.Proxy) ([]C.Rule, map[strin RP.SetRuleProvider(rp) } + for name, rawRules := range cfg.SubRules { + var rules []C.Rule + for idx, line := range rawRules { + rawRule := trimArr(strings.Split(line, ",")) + var ( + payload string + target string + params []string + ruleName = strings.ToUpper(rawRule[0]) + ) + + l := len(rawRule) + + if ruleName == "NOT" || ruleName == "OR" || ruleName == "AND" || ruleName == "SUB-RULE" { + target = rawRule[l-1] + payload = strings.Join(rawRule[1:l-1], ",") + } else { + if l < 2 { + return nil, nil, fmt.Errorf("sub-rules[%d] [%s] error: format invalid", idx, line) + } + if l < 4 { + rawRule = append(rawRule, make([]string, 4-l)...) + } + if ruleName == "MATCH" { + l = 2 + } + if l >= 3 { + l = 3 + payload = rawRule[1] + } + target = rawRule[l-1] + params = rawRule[l:] + } + + if _, ok := proxies[target]; !ok && ruleName != "SUB-RULE" { + return nil, nil, fmt.Errorf("sub-rules[%d:%s] [%s] error: proxy [%s] not found", idx, name, line, target) + } + + params = trimArr(params) + parsed, parseErr := R.ParseRule(ruleName, payload, target, params, subRules) + if parseErr != nil { + return nil, nil, fmt.Errorf("sub-rules[%d] [%s] error: %s", idx, line, parseErr.Error()) + } + + rules = append(rules, parsed) + } + (*subRules)[name] = rules + } + + if err = verifySubRule(subRules); err != nil { + return nil, nil, err + } + + return +} + +func verifySubRule(subRules *map[string][]C.Rule) error { + for name := range *subRules { + err := verifySubRuleCircularReferences(name, subRules, []string{}) + if err != nil { + return err + } + } + return nil +} + +func verifySubRuleCircularReferences(n string, subRules *map[string][]C.Rule, arr []string) error { + isInArray := func(v string, array []string) bool { + for _, c := range array { + if v == c { + return true + } + } + return false + } + + arr = append(arr, n) + for i, rule := range (*subRules)[n] { + if rule.RuleType() == C.SubRules { + if _, ok := (*subRules)[rule.Adapter()]; !ok { + return fmt.Errorf("sub-rule[%d:%s] error: [%s] not found", i, n, rule.Adapter()) + } + if isInArray(rule.Adapter(), arr) { + arr = append(arr, rule.Adapter()) + return fmt.Errorf("sub-rule error: circular references [%s]", strings.Join(arr, "->")) + } + + if err := verifySubRuleCircularReferences(rule.Adapter(), subRules, arr); err != nil { + return err + } + } + } + return nil +} + +func parseRules(cfg *RawConfig, proxies map[string]C.Proxy, subRules *map[string][]C.Rule) ([]C.Rule, error) { var rules []C.Rule rulesConfig := cfg.Rule @@ -592,12 +697,12 @@ func parseRules(cfg *RawConfig, proxies map[string]C.Proxy) ([]C.Rule, map[strin l := len(rule) - if ruleName == "NOT" || ruleName == "OR" || ruleName == "AND" { + if ruleName == "NOT" || ruleName == "OR" || ruleName == "AND" || ruleName == "SUB-RULE" { target = rule[l-1] payload = strings.Join(rule[1:l-1], ",") } else { if l < 2 { - return nil, nil, fmt.Errorf("rules[%d] [%s] error: format invalid", idx, line) + return nil, fmt.Errorf("rules[%d] [%s] error: format invalid", idx, line) } if l < 4 { rule = append(rule, make([]string, 4-l)...) @@ -612,15 +717,18 @@ func parseRules(cfg *RawConfig, proxies map[string]C.Proxy) ([]C.Rule, map[strin target = rule[l-1] params = rule[l:] } - if _, ok := proxies[target]; !ok { - return nil, nil, fmt.Errorf("rules[%d] [%s] error: proxy [%s] not found", idx, line, target) + if ruleName != "SUB-RULE" { + return nil, fmt.Errorf("rules[%d] [%s] error: proxy [%s] not found", idx, line, target) + } else if _, ok = (*subRules)[target]; !ok { + return nil, fmt.Errorf("rules[%d] [%s] error: sub-rule [%s] not found", idx, line, target) + } } params = trimArr(params) - parsed, parseErr := R.ParseRule(ruleName, payload, target, params) + parsed, parseErr := R.ParseRule(ruleName, payload, target, params, subRules) if parseErr != nil { - return nil, nil, fmt.Errorf("rules[%d] [%s] error: %s", idx, line, parseErr.Error()) + return nil, fmt.Errorf("rules[%d] [%s] error: %s", idx, line, parseErr.Error()) } rules = append(rules, parsed) @@ -628,7 +736,7 @@ func parseRules(cfg *RawConfig, proxies map[string]C.Proxy) ([]C.Rule, map[strin runtime.GC() - return rules, ruleProviders, nil + return rules, nil } func parseHosts(cfg *RawConfig) (*trie.DomainTrie[netip.Addr], error) { diff --git a/constant/rule.go b/constant/rule.go index a403ac63..223dec6e 100644 --- a/constant/rule.go +++ b/constant/rule.go @@ -19,6 +19,7 @@ const ( Network Uid INTYPE + SubRules MATCH AND OR @@ -65,6 +66,8 @@ func (rt RuleType) String() string { return "Uid" case INTYPE: return "InType" + case SubRules: + return "SubRules" case AND: return "AND" case OR: @@ -78,7 +81,7 @@ func (rt RuleType) String() string { type Rule interface { RuleType() RuleType - Match(metadata *Metadata) bool + Match(metadata *Metadata) (bool, string) Adapter() string Payload() string ShouldResolveIP() bool diff --git a/rules/common/base.go b/rules/common/base.go index 42b4d770..abc2b434 100644 --- a/rules/common/base.go +++ b/rules/common/base.go @@ -5,7 +5,7 @@ import ( ) var ( - errPayload = errors.New("payload error") + errPayload = errors.New("payloadRule error") initFlag bool noResolve = "no-resolve" ) diff --git a/rules/common/domain.go b/rules/common/domain.go index 4a8a7d27..2f0e4f2f 100644 --- a/rules/common/domain.go +++ b/rules/common/domain.go @@ -18,11 +18,11 @@ func (d *Domain) RuleType() C.RuleType { return C.Domain } -func (d *Domain) Match(metadata *C.Metadata) bool { +func (d *Domain) Match(metadata *C.Metadata) (bool, string) { if metadata.AddrType != C.AtypDomainName { - return false + return false, "" } - return metadata.Host == d.domain + return metadata.Host == d.domain, d.adapter } func (d *Domain) Adapter() string { @@ -47,4 +47,4 @@ func NewDomain(domain string, adapter string) *Domain { } } -var _ C.Rule = (*Domain)(nil) +//var _ C.Rule = (*Domain)(nil) diff --git a/rules/common/domain_keyword.go b/rules/common/domain_keyword.go index 667b2861..58257544 100644 --- a/rules/common/domain_keyword.go +++ b/rules/common/domain_keyword.go @@ -18,12 +18,12 @@ func (dk *DomainKeyword) RuleType() C.RuleType { return C.DomainKeyword } -func (dk *DomainKeyword) Match(metadata *C.Metadata) bool { +func (dk *DomainKeyword) Match(metadata *C.Metadata) (bool, string) { if metadata.AddrType != C.AtypDomainName { - return false + return false, "" } domain := metadata.Host - return strings.Contains(domain, dk.keyword) + return strings.Contains(domain, dk.keyword), dk.adapter } func (dk *DomainKeyword) Adapter() string { @@ -48,4 +48,4 @@ func NewDomainKeyword(keyword string, adapter string) *DomainKeyword { } } -var _ C.Rule = (*DomainKeyword)(nil) +//var _ C.Rule = (*DomainKeyword)(nil) diff --git a/rules/common/domain_suffix.go b/rules/common/domain_suffix.go index c2edcd16..c9016744 100644 --- a/rules/common/domain_suffix.go +++ b/rules/common/domain_suffix.go @@ -18,12 +18,12 @@ func (ds *DomainSuffix) RuleType() C.RuleType { return C.DomainSuffix } -func (ds *DomainSuffix) Match(metadata *C.Metadata) bool { +func (ds *DomainSuffix) Match(metadata *C.Metadata) (bool, string) { if metadata.AddrType != C.AtypDomainName { - return false + return false, "" } domain := metadata.Host - return strings.HasSuffix(domain, "."+ds.suffix) || domain == ds.suffix + return strings.HasSuffix(domain, "."+ds.suffix) || domain == ds.suffix, ds.adapter } func (ds *DomainSuffix) Adapter() string { @@ -48,4 +48,4 @@ func NewDomainSuffix(suffix string, adapter string) *DomainSuffix { } } -var _ C.Rule = (*DomainSuffix)(nil) +//var _ C.Rule = (*DomainSuffix)(nil) diff --git a/rules/common/final.go b/rules/common/final.go index e42baf92..8aa5ed7b 100644 --- a/rules/common/final.go +++ b/rules/common/final.go @@ -13,8 +13,8 @@ func (f *Match) RuleType() C.RuleType { return C.MATCH } -func (f *Match) Match(metadata *C.Metadata) bool { - return true +func (f *Match) Match(metadata *C.Metadata) (bool, string) { + return true, f.adapter } func (f *Match) Adapter() string { @@ -32,4 +32,4 @@ func NewMatch(adapter string) *Match { } } -var _ C.Rule = (*Match)(nil) +//var _ C.Rule = (*Match)(nil) diff --git a/rules/common/geoip.go b/rules/common/geoip.go index 0a7670e1..ada862d2 100644 --- a/rules/common/geoip.go +++ b/rules/common/geoip.go @@ -25,10 +25,10 @@ func (g *GEOIP) RuleType() C.RuleType { return C.GEOIP } -func (g *GEOIP) Match(metadata *C.Metadata) bool { +func (g *GEOIP) Match(metadata *C.Metadata) (bool, string) { ip := metadata.DstIP if !ip.IsValid() { - return false + return false, "" } if strings.EqualFold(g.country, "LAN") { @@ -37,13 +37,13 @@ func (g *GEOIP) Match(metadata *C.Metadata) bool { ip.IsLoopback() || ip.IsMulticast() || ip.IsLinkLocalUnicast() || - resolver.IsFakeBroadcastIP(ip) + resolver.IsFakeBroadcastIP(ip), g.adapter } if !C.GeodataMode { record, _ := mmdb.Instance().Country(ip.AsSlice()) - return strings.EqualFold(record.Country.IsoCode, g.country) + return strings.EqualFold(record.Country.IsoCode, g.country), g.adapter } - return g.geoIPMatcher.Match(ip.AsSlice()) + return g.geoIPMatcher.Match(ip.AsSlice()), g.adapter } func (g *GEOIP) Adapter() string { @@ -98,4 +98,4 @@ func NewGEOIP(country string, adapter string, noResolveIP bool) (*GEOIP, error) return geoip, nil } -var _ C.Rule = (*GEOIP)(nil) +//var _ C.Rule = (*GEOIP)(nil) diff --git a/rules/common/geosite.go b/rules/common/geosite.go index c88fd78d..9897f349 100644 --- a/rules/common/geosite.go +++ b/rules/common/geosite.go @@ -23,13 +23,13 @@ func (gs *GEOSITE) RuleType() C.RuleType { return C.GEOSITE } -func (gs *GEOSITE) Match(metadata *C.Metadata) bool { +func (gs *GEOSITE) Match(metadata *C.Metadata) (bool, string) { if metadata.AddrType != C.AtypDomainName { - return false + return false, "" } domain := metadata.Host - return gs.matcher.ApplyDomain(domain) + return gs.matcher.ApplyDomain(domain), gs.adapter } func (gs *GEOSITE) Adapter() string { @@ -75,4 +75,4 @@ func NewGEOSITE(country string, adapter string) (*GEOSITE, error) { return geoSite, nil } -var _ C.Rule = (*GEOSITE)(nil) +//var _ C.Rule = (*GEOSITE)(nil) diff --git a/rules/common/in_type.go b/rules/common/in_type.go index c577c843..520c9594 100644 --- a/rules/common/in_type.go +++ b/rules/common/in_type.go @@ -13,13 +13,13 @@ type InType struct { payload string } -func (u *InType) Match(metadata *C.Metadata) bool { +func (u *InType) Match(metadata *C.Metadata) (bool, string) { for _, tp := range u.types { if metadata.Type == tp { - return true + return true, u.adapter } } - return false + return false, "" } func (u *InType) RuleType() C.RuleType { diff --git a/rules/common/ipcidr.go b/rules/common/ipcidr.go index 5ac17cf4..8ab6cf5a 100644 --- a/rules/common/ipcidr.go +++ b/rules/common/ipcidr.go @@ -35,12 +35,12 @@ func (i *IPCIDR) RuleType() C.RuleType { return C.IPCIDR } -func (i *IPCIDR) Match(metadata *C.Metadata) bool { +func (i *IPCIDR) Match(metadata *C.Metadata) (bool, string) { ip := metadata.DstIP if i.isSourceIP { ip = metadata.SrcIP } - return ip.IsValid() && i.ipnet.Contains(ip) + return ip.IsValid() && i.ipnet.Contains(ip), i.adapter } func (i *IPCIDR) Adapter() string { @@ -74,4 +74,4 @@ func NewIPCIDR(s string, adapter string, opts ...IPCIDROption) (*IPCIDR, error) return ipcidr, nil } -var _ C.Rule = (*IPCIDR)(nil) +//var _ C.Rule = (*IPCIDR)(nil) diff --git a/rules/common/ipsuffix.go b/rules/common/ipsuffix.go index 18271244..b01557dc 100644 --- a/rules/common/ipsuffix.go +++ b/rules/common/ipsuffix.go @@ -22,7 +22,7 @@ func (is *IPSuffix) RuleType() C.RuleType { return C.IPSuffix } -func (is *IPSuffix) Match(metadata *C.Metadata) bool { +func (is *IPSuffix) Match(metadata *C.Metadata) (bool, string) { ip := metadata.DstIP if is.isSourceIP { ip = metadata.SrcIP @@ -30,7 +30,7 @@ func (is *IPSuffix) Match(metadata *C.Metadata) bool { mIPBytes := ip.AsSlice() if len(is.ipBytes) != len(mIPBytes) { - return false + return false, "" } size := len(mIPBytes) @@ -38,15 +38,15 @@ func (is *IPSuffix) Match(metadata *C.Metadata) bool { for i := bits / 8; i > 0; i-- { if is.ipBytes[size-i] != mIPBytes[size-i] { - return false + return false, "" } } if (is.ipBytes[size-bits/8-1] << (8 - bits%8)) != (mIPBytes[size-bits/8-1] << (8 - bits%8)) { - return false + return false, "" } - return true + return true, is.adapter } func (is *IPSuffix) Adapter() string { diff --git a/rules/common/network_type.go b/rules/common/network_type.go index 107df91e..fb6b5077 100644 --- a/rules/common/network_type.go +++ b/rules/common/network_type.go @@ -36,8 +36,8 @@ func (n *NetworkType) RuleType() C.RuleType { return C.Network } -func (n *NetworkType) Match(metadata *C.Metadata) bool { - return n.network == metadata.NetWork +func (n *NetworkType) Match(metadata *C.Metadata) (bool, string) { + return n.network == metadata.NetWork, n.adapter } func (n *NetworkType) Adapter() string { diff --git a/rules/common/port.go b/rules/common/port.go index 06fde6c2..270e5b20 100644 --- a/rules/common/port.go +++ b/rules/common/port.go @@ -24,11 +24,11 @@ func (p *Port) RuleType() C.RuleType { return C.DstPort } -func (p *Port) Match(metadata *C.Metadata) bool { +func (p *Port) Match(metadata *C.Metadata) (bool, string) { if p.isSource { - return p.matchPortReal(metadata.SrcPort) + return p.matchPortReal(metadata.SrcPort), p.adapter } - return p.matchPortReal(metadata.DstPort) + return p.matchPortReal(metadata.DstPort), p.adapter } func (p *Port) Adapter() string { diff --git a/rules/common/process.go b/rules/common/process.go index 69d83632..9263c32d 100644 --- a/rules/common/process.go +++ b/rules/common/process.go @@ -17,12 +17,12 @@ func (ps *Process) RuleType() C.RuleType { return C.Process } -func (ps *Process) Match(metadata *C.Metadata) bool { +func (ps *Process) Match(metadata *C.Metadata) (bool, string) { if ps.nameOnly { - return strings.EqualFold(metadata.Process, ps.process) + return strings.EqualFold(metadata.Process, ps.process), ps.adapter } - return strings.EqualFold(metadata.ProcessPath, ps.process) + return strings.EqualFold(metadata.ProcessPath, ps.process), ps.adapter } func (ps *Process) Adapter() string { diff --git a/rules/common/uid.go b/rules/common/uid.go index f7ea4875..5a989f67 100644 --- a/rules/common/uid.go +++ b/rules/common/uid.go @@ -71,10 +71,10 @@ func (u *Uid) RuleType() C.RuleType { return C.Uid } -func (u *Uid) Match(metadata *C.Metadata) bool { +func (u *Uid) Match(metadata *C.Metadata) (bool, string) { srcPort, err := strconv.ParseUint(metadata.SrcPort, 10, 16) if err != nil { - return false + return false, "" } var uid int32 if metadata.Uid != nil { @@ -83,15 +83,15 @@ func (u *Uid) Match(metadata *C.Metadata) bool { metadata.Uid = &uid } else { log.Warnln("[UID] could not get uid from %s", metadata.String()) - return false + return false, "" } for _, _uid := range u.uids { if _uid.Contains(uid) { - return true + return true, u.adapter } } - return false + return false, "" } func (u *Uid) Adapter() string { diff --git a/rules/logic/and.go b/rules/logic/and.go index 5a9b4d0f..a8fc1bad 100644 --- a/rules/logic/and.go +++ b/rules/logic/and.go @@ -20,9 +20,9 @@ func (A *AND) ShouldFindProcess() bool { } func NewAND(payload string, adapter string, - parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)) (*AND, error) { + parse func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) (*AND, error) { and := &AND{Base: &common.Base{}, payload: payload, adapter: adapter} - rules, err := parseRuleByPayload(payload, parse) + rules, err := ParseRuleByPayload(payload, parse) if err != nil { return nil, err } @@ -45,14 +45,14 @@ func (A *AND) RuleType() C.RuleType { return C.AND } -func (A *AND) Match(metadata *C.Metadata) bool { +func (A *AND) Match(metadata *C.Metadata) (bool, string) { for _, rule := range A.rules { - if !rule.Match(metadata) { - return false + if m, _ := rule.Match(metadata); !m { + return false, "" } } - return true + return true, A.adapter } func (A *AND) Adapter() string { diff --git a/rules/logic/common.go b/rules/logic/common.go index 736ead43..080771ba 100644 --- a/rules/logic/common.go +++ b/rules/logic/common.go @@ -9,7 +9,7 @@ import ( _ "unsafe" ) -func parseRuleByPayload(payload string, parseRule func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)) ([]C.Rule, error) { +func ParseRuleByPayload(payload string, parseRule func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) ([]C.Rule, error) { regex, err := regexp.Compile("\\(.*\\)") if err != nil { return nil, err @@ -59,13 +59,13 @@ func payloadToRule(subPayload string, parseRule func(tp, payload, target string, return parseRule(tp, param[0], "", param[1:]) } -func parseLogicSubRule(parseRule func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)) func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error) { +func parseLogicSubRule(parseRule func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error) { return func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error) { switch tp { - case "MATCH": - return nil, fmt.Errorf("unsupported rule type on logic rule") + case "MATCH", "SUB-RULE": + return nil, fmt.Errorf("unsupported rule type [%s] on logic rule", tp) default: - return parseRule(tp, payload, target, params) + return parseRule(tp, payload, target, params, nil) } } } diff --git a/rules/logic/logic_test.go b/rules/logic/logic_test.go index b7ea9ebe..dcc92d02 100644 --- a/rules/logic/logic_test.go +++ b/rules/logic/logic_test.go @@ -3,13 +3,15 @@ package logic import ( "fmt" "github.com/Dreamacro/clash/constant" + C "github.com/Dreamacro/clash/constant" RC "github.com/Dreamacro/clash/rules/common" RP "github.com/Dreamacro/clash/rules/provider" + "github.com/Dreamacro/clash/rules/sub_rule" "github.com/stretchr/testify/assert" "testing" ) -func ParseRule(tp, payload, target string, params []string) (parsed constant.Rule, parseErr error) { +func ParseRule(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed constant.Rule, parseErr error) { switch tp { case "DOMAIN": parsed = RC.NewDomain(payload, target) @@ -46,6 +48,8 @@ func ParseRule(tp, payload, target string, params []string) (parsed constant.Rul parsed, parseErr = RC.NewUid(payload, target) case "IN-TYPE": parsed, parseErr = RC.NewInType(payload, target) + case "SUB-RULE": + parsed, parseErr = sub_rule.NewSubRule(payload, target, subRules, ParseRule) case "AND": parsed, parseErr = NewAND(payload, target, ParseRule) case "OR": @@ -54,7 +58,7 @@ func ParseRule(tp, payload, target string, params []string) (parsed constant.Rul parsed, parseErr = NewNOT(payload, target, ParseRule) case "RULE-SET": noResolve := RC.HasNoResolve(params) - parsed, parseErr = RP.NewRuleSet(payload, target, noResolve, ParseRule) + parsed, parseErr = RP.NewRuleSet(payload, target, noResolve) case "MATCH": parsed = RC.NewMatch(target) parseErr = nil @@ -70,12 +74,13 @@ func TestAND(t *testing.T) { assert.Equal(t, nil, err) assert.Equal(t, "DIRECT", and.adapter) assert.Equal(t, false, and.ShouldResolveIP()) - assert.Equal(t, true, and.Match(&constant.Metadata{ + m, _ := and.Match(&constant.Metadata{ Host: "baidu.com", AddrType: constant.AtypDomainName, NetWork: constant.TCP, DstPort: "20000", - })) + }) + assert.Equal(t, true, m) and, err = NewAND("(DOMAIN,baidu.com),(NETWORK,TCP),(DST-PORT,10001-65535))", "DIRECT", ParseRule) assert.NotEqual(t, nil, err) @@ -87,9 +92,10 @@ func TestAND(t *testing.T) { func TestNOT(t *testing.T) { not, err := NewNOT("((DST-PORT,6000-6500))", "REJECT", ParseRule) assert.Equal(t, nil, err) - assert.Equal(t, false, not.Match(&constant.Metadata{ + m, _ := not.Match(&constant.Metadata{ DstPort: "6100", - })) + }) + assert.Equal(t, false, m) _, err = NewNOT("((DST-PORT,5600-6666),(DOMAIN,baidu.com))", "DIRECT", ParseRule) assert.NotEqual(t, nil, err) @@ -101,8 +107,9 @@ func TestNOT(t *testing.T) { func TestOR(t *testing.T) { or, err := NewOR("((DOMAIN,baidu.com),(NETWORK,TCP),(DST-PORT,10001-65535))", "DIRECT", ParseRule) assert.Equal(t, nil, err) - assert.Equal(t, true, or.Match(&constant.Metadata{ + m, _ := or.Match(&constant.Metadata{ NetWork: constant.TCP, - })) + }) + assert.Equal(t, true, m) assert.Equal(t, false, or.ShouldResolveIP()) } diff --git a/rules/logic/not.go b/rules/logic/not.go index dc14e1d1..e584a615 100644 --- a/rules/logic/not.go +++ b/rules/logic/not.go @@ -17,9 +17,9 @@ func (not *NOT) ShouldFindProcess() bool { return false } -func NewNOT(payload string, adapter string, parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)) (*NOT, error) { +func NewNOT(payload string, adapter string, parse func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) (*NOT, error) { not := &NOT{Base: &common.Base{}, adapter: adapter} - rule, err := parseRuleByPayload(payload, parse) + rule, err := ParseRuleByPayload(payload, parse) if err != nil { return nil, err } @@ -38,8 +38,16 @@ func (not *NOT) RuleType() C.RuleType { return C.NOT } -func (not *NOT) Match(metadata *C.Metadata) bool { - return not.rule == nil || !not.rule.Match(metadata) +func (not *NOT) Match(metadata *C.Metadata) (bool, string) { + if not.rule == nil { + return true, not.adapter + } + + if m, _ := not.rule.Match(metadata); m { + return true, not.adapter + } + + return false, "" } func (not *NOT) Adapter() string { diff --git a/rules/logic/or.go b/rules/logic/or.go index 08698b02..d1aae9ac 100644 --- a/rules/logic/or.go +++ b/rules/logic/or.go @@ -23,14 +23,14 @@ func (or *OR) RuleType() C.RuleType { return C.OR } -func (or *OR) Match(metadata *C.Metadata) bool { +func (or *OR) Match(metadata *C.Metadata) (bool, string) { for _, rule := range or.rules { - if rule.Match(metadata) { - return true + if m, _ := rule.Match(metadata); m { + return true, or.adapter } } - return false + return false, "" } func (or *OR) Adapter() string { @@ -45,9 +45,9 @@ func (or *OR) ShouldResolveIP() bool { return or.needIP } -func NewOR(payload string, adapter string, parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)) (*OR, error) { +func NewOR(payload string, adapter string, parse func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) (*OR, error) { or := &OR{Base: &common.Base{}, payload: payload, adapter: adapter} - rules, err := parseRuleByPayload(payload, parse) + rules, err := ParseRuleByPayload(payload, parse) if err != nil { return nil, err } diff --git a/rules/parser.go b/rules/parser.go index c6ca8847..878b0633 100644 --- a/rules/parser.go +++ b/rules/parser.go @@ -6,9 +6,10 @@ import ( RC "github.com/Dreamacro/clash/rules/common" "github.com/Dreamacro/clash/rules/logic" RP "github.com/Dreamacro/clash/rules/provider" + "github.com/Dreamacro/clash/rules/sub_rule" ) -func ParseRule(tp, payload, target string, params []string) (parsed C.Rule, parseErr error) { +func ParseRule(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error) { switch tp { case "DOMAIN": parsed = RC.NewDomain(payload, target) @@ -45,6 +46,8 @@ func ParseRule(tp, payload, target string, params []string) (parsed C.Rule, pars parsed, parseErr = RC.NewUid(payload, target) case "IN-TYPE": parsed, parseErr = RC.NewInType(payload, target) + case "SUB-RULE": + parsed, parseErr = sub_rule.NewSubRule(payload, target, subRules, ParseRule) case "AND": parsed, parseErr = logic.NewAND(payload, target, ParseRule) case "OR": @@ -53,7 +56,7 @@ func ParseRule(tp, payload, target string, params []string) (parsed C.Rule, pars parsed, parseErr = logic.NewNOT(payload, target, ParseRule) case "RULE-SET": noResolve := RC.HasNoResolve(params) - parsed, parseErr = RP.NewRuleSet(payload, target, noResolve, ParseRule) + parsed, parseErr = RP.NewRuleSet(payload, target, noResolve) case "MATCH": parsed = RC.NewMatch(target) parseErr = nil diff --git a/rules/provider/classical_strategy.go b/rules/provider/classical_strategy.go index 430acead..727688fc 100644 --- a/rules/provider/classical_strategy.go +++ b/rules/provider/classical_strategy.go @@ -16,7 +16,7 @@ type classicalStrategy struct { func (c *classicalStrategy) Match(metadata *C.Metadata) bool { for _, rule := range c.rules { - if rule.Match(metadata) { + if m, _ := rule.Match(metadata); m { return true } } @@ -66,13 +66,13 @@ func ruleParse(ruleRaw string) (string, string, []string) { return "", "", nil } -func NewClassicalStrategy(parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)) *classicalStrategy { +func NewClassicalStrategy(parse func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) *classicalStrategy { return &classicalStrategy{rules: []C.Rule{}, parse: func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error) { switch tp { - case "MATCH": + case "MATCH", "SUB-RULE": return nil, fmt.Errorf("unsupported rule type on rule-set") default: - return parse(tp, payload, target, params) + return parse(tp, payload, target, params, nil) } }} } diff --git a/rules/provider/parse.go b/rules/provider/parse.go index 80311af0..86e21a30 100644 --- a/rules/provider/parse.go +++ b/rules/provider/parse.go @@ -17,7 +17,7 @@ type ruleProviderSchema struct { Interval int `provider:"interval,omitempty"` } -func ParseRuleProvider(name string, mapping map[string]interface{}, parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)) (P.RuleProvider, error) { +func ParseRuleProvider(name string, mapping map[string]interface{}, parse func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) (P.RuleProvider, error) { schema := &ruleProviderSchema{} decoder := structure.NewDecoder(structure.Option{TagName: "provider", WeaklyTypedInput: true}) if err := decoder.Decode(mapping, schema); err != nil { diff --git a/rules/provider/provider.go b/rules/provider/provider.go index ce96c04f..9ae125fb 100644 --- a/rules/provider/provider.go +++ b/rules/provider/provider.go @@ -103,7 +103,7 @@ func (rp *ruleSetProvider) MarshalJSON() ([]byte, error) { } func NewRuleSetProvider(name string, behavior P.RuleType, interval time.Duration, vehicle P.Vehicle, - parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)) P.RuleProvider { + parse func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) P.RuleProvider { rp := &ruleSetProvider{ behavior: behavior, } @@ -126,7 +126,7 @@ func NewRuleSetProvider(name string, behavior P.RuleType, interval time.Duration return wrapper } -func newStrategy(behavior P.RuleType, parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)) ruleStrategy { +func newStrategy(behavior P.RuleType, parse func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) ruleStrategy { switch behavior { case P.Domain: strategy := NewDomainStrategy() diff --git a/rules/provider/rule_set.go b/rules/provider/rule_set.go index 84aaf0fb..326e3b0d 100644 --- a/rules/provider/rule_set.go +++ b/rules/provider/rule_set.go @@ -23,8 +23,8 @@ func (rs *RuleSet) RuleType() C.RuleType { return C.RuleSet } -func (rs *RuleSet) Match(metadata *C.Metadata) bool { - return rs.getProviders().Match(metadata) +func (rs *RuleSet) Match(metadata *C.Metadata) (bool, string) { + return rs.getProviders().Match(metadata), rs.adapter } func (rs *RuleSet) Adapter() string { @@ -47,7 +47,7 @@ func (rs *RuleSet) getProviders() P.RuleProvider { return rs.ruleProvider } -func NewRuleSet(ruleProviderName string, adapter string, noResolveIP bool, parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)) (*RuleSet, error) { +func NewRuleSet(ruleProviderName string, adapter string, noResolveIP bool) (*RuleSet, error) { rp, ok := RuleProviders()[ruleProviderName] if !ok { return nil, fmt.Errorf("rule set %s not found", ruleProviderName) diff --git a/rules/sub_rule/sub_rules.go b/rules/sub_rule/sub_rules.go new file mode 100644 index 00000000..2b452b5f --- /dev/null +++ b/rules/sub_rule/sub_rules.go @@ -0,0 +1,91 @@ +package sub_rule + +import ( + "fmt" + C "github.com/Dreamacro/clash/constant" + "github.com/Dreamacro/clash/rules/common" + "github.com/Dreamacro/clash/rules/logic" +) + +type SubRule struct { + *common.Base + payload string + payloadRule C.Rule + subName string + subRules *map[string][]C.Rule + shouldFindProcess *bool + shouldResolveIP *bool +} + +func NewSubRule(payload, subName string, sub *map[string][]C.Rule, + parse func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) (*SubRule, error) { + payloadRule, err := logic.ParseRuleByPayload(fmt.Sprintf("(%s)", payload), parse) + if err != nil { + return nil, err + } + if len(payloadRule) != 1 { + return nil, fmt.Errorf("Sub-Rule rule must contain one rule") + } + + return &SubRule{ + Base: &common.Base{}, + payload: payload, + payloadRule: payloadRule[0], + subName: subName, + subRules: sub, + }, nil +} + +func (r *SubRule) RuleType() C.RuleType { + return C.SubRules +} + +func (r *SubRule) Match(metadata *C.Metadata) (bool, string) { + + return match(metadata, r.subName, r.subRules) +} + +func match(metadata *C.Metadata, name string, subRules *map[string][]C.Rule) (bool, string) { + for _, rule := range (*subRules)[name] { + if m, a := rule.Match(metadata); m { + if rule.RuleType() == C.SubRules { + match(metadata, rule.Adapter(), subRules) + } else { + return m, a + } + } + } + return false, "" +} + +func (r *SubRule) ShouldResolveIP() bool { + if r.shouldResolveIP == nil { + s := false + for _, rule := range (*r.subRules)[r.subName] { + s = s || rule.ShouldResolveIP() + } + r.shouldResolveIP = &s + } + + return *r.shouldResolveIP +} + +func (r *SubRule) ShouldFindProcess() bool { + if r.shouldFindProcess == nil { + s := false + for _, rule := range (*r.subRules)[r.subName] { + s = s || rule.ShouldFindProcess() + } + r.shouldFindProcess = &s + } + + return *r.shouldFindProcess +} + +func (r *SubRule) Adapter() string { + return r.subName +} + +func (r *SubRule) Payload() string { + return r.payload +} diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index 3c74e14d..b83da180 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -410,8 +410,8 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) { } } - if rule.Match(metadata) { - adapter, ok := proxies[rule.Adapter()] + if matched, ada := rule.Match(metadata); matched { + adapter, ok := proxies[ada] if !ok { continue } From ef2f8317c7249a366d7737c8a001af81636c888e Mon Sep 17 00:00:00 2001 From: metacubex Date: Sun, 11 Sep 2022 15:24:56 +0800 Subject: [PATCH 09/22] Fix: wechat protocol is not working if no obfs string is configured --- transport/hysteria/obfs/dummy.go | 18 ++++++++++++++++++ transport/hysteria/transport/client.go | 14 ++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 transport/hysteria/obfs/dummy.go diff --git a/transport/hysteria/obfs/dummy.go b/transport/hysteria/obfs/dummy.go new file mode 100644 index 00000000..3edff101 --- /dev/null +++ b/transport/hysteria/obfs/dummy.go @@ -0,0 +1,18 @@ +package obfs + +type DummyObfuscator struct{} + +func NewDummyObfuscator() *DummyObfuscator { + return &DummyObfuscator{} +} + +func (x *DummyObfuscator) Deobfuscate(in []byte, out []byte) int { + if len(out) < len(in) { + return 0 + } + return copy(out, in) +} + +func (x *DummyObfuscator) Obfuscate(in []byte, out []byte) int { + return copy(out, in) +} diff --git a/transport/hysteria/transport/client.go b/transport/hysteria/transport/client.go index d350b4ad..43330cd3 100644 --- a/transport/hysteria/transport/client.go +++ b/transport/hysteria/transport/client.go @@ -7,7 +7,7 @@ import ( "github.com/Dreamacro/clash/transport/hysteria/conns/faketcp" "github.com/Dreamacro/clash/transport/hysteria/conns/udp" "github.com/Dreamacro/clash/transport/hysteria/conns/wechat" - "github.com/Dreamacro/clash/transport/hysteria/obfs" + obfsPkg "github.com/Dreamacro/clash/transport/hysteria/obfs" "github.com/lucas-clemente/quic-go" "net" ) @@ -16,7 +16,7 @@ type ClientTransport struct { Dialer *net.Dialer } -func (ct *ClientTransport) quicPacketConn(proto string, server string, obfs obfs.Obfuscator, dialer PacketDialer) (net.PacketConn, error) { +func (ct *ClientTransport) quicPacketConn(proto string, server string, obfs obfsPkg.Obfuscator, dialer PacketDialer) (net.PacketConn, error) { if len(proto) == 0 || proto == "udp" { conn, err := dialer.ListenPacket() if err != nil { @@ -33,12 +33,10 @@ func (ct *ClientTransport) quicPacketConn(proto string, server string, obfs obfs if err != nil { return nil, err } - if obfs != nil { - oc := wechat.NewObfsWeChatUDPConn(conn, obfs) - return oc, nil - } else { - return conn, nil + if obfs == nil { + obfs = obfsPkg.NewDummyObfuscator() } + return wechat.NewObfsWeChatUDPConn(conn, obfs), nil } else if proto == "faketcp" { var conn *faketcp.TCPConn conn, err := faketcp.Dial("tcp", server) @@ -62,7 +60,7 @@ type PacketDialer interface { RemoteAddr(host string) (net.Addr, error) } -func (ct *ClientTransport) QUICDial(proto string, server string, tlsConfig *tls.Config, quicConfig *quic.Config, obfs obfs.Obfuscator, dialer PacketDialer) (quic.Connection, error) { +func (ct *ClientTransport) QUICDial(proto string, server string, tlsConfig *tls.Config, quicConfig *quic.Config, obfs obfsPkg.Obfuscator, dialer PacketDialer) (quic.Connection, error) { serverUDPAddr, err := dialer.RemoteAddr(server) if err != nil { return nil, err From 4597ed49cfef9a6a41a6bee3b6e574b390953701 Mon Sep 17 00:00:00 2001 From: Skyxim Date: Sun, 11 Sep 2022 16:19:42 +0800 Subject: [PATCH 10/22] fix: adjust sub_rule to logic package, and fix not rule failed --- rules/logic/logic_test.go | 18 ++++++++---------- rules/logic/not.go | 2 +- rules/{sub_rule => logic}/sub_rules.go | 6 +++--- rules/parser.go | 3 +-- 4 files changed, 13 insertions(+), 16 deletions(-) rename rules/{sub_rule => logic}/sub_rules.go (93%) diff --git a/rules/logic/logic_test.go b/rules/logic/logic_test.go index dcc92d02..4ec72cc4 100644 --- a/rules/logic/logic_test.go +++ b/rules/logic/logic_test.go @@ -2,16 +2,14 @@ package logic import ( "fmt" - "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant" RC "github.com/Dreamacro/clash/rules/common" RP "github.com/Dreamacro/clash/rules/provider" - "github.com/Dreamacro/clash/rules/sub_rule" "github.com/stretchr/testify/assert" "testing" ) -func ParseRule(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed constant.Rule, parseErr error) { +func ParseRule(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error) { switch tp { case "DOMAIN": parsed = RC.NewDomain(payload, target) @@ -49,7 +47,7 @@ func ParseRule(tp, payload, target string, params []string, subRules *map[string case "IN-TYPE": parsed, parseErr = RC.NewInType(payload, target) case "SUB-RULE": - parsed, parseErr = sub_rule.NewSubRule(payload, target, subRules, ParseRule) + parsed, parseErr = NewSubRule(payload, target, subRules, ParseRule) case "AND": parsed, parseErr = NewAND(payload, target, ParseRule) case "OR": @@ -74,10 +72,10 @@ func TestAND(t *testing.T) { assert.Equal(t, nil, err) assert.Equal(t, "DIRECT", and.adapter) assert.Equal(t, false, and.ShouldResolveIP()) - m, _ := and.Match(&constant.Metadata{ + m, _ := and.Match(&C.Metadata{ Host: "baidu.com", - AddrType: constant.AtypDomainName, - NetWork: constant.TCP, + AddrType: C.AtypDomainName, + NetWork: C.TCP, DstPort: "20000", }) assert.Equal(t, true, m) @@ -92,7 +90,7 @@ func TestAND(t *testing.T) { func TestNOT(t *testing.T) { not, err := NewNOT("((DST-PORT,6000-6500))", "REJECT", ParseRule) assert.Equal(t, nil, err) - m, _ := not.Match(&constant.Metadata{ + m, _ := not.Match(&C.Metadata{ DstPort: "6100", }) assert.Equal(t, false, m) @@ -107,8 +105,8 @@ func TestNOT(t *testing.T) { func TestOR(t *testing.T) { or, err := NewOR("((DOMAIN,baidu.com),(NETWORK,TCP),(DST-PORT,10001-65535))", "DIRECT", ParseRule) assert.Equal(t, nil, err) - m, _ := or.Match(&constant.Metadata{ - NetWork: constant.TCP, + m, _ := or.Match(&C.Metadata{ + NetWork: C.TCP, }) assert.Equal(t, true, m) assert.Equal(t, false, or.ShouldResolveIP()) diff --git a/rules/logic/not.go b/rules/logic/not.go index e584a615..6a5b34d8 100644 --- a/rules/logic/not.go +++ b/rules/logic/not.go @@ -43,7 +43,7 @@ func (not *NOT) Match(metadata *C.Metadata) (bool, string) { return true, not.adapter } - if m, _ := not.rule.Match(metadata); m { + if m, _ := not.rule.Match(metadata); !m { return true, not.adapter } diff --git a/rules/sub_rule/sub_rules.go b/rules/logic/sub_rules.go similarity index 93% rename from rules/sub_rule/sub_rules.go rename to rules/logic/sub_rules.go index 2b452b5f..b4ad7613 100644 --- a/rules/sub_rule/sub_rules.go +++ b/rules/logic/sub_rules.go @@ -1,10 +1,10 @@ -package sub_rule +package logic import ( "fmt" + C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/rules/common" - "github.com/Dreamacro/clash/rules/logic" ) type SubRule struct { @@ -19,7 +19,7 @@ type SubRule struct { func NewSubRule(payload, subName string, sub *map[string][]C.Rule, parse func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) (*SubRule, error) { - payloadRule, err := logic.ParseRuleByPayload(fmt.Sprintf("(%s)", payload), parse) + payloadRule, err := ParseRuleByPayload(fmt.Sprintf("(%s)", payload), parse) if err != nil { return nil, err } diff --git a/rules/parser.go b/rules/parser.go index 878b0633..6f9e229f 100644 --- a/rules/parser.go +++ b/rules/parser.go @@ -6,7 +6,6 @@ import ( RC "github.com/Dreamacro/clash/rules/common" "github.com/Dreamacro/clash/rules/logic" RP "github.com/Dreamacro/clash/rules/provider" - "github.com/Dreamacro/clash/rules/sub_rule" ) func ParseRule(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error) { @@ -47,7 +46,7 @@ func ParseRule(tp, payload, target string, params []string, subRules *map[string case "IN-TYPE": parsed, parseErr = RC.NewInType(payload, target) case "SUB-RULE": - parsed, parseErr = sub_rule.NewSubRule(payload, target, subRules, ParseRule) + parsed, parseErr = logic.NewSubRule(payload, target, subRules, ParseRule) case "AND": parsed, parseErr = logic.NewAND(payload, target, ParseRule) case "OR": From 6e8d8befb8dcbaf72a6b1733e27d9c3516286ce6 Mon Sep 17 00:00:00 2001 From: Ross Shen Date: Sun, 18 Sep 2022 23:19:25 +0800 Subject: [PATCH 11/22] docker: add iptables package --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 44dc3b52..c7a864e7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,11 +16,11 @@ RUN go mod download &&\ FROM alpine:latest LABEL org.opencontainers.image.source="https://github.com/MetaCubeX/Clash.Meta" -RUN apk add --no-cache ca-certificates tzdata +RUN apk add --no-cache ca-certificates tzdata iptables VOLUME ["/root/.config/clash/"] COPY --from=builder /clash-config/ /root/.config/clash/ COPY --from=builder /clash /clash RUN chmod +x /clash -ENTRYPOINT [ "/clash" ] \ No newline at end of file +ENTRYPOINT [ "/clash" ] From e1ec4a250274c5f207e679de0c43075136718504 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Mon, 19 Sep 2022 17:37:16 +0800 Subject: [PATCH 12/22] fix: wrong host shown when using uot --- adapter/outbound/shadowsocks.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/adapter/outbound/shadowsocks.go b/adapter/outbound/shadowsocks.go index b26f8802..60a7c334 100644 --- a/adapter/outbound/shadowsocks.go +++ b/adapter/outbound/shadowsocks.go @@ -82,8 +82,7 @@ func (ss *ShadowSocks) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, e } } if metadata.NetWork == C.UDP && ss.option.UDPOverTCP { - metadata.Host = uot.UOTMagicAddress - metadata.DstPort = "443" + return ss.method.DialConn(c, M.ParseSocksaddr(uot.UOTMagicAddress+":443")) } return ss.method.DialConn(c, M.ParseSocksaddr(metadata.RemoteAddress())) } From 82c9a1a2bb8df912c8bad5980dc4e22e4692cafb Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Mon, 19 Sep 2022 18:26:43 +0800 Subject: [PATCH 13/22] chore: add xudp support for vmess --- adapter/outbound/vmess.go | 30 ++++++++++++++++++++++++++---- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/adapter/outbound/vmess.go b/adapter/outbound/vmess.go index fc8e1e87..e8c0b7ab 100644 --- a/adapter/outbound/vmess.go +++ b/adapter/outbound/vmess.go @@ -52,6 +52,8 @@ type VmessOption struct { GrpcOpts GrpcOptions `proxy:"grpc-opts,omitempty"` WSOpts WSOptions `proxy:"ws-opts,omitempty"` PacketAddr bool `proxy:"packet-addr,omitempty"` + XUDP bool `proxy:"xudp,omitempty"` + PacketEncoding string `proxy:"packet_encoding,omitempty"` AuthenticatedLength bool `proxy:"authenticated-length,omitempty"` } @@ -197,7 +199,11 @@ func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { return nil, err } if metadata.NetWork == C.UDP { - return v.client.DialPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress())) + if v.option.XUDP { + return v.client.DialXUDPPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress())) + } else { + return v.client.DialPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress())) + } } else { return v.client.DialConn(c, M.ParseSocksaddr(metadata.RemoteAddress())) } @@ -244,6 +250,8 @@ func (v *Vmess) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o } if v.option.PacketAddr { + _metadata := *metadata // make a copy + metadata = &_metadata metadata.Host = packetaddr.SeqPacketMagicAddress metadata.DstPort = "443" } @@ -257,7 +265,11 @@ func (v *Vmess) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o } defer safeConnClose(c, err) - c, err = v.client.DialPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress())) + if v.option.XUDP { + c, err = v.client.DialXUDPPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress())) + } else { + c, err = v.client.DialPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress())) + } } else { c, err = dialer.DialContext(ctx, "tcp", v.addr, v.Base.DialOptions(opts...)...) if err != nil { @@ -274,7 +286,7 @@ func (v *Vmess) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o } if v.option.PacketAddr { - return newPacketConn(&threadSafePacketConn{PacketConn: packetaddr.NewBindClient(c)}, v), nil + return newPacketConn(&threadSafePacketConn{PacketConn: packetaddr.NewBindConn(c)}, v), nil } else if pc, ok := c.(net.PacketConn); ok { return newPacketConn(&threadSafePacketConn{PacketConn: pc}, v), nil } @@ -284,7 +296,7 @@ func (v *Vmess) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o // ListenPacketOnStreamConn implements C.ProxyAdapter func (v *Vmess) ListenPacketOnStreamConn(c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) { if v.option.PacketAddr { - return newPacketConn(&threadSafePacketConn{PacketConn: packetaddr.NewBindClient(c)}, v), nil + return newPacketConn(&threadSafePacketConn{PacketConn: packetaddr.NewBindConn(c)}, v), nil } else if pc, ok := c.(net.PacketConn); ok { return newPacketConn(&threadSafePacketConn{PacketConn: pc}, v), nil } @@ -307,6 +319,16 @@ func NewVmess(option VmessOption) (*Vmess, error) { return nil, err } + switch option.PacketEncoding { + case "packetaddr": + option.PacketAddr = true + case "xudp": + option.XUDP = true + } + if option.XUDP { + option.PacketAddr = false + } + switch option.Network { case "h2", "grpc": if !option.TLS { diff --git a/go.mod b/go.mod index a6ecb70e..8613fb18 100644 --- a/go.mod +++ b/go.mod @@ -19,9 +19,9 @@ require ( github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 github.com/miekg/dns v1.1.49 github.com/oschwald/geoip2-golang v1.7.0 - github.com/sagernet/sing v0.0.0-20220627234642-a817f7084d9c - github.com/sagernet/sing-shadowsocks v0.0.0-20220627234717-689e0165ef2c - github.com/sagernet/sing-vmess v0.0.0-20220616051646-3d3fc5d01eec + github.com/sagernet/sing v0.0.0-20220916071326-834794b006ea + github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 + github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.2 github.com/vishvananda/netlink v1.2.1-beta.2 @@ -29,11 +29,11 @@ require ( go.etcd.io/bbolt v1.3.6 go.uber.org/atomic v1.9.0 go.uber.org/automaxprocs v1.5.1 - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e + golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 golang.org/x/exp v0.0.0-20220608143224-64259d1afd70 golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f - golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e + golang.org/x/sys v0.0.0-20220913120320-3275c407cedc golang.org/x/time v0.0.0-20220411224347-583f2d630306 golang.zx2c4.com/wireguard v0.0.0-20220601130007-6a08d81f6bc4 golang.zx2c4.com/wireguard/windows v0.5.4-0.20220328111914-004c22c5647e diff --git a/go.sum b/go.sum index a1c42dc0..c1654e72 100644 --- a/go.sum +++ b/go.sum @@ -175,12 +175,12 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sagernet/sing v0.0.0-20220627234642-a817f7084d9c h1:98QC0wtaD648MFPw82KaT1O9LloQgR4ZyIDtNtsno8Y= -github.com/sagernet/sing v0.0.0-20220627234642-a817f7084d9c/go.mod h1:I67R/q5f67xDExL2kL3RLIP7kGJBOPkYXkpRAykgC+E= -github.com/sagernet/sing-shadowsocks v0.0.0-20220627234717-689e0165ef2c h1:Jhgjyb2jXL4GtwJec6/kgeTqaQXsvMiNX2wAkGOSD3I= -github.com/sagernet/sing-shadowsocks v0.0.0-20220627234717-689e0165ef2c/go.mod h1:ng5pxdNnKZWlxzZTXRqWeY0ftzhScPZmjgJGJeRuPYY= -github.com/sagernet/sing-vmess v0.0.0-20220616051646-3d3fc5d01eec h1:jUSfKmyL6K9O2TvIvcVacZ4eNXHYbNSfdph+DRPyVlU= -github.com/sagernet/sing-vmess v0.0.0-20220616051646-3d3fc5d01eec/go.mod h1:jDZ8fJgOea7Y7MMHWgfqwLBVLnhtW2zuxS5wjtDaB84= +github.com/sagernet/sing v0.0.0-20220916071326-834794b006ea h1:ZAWvZdeByPBBz3Vs+w3Erbh+DDo7D4biokoPhXl0nNU= +github.com/sagernet/sing v0.0.0-20220916071326-834794b006ea/go.mod h1:x3NHUeJBQwV75L51zwmLKQdLtRvR+M4PmXkfQtU1vIY= +github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4= +github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM= +github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d h1:/GNWxSrQj4chFYk2jahIXNPdvUa9DW8IdgyqYFbq9oQ= +github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d/go.mod h1:u66Vv7NHXJWfeAmhh7JuJp/cwxmuQlM56QoZ7B7Mmd0= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -247,8 +247,8 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= +golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220608143224-64259d1afd70 h1:8uGxpY2cLF9H/NSHUiEWUIBZqIcsMzMWIMPCCUkyYgc= golang.org/x/exp v0.0.0-20220608143224-64259d1afd70/go.mod h1:yh0Ynu2b5ZUe3MQfp2nM0ecK7wsgouWTDN0FNeJuIys= @@ -337,8 +337,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e h1:NHvCuwuS43lGnYhten69ZWqi2QOj/CiDNcKbVqwVoew= -golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220913120320-3275c407cedc h1:dpclq5m2YrqPGStKmtw7IcNbKLfbIqKXvNxDJKdIKYc= +golang.org/x/sys v0.0.0-20220913120320-3275c407cedc/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From b133bc58f02e60bf2b21598bcbc8d4bb2c1d4fa6 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Wed, 21 Sep 2022 19:06:13 +0800 Subject: [PATCH 14/22] fix: upgrade sing-vmess to let xudp work --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 8613fb18..08a8d3d2 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/go-chi/chi/v5 v5.0.7 github.com/go-chi/cors v1.2.1 github.com/go-chi/render v1.0.1 - github.com/gofrs/uuid v4.2.0+incompatible + github.com/gofrs/uuid v4.3.0+incompatible github.com/google/gopacket v1.1.19 github.com/gorilla/websocket v1.5.0 github.com/hashicorp/golang-lru v0.5.4 @@ -19,9 +19,9 @@ require ( github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 github.com/miekg/dns v1.1.49 github.com/oschwald/geoip2-golang v1.7.0 - github.com/sagernet/sing v0.0.0-20220916071326-834794b006ea + github.com/sagernet/sing v0.0.0-20220921101604-86d7d510231f github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 - github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d + github.com/sagernet/sing-vmess v0.0.0-20220921104047-5231f5f964db github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.2 github.com/vishvananda/netlink v1.2.1-beta.2 @@ -29,7 +29,7 @@ require ( go.etcd.io/bbolt v1.3.6 go.uber.org/atomic v1.9.0 go.uber.org/automaxprocs v1.5.1 - golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 + golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 golang.org/x/exp v0.0.0-20220608143224-64259d1afd70 golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f diff --git a/go.sum b/go.sum index c1654e72..36e61f1c 100644 --- a/go.sum +++ b/go.sum @@ -49,8 +49,8 @@ github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1 github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= -github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= +github.com/gofrs/uuid v4.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= @@ -175,12 +175,12 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sagernet/sing v0.0.0-20220916071326-834794b006ea h1:ZAWvZdeByPBBz3Vs+w3Erbh+DDo7D4biokoPhXl0nNU= -github.com/sagernet/sing v0.0.0-20220916071326-834794b006ea/go.mod h1:x3NHUeJBQwV75L51zwmLKQdLtRvR+M4PmXkfQtU1vIY= +github.com/sagernet/sing v0.0.0-20220921101604-86d7d510231f h1:GX416thAwyc0vHBOal/qplvdhFgYO2dHD5GqADCJ0Ig= +github.com/sagernet/sing v0.0.0-20220921101604-86d7d510231f/go.mod h1:x3NHUeJBQwV75L51zwmLKQdLtRvR+M4PmXkfQtU1vIY= github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4= github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM= -github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d h1:/GNWxSrQj4chFYk2jahIXNPdvUa9DW8IdgyqYFbq9oQ= -github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d/go.mod h1:u66Vv7NHXJWfeAmhh7JuJp/cwxmuQlM56QoZ7B7Mmd0= +github.com/sagernet/sing-vmess v0.0.0-20220921104047-5231f5f964db h1:9tY1sePDOPOlXipWda6H80Egv28OLyaepO5HQmlT7TM= +github.com/sagernet/sing-vmess v0.0.0-20220921104047-5231f5f964db/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -247,8 +247,8 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 h1:a5Yg6ylndHHYJqIPrdq0AhvR6KTvDTAvgBtaidhEevY= +golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220608143224-64259d1afd70 h1:8uGxpY2cLF9H/NSHUiEWUIBZqIcsMzMWIMPCCUkyYgc= golang.org/x/exp v0.0.0-20220608143224-64259d1afd70/go.mod h1:yh0Ynu2b5ZUe3MQfp2nM0ecK7wsgouWTDN0FNeJuIys= From 88e4a9a755a2e8488cf98e82133221f20e0389f5 Mon Sep 17 00:00:00 2001 From: Stash Networks Date: Wed, 21 Sep 2022 23:42:33 +0800 Subject: [PATCH 15/22] Chore: compatible with Stash hysteria config --- adapter/outbound/hysteria.go | 74 +++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/adapter/outbound/hysteria.go b/adapter/outbound/hysteria.go index 9446cf93..490b14e1 100644 --- a/adapter/outbound/hysteria.go +++ b/adapter/outbound/hysteria.go @@ -4,27 +4,29 @@ import ( "context" "crypto/sha256" "crypto/tls" + "encoding/base64" "encoding/hex" "encoding/pem" "fmt" - tlsC "github.com/Dreamacro/clash/component/tls" - "github.com/Dreamacro/clash/transport/hysteria/core" - "github.com/Dreamacro/clash/transport/hysteria/obfs" - "github.com/Dreamacro/clash/transport/hysteria/pmtud_fix" - "github.com/Dreamacro/clash/transport/hysteria/transport" - "github.com/lucas-clemente/quic-go" "net" "os" "regexp" "strconv" "time" + "github.com/lucas-clemente/quic-go" + "github.com/lucas-clemente/quic-go/congestion" + M "github.com/sagernet/sing/common/metadata" + "github.com/Dreamacro/clash/component/dialer" + tlsC "github.com/Dreamacro/clash/component/tls" C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/log" hyCongestion "github.com/Dreamacro/clash/transport/hysteria/congestion" - "github.com/lucas-clemente/quic-go/congestion" - M "github.com/sagernet/sing/common/metadata" + "github.com/Dreamacro/clash/transport/hysteria/core" + "github.com/Dreamacro/clash/transport/hysteria/obfs" + "github.com/Dreamacro/clash/transport/hysteria/pmtud_fix" + "github.com/Dreamacro/clash/transport/hysteria/transport" ) const ( @@ -85,23 +87,27 @@ func (h *Hysteria) ListenPacketContext(ctx context.Context, metadata *C.Metadata type HysteriaOption struct { BasicOption - Name string `proxy:"name"` - Server string `proxy:"server"` - Port int `proxy:"port"` - Protocol string `proxy:"protocol,omitempty"` - Up string `proxy:"up"` - Down string `proxy:"down"` - AuthString string `proxy:"auth_str,omitempty"` - Obfs string `proxy:"obfs,omitempty"` - SNI string `proxy:"sni,omitempty"` - SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"` - Fingerprint string `proxy:"fingerprint,omitempty"` - ALPN string `proxy:"alpn,omitempty"` - CustomCA string `proxy:"ca,omitempty"` - CustomCAString string `proxy:"ca_str,omitempty"` - ReceiveWindowConn int `proxy:"recv_window_conn,omitempty"` - ReceiveWindow int `proxy:"recv_window,omitempty"` - DisableMTUDiscovery bool `proxy:"disable_mtu_discovery,omitempty"` + Name string `proxy:"name"` + Server string `proxy:"server"` + Port int `proxy:"port"` + Protocol string `proxy:"protocol,omitempty"` + ObfsProtocol string `proxy:"obfs-protocol,omitempty"` // compatible with Stash + Up string `proxy:"up"` + UpSpeed int `proxy:"up-speed,omitempty"` // compatible with Stash + Down string `proxy:"down"` + DownSpeed int `proxy:"down-speed,omitempty"` // compatible with Stash + Auth string `proxy:"auth,omitempty"` + AuthString string `proxy:"auth_str,omitempty"` + Obfs string `proxy:"obfs,omitempty"` + SNI string `proxy:"sni,omitempty"` + SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"` + Fingerprint string `proxy:"fingerprint,omitempty"` + ALPN []string `proxy:"alpn,omitempty"` + CustomCA string `proxy:"ca,omitempty"` + CustomCAString string `proxy:"ca_str,omitempty"` + ReceiveWindowConn int `proxy:"recv_window_conn,omitempty"` + ReceiveWindow int `proxy:"recv_window,omitempty"` + DisableMTUDiscovery bool `proxy:"disable_mtu_discovery,omitempty"` } func (c *HysteriaOption) Speed() (uint64, uint64, error) { @@ -172,7 +178,7 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) { } if len(option.ALPN) > 0 { - tlsConfig.NextProtos = []string{option.ALPN} + tlsConfig.NextProtos = option.ALPN } else { tlsConfig.NextProtos = []string{DefaultALPN} } @@ -186,6 +192,9 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) { DisablePathMTUDiscovery: option.DisableMTUDiscovery, EnableDatagrams: true, } + if option.ObfsProtocol != "" { + option.Protocol = option.ObfsProtocol + } if option.Protocol == "" { option.Protocol = DefaultProtocol } @@ -202,6 +211,12 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) { } var auth = []byte(option.AuthString) + if option.Auth != "" { + auth, err = base64.StdEncoding.DecodeString(option.Auth) + if err != nil { + return nil, err + } + } var obfuscator obfs.Obfuscator if len(option.Obfs) > 0 { obfuscator = obfs.NewXPlusObfuscator([]byte(option.Obfs)) @@ -211,7 +226,12 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) { if err != nil { return nil, err } - + if option.UpSpeed != 0 { + up = uint64(option.UpSpeed * mbpsToBps) + } + if option.DownSpeed != 0 { + down = uint64(option.DownSpeed * mbpsToBps) + } client, err := core.NewClient( addr, option.Protocol, auth, tlsConfig, quicConfig, clientTransport, up, down, func(refBPS uint64) congestion.CongestionControl { return hyCongestion.NewBrutalSender(congestion.ByteCount(refBPS)) From 7e9549c05a1f1c144bc0ae86c0be8a9ceb671c96 Mon Sep 17 00:00:00 2001 From: oluceps Date: Sat, 1 Oct 2022 22:34:39 +0800 Subject: [PATCH 16/22] add: flake.nix and other required files for nix build --- default.nix | 41 +++++++++++++++++++++++++++++++++++++++++ flake.lock | 43 +++++++++++++++++++++++++++++++++++++++++++ flake.nix | 19 +++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100755 default.nix create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/default.nix b/default.nix new file mode 100755 index 00000000..112c3d35 --- /dev/null +++ b/default.nix @@ -0,0 +1,41 @@ +{ lib +, fetchFromGitHub +, buildGoModule +}: +buildGoModule rec { + pname = "clash-meta"; + version = "1.13.1"; + + src = fetchFromGitHub { + owner = "MetaCubeX"; + repo = "Clash.Meta"; + rev = "1684756b79a232ee8f875bcfd87371f5c0ef066b"; + sha256 = "sha256-7g/Wcll0w4EhPI+KodtLHINqaR2larQNnP9YAsgNiN4="; + }; + + vendorSha256 = "sha256-7HjYcoqWA5gvPUc5psCgy0UTc17CBzBJ/OiGvII/iBA="; + + # Do not build testing suit + excludedPackages = [ "./test" ]; + + CGO_ENABLED = 0; + + ldflags = [ + "-s" + "-w" + "-X github.com/Dreamacro/clash/constant.Version=${version}" + ]; + + # network required + doCheck = false; + + postInstall = '' + mv $out/bin/clash $out/bin/clash-meta + ''; + + meta = with lib; { + description = "Another Clash Kernel"; + homepage = "https://github.com/MetaCubeX/Clash.Meta"; + license = licenses.gpl3Only; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..df343f24 --- /dev/null +++ b/flake.lock @@ -0,0 +1,43 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1664614409, + "narHash": "sha256-5y+zhLMzc/k4NYnCfW+seM9oaNuUI/UeGMGPFRj8cR0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b746456c6f6ef8404ef6011df5eceba8644c49a9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "master", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "utils": "utils" + } + }, + "utils": { + "locked": { + "lastModified": 1659877975, + "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..297a284f --- /dev/null +++ b/flake.nix @@ -0,0 +1,19 @@ +{ + description = "Another Clash Kernel"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/master"; + + inputs.utils.url = "github:numtide/flake-utils"; + + outputs = { self, nixpkgs, utils }: + (utils.lib.eachDefaultSystem + (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + + { + defaultPackages = pkgs.callPackage ./. { }; + }) + ); +} From 1bcc916807702768826edc54a865a51b5185c785 Mon Sep 17 00:00:00 2001 From: metacubex Date: Sat, 1 Oct 2022 23:09:23 +0800 Subject: [PATCH 17/22] chore: upgrade dependencies --- go.mod | 60 ++++++++++++++-------------- go.sum | 123 ++++++++++++++++++++++++++++++--------------------------- 2 files changed, 94 insertions(+), 89 deletions(-) diff --git a/go.mod b/go.mod index 08a8d3d2..34c45cda 100644 --- a/go.mod +++ b/go.mod @@ -3,43 +3,43 @@ module github.com/Dreamacro/clash go 1.19 require ( - github.com/cilium/ebpf v0.9.1 + github.com/cilium/ebpf v0.9.3 github.com/coreos/go-iptables v0.6.0 - github.com/database64128/tfo-go v1.1.0 - github.com/dlclark/regexp2 v1.4.0 + github.com/database64128/tfo-go v1.1.2 + github.com/dlclark/regexp2 v1.7.0 github.com/go-chi/chi/v5 v5.0.7 github.com/go-chi/cors v1.2.1 - github.com/go-chi/render v1.0.1 + github.com/go-chi/render v1.0.2 github.com/gofrs/uuid v4.3.0+incompatible github.com/google/gopacket v1.1.19 github.com/gorilla/websocket v1.5.0 github.com/hashicorp/golang-lru v0.5.4 - github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f - github.com/lucas-clemente/quic-go v0.27.2 + github.com/insomniacslk/dhcp v0.0.0-20221001123530-5308ebe5334c + github.com/lucas-clemente/quic-go v0.29.1 github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 - github.com/miekg/dns v1.1.49 - github.com/oschwald/geoip2-golang v1.7.0 + github.com/miekg/dns v1.1.50 + github.com/oschwald/geoip2-golang v1.8.0 github.com/sagernet/sing v0.0.0-20220921101604-86d7d510231f github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 - github.com/sagernet/sing-vmess v0.0.0-20220921104047-5231f5f964db - github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.7.2 + github.com/sagernet/sing-vmess v0.0.0-20220921140858-b6a1bdee672f + github.com/sirupsen/logrus v1.9.0 + github.com/stretchr/testify v1.8.0 github.com/vishvananda/netlink v1.2.1-beta.2 - github.com/xtls/go v0.0.0-20210920065950-d4af136d3672 + github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837 go.etcd.io/bbolt v1.3.6 - go.uber.org/atomic v1.9.0 + go.uber.org/atomic v1.10.0 go.uber.org/automaxprocs v1.5.1 - golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 - golang.org/x/exp v0.0.0-20220608143224-64259d1afd70 - golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e - golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f - golang.org/x/sys v0.0.0-20220913120320-3275c407cedc - golang.org/x/time v0.0.0-20220411224347-583f2d630306 - golang.zx2c4.com/wireguard v0.0.0-20220601130007-6a08d81f6bc4 + golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be + golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 + golang.org/x/net v0.0.0-20220930213112-107f3e3c3b0b + golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 + golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec + golang.org/x/time v0.0.0-20220922220347-f3bd1da661af + golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c golang.zx2c4.com/wireguard/windows v0.5.4-0.20220328111914-004c22c5647e - google.golang.org/protobuf v1.28.0 + google.golang.org/protobuf v1.28.1 gopkg.in/yaml.v3 v3.0.1 - gvisor.dev/gvisor v0.0.0-20220810234332-45096a971e66 + gvisor.dev/gvisor v0.0.0-20220930175839-a705f5d5e730 ) replace github.com/vishvananda/netlink => github.com/MetaCubeX/netlink v1.2.0-beta.0.20220529072258-d6853f887820 @@ -47,27 +47,27 @@ replace github.com/vishvananda/netlink => github.com/MetaCubeX/netlink v1.2.0-be replace github.com/lucas-clemente/quic-go => github.com/tobyxdd/quic-go v0.28.1-0.20220706211558-7780039ad599 require ( + github.com/ajg/form v1.5.1 // indirect github.com/cheekybits/genny v1.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect - github.com/google/btree v1.0.1 // indirect - github.com/klauspost/cpuid/v2 v2.0.12 // indirect + github.com/google/btree v1.1.2 // indirect + github.com/klauspost/cpuid/v2 v2.1.1 // indirect github.com/marten-seemann/qpack v0.2.1 // indirect github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect github.com/marten-seemann/qtls-go1-17 v0.1.2 // indirect github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect - github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1 // indirect + github.com/marten-seemann/qtls-go1-19 v0.1.0 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/onsi/ginkgo v1.16.5 // indirect - github.com/oschwald/maxminddb-golang v1.9.0 // indirect + github.com/oschwald/maxminddb-golang v1.10.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/u-root/uio v0.0.0-20220204230159-dac05f7d2cb4 // indirect - github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect - golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect + github.com/vishvananda/netns v0.0.0-20220913150850-18c4f4234207 // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/text v0.3.8-0.20220124021120-d1c84af989ab // indirect - golang.org/x/tools v0.1.10 // indirect - golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect + golang.org/x/tools v0.1.12 // indirect golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect diff --git a/go.sum b/go.sum index 36e61f1c..b4e55d35 100644 --- a/go.sum +++ b/go.sum @@ -10,25 +10,27 @@ git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGy github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/MetaCubeX/netlink v1.2.0-beta.0.20220529072258-d6853f887820 h1:fGKWZ25VApYnuPZoNeqdH/nZtHa2XMajwH6Yj/OgoVc= github.com/MetaCubeX/netlink v1.2.0-beta.0.20220529072258-d6853f887820/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= -github.com/cilium/ebpf v0.9.1 h1:64sn2K3UKw8NbP/blsixRpF3nXuyhz/VjRlRzvlBRu4= -github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY= +github.com/cilium/ebpf v0.9.3 h1:5KtxXZU+scyERvkJMEm16TbScVvuuMrlhPly78ZMbSc= +github.com/cilium/ebpf v0.9.3/go.mod h1:w27N4UjpaQ9X/DGrSugxUG+H+NhgntDuPb5lCzxCn8A= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk= github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/database64128/tfo-go v1.1.0 h1:VO0polyGNSAmr99nYw9GQeMz7ZOcQ/QbjlTwniHwfTQ= -github.com/database64128/tfo-go v1.1.0/go.mod h1:95pOT8bnV3P2Lmu9upHNWFHz6dYGJ9cr7pnb0tGQAG8= +github.com/database64128/tfo-go v1.1.2 h1:GwxtJp09BdUTVEoeT421t231eNZoGOCRkklbl4WI1kU= +github.com/database64128/tfo-go v1.1.2/go.mod h1:jgrSUPyOvTGQyn6irCOpk7L2W/q/0VLZZcovQiMi+bI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= -github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod h1:PjfxuH4FZdUyfMdtBio2lsRr1AKEaVPwelzuHuh8Lqc= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= @@ -44,8 +46,8 @@ github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= -github.com/go-chi/render v1.0.1 h1:4/5tis2cKaNdnv9zFLfXzcquC9HbeZgCnxGnKrltBS8= -github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns= +github.com/go-chi/render v1.0.2 h1:4ER/udB0+fMWB2Jlf15RV3F4A2FDuYi/9f+lFttR/Lg= +github.com/go-chi/render v1.0.2/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -71,15 +73,15 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= @@ -97,8 +99,8 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis= -github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f h1:l1QCwn715k8nYkj4Ql50rzEog3WnMdrd4YYMMwemxEo= -github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E= +github.com/insomniacslk/dhcp v0.0.0-20221001123530-5308ebe5334c h1:OCFM4+DXTWfNlyeoddrTwdup/ztkGSyAMR2UGcPckNQ= +github.com/insomniacslk/dhcp v0.0.0-20221001123530-5308ebe5334c/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ= @@ -109,8 +111,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= +github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -129,8 +131,9 @@ github.com/marten-seemann/qtls-go1-17 v0.1.2 h1:JADBlm0LYiVbuSySCHeY863dNkcpMmDR github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM= github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1 h1:7m/WlWcSROrcK5NxuXaxYD32BZqe/LEEnBrWcH/cOqQ= github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= +github.com/marten-seemann/qtls-go1-19 v0.1.0 h1:rLFKD/9mp/uq1SYGYuVZhm83wkmU95pK5df3GufyYYU= +github.com/marten-seemann/qtls-go1-19 v0.1.0/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y= github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= @@ -140,8 +143,8 @@ github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZ github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/miekg/dns v1.1.49 h1:qe0mQU3Z/XpFeE+AEBo2rqaS1IPBJ3anmqZ4XiZJVG8= -github.com/miekg/dns v1.1.49/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= +github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= @@ -161,10 +164,10 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/oschwald/geoip2-golang v1.7.0 h1:JW1r5AKi+vv2ujSxjKthySK3jo8w8oKWPyXsw+Qs/S8= -github.com/oschwald/geoip2-golang v1.7.0/go.mod h1:mdI/C7iK7NVMcIDDtf4bCKMJ7r0o7UwGeCo9eiitCMQ= -github.com/oschwald/maxminddb-golang v1.9.0 h1:tIk4nv6VT9OiPyrnDAfJS1s1xKDQMZOsGojab6EjC1Y= -github.com/oschwald/maxminddb-golang v1.9.0/go.mod h1:TK+s/Z2oZq0rSl4PSeAEoP0bgm82Cp5HyvYbt8K3zLY= +github.com/oschwald/geoip2-golang v1.8.0 h1:KfjYB8ojCEn/QLqsDU0AzrJ3R5Qa9vFlx3z6SLNcKTs= +github.com/oschwald/geoip2-golang v1.8.0/go.mod h1:R7bRvYjOeaoenAp9sKRS8GX5bJWcZ0laWO5+DauEktw= +github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg= +github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -179,8 +182,8 @@ github.com/sagernet/sing v0.0.0-20220921101604-86d7d510231f h1:GX416thAwyc0vHBOa github.com/sagernet/sing v0.0.0-20220921101604-86d7d510231f/go.mod h1:x3NHUeJBQwV75L51zwmLKQdLtRvR+M4PmXkfQtU1vIY= github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4= github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM= -github.com/sagernet/sing-vmess v0.0.0-20220921104047-5231f5f964db h1:9tY1sePDOPOlXipWda6H80Egv28OLyaepO5HQmlT7TM= -github.com/sagernet/sing-vmess v0.0.0-20220921104047-5231f5f964db/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM= +github.com/sagernet/sing-vmess v0.0.0-20220921140858-b6a1bdee672f h1:xyJ3Wbibcug4DxLi/FCHX2Td667SfieyZv645b8+eEE= +github.com/sagernet/sing-vmess v0.0.0-20220921140858-b6a1bdee672f/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= @@ -204,19 +207,21 @@ github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1l github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tobyxdd/quic-go v0.28.1-0.20220706211558-7780039ad599 h1:We+z04jRpTGxFggeGWf+GbinhlIk1I1kMMEgujhUfiA= github.com/tobyxdd/quic-go v0.28.1-0.20220706211558-7780039ad599/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0= @@ -226,17 +231,17 @@ github.com/u-root/uio v0.0.0-20220204230159-dac05f7d2cb4/go.mod h1:LpEX5FO/cB+WF github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg= -github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/xtls/go v0.0.0-20210920065950-d4af136d3672 h1:4mkzGhKqt3JO1BWYjtD3iRFyAx4ow67hmSqOcGjuxqQ= -github.com/xtls/go v0.0.0-20210920065950-d4af136d3672/go.mod h1:YGGVbz9cOxyKFUmhW7LGaLZaMA0cPlHJinvAmVxEMSU= +github.com/vishvananda/netns v0.0.0-20220913150850-18c4f4234207 h1:nn7SOQy8xCu3iXNv7oiBhhEQtbWdnEOMnuKBlHvrqIM= +github.com/vishvananda/netns v0.0.0-20220913150850-18c4f4234207/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837 h1:AHhUwwFJGl27E46OpdJHplZkK09m7aETNBNzhT6t15M= +github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837/go.mod h1:YJTRELIWrGxR1s8xcEBgxcxBfwQfMGjdvNLTjN9XFgY= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.5.1 h1:e1YG66Lrk73dn4qhg8WFSvhF0JuFQF0ERIp4rpuV8Qk= go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66vU6XU= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= @@ -247,11 +252,11 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 h1:a5Yg6ylndHHYJqIPrdq0AhvR6KTvDTAvgBtaidhEevY= -golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A= +golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20220608143224-64259d1afd70 h1:8uGxpY2cLF9H/NSHUiEWUIBZqIcsMzMWIMPCCUkyYgc= -golang.org/x/exp v0.0.0-20220608143224-64259d1afd70/go.mod h1:yh0Ynu2b5ZUe3MQfp2nM0ecK7wsgouWTDN0FNeJuIys= +golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 h1:RjggHMcaTVp0LOVZcW0bo8alwHrOaCrGUDgfWUHhnN4= +golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -259,8 +264,8 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -285,8 +290,9 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e h1:TsQ7F31D3bUCLeqPT0u+yjp1guoArKaNKmCr22PYgTQ= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220930213112-107f3e3c3b0b h1:uKO3Js8lXGjpjdc4J3rqs0/Ex5yDKUGfk43tTYWVLas= +golang.org/x/net v0.0.0-20220930213112-107f3e3c3b0b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -299,8 +305,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 h1:cu5kTvlzcw1Q5S9f5ip1/cpiB4nXvw1XYzFPGgzLUOY= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -315,7 +321,6 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -337,8 +342,10 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220913120320-3275c407cedc h1:dpclq5m2YrqPGStKmtw7IcNbKLfbIqKXvNxDJKdIKYc= -golang.org/x/sys v0.0.0-20220913120320-3275c407cedc/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI= +golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -351,8 +358,8 @@ golang.org/x/text v0.3.8-0.20220124021120-d1c84af989ab h1:eHo2TTVBaAPw9lDGK2Gb9G golang.org/x/text v0.3.8-0.20220124021120-d1c84af989ab/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= -golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -365,18 +372,16 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY= golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= -golang.zx2c4.com/wireguard v0.0.0-20220601130007-6a08d81f6bc4 h1:QlbNZ9SwDAepRQwgeWHLi3rfEMo/kVEU4SmgsNM7HmQ= -golang.zx2c4.com/wireguard v0.0.0-20220601130007-6a08d81f6bc4/go.mod h1:bVQfyl2sCM/QIIGHpWbFGfHPuDvqnCNkT6MQLTCjO/U= +golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c h1:Okh6a1xpnJslG9Mn84pId1Mn+Q8cvpo4HCeeFWHo0cA= +golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c/go.mod h1:enML0deDxY1ux+B6ANGiwtg0yAJi1rctkTpcHNAVPyg= golang.zx2c4.com/wireguard/windows v0.5.4-0.20220328111914-004c22c5647e h1:yV04h6Tx19uDR6LvuEbR19cDU+3QrB9LuGjtF7F5G0w= golang.zx2c4.com/wireguard/windows v0.5.4-0.20220328111914-004c22c5647e/go.mod h1:1CeiatTZwcwSFA3cAtMm8CQoroviTldnxd7DOgM/vI4= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= @@ -403,8 +408,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= @@ -423,8 +428,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -gvisor.dev/gvisor v0.0.0-20220810234332-45096a971e66 h1:GrHxpIMY0lHZ3Q8rp3m4iOb0pJsnCQ/5AHaN9SXE69E= -gvisor.dev/gvisor v0.0.0-20220810234332-45096a971e66/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM= +gvisor.dev/gvisor v0.0.0-20220930175839-a705f5d5e730 h1:VpvwiV2p5hSzLT6Ba63fmqaR3VNkE8jrUUlDl0z8nZY= +gvisor.dev/gvisor v0.0.0-20220930175839-a705f5d5e730/go.mod h1:D0iRe6RVONyvN6uEi/rqBtONyitX5GaHMDDbeMzwgiE= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From ddf1c74091712911e43839545b0d454ffa211f4e Mon Sep 17 00:00:00 2001 From: metacubex Date: Sat, 1 Oct 2022 23:30:41 +0800 Subject: [PATCH 18/22] adjust: routes for windows --- listener/tun/ipstack/commons/router_windows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/listener/tun/ipstack/commons/router_windows.go b/listener/tun/ipstack/commons/router_windows.go index 2abfa0ff..e2296173 100644 --- a/listener/tun/ipstack/commons/router_windows.go +++ b/listener/tun/ipstack/commons/router_windows.go @@ -88,7 +88,7 @@ startOver: allowedIPs []netip.Prefix // add default - routeArr = []string{"0.0.0.0/0"} + routeArr = []string{"0.0.0.0/1"} ) for _, route := range routeArr { From e2d71abecd40dfff82460742efb74fb94b377c9f Mon Sep 17 00:00:00 2001 From: Kaming Chan Date: Mon, 25 Jul 2022 12:44:00 +0800 Subject: [PATCH 19/22] Fix: handle parse socks5 udp address properly (#2220) (cherry picked from commit bec4df7b122e6a4db0f831ed6176732b2a09fb63) --- transport/snell/snell.go | 3 +++ transport/trojan/trojan.go | 3 +++ 2 files changed, 6 insertions(+) diff --git a/transport/snell/snell.go b/transport/snell/snell.go index c6b7a569..e2bd2820 100644 --- a/transport/snell/snell.go +++ b/transport/snell/snell.go @@ -241,6 +241,9 @@ func ReadPacket(r io.Reader, payload []byte) (net.Addr, int, error) { return nil, 0, errors.New("remote address invalid") } uAddr := addr.UDPAddr() + if uAddr == nil { + return nil, 0, errors.New("parse addr error") + } length := len(payload) if n-headLen < length { diff --git a/transport/trojan/trojan.go b/transport/trojan/trojan.go index 4ebb431b..937b5f91 100644 --- a/transport/trojan/trojan.go +++ b/transport/trojan/trojan.go @@ -250,6 +250,9 @@ func ReadPacket(r io.Reader, payload []byte) (net.Addr, int, int, error) { return nil, 0, 0, errors.New("read addr error") } uAddr := addr.UDPAddr() + if uAddr == nil { + return nil, 0, 0, errors.New("parse addr error") + } if _, err = io.ReadFull(r, payload[:2]); err != nil { return nil, 0, 0, errors.New("read length error") From 13445d815bc6ccf0f2d2a5e535ac1f413b4a7ae3 Mon Sep 17 00:00:00 2001 From: oluceps Date: Sun, 2 Oct 2022 00:18:35 +0800 Subject: [PATCH 20/22] add: flake auto track latest commit --- default.nix | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/default.nix b/default.nix index 112c3d35..7e9eb182 100755 --- a/default.nix +++ b/default.nix @@ -4,15 +4,8 @@ }: buildGoModule rec { pname = "clash-meta"; - version = "1.13.1"; - - src = fetchFromGitHub { - owner = "MetaCubeX"; - repo = "Clash.Meta"; - rev = "1684756b79a232ee8f875bcfd87371f5c0ef066b"; - sha256 = "sha256-7g/Wcll0w4EhPI+KodtLHINqaR2larQNnP9YAsgNiN4="; - }; - + version = "dev"; + src = ./.; vendorSha256 = "sha256-7HjYcoqWA5gvPUc5psCgy0UTc17CBzBJ/OiGvII/iBA="; # Do not build testing suit From 6b2eae36f28ca441ab2ef59d1fcd86e27d62fc8f Mon Sep 17 00:00:00 2001 From: metacubex Date: Sun, 2 Oct 2022 01:00:07 +0800 Subject: [PATCH 21/22] adjust: gvisor version --- go.mod | 3 ++- go.sum | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 34c45cda..2a835cdf 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,8 @@ require ( golang.zx2c4.com/wireguard/windows v0.5.4-0.20220328111914-004c22c5647e google.golang.org/protobuf v1.28.1 gopkg.in/yaml.v3 v3.0.1 - gvisor.dev/gvisor v0.0.0-20220930175839-a705f5d5e730 + gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c + ) replace github.com/vishvananda/netlink => github.com/MetaCubeX/netlink v1.2.0-beta.0.20220529072258-d6853f887820 diff --git a/go.sum b/go.sum index b4e55d35..8f9d8ac7 100644 --- a/go.sum +++ b/go.sum @@ -428,8 +428,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -gvisor.dev/gvisor v0.0.0-20220930175839-a705f5d5e730 h1:VpvwiV2p5hSzLT6Ba63fmqaR3VNkE8jrUUlDl0z8nZY= -gvisor.dev/gvisor v0.0.0-20220930175839-a705f5d5e730/go.mod h1:D0iRe6RVONyvN6uEi/rqBtONyitX5GaHMDDbeMzwgiE= +gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c h1:m5lcgWnL3OElQNVyp3qcncItJ2c0sQlSGjYK2+nJTA4= +gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 6dd8cf6c0a4290c22e4007e34c17f519c5315e35 Mon Sep 17 00:00:00 2001 From: oluceps Date: Sun, 2 Oct 2022 02:15:37 +0800 Subject: [PATCH 22/22] refactor: multi-platform support for nix build --- flake.lock | 6 +++--- flake.nix | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/flake.lock b/flake.lock index df343f24..01b81807 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1664614409, - "narHash": "sha256-5y+zhLMzc/k4NYnCfW+seM9oaNuUI/UeGMGPFRj8cR0=", + "lastModified": 1664638641, + "narHash": "sha256-r2gVLq9DD1A0Igv4AdkmpuuVykXmKVsJTAJinS/ZFrM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b746456c6f6ef8404ef6011df5eceba8644c49a9", + "rev": "cb81a9ca94e7631bc67788d858e214d56571983a", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 297a284f..3e8fd557 100644 --- a/flake.nix +++ b/flake.nix @@ -6,14 +6,22 @@ inputs.utils.url = "github:numtide/flake-utils"; outputs = { self, nixpkgs, utils }: - (utils.lib.eachDefaultSystem + utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; in - { - defaultPackages = pkgs.callPackage ./. { }; - }) - ); + packages = rec{ + clash-meta = pkgs.callPackage ./. { }; + default = clash-meta; + }; + + apps = rec { + clash-meta = utils.lib.mkApp { drv = self.packages.${system}.clash-meta; }; + default = clash-meta; + }; + } + ); } +