diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d6420fd3..08c80e75 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -123,7 +123,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: "1.20" + go-version: "1.21" check-latest: true - name: Test diff --git a/Dockerfile b/Dockerfile index f5dcc307..6c5a91f9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,9 +4,9 @@ RUN echo "I'm building for $TARGETPLATFORM" RUN apk add --no-cache gzip && \ mkdir /clash-config && \ - wget -O /clash-config/Country.mmdb https://raw.githubusercontent.com/Loyalsoldier/geoip/release/Country.mmdb && \ - wget -O /clash-config/geosite.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat && \ - wget -O /clash-config/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat + wget -O /clash-config/geoip.metadb https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.metadb && \ + wget -O /clash-config/geosite.dat https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat && \ + wget -O /clash-config/geoip.dat https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat COPY docker/file-name.sh /clash/file-name.sh WORKDIR /clash diff --git a/adapter/adapter.go b/adapter/adapter.go index 32b6bae0..6cc79c3a 100644 --- a/adapter/adapter.go +++ b/adapter/adapter.go @@ -9,6 +9,7 @@ import ( "net/http" "net/netip" "net/url" + "strconv" "time" "github.com/Dreamacro/clash/common/atomic" @@ -176,6 +177,7 @@ func (p *Proxy) MarshalJSON() ([]byte, error) { _ = json.Unmarshal(inner, &mapping) mapping["history"] = p.DelayHistory() mapping["extra"] = p.ExtraDelayHistory() + mapping["alive"] = p.Alive() mapping["name"] = p.Name() mapping["udp"] = p.SupportUDP() mapping["xudp"] = p.SupportXUDP() @@ -326,11 +328,15 @@ func urlToMetadata(rawURL string) (addr C.Metadata, err error) { return } } + uintPort, err := strconv.ParseUint(port, 10, 16) + if err != nil { + return + } addr = C.Metadata{ Host: u.Hostname(), DstIP: netip.Addr{}, - DstPort: port, + DstPort: uint16(uintPort), } return } diff --git a/adapter/inbound/listen.go b/adapter/inbound/listen.go index fa82db92..8b7b5fb2 100644 --- a/adapter/inbound/listen.go +++ b/adapter/inbound/listen.go @@ -17,6 +17,10 @@ func SetTfo(open bool) { lc.DisableTFO = !open } +func SetMPTCP(open bool) { + setMultiPathTCP(&lc.ListenConfig, open) +} + func ListenContext(ctx context.Context, network, address string) (net.Listener, error) { return lc.Listen(ctx, network, address) } diff --git a/adapter/inbound/mptcp_go120.go b/adapter/inbound/mptcp_go120.go new file mode 100644 index 00000000..f9b22533 --- /dev/null +++ b/adapter/inbound/mptcp_go120.go @@ -0,0 +1,10 @@ +//go:build !go1.21 + +package inbound + +import "net" + +const multipathTCPAvailable = false + +func setMultiPathTCP(listenConfig *net.ListenConfig, open bool) { +} diff --git a/adapter/inbound/mptcp_go121.go b/adapter/inbound/mptcp_go121.go new file mode 100644 index 00000000..6b35d1a8 --- /dev/null +++ b/adapter/inbound/mptcp_go121.go @@ -0,0 +1,11 @@ +//go:build go1.21 + +package inbound + +import "net" + +const multipathTCPAvailable = true + +func setMultiPathTCP(listenConfig *net.ListenConfig, open bool) { + listenConfig.SetMultipathTCP(open) +} diff --git a/adapter/inbound/socket.go b/adapter/inbound/socket.go index e41ee925..d75901f1 100644 --- a/adapter/inbound/socket.go +++ b/adapter/inbound/socket.go @@ -3,6 +3,7 @@ package inbound import ( "net" "net/netip" + "strconv" C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/context" @@ -37,7 +38,9 @@ func NewInner(conn net.Conn, address string) *context.ConnContext { metadata.DNSMode = C.DNSNormal metadata.Process = C.ClashName if h, port, err := net.SplitHostPort(address); err == nil { - metadata.DstPort = port + if port, err := strconv.ParseUint(port, 10, 16); err == nil { + metadata.DstPort = uint16(port) + } if ip, err := netip.ParseAddr(h); err == nil { metadata.DstIP = ip } else { diff --git a/adapter/inbound/util.go b/adapter/inbound/util.go index 88e989f9..626687c0 100644 --- a/adapter/inbound/util.go +++ b/adapter/inbound/util.go @@ -20,14 +20,14 @@ func parseSocksAddr(target socks5.Addr) *C.Metadata { case socks5.AtypDomainName: // trim for FQDN metadata.Host = strings.TrimRight(string(target[2:2+target[1]]), ".") - metadata.DstPort = strconv.Itoa((int(target[2+target[1]]) << 8) | int(target[2+target[1]+1])) + metadata.DstPort = uint16((int(target[2+target[1]]) << 8) | int(target[2+target[1]+1])) case socks5.AtypIPv4: metadata.DstIP = nnip.IpToAddr(net.IP(target[1 : 1+net.IPv4len])) - metadata.DstPort = strconv.Itoa((int(target[1+net.IPv4len]) << 8) | int(target[1+net.IPv4len+1])) + metadata.DstPort = uint16((int(target[1+net.IPv4len]) << 8) | int(target[1+net.IPv4len+1])) case socks5.AtypIPv6: ip6, _ := netip.AddrFromSlice(target[1 : 1+net.IPv6len]) metadata.DstIP = ip6.Unmap() - metadata.DstPort = strconv.Itoa((int(target[1+net.IPv6len]) << 8) | int(target[1+net.IPv6len+1])) + metadata.DstPort = uint16((int(target[1+net.IPv6len]) << 8) | int(target[1+net.IPv6len+1])) } return metadata @@ -43,11 +43,16 @@ func parseHTTPAddr(request *http.Request) *C.Metadata { // trim FQDN (#737) host = strings.TrimRight(host, ".") + var uint16Port uint16 + if port, err := strconv.ParseUint(port, 10, 16); err == nil { + uint16Port = uint16(port) + } + metadata := &C.Metadata{ NetWork: C.TCP, Host: host, DstIP: netip.Addr{}, - DstPort: port, + DstPort: uint16Port, } ip, err := netip.ParseAddr(host) @@ -58,10 +63,10 @@ func parseHTTPAddr(request *http.Request) *C.Metadata { return metadata } -func parseAddr(addr net.Addr) (netip.Addr, string, error) { +func parseAddr(addr net.Addr) (netip.Addr, uint16, error) { // Filter when net.Addr interface is nil if addr == nil { - return netip.Addr{}, "", errors.New("nil addr") + return netip.Addr{}, 0, errors.New("nil addr") } if rawAddr, ok := addr.(interface{ RawAddr() net.Addr }); ok { ip, port, err := parseAddr(rawAddr.RawAddr()) @@ -72,9 +77,14 @@ func parseAddr(addr net.Addr) (netip.Addr, string, error) { addrStr := addr.String() host, port, err := net.SplitHostPort(addrStr) if err != nil { - return netip.Addr{}, "", err + return netip.Addr{}, 0, err + } + + var uint16Port uint16 + if port, err := strconv.ParseUint(port, 10, 16); err == nil { + uint16Port = uint16(port) } ip, err := netip.ParseAddr(host) - return ip, port, err + return ip, uint16Port, err } diff --git a/adapter/outbound/base.go b/adapter/outbound/base.go index f2ce56c9..ba991bfc 100644 --- a/adapter/outbound/base.go +++ b/adapter/outbound/base.go @@ -21,6 +21,7 @@ type Base struct { udp bool xudp bool tfo bool + mpTcp bool rmark int id string prefer C.DNSPrefer @@ -143,11 +144,16 @@ func (b *Base) DialOptions(opts ...dialer.Option) []dialer.Option { opts = append(opts, dialer.WithTFO(true)) } + if b.mpTcp { + opts = append(opts, dialer.WithMPTCP(true)) + } + return opts } type BasicOption struct { TFO bool `proxy:"tfo,omitempty" group:"tfo,omitempty"` + MPTCP bool `proxy:"mptcp,omitempty" group:"mptcp,omitempty"` 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"` @@ -161,6 +167,7 @@ type BaseOption struct { UDP bool XUDP bool TFO bool + MPTCP bool Interface string RoutingMark int Prefer C.DNSPrefer @@ -174,6 +181,7 @@ func NewBase(opt BaseOption) *Base { udp: opt.UDP, xudp: opt.XUDP, tfo: opt.TFO, + mpTcp: opt.MPTCP, iface: opt.Interface, rmark: opt.RoutingMark, prefer: opt.Prefer, diff --git a/adapter/outbound/http.go b/adapter/outbound/http.go index 78735b2d..0b652ca9 100644 --- a/adapter/outbound/http.go +++ b/adapter/outbound/http.go @@ -177,6 +177,7 @@ func NewHttp(option HttpOption) (*Http, error) { addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)), tp: C.Http, tfo: option.TFO, + mpTcp: option.MPTCP, iface: option.Interface, rmark: option.RoutingMark, prefer: C.NewDNSPrefer(option.IPVersion), diff --git a/adapter/outbound/shadowsocks.go b/adapter/outbound/shadowsocks.go index 32558eac..c1481622 100644 --- a/adapter/outbound/shadowsocks.go +++ b/adapter/outbound/shadowsocks.go @@ -315,6 +315,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) { tp: C.Shadowsocks, udp: option.UDP, tfo: option.TFO, + mpTcp: option.MPTCP, iface: option.Interface, rmark: option.RoutingMark, prefer: C.NewDNSPrefer(option.IPVersion), diff --git a/adapter/outbound/shadowsocksr.go b/adapter/outbound/shadowsocksr.go index 07778032..cd6854af 100644 --- a/adapter/outbound/shadowsocksr.go +++ b/adapter/outbound/shadowsocksr.go @@ -181,6 +181,7 @@ func NewShadowSocksR(option ShadowSocksROption) (*ShadowSocksR, error) { tp: C.ShadowsocksR, udp: option.UDP, tfo: option.TFO, + mpTcp: option.MPTCP, iface: option.Interface, rmark: option.RoutingMark, prefer: C.NewDNSPrefer(option.IPVersion), diff --git a/adapter/outbound/snell.go b/adapter/outbound/snell.go index fc1f4eb3..d0b9e748 100644 --- a/adapter/outbound/snell.go +++ b/adapter/outbound/snell.go @@ -59,8 +59,7 @@ func (s *Snell) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M err := snell.WriteUDPHeader(c, s.version) return c, err } - port, _ := strconv.ParseUint(metadata.DstPort, 10, 16) - err := snell.WriteHeader(c, metadata.String(), uint(port), s.version) + err := snell.WriteHeader(c, metadata.String(), uint(metadata.DstPort), s.version) return c, err } @@ -72,8 +71,7 @@ func (s *Snell) DialContext(ctx context.Context, metadata *C.Metadata, opts ...d return nil, err } - port, _ := strconv.ParseUint(metadata.DstPort, 10, 16) - if err = snell.WriteHeader(c, metadata.String(), uint(port), s.version); err != nil { + if err = snell.WriteHeader(c, metadata.String(), uint(metadata.DstPort), s.version); err != nil { c.Close() return nil, err } @@ -183,6 +181,7 @@ func NewSnell(option SnellOption) (*Snell, error) { tp: C.Snell, udp: option.UDP, tfo: option.TFO, + mpTcp: option.MPTCP, iface: option.Interface, rmark: option.RoutingMark, prefer: C.NewDNSPrefer(option.IPVersion), diff --git a/adapter/outbound/socks5.go b/adapter/outbound/socks5.go index 9af4d0fc..f451cd1a 100644 --- a/adapter/outbound/socks5.go +++ b/adapter/outbound/socks5.go @@ -196,6 +196,7 @@ func NewSocks5(option Socks5Option) (*Socks5, error) { tp: C.Socks5, udp: option.UDP, tfo: option.TFO, + mpTcp: option.MPTCP, iface: option.Interface, rmark: option.RoutingMark, prefer: C.NewDNSPrefer(option.IPVersion), diff --git a/adapter/outbound/trojan.go b/adapter/outbound/trojan.go index 81fb1ceb..ec420bf3 100644 --- a/adapter/outbound/trojan.go +++ b/adapter/outbound/trojan.go @@ -14,7 +14,6 @@ import ( C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/transport/gun" "github.com/Dreamacro/clash/transport/trojan" - "github.com/Dreamacro/clash/transport/vless" ) type Trojan struct { @@ -45,8 +44,6 @@ type TrojanOption struct { RealityOpts RealityOptions `proxy:"reality-opts,omitempty"` GrpcOpts GrpcOptions `proxy:"grpc-opts,omitempty"` WSOpts WSOptions `proxy:"ws-opts,omitempty"` - Flow string `proxy:"flow,omitempty"` - FlowShow bool `proxy:"flow-show,omitempty"` ClientFingerprint string `proxy:"client-fingerprint,omitempty"` } @@ -95,11 +92,6 @@ func (t *Trojan) StreamConnContext(ctx context.Context, c net.Conn, metadata *C. return nil, fmt.Errorf("%s connect error: %w", t.addr, err) } - c, err = t.instance.PresetXTLSConn(c) - if err != nil { - return nil, err - } - if metadata.NetWork == C.UDP { err = t.instance.WriteHeader(c, trojan.CommandUDP, serializesSocksAddr(metadata)) return c, err @@ -117,12 +109,6 @@ func (t *Trojan) DialContext(ctx context.Context, metadata *C.Metadata, opts ... return nil, err } - c, err = t.instance.PresetXTLSConn(c) - if err != nil { - c.Close() - return nil, err - } - if err = t.instance.WriteHeader(c, trojan.CommandTCP, serializesSocksAddr(metadata)); err != nil { c.Close() return nil, err @@ -237,24 +223,10 @@ func NewTrojan(option TrojanOption) (*Trojan, error) { ALPN: option.ALPN, ServerName: option.Server, SkipCertVerify: option.SkipCertVerify, - FlowShow: option.FlowShow, Fingerprint: option.Fingerprint, ClientFingerprint: option.ClientFingerprint, } - switch option.Network { - case "", "tcp": - if len(option.Flow) >= 16 { - option.Flow = option.Flow[:16] - switch option.Flow { - case vless.XRO, vless.XRD, vless.XRS: - tOption.Flow = option.Flow - default: - return nil, fmt.Errorf("unsupported xtls flow type: %s", option.Flow) - } - } - } - if option.SNI != "" { tOption.ServerName = option.SNI } @@ -266,6 +238,7 @@ func NewTrojan(option TrojanOption) (*Trojan, error) { tp: C.Trojan, udp: option.UDP, tfo: option.TFO, + mpTcp: option.MPTCP, iface: option.Interface, rmark: option.RoutingMark, prefer: C.NewDNSPrefer(option.IPVersion), diff --git a/adapter/outbound/tuic.go b/adapter/outbound/tuic.go index 86b34dc8..c10a853a 100644 --- a/adapter/outbound/tuic.go +++ b/adapter/outbound/tuic.go @@ -162,7 +162,7 @@ func NewTuic(option TuicOption) (*Tuic, error) { tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig) } - if len(option.ALPN) > 0 { + if option.ALPN != nil { // structure's Decode will ensure value not nil when input has value even it was set an empty array tlsConfig.NextProtos = option.ALPN } else { tlsConfig.NextProtos = []string{"h3"} diff --git a/adapter/outbound/util.go b/adapter/outbound/util.go index 68d6b355..7f3ec4c3 100644 --- a/adapter/outbound/util.go +++ b/adapter/outbound/util.go @@ -4,10 +4,8 @@ import ( "bytes" "context" "crypto/tls" - xtls "github.com/xtls/go" "net" "net/netip" - "strconv" "sync" "time" @@ -17,9 +15,8 @@ import ( ) var ( - globalClientSessionCache tls.ClientSessionCache - globalClientXSessionCache xtls.ClientSessionCache - once sync.Once + globalClientSessionCache tls.ClientSessionCache + once sync.Once ) func tcpKeepAlive(c net.Conn) { @@ -36,18 +33,11 @@ func getClientSessionCache() tls.ClientSessionCache { return globalClientSessionCache } -func getClientXSessionCache() xtls.ClientSessionCache { - once.Do(func() { - globalClientXSessionCache = xtls.NewLRUClientSessionCache(128) - }) - return globalClientXSessionCache -} - func serializesSocksAddr(metadata *C.Metadata) []byte { var buf [][]byte addrType := metadata.AddrType() aType := uint8(addrType) - p, _ := strconv.ParseUint(metadata.DstPort, 10, 16) + p := uint(metadata.DstPort) port := []byte{uint8(p >> 8), uint8(p & 0xff)} switch addrType { case socks5.AtypDomainName: diff --git a/adapter/outbound/vless.go b/adapter/outbound/vless.go index 803e0f57..83ce4e57 100644 --- a/adapter/outbound/vless.go +++ b/adapter/outbound/vless.go @@ -56,7 +56,6 @@ type VlessOption struct { Port int `proxy:"port"` UUID string `proxy:"uuid"` Flow string `proxy:"flow,omitempty"` - FlowShow bool `proxy:"flow-show,omitempty"` TLS bool `proxy:"tls,omitempty"` UDP bool `proxy:"udp,omitempty"` PacketAddr bool `proxy:"packet-addr,omitempty"` @@ -133,7 +132,7 @@ func (v *Vless) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M c, err = vmess.StreamWebsocketConn(ctx, c, wsOpts) case "http": // readability first, so just copy default TLS logic - c, err = v.streamTLSOrXTLSConn(ctx, c, false) + c, err = v.streamTLSConn(ctx, c, false) if err != nil { return nil, err } @@ -148,7 +147,7 @@ func (v *Vless) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M c = vmess.StreamHTTPConn(c, httpOpts) case "h2": - c, err = v.streamTLSOrXTLSConn(ctx, c, true) + c, err = v.streamTLSConn(ctx, c, true) if err != nil { return nil, err } @@ -163,8 +162,8 @@ func (v *Vless) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M c, err = gun.StreamGunWithConn(c, v.gunTLSConfig, v.gunConfig, v.realityConfig) default: // default tcp network - // handle TLS And XTLS - c, err = v.streamTLSOrXTLSConn(ctx, c, false) + // handle TLS + c, err = v.streamTLSConn(ctx, c, false) } if err != nil { @@ -180,7 +179,7 @@ func (v *Vless) streamConn(c net.Conn, metadata *C.Metadata) (conn net.Conn, err metadata = &C.Metadata{ NetWork: C.UDP, Host: packetaddr.SeqPacketMagicAddress, - DstPort: "443", + DstPort: 443, } } else { metadata = &C.Metadata{ // a clear metadata only contains ip @@ -202,23 +201,10 @@ func (v *Vless) streamConn(c net.Conn, metadata *C.Metadata) (conn net.Conn, err return } -func (v *Vless) streamTLSOrXTLSConn(ctx context.Context, conn net.Conn, isH2 bool) (net.Conn, error) { - host, _, _ := net.SplitHostPort(v.addr) +func (v *Vless) streamTLSConn(ctx context.Context, conn net.Conn, isH2 bool) (net.Conn, error) { + if v.option.TLS { + host, _, _ := net.SplitHostPort(v.addr) - if v.isLegacyXTLSEnabled() && !isH2 { - xtlsOpts := vless.XTLSConfig{ - Host: host, - SkipCertVerify: v.option.SkipCertVerify, - Fingerprint: v.option.Fingerprint, - } - - if v.option.ServerName != "" { - xtlsOpts.Host = v.option.ServerName - } - - return vless.StreamXTLSConn(ctx, conn, &xtlsOpts) - - } else if v.option.TLS { tlsOpts := vmess.TLSConfig{ Host: host, SkipCertVerify: v.option.SkipCertVerify, @@ -241,10 +227,6 @@ func (v *Vless) streamTLSOrXTLSConn(ctx context.Context, conn net.Conn, isH2 boo return conn, nil } -func (v *Vless) isLegacyXTLSEnabled() bool { - return v.client.Addons != nil && v.client.Addons.Flow != vless.XRV -} - // DialContext implements C.ProxyAdapter func (v *Vless) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (_ C.Conn, err error) { // gun transport @@ -417,12 +399,11 @@ func parseVlessAddr(metadata *C.Metadata, xudp bool) *vless.DstAddr { copy(addr[1:], metadata.Host) } - port, _ := strconv.ParseUint(metadata.DstPort, 10, 16) return &vless.DstAddr{ UDP: metadata.NetWork == C.UDP, AddrType: addrType, Addr: addr, - Port: uint16(port), + Port: metadata.DstPort, Mux: metadata.NetWork == C.UDP && xudp, } } @@ -526,11 +507,11 @@ func NewVless(option VlessOption) (*Vless, error) { switch option.Flow { case vless.XRV: log.Warnln("To use %s, ensure your server is upgrade to Xray-core v1.8.0+", vless.XRV) - fallthrough - case vless.XRO, vless.XRD, vless.XRS: addons = &vless.Addons{ Flow: option.Flow, } + case vless.XRO, vless.XRD, vless.XRS: + log.Fatalln("Legacy XTLS protocol %s is deprecated and no longer supported", option.Flow) default: return nil, fmt.Errorf("unsupported xtls flow type: %s", option.Flow) } @@ -549,7 +530,7 @@ func NewVless(option VlessOption) (*Vless, error) { option.PacketAddr = false } - client, err := vless.NewClient(option.UUID, addons, option.FlowShow) + client, err := vless.NewClient(option.UUID, addons) if err != nil { return nil, err } @@ -562,6 +543,7 @@ func NewVless(option VlessOption) (*Vless, error) { udp: option.UDP, xudp: option.XUDP, tfo: option.TFO, + mpTcp: option.MPTCP, iface: option.Interface, rmark: option.RoutingMark, prefer: C.NewDNSPrefer(option.IPVersion), diff --git a/adapter/outbound/vmess.go b/adapter/outbound/vmess.go index acf6de75..8a94c082 100644 --- a/adapter/outbound/vmess.go +++ b/adapter/outbound/vmess.go @@ -436,6 +436,7 @@ func NewVmess(option VmessOption) (*Vmess, error) { udp: option.UDP, xudp: option.XUDP, tfo: option.TFO, + mpTcp: option.MPTCP, iface: option.Interface, rmark: option.RoutingMark, prefer: C.NewDNSPrefer(option.IPVersion), diff --git a/adapter/outbound/wireguard.go b/adapter/outbound/wireguard.go index c12321f3..e6738596 100644 --- a/adapter/outbound/wireguard.go +++ b/adapter/outbound/wireguard.go @@ -374,8 +374,7 @@ func (w *WireGuard) DialContext(ctx context.Context, metadata *C.Metadata, opts options = append(options, dialer.WithNetDialer(wgNetDialer{tunDevice: w.tunDevice})) conn, err = dialer.NewDialer(options...).DialContext(ctx, "tcp", metadata.RemoteAddress()) } else { - port, _ := strconv.Atoi(metadata.DstPort) - conn, err = w.tunDevice.DialContext(ctx, "tcp", M.SocksaddrFrom(metadata.DstIP, uint16(port)).Unwrap()) + conn, err = w.tunDevice.DialContext(ctx, "tcp", M.SocksaddrFrom(metadata.DstIP, metadata.DstPort).Unwrap()) } if err != nil { return nil, err @@ -412,8 +411,7 @@ func (w *WireGuard) ListenPacketContext(ctx context.Context, metadata *C.Metadat } metadata.DstIP = ip } - port, _ := strconv.Atoi(metadata.DstPort) - pc, err = w.tunDevice.ListenPacket(ctx, M.SocksaddrFrom(metadata.DstIP, uint16(port)).Unwrap()) + pc, err = w.tunDevice.ListenPacket(ctx, M.SocksaddrFrom(metadata.DstIP, metadata.DstPort).Unwrap()) if err != nil { return nil, err } diff --git a/adapter/provider/provider.go b/adapter/provider/provider.go index 10861217..d547dcb7 100644 --- a/adapter/provider/provider.go +++ b/adapter/provider/provider.go @@ -299,7 +299,7 @@ func proxiesParseAndFilter(filter string, excludeFilter string, excludeTypeArray if err := yaml.Unmarshal(buf, schema); err != nil { proxies, err1 := convert.ConvertsV2Ray(buf) if err1 != nil { - return nil, fmt.Errorf("%s, %w", err.Error(), err1) + return nil, fmt.Errorf("%w, %w", err, err1) } schema.Proxies = proxies } diff --git a/common/buf/sing.go b/common/buf/sing.go index 93140887..4585bf74 100644 --- a/common/buf/sing.go +++ b/common/buf/sing.go @@ -11,8 +11,6 @@ type Buffer = buf.Buffer var New = buf.New var NewSize = buf.NewSize -var StackNew = buf.StackNew -var StackNewSize = buf.StackNewSize var With = buf.With var As = buf.As diff --git a/common/cache/lrucache.go b/common/cache/lrucache.go index 73600e71..1373b0be 100644 --- a/common/cache/lrucache.go +++ b/common/cache/lrucache.go @@ -82,6 +82,9 @@ func New[K comparable, V any](options ...Option[K, V]) *LruCache[K, V] { // Get returns the any representation of a cached response and a bool // set to true if the key was found. func (c *LruCache[K, V]) Get(key K) (V, bool) { + c.mu.Lock() + defer c.mu.Unlock() + el := c.get(key) if el == nil { return getZero[V](), false @@ -91,11 +94,29 @@ func (c *LruCache[K, V]) Get(key K) (V, bool) { return value, true } +func (c *LruCache[K, V]) GetOrStore(key K, constructor func() V) (V, bool) { + c.mu.Lock() + defer c.mu.Unlock() + + el := c.get(key) + if el == nil { + value := constructor() + c.set(key, value) + return value, false + } + value := el.value + + return value, true +} + // GetWithExpire returns the any representation of a cached response, // a time.Time Give expected expires, // and a bool set to true if the key was found. // This method will NOT check the maxAge of element and will NOT update the expires. func (c *LruCache[K, V]) GetWithExpire(key K) (V, time.Time, bool) { + c.mu.Lock() + defer c.mu.Unlock() + el := c.get(key) if el == nil { return getZero[V](), time.Time{}, false @@ -115,11 +136,18 @@ func (c *LruCache[K, V]) Exist(key K) bool { // Set stores the any representation of a response for a given key. func (c *LruCache[K, V]) Set(key K, value V) { + c.mu.Lock() + defer c.mu.Unlock() + + c.set(key, value) +} + +func (c *LruCache[K, V]) set(key K, value V) { expires := int64(0) if c.maxAge > 0 { expires = time.Now().Unix() + c.maxAge } - c.SetWithExpire(key, value, time.Unix(expires, 0)) + c.setWithExpire(key, value, time.Unix(expires, 0)) } // SetWithExpire stores the any representation of a response for a given key and given expires. @@ -128,6 +156,10 @@ func (c *LruCache[K, V]) SetWithExpire(key K, value V, expires time.Time) { c.mu.Lock() defer c.mu.Unlock() + c.setWithExpire(key, value, expires) +} + +func (c *LruCache[K, V]) setWithExpire(key K, value V, expires time.Time) { if le, ok := c.cache[key]; ok { c.lru.MoveToBack(le) e := le.Value @@ -165,9 +197,6 @@ func (c *LruCache[K, V]) CloneTo(n *LruCache[K, V]) { } func (c *LruCache[K, V]) get(key K) *entry[K, V] { - c.mu.Lock() - defer c.mu.Unlock() - le, ok := c.cache[key] if !ok { return nil @@ -191,12 +220,11 @@ func (c *LruCache[K, V]) get(key K) *entry[K, V] { // Delete removes the value associated with a key. func (c *LruCache[K, V]) Delete(key K) { c.mu.Lock() + defer c.mu.Unlock() if le, ok := c.cache[key]; ok { c.deleteElement(le) } - - c.mu.Unlock() } func (c *LruCache[K, V]) maybeDeleteOldest() { @@ -219,10 +247,10 @@ func (c *LruCache[K, V]) deleteElement(le *list.Element[*entry[K, V]]) { func (c *LruCache[K, V]) Clear() error { c.mu.Lock() + defer c.mu.Unlock() c.cache = make(map[K]*list.Element[*entry[K, V]]) - c.mu.Unlock() return nil } diff --git a/common/picker/picker.go b/common/picker/picker.go index 97004460..3a7688ca 100644 --- a/common/picker/picker.go +++ b/common/picker/picker.go @@ -47,6 +47,7 @@ func (p *Picker[T]) Wait() T { p.wg.Wait() if p.cancel != nil { p.cancel() + p.cancel = nil } return p.result } @@ -69,6 +70,7 @@ func (p *Picker[T]) Go(f func() (T, error)) { p.result = ret if p.cancel != nil { p.cancel() + p.cancel = nil } }) } else { @@ -78,3 +80,13 @@ func (p *Picker[T]) Go(f func() (T, error)) { } }() } + +// Close cancels the picker context and releases resources associated with it. +// If Wait has been called, then there is no need to call Close. +func (p *Picker[T]) Close() error { + if p.cancel != nil { + p.cancel() + p.cancel = nil + } + return nil +} diff --git a/common/pool/alloc.go b/common/pool/alloc.go index 25f79897..5722b047 100644 --- a/common/pool/alloc.go +++ b/common/pool/alloc.go @@ -32,23 +32,32 @@ func NewAllocator() *Allocator { // Get a []byte from pool with most appropriate cap func (alloc *Allocator) Get(size int) []byte { - if size <= 0 || size > 65536 { + switch { + case size < 0: + panic("alloc.Get: len out of range") + case size == 0: return nil - } + case size > 65536: + return make([]byte, size) + default: + bits := msb(size) + if size == 1< 65536 { + return nil + } + bits := msb(cap(buf)) - if cap(buf) == 0 || cap(buf) > 65536 || cap(buf) != 1< 0 { - return nil, errorsJoin(errs...) + return nil, errors.Join(errs...) } return nil, os.ErrDeadlineExceeded } @@ -261,7 +265,7 @@ func serialDialContext(ctx context.Context, network string, ips []netip.Addr, po errs = append(errs, err) } } - return nil, errorsJoin(errs...) + return nil, errors.Join(errs...) } type dialResult struct { diff --git a/component/dialer/error.go b/component/dialer/error.go index f2f6b4b7..035baa03 100644 --- a/component/dialer/error.go +++ b/component/dialer/error.go @@ -2,17 +2,9 @@ package dialer import ( "errors" - - E "github.com/sagernet/sing/common/exceptions" ) var ( ErrorNoIpAddress = errors.New("no ip address") ErrorInvalidedNetworkStack = errors.New("invalided network stack") ) - -func errorsJoin(errs ...error) error { - // compatibility with golang<1.20 - // maybe use errors.Join(errs...) is better after we drop the old version's support - return E.Errors(errs...) -} diff --git a/component/dialer/mptcp_go120.go b/component/dialer/mptcp_go120.go new file mode 100644 index 00000000..6e564673 --- /dev/null +++ b/component/dialer/mptcp_go120.go @@ -0,0 +1,12 @@ +//go:build !go1.21 + +package dialer + +import ( + "net" +) + +const multipathTCPAvailable = false + +func setMultiPathTCP(dialer *net.Dialer) { +} diff --git a/component/dialer/mptcp_go121.go b/component/dialer/mptcp_go121.go new file mode 100644 index 00000000..360826c8 --- /dev/null +++ b/component/dialer/mptcp_go121.go @@ -0,0 +1,11 @@ +//go:build go1.21 + +package dialer + +import "net" + +const multipathTCPAvailable = true + +func setMultiPathTCP(dialer *net.Dialer) { + dialer.SetMultipathTCP(true) +} diff --git a/component/dialer/options.go b/component/dialer/options.go index 096c7a5c..30771e71 100644 --- a/component/dialer/options.go +++ b/component/dialer/options.go @@ -25,6 +25,7 @@ type option struct { network int prefer int tfo bool + mpTcp bool resolver resolver.Resolver netDialer NetDialer } @@ -83,6 +84,12 @@ func WithTFO(tfo bool) Option { } } +func WithMPTCP(mpTcp bool) Option { + return func(opt *option) { + opt.mpTcp = mpTcp + } +} + func WithNetDialer(netDialer NetDialer) Option { return func(opt *option) { opt.netDialer = netDialer diff --git a/component/iface/iface.go b/component/iface/iface.go index dca6cca1..c32b65ab 100644 --- a/component/iface/iface.go +++ b/component/iface/iface.go @@ -24,8 +24,6 @@ var ( var interfaces = singledo.NewSingle[map[string]*Interface](time.Second * 20) -const FlagRunning = 32 // interface is in running state, compatibility with golang<1.20 - func ResolveInterface(name string) (*Interface, error) { value, err, _ := interfaces.Do(func() (map[string]*Interface, error) { ifaces, err := net.Interfaces() @@ -41,7 +39,7 @@ func ResolveInterface(name string) (*Interface, error) { continue } // if not available device like Meta, dummy0, docker0, etc. - if (iface.Flags&net.FlagMulticast == 0) || (iface.Flags&net.FlagPointToPoint != 0) || (iface.Flags&FlagRunning == 0) { + if (iface.Flags&net.FlagMulticast == 0) || (iface.Flags&net.FlagPointToPoint != 0) || (iface.Flags&net.FlagRunning == 0) { continue } diff --git a/component/mmdb/mmdb.go b/component/mmdb/mmdb.go index 14f6f997..5db8bee9 100644 --- a/component/mmdb/mmdb.go +++ b/component/mmdb/mmdb.go @@ -12,42 +12,68 @@ import ( C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/log" - "github.com/oschwald/geoip2-golang" + "github.com/oschwald/maxminddb-golang" +) + +type databaseType = uint8 + +const ( + typeMaxmind databaseType = iota + typeSing + typeMetaV0 ) var ( - mmdb *geoip2.Reader - once sync.Once + reader Reader + once sync.Once ) func LoadFromBytes(buffer []byte) { once.Do(func() { - var err error - mmdb, err = geoip2.FromBytes(buffer) + mmdb, err := maxminddb.FromBytes(buffer) if err != nil { log.Fatalln("Can't load mmdb: %s", err.Error()) } + reader = Reader{Reader: mmdb} + switch mmdb.Metadata.DatabaseType { + case "sing-geoip": + reader.databaseType = typeSing + case "Meta-geoip0": + reader.databaseType = typeMetaV0 + default: + reader.databaseType = typeMaxmind + } }) } func Verify() bool { - instance, err := geoip2.Open(C.Path.MMDB()) + instance, err := maxminddb.Open(C.Path.MMDB()) if err == nil { instance.Close() } return err == nil } -func Instance() *geoip2.Reader { +func Instance() Reader { once.Do(func() { - var err error - mmdb, err = geoip2.Open(C.Path.MMDB()) + mmdbPath := C.Path.MMDB() + log.Debugln("Load MMDB file: %s", mmdbPath) + mmdb, err := maxminddb.Open(mmdbPath) if err != nil { - log.Fatalln("Can't load mmdb: %s", err.Error()) + log.Fatalln("Can't load MMDB: %s", err.Error()) + } + reader = Reader{Reader: mmdb} + switch mmdb.Metadata.DatabaseType { + case "sing-geoip": + reader.databaseType = typeSing + case "Meta-geoip0": + reader.databaseType = typeMetaV0 + default: + reader.databaseType = typeMaxmind } }) - return mmdb + return reader } func DownloadMMDB(path string) (err error) { diff --git a/component/mmdb/reader.go b/component/mmdb/reader.go new file mode 100644 index 00000000..4db53d4f --- /dev/null +++ b/component/mmdb/reader.go @@ -0,0 +1,56 @@ +package mmdb + +import ( + "fmt" + "net" + + "github.com/oschwald/maxminddb-golang" + "github.com/sagernet/sing/common" +) + +type geoip2Country struct { + Country struct { + IsoCode string `maxminddb:"iso_code"` + } `maxminddb:"country"` +} + +type Reader struct { + *maxminddb.Reader + databaseType +} + +func (r Reader) LookupCode(ipAddress net.IP) []string { + switch r.databaseType { + case typeMaxmind: + var country geoip2Country + _ = r.Lookup(ipAddress, &country) + if country.Country.IsoCode == "" { + return []string{} + } + return []string{country.Country.IsoCode} + + case typeSing: + var code string + _ = r.Lookup(ipAddress, &code) + if code == "" { + return []string{} + } + return []string{code} + + case typeMetaV0: + var record any + _ = r.Lookup(ipAddress, &record) + switch record := record.(type) { + case string: + return []string{record} + case []any: // lookup returned type of slice is []any + return common.Map(record, func(it any) string { + return it.(string) + }) + } + return []string{} + + default: + panic(fmt.Sprint("unknown geoip database type:", r.databaseType)) + } +} diff --git a/component/resource/vehicle.go b/component/resource/vehicle.go index 927a9604..2f4bfbc8 100644 --- a/component/resource/vehicle.go +++ b/component/resource/vehicle.go @@ -2,12 +2,14 @@ package resource import ( "context" - clashHttp "github.com/Dreamacro/clash/component/http" - types "github.com/Dreamacro/clash/constant/provider" + "errors" "io" "net/http" "os" "time" + + clashHttp "github.com/Dreamacro/clash/component/http" + types "github.com/Dreamacro/clash/constant/provider" ) type FileVehicle struct { @@ -54,8 +56,10 @@ func (h *HTTPVehicle) Read() ([]byte, error) { if err != nil { return nil, err } - defer resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode > 299 { + return nil, errors.New(resp.Status) + } buf, err := io.ReadAll(resp.Body) if err != nil { return nil, err diff --git a/component/sniffer/dispatcher.go b/component/sniffer/dispatcher.go index fa1c6827..f813eec2 100644 --- a/component/sniffer/dispatcher.go +++ b/component/sniffer/dispatcher.go @@ -5,7 +5,6 @@ import ( "fmt" "net" "net/netip" - "strconv" "sync" "time" @@ -26,29 +25,23 @@ var ( var Dispatcher *SnifferDispatcher type SnifferDispatcher struct { - enable bool - sniffers map[sniffer.Sniffer]SnifferConfig - forceDomain *trie.DomainSet - skipSNI *trie.DomainSet - skipList *cache.LruCache[string, uint8] - rwMux sync.RWMutex - forceDnsMapping bool - parsePureIp bool + enable bool + sniffers map[sniffer.Sniffer]SnifferConfig + forceDomain *trie.DomainSet + skipSNI *trie.DomainSet + skipList *cache.LruCache[string, uint8] + rwMux sync.RWMutex + forceDnsMapping bool + parsePureIp bool } func (sd *SnifferDispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata) { if (metadata.Host == "" && sd.parsePureIp) || sd.forceDomain.Has(metadata.Host) || (metadata.DNSMode == C.DNSMapping && sd.forceDnsMapping) { - port, err := strconv.ParseUint(metadata.DstPort, 10, 16) - if err != nil { - log.Debugln("[Sniffer] Dst port is error") - return - } - inWhitelist := false overrideDest := false for sniffer, config := range sd.sniffers { if sniffer.SupportNetwork() == C.TCP || sniffer.SupportNetwork() == C.ALLNet { - inWhitelist = sniffer.SupportPort(uint16(port)) + inWhitelist = sniffer.SupportPort(metadata.DstPort) if inWhitelist { overrideDest = config.OverrideDest break @@ -61,7 +54,7 @@ func (sd *SnifferDispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata } sd.rwMux.RLock() - dst := fmt.Sprintf("%s:%s", metadata.DstIP, metadata.DstPort) + dst := fmt.Sprintf("%s:%d", metadata.DstIP, metadata.DstPort) if count, ok := sd.skipList.Get(dst); ok && count > 5 { log.Debugln("[Sniffer] Skip sniffing[%s] due to multiple failures", dst) defer sd.rwMux.RUnlock() @@ -71,7 +64,7 @@ func (sd *SnifferDispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata if host, err := sd.sniffDomain(conn, metadata); err != nil { sd.cacheSniffFailed(metadata) - log.Debugln("[Sniffer] All sniffing sniff failed with from [%s:%s] to [%s:%s]", metadata.SrcIP, metadata.SrcPort, metadata.String(), metadata.DstPort) + log.Debugln("[Sniffer] All sniffing sniff failed with from [%s:%d] to [%s:%d]", metadata.SrcIP, metadata.SrcPort, metadata.String(), metadata.DstPort) return } else { if sd.skipSNI.Has(host) { @@ -149,7 +142,7 @@ func (sd *SnifferDispatcher) sniffDomain(conn *N.BufferedConn, metadata *C.Metad func (sd *SnifferDispatcher) cacheSniffFailed(metadata *C.Metadata) { sd.rwMux.Lock() - dst := fmt.Sprintf("%s:%s", metadata.DstIP, metadata.DstPort) + dst := fmt.Sprintf("%s:%d", metadata.DstIP, metadata.DstPort) count, _ := sd.skipList.Get(dst) if count <= 5 { count++ diff --git a/component/tls/config.go b/component/tls/config.go index 2896a1be..d7382f7c 100644 --- a/component/tls/config.go +++ b/component/tls/config.go @@ -10,8 +10,6 @@ import ( "fmt" "strings" "sync" - - xtls "github.com/xtls/go" ) var trustCerts []*x509.Certificate @@ -122,27 +120,3 @@ func GetGlobalTLSConfig(tlsConfig *tls.Config) *tls.Config { tlsConfig.RootCAs = certPool return tlsConfig } - -// GetSpecifiedFingerprintXTLSConfig specified fingerprint -func GetSpecifiedFingerprintXTLSConfig(tlsConfig *xtls.Config, fingerprint string) (*xtls.Config, error) { - if fingerprintBytes, err := convertFingerprint(fingerprint); err != nil { - return nil, err - } else { - tlsConfig = GetGlobalXTLSConfig(tlsConfig) - tlsConfig.VerifyPeerCertificate = verifyFingerprint(fingerprintBytes) - tlsConfig.InsecureSkipVerify = true - return tlsConfig, nil - } -} - -func GetGlobalXTLSConfig(tlsConfig *xtls.Config) *xtls.Config { - certPool := getCertPool() - if tlsConfig == nil { - return &xtls.Config{ - RootCAs: certPool, - } - } - - tlsConfig.RootCAs = certPool - return tlsConfig -} diff --git a/config/config.go b/config/config.go index e2e96936..cb30999b 100644 --- a/config/config.go +++ b/config/config.go @@ -51,6 +51,7 @@ type General struct { IPv6 bool `json:"ipv6"` Interface string `json:"interface-name"` RoutingMark int `json:"-"` + GeoXUrl GeoXUrl `json:"geox-url"` GeodataMode bool `json:"geodata-mode"` GeodataLoader string `json:"geodata-loader"` TCPConcurrent bool `json:"tcp-concurrent"` @@ -75,6 +76,7 @@ type Inbound struct { AllowLan bool `json:"allow-lan"` BindAddress string `json:"bind-address"` InboundTfo bool `json:"inbound-tfo"` + InboundMPTCP bool `json:"inbound-mptcp"` } // Controller config @@ -242,6 +244,7 @@ type RawConfig struct { ShadowSocksConfig string `yaml:"ss-config"` VmessConfig string `yaml:"vmess-config"` InboundTfo bool `yaml:"inbound-tfo"` + InboundMPTCP bool `yaml:"inbound-mptcp"` Authentication []string `yaml:"authentication"` AllowLan bool `yaml:"allow-lan"` BindAddress string `yaml:"bind-address"` @@ -273,7 +276,7 @@ type RawConfig struct { IPTables IPTables `yaml:"iptables"` Experimental Experimental `yaml:"experimental"` Profile Profile `yaml:"profile"` - GeoXUrl RawGeoXUrl `yaml:"geox-url"` + GeoXUrl GeoXUrl `yaml:"geox-url"` Proxy []map[string]any `yaml:"proxies"` ProxyGroup []map[string]any `yaml:"proxy-groups"` Rule []string `yaml:"rules"` @@ -282,7 +285,7 @@ type RawConfig struct { Listeners []map[string]any `yaml:"listeners"` } -type RawGeoXUrl struct { +type GeoXUrl struct { GeoIp string `yaml:"geoip" json:"geoip"` Mmdb string `yaml:"mmdb" json:"mmdb"` GeoSite string `yaml:"geosite" json:"geosite"` @@ -418,10 +421,10 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) { Profile: Profile{ StoreSelected: true, }, - GeoXUrl: RawGeoXUrl{ - Mmdb: "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/country.mmdb", - GeoIp: "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat", - GeoSite: "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat", + GeoXUrl: GeoXUrl{ + Mmdb: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.metadb", + GeoIp: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat", + GeoSite: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat", }, } @@ -448,7 +451,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) { config.General = general if len(config.General.GlobalClientFingerprint) != 0 { - log.Debugln("GlobalClientFingerprint:%s", config.General.GlobalClientFingerprint) + log.Debugln("GlobalClientFingerprint: %s", config.General.GlobalClientFingerprint) tlsC.SetGlobalUtlsClient(config.General.GlobalClientFingerprint) } @@ -532,6 +535,10 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) { func parseGeneral(cfg *RawConfig) (*General, error) { externalUI := cfg.ExternalUI geodata.SetLoader(cfg.GeodataLoader) + C.GeoIpUrl = cfg.GeoXUrl.GeoIp + C.GeoSiteUrl = cfg.GeoXUrl.GeoSite + C.MmdbUrl = cfg.GeoXUrl.Mmdb + C.GeodataMode = cfg.GeodataMode // checkout externalUI exist if externalUI != "" { externalUI = C.Path.Resolve(externalUI) @@ -552,6 +559,7 @@ func parseGeneral(cfg *RawConfig) (*General, error) { AllowLan: cfg.AllowLan, BindAddress: cfg.BindAddress, InboundTfo: cfg.InboundTfo, + InboundMPTCP: cfg.InboundMPTCP, }, Controller: Controller{ ExternalController: cfg.ExternalController, @@ -565,6 +573,7 @@ func parseGeneral(cfg *RawConfig) (*General, error) { IPv6: cfg.IPv6, Interface: cfg.Interface, RoutingMark: cfg.RoutingMark, + GeoXUrl: cfg.GeoXUrl, GeodataMode: cfg.GeodataMode, GeodataLoader: cfg.GeodataLoader, TCPConcurrent: cfg.TCPConcurrent, @@ -712,6 +721,9 @@ func parseRuleProviders(cfg *RawConfig) (ruleProviders map[string]providerTypes. func parseSubRules(cfg *RawConfig, proxies map[string]C.Proxy) (subRules map[string][]C.Rule, err error) { subRules = map[string][]C.Rule{} + for name := range cfg.SubRules { + subRules[name] = make([]C.Rule, 0) + } for name, rawRules := range cfg.SubRules { if len(name) == 0 { return nil, fmt.Errorf("sub-rule name is empty") diff --git a/config/initial.go b/config/initial.go index 0921040d..6d6429ab 100644 --- a/config/initial.go +++ b/config/initial.go @@ -2,7 +2,6 @@ package config import ( "fmt" - "github.com/Dreamacro/clash/component/geodata" "os" C "github.com/Dreamacro/clash/constant" @@ -28,23 +27,6 @@ func Init(dir string) error { f.Write([]byte(`mixed-port: 7890`)) f.Close() } - buf, _ := os.ReadFile(C.Path.Config()) - rawCfg, err := UnmarshalRawConfig(buf) - if err != nil { - log.Errorln(err.Error()) - fmt.Printf("configuration file %s test failed\n", C.Path.Config()) - os.Exit(1) - } - if !C.GeodataMode { - C.GeodataMode = rawCfg.GeodataMode - } - C.GeoIpUrl = rawCfg.GeoXUrl.GeoIp - C.GeoSiteUrl = rawCfg.GeoXUrl.GeoSite - C.MmdbUrl = rawCfg.GeoXUrl.Mmdb - // initial GeoIP - if err := geodata.InitGeoIP(); err != nil { - return fmt.Errorf("can't initial GeoIP: %w", err) - } return nil } diff --git a/config/updateGeo.go b/config/updateGeo.go index e76301ba..b75d3184 100644 --- a/config/updateGeo.go +++ b/config/updateGeo.go @@ -14,7 +14,7 @@ import ( clashHttp "github.com/Dreamacro/clash/component/http" C "github.com/Dreamacro/clash/constant" - "github.com/oschwald/geoip2-golang" + "github.com/oschwald/maxminddb-golang" ) func UpdateGeoDatabases() error { @@ -44,7 +44,7 @@ func UpdateGeoDatabases() error { return fmt.Errorf("can't download MMDB database file: %w", err) } - instance, err := geoip2.FromBytes(data) + instance, err := maxminddb.FromBytes(data) if err != nil { return fmt.Errorf("invalid MMDB database file: %s", err) } diff --git a/constant/metadata.go b/constant/metadata.go index de26a05f..dbd31fd8 100644 --- a/constant/metadata.go +++ b/constant/metadata.go @@ -128,10 +128,10 @@ type Metadata struct { Type Type `json:"type"` SrcIP netip.Addr `json:"sourceIP"` DstIP netip.Addr `json:"destinationIP"` - SrcPort string `json:"sourcePort"` - DstPort string `json:"destinationPort"` + SrcPort uint16 `json:"sourcePort,string"` // `,string` is used to compatible with old version json output + DstPort uint16 `json:"destinationPort,string"` // `,string` is used to compatible with old version json output InIP netip.Addr `json:"inboundIP"` - InPort string `json:"inboundPort"` + InPort uint16 `json:"inboundPort,string"` // `,string` is used to compatible with old version json output InName string `json:"inboundName"` InUser string `json:"inboundUser"` Host string `json:"host"` @@ -147,11 +147,11 @@ type Metadata struct { } func (m *Metadata) RemoteAddress() string { - return net.JoinHostPort(m.String(), m.DstPort) + return net.JoinHostPort(m.String(), strconv.FormatUint(uint64(m.DstPort), 10)) } func (m *Metadata) SourceAddress() string { - return net.JoinHostPort(m.SrcIP.String(), m.SrcPort) + return net.JoinHostPort(m.SrcIP.String(), strconv.FormatUint(uint64(m.SrcPort), 10)) } func (m *Metadata) SourceDetail() string { @@ -172,7 +172,7 @@ func (m *Metadata) SourceDetail() string { } func (m *Metadata) SourceValid() bool { - return m.SrcPort != "" && m.SrcIP.IsValid() + return m.SrcPort != 0 && m.SrcIP.IsValid() } func (m *Metadata) AddrType() int { @@ -211,8 +211,7 @@ func (m *Metadata) Pure() *Metadata { } func (m *Metadata) AddrPort() netip.AddrPort { - port, _ := strconv.ParseUint(m.DstPort, 10, 16) - return netip.AddrPortFrom(m.DstIP.Unmap(), uint16(port)) + return netip.AddrPortFrom(m.DstIP.Unmap(), m.DstPort) } func (m *Metadata) UDPAddr() *net.UDPAddr { @@ -242,6 +241,11 @@ func (m *Metadata) SetRemoteAddress(rawAddress string) error { return err } + var uint16Port uint16 + if port, err := strconv.ParseUint(port, 10, 16); err == nil { + uint16Port = uint16(port) + } + if ip, err := netip.ParseAddr(host); err != nil { m.Host = host m.DstIP = netip.Addr{} @@ -249,7 +253,7 @@ func (m *Metadata) SetRemoteAddress(rawAddress string) error { m.Host = "" m.DstIP = ip.Unmap() } - m.DstPort = port + m.DstPort = uint16Port return nil } diff --git a/constant/path.go b/constant/path.go index 897dcfdc..d7477e0e 100644 --- a/constant/path.go +++ b/constant/path.go @@ -6,6 +6,7 @@ import ( "os" P "path" "path/filepath" + "strconv" "strings" ) @@ -22,7 +23,7 @@ var Path = func() *path { if err != nil { homeDir, _ = os.Getwd() } - allowUnsafePath := strings.TrimSpace(os.Getenv("SKIP_SAFE_PATH_CHECK")) == "1" + allowUnsafePath, _ := strconv.ParseBool(os.Getenv("SKIP_SAFE_PATH_CHECK")) homeDir = P.Join(homeDir, ".config", Name) return &path{homeDir: homeDir, configFile: "config.yaml", allowUnsafePath: allowUnsafePath} }() @@ -90,13 +91,15 @@ func (p *path) MMDB() string { // 目录则直接跳过 continue } else { - if strings.EqualFold(fi.Name(), "Country.mmdb") { + if strings.EqualFold(fi.Name(), "Country.mmdb") || + strings.EqualFold(fi.Name(), "geoip.db") || + strings.EqualFold(fi.Name(), "geoip.metadb") { GeoipName = fi.Name() return P.Join(p.homeDir, fi.Name()) } } } - return P.Join(p.homeDir, "Country.mmdb") + return P.Join(p.homeDir, "geoip.metadb") } func (p *path) OldCache() string { diff --git a/constant/tun.go b/constant/tun.go index 38f51155..5e2841bc 100644 --- a/constant/tun.go +++ b/constant/tun.go @@ -10,12 +10,14 @@ var StackTypeMapping = map[string]TUNStack{ strings.ToLower(TunGvisor.String()): TunGvisor, strings.ToLower(TunSystem.String()): TunSystem, strings.ToLower(TunLWIP.String()): TunLWIP, + strings.ToLower(TunMixed.String()): TunMixed, } const ( TunGvisor TUNStack = iota TunSystem TunLWIP + TunMixed ) type TUNStack int @@ -64,6 +66,8 @@ func (e TUNStack) String() string { return "System" case TunLWIP: return "LWIP" + case TunMixed: + return "Mixed" default: return "unknown" } diff --git a/dns/enhancer.go b/dns/enhancer.go index 76d4460e..ab144fd3 100644 --- a/dns/enhancer.go +++ b/dns/enhancer.go @@ -109,7 +109,7 @@ func NewEnhancer(cfg Config) *ResolverEnhancer { if cfg.EnhancedMode != C.DNSNormal { fakePool = cfg.Pool - mapping = cache.New(cache.WithSize[netip.Addr, string](4096), cache.WithStale[netip.Addr, string](true)) + mapping = cache.New(cache.WithSize[netip.Addr, string](4096)) } return &ResolverEnhancer{ diff --git a/dns/filters.go b/dns/filters.go index 58b261ac..47e7adcd 100644 --- a/dns/filters.go +++ b/dns/filters.go @@ -2,6 +2,7 @@ package dns import ( "net/netip" + "strings" "github.com/Dreamacro/clash/component/geodata" "github.com/Dreamacro/clash/component/geodata/router" @@ -9,7 +10,6 @@ import ( "github.com/Dreamacro/clash/component/trie" C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/log" - "strings" ) type fallbackIPFilter interface { @@ -24,8 +24,13 @@ var geoIPMatcher *router.GeoIPMatcher func (gf *geoipFilter) Match(ip netip.Addr) bool { if !C.GeodataMode { - record, _ := mmdb.Instance().Country(ip.AsSlice()) - return !strings.EqualFold(record.Country.IsoCode, gf.code) && !ip.IsPrivate() + codes := mmdb.Instance().LookupCode(ip.AsSlice()) + for _, code := range codes { + if !strings.EqualFold(code, gf.code) && !ip.IsPrivate() { + return true + } + } + return false } if geoIPMatcher == nil { diff --git a/dns/middleware.go b/dns/middleware.go index f2dd9c96..695432da 100644 --- a/dns/middleware.go +++ b/dns/middleware.go @@ -129,6 +129,10 @@ func withMapping(mapping *cache.LruCache[netip.Addr, string]) middleware { continue } + if ttl < 1 { + ttl = 1 + } + mapping.SetWithExpire(ip, host, time.Now().Add(time.Second*time.Duration(ttl))) } diff --git a/dns/util.go b/dns/util.go index edd26a42..77f677cb 100644 --- a/dns/util.go +++ b/dns/util.go @@ -7,6 +7,7 @@ import ( "fmt" "net" "net/netip" + "strconv" "strings" "time" @@ -193,6 +194,10 @@ func getDialHandler(r *Resolver, proxyAdapter C.ProxyAdapter, proxyName string, if err != nil { return nil, err } + uintPort, err := strconv.ParseUint(port, 10, 16) + if err != nil { + return nil, err + } if proxyAdapter == nil { var ok bool proxyAdapter, ok = tunnel.Proxies()[proxyName] @@ -206,7 +211,7 @@ func getDialHandler(r *Resolver, proxyAdapter C.ProxyAdapter, proxyName string, metadata := &C.Metadata{ NetWork: C.TCP, Host: host, - DstPort: port, + DstPort: uint16(uintPort), } if proxyAdapter != nil { if proxyAdapter.IsL3Protocol(metadata) { // L3 proxy should resolve domain before to avoid loopback @@ -231,7 +236,7 @@ func getDialHandler(r *Resolver, proxyAdapter C.ProxyAdapter, proxyName string, NetWork: C.UDP, Host: "", DstIP: dstIP, - DstPort: port, + DstPort: uint16(uintPort), } if proxyAdapter == nil { return dialer.DialContext(ctx, network, addr, opts...) @@ -257,6 +262,10 @@ func listenPacket(ctx context.Context, proxyAdapter C.ProxyAdapter, proxyName st if err != nil { return nil, err } + uintPort, err := strconv.ParseUint(port, 10, 16) + if err != nil { + return nil, err + } if proxyAdapter == nil { var ok bool proxyAdapter, ok = tunnel.Proxies()[proxyName] @@ -274,7 +283,7 @@ func listenPacket(ctx context.Context, proxyAdapter C.ProxyAdapter, proxyName st NetWork: C.UDP, Host: "", DstIP: dstIP, - DstPort: port, + DstPort: uint16(uintPort), } if proxyAdapter == nil { return dialer.ListenPacket(ctx, dialer.ParseNetwork(network, dstIP), "", opts...) @@ -288,12 +297,16 @@ func listenPacket(ctx context.Context, proxyAdapter C.ProxyAdapter, proxyName st } func batchExchange(ctx context.Context, clients []dnsClient, m *D.Msg) (msg *D.Msg, cache bool, err error) { + cache = true fast, ctx := picker.WithTimeout[*D.Msg](ctx, resolver.DefaultDNSTimeout) + defer fast.Close() domain := msgToDomain(m) for _, client := range clients { + if _, isRCodeClient := client.(rcodeClient); isRCodeClient { + msg, err = client.Exchange(m) + return msg, false, err + } client := client // shadow define client to ensure the value captured by the closure will not be changed in the next loop - _, cache = client.(rcodeClient) - cache = !cache fast.Go(func() (*D.Msg, error) { log.Debugln("[DNS] resolve %s from %s", domain, client.Address()) m, err := client.ExchangeContext(ctx, m) @@ -302,21 +315,19 @@ func batchExchange(ctx context.Context, clients []dnsClient, m *D.Msg) (msg *D.M } else if cache && (m.Rcode == D.RcodeServerFailure || m.Rcode == D.RcodeRefused) { // currently, cache indicates whether this msg was from a RCode client, // so we would ignore RCode errors from RCode clients. - return nil, errors.New("server failure") + return nil, errors.New("server failure: " + D.RcodeToString[m.Rcode]) } log.Debugln("[DNS] %s --> %s, from %s", domain, msgToIP(m), client.Address()) return m, nil }) } - elm := fast.Wait() - if elm == nil { - err := errors.New("all DNS requests failed") + msg = fast.Wait() + if msg == nil { + err = errors.New("all DNS requests failed") if fErr := fast.Error(); fErr != nil { - err = fmt.Errorf("%w, first error: %s", err, fErr.Error()) + err = fmt.Errorf("%w, first error: %w", err, fErr) } - return nil, true, err } - msg = elm return } diff --git a/docs/config.yaml b/docs/config.yaml index 0cec9a04..6ae3910e 100644 --- a/docs/config.yaml +++ b/docs/config.yaml @@ -19,9 +19,9 @@ mode: rule #自定义 geodata url geox-url: - geoip: "https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geoip.dat" - geosite: "https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geosite.dat" - mmdb: "https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/Country.mmdb" + geoip: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat" + geosite: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat" + mmdb: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.metadb" log-level: debug # 日志等级 silent/error/warning/info/debug diff --git a/go.mod b/go.mod index d3586419..3167d9ea 100644 --- a/go.mod +++ b/go.mod @@ -1,56 +1,54 @@ module github.com/Dreamacro/clash -go 1.19 +go 1.20 require ( github.com/3andne/restls-client-go v0.1.4 github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da - github.com/cilium/ebpf v0.10.0 - github.com/coreos/go-iptables v0.6.0 + github.com/cilium/ebpf v0.11.0 + github.com/coreos/go-iptables v0.7.0 github.com/dlclark/regexp2 v1.10.0 - github.com/go-chi/chi/v5 v5.0.8 + github.com/go-chi/chi/v5 v5.0.10 github.com/go-chi/cors v1.2.1 - github.com/go-chi/render v1.0.2 + github.com/go-chi/render v1.0.3 github.com/gofrs/uuid/v5 v5.0.0 github.com/gorilla/websocket v1.5.0 - github.com/hashicorp/golang-lru v0.5.4 - github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb + github.com/insomniacslk/dhcp v0.0.0-20230731140434-0f9eb93a696c github.com/jpillora/backoff v1.0.0 github.com/klauspost/cpuid/v2 v2.2.5 github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 github.com/mdlayher/netlink v1.7.2 github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 - github.com/metacubex/quic-go v0.36.1-0.20230626040200-6396910a557f - github.com/metacubex/sing-shadowsocks v0.2.2 - github.com/metacubex/sing-shadowsocks2 v0.1.0 - github.com/metacubex/sing-tun v0.1.5-0.20230618235243-65051e73b018 - github.com/metacubex/sing-vmess v0.1.5 + github.com/metacubex/quic-go v0.37.4-0.20230809092428-5acf8eb2de86 + github.com/metacubex/sing-shadowsocks v0.2.4 + github.com/metacubex/sing-shadowsocks2 v0.1.3 + github.com/metacubex/sing-tun v0.1.11 + github.com/metacubex/sing-vmess v0.1.8-0.20230801054944-603005461ff8 github.com/metacubex/sing-wireguard v0.0.0-20230611155257-1498ae315a28 - github.com/miekg/dns v1.1.54 - github.com/mroth/weightedrand/v2 v2.0.1 + github.com/miekg/dns v1.1.55 + github.com/mroth/weightedrand/v2 v2.0.2 github.com/openacid/low v0.1.21 - github.com/oschwald/geoip2-golang v1.8.0 + github.com/oschwald/maxminddb-golang v1.12.0 github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 - github.com/sagernet/sing v0.2.5 - github.com/sagernet/sing-mux v0.1.0 - github.com/sagernet/sing-shadowtls v0.1.2 + github.com/sagernet/sing v0.2.9 + github.com/sagernet/sing-mux v0.1.2 + github.com/sagernet/sing-shadowtls v0.1.4 github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77 github.com/samber/lo v1.38.1 - github.com/shirou/gopsutil/v3 v3.23.5 - github.com/sirupsen/logrus v1.9.2 - github.com/stretchr/testify v1.8.3 - github.com/xtls/go v0.0.0-20230107031059-4610f88d00f3 + github.com/shirou/gopsutil/v3 v3.23.7 + github.com/sirupsen/logrus v1.9.3 + github.com/stretchr/testify v1.8.4 github.com/zhangyunhao116/fastrand v0.3.0 go.etcd.io/bbolt v1.3.7 - go.uber.org/automaxprocs v1.5.2 - golang.org/x/crypto v0.10.0 - golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 - golang.org/x/net v0.11.0 - golang.org/x/sync v0.2.0 - golang.org/x/sys v0.9.0 - google.golang.org/protobuf v1.30.0 + go.uber.org/automaxprocs v1.5.3 + golang.org/x/crypto v0.12.0 + golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b + golang.org/x/net v0.14.0 + golang.org/x/sync v0.3.0 + golang.org/x/sys v0.11.0 + google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 lukechampine.com/blake3 v1.2.1 ) @@ -80,13 +78,11 @@ require ( github.com/metacubex/gvisor v0.0.0-20230611153922-78842f086475 // indirect github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 // indirect github.com/onsi/ginkgo/v2 v2.9.5 // indirect - github.com/oschwald/maxminddb-golang v1.10.0 // indirect github.com/pierrec/lz4/v4 v4.1.14 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.2 // indirect - github.com/quic-go/qtls-go1-20 v0.2.2 // indirect + github.com/quic-go/qtls-go1-20 v0.3.1 // indirect github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 // indirect @@ -100,10 +96,10 @@ require ( github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect - golang.org/x/mod v0.10.0 // indirect - golang.org/x/text v0.10.0 // indirect + golang.org/x/mod v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.9.1 // indirect ) -replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20230618234508-ce8816d0274b +replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20230714010500-e24664dc75a7 diff --git a/go.sum b/go.sum index 6992e575..a90f4dba 100644 --- a/go.sum +++ b/go.sum @@ -14,10 +14,10 @@ github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.10.0 h1:nk5HPMeoBXtOzbkZBWym+ZWq1GIiHUsBFXxwewXAHLQ= -github.com/cilium/ebpf v0.10.0/go.mod h1:DPiVdY/kT534dgc9ERmvP8mWA+9gvwgKfRvk4nNWnoE= -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/cilium/ebpf v0.11.0 h1:V8gS/bTCCjX9uUnkUFUpPsksM8n1lXBAvHcpiFk1X2Y= +github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUgWsVs= +github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8= +github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= 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= @@ -32,15 +32,15 @@ github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1 h1:tlDMEdcPRQKBE github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1/go.mod h1:4RfsapbGx2j/vU5xC/5/9qB3kn9Awp1YDiEnN43QrJ4= github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010 h1:fuGucgPk5dN6wzfnxl3D0D3rVLw4v2SbBT9jb4VnxzA= github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010/go.mod h1:JtBcj7sBuTTRupn7c2bFspMDIObMJsVK8TeUvpShPok= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0= -github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= +github.com/go-chi/chi/v5 v5.0.10/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.2 h1:4ER/udB0+fMWB2Jlf15RV3F4A2FDuYi/9f+lFttR/Lg= -github.com/go-chi/render v1.0.2/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= +github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4= +github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -64,13 +64,11 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb h1:6fDKEAXwe3rsfS4khW3EZ8kEqmSiV9szhMPcDrD+Y7Q= -github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb/go.mod h1:7474bZ1YNCvarT6WFKie4kEET6J0KYRDC4XJqqXzQW4= +github.com/insomniacslk/dhcp v0.0.0-20230731140434-0f9eb93a696c h1:P/3mFnHCv1A/ej4m8pF5EB6FUt9qEL2Q9lfrcUNwCYs= +github.com/insomniacslk/dhcp v0.0.0-20230731140434-0f9eb93a696c/go.mod h1:7474bZ1YNCvarT6WFKie4kEET6J0KYRDC4XJqqXzQW4= github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= @@ -94,24 +92,24 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88= github.com/metacubex/gvisor v0.0.0-20230611153922-78842f086475 h1:qSEOvPPaMrWggFyFhFYGyMR8i1HKyhXjdi1QYUAa2ww= github.com/metacubex/gvisor v0.0.0-20230611153922-78842f086475/go.mod h1:wehEpqiogdeyncfhckJP5gD2LtBgJW0wnDC24mJ+8Jg= -github.com/metacubex/quic-go v0.36.1-0.20230626040200-6396910a557f h1:w4SyW/AoLVvHN3YRiOU/Jb159r8fOBDiVA5e5XVLzM4= -github.com/metacubex/quic-go v0.36.1-0.20230626040200-6396910a557f/go.mod h1:mnMWBbeYt+xTvFQrAWu9IJH0h++EjnAS2B/aj+VEXzQ= -github.com/metacubex/sing v0.0.0-20230618234508-ce8816d0274b h1:mVd3v+zMQq61rJe/pJJSh0/Iin9UnkQaZTH2NOg/2Vg= -github.com/metacubex/sing v0.0.0-20230618234508-ce8816d0274b/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= -github.com/metacubex/sing-shadowsocks v0.2.2 h1:prciO78IwtR4Sp+/CnP+aZSzpBRfL7zKaYez1S4EOnI= -github.com/metacubex/sing-shadowsocks v0.2.2/go.mod h1:haolI+8Yc8MhNDqNuoRP4X5vaquXWNYeL1YxrQZ5kCU= -github.com/metacubex/sing-shadowsocks2 v0.1.0 h1:ZxPEToY1RaRtG6ljz2n13ASMVqyAM7Bh11TmWoExYu4= -github.com/metacubex/sing-shadowsocks2 v0.1.0/go.mod h1:6C4EkvqMz5h7jECKrQeIByoLDHxiepsgPajIrxqxj/s= -github.com/metacubex/sing-tun v0.1.5-0.20230618235243-65051e73b018 h1:M7vBGA4RL4BBLSYfi15u/9QdVSqPkhuL4KRCuRhxuQY= -github.com/metacubex/sing-tun v0.1.5-0.20230618235243-65051e73b018/go.mod h1:DSVNjWT0rkkg8zn2+wpDvxgXuXRmMiNFDnVmnUctbAc= -github.com/metacubex/sing-vmess v0.1.5 h1:wODu17P27aGw0GhSIb/rIZWNh3/F5ghF/1PDDt95CQY= -github.com/metacubex/sing-vmess v0.1.5/go.mod h1:s00xTd3c/zOMQHyPec0G/pbUklndleiH0QaHZRd4Ykg= +github.com/metacubex/quic-go v0.37.4-0.20230809092428-5acf8eb2de86 h1:qGExcB3lYk51LPEJh5HTdQplbZmuTn+tkcuhuas1LC8= +github.com/metacubex/quic-go v0.37.4-0.20230809092428-5acf8eb2de86/go.mod h1:HhHoyskMk4kzfLPKcm7EF7pGXF89KRVwjbGrEaN6lIU= +github.com/metacubex/sing v0.0.0-20230714010500-e24664dc75a7 h1:XY3Y6nPL45XuN/k3rDXJ1TJknLo8rTo1SVuDOmOEf4E= +github.com/metacubex/sing v0.0.0-20230714010500-e24664dc75a7/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= +github.com/metacubex/sing-shadowsocks v0.2.4 h1:Gc99Z17JVif1PKKq1pjqhSmc2kvHUgk+AqxOstCzhQ0= +github.com/metacubex/sing-shadowsocks v0.2.4/go.mod h1:w9qoEZSh9aKeXSLXHe0DGbG2UE9/2VlLGwukzQZ7byI= +github.com/metacubex/sing-shadowsocks2 v0.1.3 h1:nZvH+4jQXZ92NeNdR9fXaUGTPNJPt6u0nkcuh/NEt5Y= +github.com/metacubex/sing-shadowsocks2 v0.1.3/go.mod h1:5Mt93RlmRlIcDmvtapkhQJ8YTRGLFhHciLYopJjs7j8= +github.com/metacubex/sing-tun v0.1.11 h1:B8meDewklvKkeUfjqR2ViuYLam0/m4IgkTi3qcJIOuc= +github.com/metacubex/sing-tun v0.1.11/go.mod h1:vbki176Y5sxXC1DWXucrPh3q5j8cKai1D87y8m8rjQc= +github.com/metacubex/sing-vmess v0.1.8-0.20230801054944-603005461ff8 h1:AqqZCr9gOeKdO6oIzFh4b2puOUFcw8MdpmGHWRehyX8= +github.com/metacubex/sing-vmess v0.1.8-0.20230801054944-603005461ff8/go.mod h1:tyJg7b4s8NrSztl/Y1ajA7X0sJLlIsEJWkgRVocjmgY= github.com/metacubex/sing-wireguard v0.0.0-20230611155257-1498ae315a28 h1:mXFpxfR/1nADh+GoT8maWEvc6LO6uatPsARD8WzUDMA= github.com/metacubex/sing-wireguard v0.0.0-20230611155257-1498ae315a28/go.mod h1:KrDPq/dE793jGIJw9kcIvjA/proAfU0IeU7WlMXW7rs= -github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= -github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= -github.com/mroth/weightedrand/v2 v2.0.1 h1:zrEVDIaau/E4QLOKu02kpg8T8myweFlMGikIgbIdrRA= -github.com/mroth/weightedrand/v2 v2.0.1/go.mod h1:f2faGsfOGOwc1p94wzHKKZyTpcJUW7OJ/9U4yfiNAOU= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/mroth/weightedrand/v2 v2.0.2 h1:A8wJRUBcfguGl6oOQHI8fy5P4ViGRT9hdQdlG/7RiXo= +github.com/mroth/weightedrand/v2 v2.0.2/go.mod h1:f2faGsfOGOwc1p94wzHKKZyTpcJUW7OJ/9U4yfiNAOU= github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 h1:1102pQc2SEPp5+xrS26wEaeb26sZy6k9/ZXlZN+eXE4= github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7/go.mod h1:UqoUn6cHESlliMhOnKLWr+CBH+e3bazUPvFj1XZwAjs= github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= @@ -122,10 +120,8 @@ github.com/openacid/low v0.1.21 h1:Tr2GNu4N/+rGRYdOsEHOE89cxUIaDViZbVmKz29uKGo= github.com/openacid/low v0.1.21/go.mod h1:q+MsKI6Pz2xsCkzV4BLj7NR5M4EX0sGz5AqotpZDVh0= github.com/openacid/must v0.1.3/go.mod h1:luPiXCuJlEo3UUFQngVQokV0MPGryeYvtCbQPs3U1+I= github.com/openacid/testkeys v0.1.6/go.mod h1:MfA7cACzBpbiwekivj8StqX0WIRmqlMsci1c37CA3Do= -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/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs= +github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY= github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE= github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -136,19 +132,17 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:Om github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= -github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= -github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= +github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA= github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= -github.com/sagernet/sing-mux v0.1.0 h1:xihlDRNs1J+hYwmvW9/ZmaghjDx7O0Y5dty0pOLQGB4= -github.com/sagernet/sing-mux v0.1.0/go.mod h1:i3jKjV4pRTFTV/ly5V3oa2JMPy0SAZ5X8X4tDU9Hw94= -github.com/sagernet/sing-shadowtls v0.1.2 h1:wkPf4gF+cmaP0cIbArpyq+mc6GcwbMx60CssmmhEQ0s= -github.com/sagernet/sing-shadowtls v0.1.2/go.mod h1:rTxhbSY8jGWZOWjdeOe1vP3E+hkgen8aRA2p7YccM88= +github.com/sagernet/sing-mux v0.1.2 h1:av2/m6e+Gh+ECTuJZqYCjJz55BNkot0VyRMkREqyF/g= +github.com/sagernet/sing-mux v0.1.2/go.mod h1:r2V8AlOzXaRCHXK7fILCUGzuI2iILweTaG8C5xlpHxo= +github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k= +github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0= github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 h1:2ItpW1nMNkPzmBTxV0/eClCklHrFSQMnUGcpUmJxVeE= @@ -161,8 +155,8 @@ github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 h1:rc/CcqLH3lh8n+csdOuDfP+NuykE0U6AeYSJJHKDgSg= github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9/go.mod h1:a/83NAfUXvEuLpmxDssAXxgUgrEy12MId3Wd7OTs76s= -github.com/shirou/gopsutil/v3 v3.23.5 h1:5SgDCeQ0KW0S4N0znjeM/eFHXXOKyv2dVNgRq/c9P6Y= -github.com/shirou/gopsutil/v3 v3.23.5/go.mod h1:Ng3Maa27Q2KARVJ0SPZF5NdrQSC3XHKP8IIWrHgMeLY= +github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4= +github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -173,8 +167,8 @@ github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c h1:DjKMC30y6y github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c/go.mod h1:NV/a66PhhWYVmUMaotlXJ8fIEFB98u+c8l/CQIEFLrU= github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e h1:ur8uMsPIFG3i4Gi093BQITvwH9znsz2VUZmnmwHvpIo= github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e/go.mod h1:+e5fBW3bpPyo+3uLo513gIUblc03egGjMM0+5GKbzK8= -github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= -github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -183,8 +177,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ 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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= @@ -196,8 +190,6 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/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-20230107031059-4610f88d00f3 h1:a3Y4WVjCxwoyO4E2xdNvq577tW8lkSBgyrA8E9+2NtM= -github.com/xtls/go v0.0.0-20230107031059-4610f88d00f3/go.mod h1:YJTRELIWrGxR1s8xcEBgxcxBfwQfMGjdvNLTjN9XFgY= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= @@ -207,28 +199,28 @@ gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiV gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= -go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= +go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI= +golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/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.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -246,14 +238,14 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -267,8 +259,8 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T 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= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/hub/executor/executor.go b/hub/executor/executor.go index 724150e7..f4cda47a 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -360,6 +360,7 @@ func updateGeneral(general *config.General) { } inbound.SetTfo(general.InboundTfo) + inbound.SetMPTCP(general.InboundMPTCP) adapter.UnifiedDelay.Store(general.UnifiedDelay) diff --git a/rules/common/geoip.go b/rules/common/geoip.go index 0c134c63..2f96c2ef 100644 --- a/rules/common/geoip.go +++ b/rules/common/geoip.go @@ -40,8 +40,13 @@ func (g *GEOIP) Match(metadata *C.Metadata) (bool, string) { resolver.IsFakeBroadcastIP(ip), g.adapter } if !C.GeodataMode { - record, _ := mmdb.Instance().Country(ip.AsSlice()) - return strings.EqualFold(record.Country.IsoCode, g.country), g.adapter + codes := mmdb.Instance().LookupCode(ip.AsSlice()) + for _, code := range codes { + if strings.EqualFold(code, g.country) { + return true, g.adapter + } + } + return false, g.adapter } return g.geoIPMatcher.Match(ip.AsSlice()), g.adapter } diff --git a/rules/common/port.go b/rules/common/port.go index e3949f51..334d083f 100644 --- a/rules/common/port.go +++ b/rules/common/port.go @@ -2,7 +2,6 @@ package common import ( "fmt" - "strconv" "github.com/Dreamacro/clash/common/utils" C "github.com/Dreamacro/clash/constant" @@ -28,7 +27,7 @@ func (p *Port) Match(metadata *C.Metadata) (bool, string) { case C.SrcPort: targetPort = metadata.SrcPort } - return p.matchPortReal(targetPort), p.adapter + return p.portRanges.Check(targetPort), p.adapter } func (p *Port) Adapter() string { @@ -39,16 +38,10 @@ func (p *Port) Payload() string { return p.port } -func (p *Port) matchPortReal(portRef string) bool { - port, _ := strconv.Atoi(portRef) - - return p.portRanges.Check(uint16(port)) -} - func NewPort(port string, adapter string, ruleType C.RuleType) (*Port, error) { portRanges, err := utils.NewIntRanges[uint16](port) if err != nil { - return nil, fmt.Errorf("%w, %s", errPayload, err.Error()) + return nil, fmt.Errorf("%w, %w", errPayload, err) } if len(portRanges) == 0 { diff --git a/rules/common/uid.go b/rules/common/uid.go index b191a55f..3b20928f 100644 --- a/rules/common/uid.go +++ b/rules/common/uid.go @@ -23,7 +23,7 @@ func NewUid(oUid, adapter string) (*Uid, error) { uidRange, err := utils.NewIntRanges[uint32](oUid) if err != nil { - return nil, fmt.Errorf("%w, %s", errPayload, err.Error()) + return nil, fmt.Errorf("%w, %w", errPayload, err) } if len(uidRange) == 0 { diff --git a/rules/logic_test/logic_test.go b/rules/logic_test/logic_test.go index de5ae569..52318b3f 100644 --- a/rules/logic_test/logic_test.go +++ b/rules/logic_test/logic_test.go @@ -20,7 +20,7 @@ func TestAND(t *testing.T) { m, _ := and.Match(&C.Metadata{ Host: "baidu.com", NetWork: C.TCP, - DstPort: "20000", + DstPort: 20000, }) assert.Equal(t, true, m) @@ -35,7 +35,7 @@ func TestNOT(t *testing.T) { not, err := NewNOT("((DST-PORT,6000-6500))", "REJECT", ParseRule) assert.Equal(t, nil, err) m, _ := not.Match(&C.Metadata{ - DstPort: "6100", + DstPort: 6100, }) assert.Equal(t, false, m) diff --git a/test/clash_test.go b/test/clash_test.go index 3fdca5d0..60b99791 100644 --- a/test/clash_test.go +++ b/test/clash_test.go @@ -556,7 +556,7 @@ func testSuit(t *testing.T, proxy C.ProxyAdapter) { assert.NoError(t, testPingPongWithConn(t, func() net.Conn { conn, err := proxy.DialContext(context.Background(), &C.Metadata{ Host: localIP.String(), - DstPort: "10001", + DstPort: 10001, }) require.NoError(t, err) return conn @@ -565,7 +565,7 @@ func testSuit(t *testing.T, proxy C.ProxyAdapter) { assert.NoError(t, testLargeDataWithConn(t, func() net.Conn { conn, err := proxy.DialContext(context.Background(), &C.Metadata{ Host: localIP.String(), - DstPort: "10001", + DstPort: 10001, }) require.NoError(t, err) return conn @@ -578,7 +578,7 @@ func testSuit(t *testing.T, proxy C.ProxyAdapter) { pc, err := proxy.ListenPacketContext(context.Background(), &C.Metadata{ NetWork: C.UDP, DstIP: localIP, - DstPort: "10001", + DstPort: 10001, }) require.NoError(t, err) defer pc.Close() @@ -588,7 +588,7 @@ func testSuit(t *testing.T, proxy C.ProxyAdapter) { pc, err = proxy.ListenPacketContext(context.Background(), &C.Metadata{ NetWork: C.UDP, DstIP: localIP, - DstPort: "10001", + DstPort: 10001, }) require.NoError(t, err) defer pc.Close() @@ -598,7 +598,7 @@ func testSuit(t *testing.T, proxy C.ProxyAdapter) { pc, err = proxy.ListenPacketContext(context.Background(), &C.Metadata{ NetWork: C.UDP, DstIP: localIP, - DstPort: "10001", + DstPort: 10001, }) require.NoError(t, err) defer pc.Close() @@ -635,7 +635,7 @@ func benchmarkProxy(b *testing.B, proxy C.ProxyAdapter) { conn, err := proxy.DialContext(context.Background(), &C.Metadata{ Host: localIP.String(), - DstPort: "10001", + DstPort: 10001, }) require.NoError(b, err) diff --git a/test/go.mod b/test/go.mod index 957c444b..80f958a5 100644 --- a/test/go.mod +++ b/test/go.mod @@ -6,9 +6,9 @@ require ( github.com/Dreamacro/clash v0.0.0 github.com/docker/docker v20.10.21+incompatible github.com/docker/go-connections v0.4.0 - github.com/miekg/dns v1.1.54 - github.com/stretchr/testify v1.8.3 - golang.org/x/net v0.10.0 + github.com/miekg/dns v1.1.55 + github.com/stretchr/testify v1.8.4 + golang.org/x/net v0.14.0 ) replace github.com/Dreamacro/clash => ../ @@ -20,8 +20,8 @@ require ( github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 // indirect github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect github.com/andybalholm/brotli v1.0.5 // indirect - github.com/cilium/ebpf v0.10.0 // indirect - github.com/coreos/go-iptables v0.6.0 // indirect + github.com/cilium/ebpf v0.11.0 // indirect + github.com/coreos/go-iptables v0.7.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dlclark/regexp2 v1.10.0 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect @@ -32,16 +32,16 @@ require ( github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gofrs/uuid/v5 v5.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.6.0 // indirect - github.com/google/btree v1.0.1 // indirect + github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/yamux v0.1.1 // indirect - github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb // indirect + github.com/insomniacslk/dhcp v0.0.0-20230731140434-0f9eb93a696c // indirect github.com/josharian/native v1.1.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect @@ -51,65 +51,62 @@ require ( github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/socket v0.4.1 // indirect github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect - github.com/metacubex/gvisor v0.0.0-20230417114019-3c3ee672d60c // indirect - github.com/metacubex/quic-go v0.35.2-0.20230603072621-ea2663348ebb // indirect - github.com/metacubex/sing-shadowsocks v0.2.2-0.20230509230448-a5157cc00a1c // indirect - github.com/metacubex/sing-shadowsocks2 v0.0.0-20230529235701-a238874242ca // indirect - github.com/metacubex/sing-tun v0.1.5-0.20230530125750-171afb2dfd8e // indirect - github.com/metacubex/sing-wireguard v0.0.0-20230426030325-41db09ae771a // indirect + github.com/metacubex/gvisor v0.0.0-20230611153922-78842f086475 // indirect + github.com/metacubex/quic-go v0.37.4-0.20230806014204-ef9b221eec12 // indirect + github.com/metacubex/sing-shadowsocks v0.2.4 // indirect + github.com/metacubex/sing-shadowsocks2 v0.1.3 // indirect + github.com/metacubex/sing-tun v0.1.11 // indirect + github.com/metacubex/sing-vmess v0.1.8-0.20230801054944-603005461ff8 // indirect + github.com/metacubex/sing-wireguard v0.0.0-20230611155257-1498ae315a28 // indirect github.com/moby/term v0.5.0 // indirect github.com/morikuni/aec v1.0.0 // indirect - github.com/mroth/weightedrand/v2 v2.0.1 // indirect + github.com/mroth/weightedrand/v2 v2.0.2 // indirect github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 // indirect - github.com/onsi/ginkgo/v2 v2.2.0 // indirect + github.com/onsi/ginkgo/v2 v2.9.5 // indirect github.com/openacid/low v0.1.21 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect - github.com/oschwald/geoip2-golang v1.8.0 // indirect - github.com/oschwald/maxminddb-golang v1.10.0 // indirect + github.com/oschwald/maxminddb-golang v1.12.0 // indirect github.com/pierrec/lz4/v4 v4.1.14 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.2 // indirect - github.com/quic-go/qtls-go1-20 v0.2.2 // indirect + github.com/quic-go/qtls-go1-20 v0.3.1 // indirect github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect - github.com/sagernet/sing v0.2.5-0.20230530114415-221f066dba7c // indirect - github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646 // indirect - github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3 // indirect - github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 // indirect + github.com/sagernet/sing v0.2.9 // indirect + github.com/sagernet/sing-mux v0.1.2 // indirect + github.com/sagernet/sing-shadowtls v0.1.4 // indirect github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 // indirect github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 // indirect github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77 // indirect github.com/samber/lo v1.38.1 // indirect github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 // indirect - github.com/shirou/gopsutil/v3 v3.23.5 // indirect + github.com/shirou/gopsutil/v3 v3.23.7 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b // indirect github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c // indirect github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e // indirect - github.com/sirupsen/logrus v1.9.2 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect github.com/tklauser/numcpus v0.6.0 // indirect github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect - github.com/xtls/go v0.0.0-20230107031059-4610f88d00f3 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect github.com/zhangyunhao116/fastrand v0.3.0 // indirect gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect go.etcd.io/bbolt v1.3.7 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect - golang.org/x/tools v0.6.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b // indirect + golang.org/x/mod v0.11.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.9.1 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect ) diff --git a/test/go.sum b/test/go.sum index dc47342f..fbf635c6 100644 --- a/test/go.sum +++ b/test/go.sum @@ -15,10 +15,10 @@ github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.10.0 h1:nk5HPMeoBXtOzbkZBWym+ZWq1GIiHUsBFXxwewXAHLQ= -github.com/cilium/ebpf v0.10.0/go.mod h1:DPiVdY/kT534dgc9ERmvP8mWA+9gvwgKfRvk4nNWnoE= -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/cilium/ebpf v0.11.0 h1:V8gS/bTCCjX9uUnkUFUpPsksM8n1lXBAvHcpiFk1X2Y= +github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUgWsVs= +github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8= +github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= 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= @@ -41,13 +41,14 @@ github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1 h1:tlDMEdcPRQKBE github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1/go.mod h1:4RfsapbGx2j/vU5xC/5/9qB3kn9Awp1YDiEnN43QrJ4= github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010 h1:fuGucgPk5dN6wzfnxl3D0D3rVLw4v2SbBT9jb4VnxzA= github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010/go.mod h1:JtBcj7sBuTTRupn7c2bFspMDIObMJsVK8TeUvpShPok= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -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/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M= github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -56,9 +57,9 @@ github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +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.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= @@ -71,8 +72,8 @@ github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb h1:6fDKEAXwe3rsfS4khW3EZ8kEqmSiV9szhMPcDrD+Y7Q= -github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb/go.mod h1:7474bZ1YNCvarT6WFKie4kEET6J0KYRDC4XJqqXzQW4= +github.com/insomniacslk/dhcp v0.0.0-20230731140434-0f9eb93a696c h1:P/3mFnHCv1A/ej4m8pF5EB6FUt9qEL2Q9lfrcUNwCYs= +github.com/insomniacslk/dhcp v0.0.0-20230731140434-0f9eb93a696c/go.mod h1:7474bZ1YNCvarT6WFKie4kEET6J0KYRDC4XJqqXzQW4= github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= @@ -96,31 +97,33 @@ github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvOzK9ubNCCkQ+ldc4YSH/rILn53l/xGBFHHI= github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88= -github.com/metacubex/gvisor v0.0.0-20230417114019-3c3ee672d60c h1:D62872jiuzC6b+3aI8tqfeyc6YgbfarYKywTnnvXwEM= -github.com/metacubex/gvisor v0.0.0-20230417114019-3c3ee672d60c/go.mod h1:wqEuzdImyqD2MCGE8CYRJXbB77oSEJeoSSXXdwKjnsE= -github.com/metacubex/quic-go v0.35.2-0.20230603072621-ea2663348ebb h1:92YTNmYXCSycERjKn/zPbeK5DiW3dd80j3+oVTEWTE8= -github.com/metacubex/quic-go v0.35.2-0.20230603072621-ea2663348ebb/go.mod h1:6pg8+Tje9KOltnj1whuvB2i5KFUMPp1TAF3oPhc5axM= -github.com/metacubex/sing-shadowsocks v0.2.2-0.20230509230448-a5157cc00a1c h1:LpVNvlW/xE+mR8z76xJeYZlYznZXEmU4TeWeuygYdJg= -github.com/metacubex/sing-shadowsocks v0.2.2-0.20230509230448-a5157cc00a1c/go.mod h1:4uQQReKMTU7KTfOykVBe/oGJ00pl38d+BYJ99+mx26s= -github.com/metacubex/sing-shadowsocks2 v0.0.0-20230529235701-a238874242ca h1:10qc50Q1hHrfGO4NjEJpIAgHX63Y256tHE0dFCTN8J4= -github.com/metacubex/sing-shadowsocks2 v0.0.0-20230529235701-a238874242ca/go.mod h1:jVDD4N22bDPPKA73NvB7aqdlLWiAwv8D+jx7HwhcWak= -github.com/metacubex/sing-tun v0.1.5-0.20230530125750-171afb2dfd8e h1:7QlJQl4S3F3YXn48fYxjymMw8HkXg9bl++hLi4ZRyCY= -github.com/metacubex/sing-tun v0.1.5-0.20230530125750-171afb2dfd8e/go.mod h1:u9onX49LZPYuIPQ7SdM64Gnins8y5wg4Cn6ZYRSxWHU= -github.com/metacubex/sing-wireguard v0.0.0-20230426030325-41db09ae771a h1:cWKym33Qvl6HA3hj4/YuYD8hHyqQPb47wT5cJRAPgco= -github.com/metacubex/sing-wireguard v0.0.0-20230426030325-41db09ae771a/go.mod h1:Bsw2BvKMMMY0FhZPseDI50ZOalvoUPMKYyGpyqvIIqY= -github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= -github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/metacubex/gvisor v0.0.0-20230611153922-78842f086475 h1:qSEOvPPaMrWggFyFhFYGyMR8i1HKyhXjdi1QYUAa2ww= +github.com/metacubex/gvisor v0.0.0-20230611153922-78842f086475/go.mod h1:wehEpqiogdeyncfhckJP5gD2LtBgJW0wnDC24mJ+8Jg= +github.com/metacubex/quic-go v0.37.4-0.20230806014204-ef9b221eec12 h1:18tcXxLgwjUjs38QM1E1a+AAh4j+Mo/mKcJTmqHrN9c= +github.com/metacubex/quic-go v0.37.4-0.20230806014204-ef9b221eec12/go.mod h1:HhHoyskMk4kzfLPKcm7EF7pGXF89KRVwjbGrEaN6lIU= +github.com/metacubex/sing-shadowsocks v0.2.4 h1:Gc99Z17JVif1PKKq1pjqhSmc2kvHUgk+AqxOstCzhQ0= +github.com/metacubex/sing-shadowsocks v0.2.4/go.mod h1:w9qoEZSh9aKeXSLXHe0DGbG2UE9/2VlLGwukzQZ7byI= +github.com/metacubex/sing-shadowsocks2 v0.1.3 h1:nZvH+4jQXZ92NeNdR9fXaUGTPNJPt6u0nkcuh/NEt5Y= +github.com/metacubex/sing-shadowsocks2 v0.1.3/go.mod h1:5Mt93RlmRlIcDmvtapkhQJ8YTRGLFhHciLYopJjs7j8= +github.com/metacubex/sing-tun v0.1.11 h1:B8meDewklvKkeUfjqR2ViuYLam0/m4IgkTi3qcJIOuc= +github.com/metacubex/sing-tun v0.1.11/go.mod h1:vbki176Y5sxXC1DWXucrPh3q5j8cKai1D87y8m8rjQc= +github.com/metacubex/sing-vmess v0.1.8-0.20230801054944-603005461ff8 h1:AqqZCr9gOeKdO6oIzFh4b2puOUFcw8MdpmGHWRehyX8= +github.com/metacubex/sing-vmess v0.1.8-0.20230801054944-603005461ff8/go.mod h1:tyJg7b4s8NrSztl/Y1ajA7X0sJLlIsEJWkgRVocjmgY= +github.com/metacubex/sing-wireguard v0.0.0-20230611155257-1498ae315a28 h1:mXFpxfR/1nADh+GoT8maWEvc6LO6uatPsARD8WzUDMA= +github.com/metacubex/sing-wireguard v0.0.0-20230611155257-1498ae315a28/go.mod h1:KrDPq/dE793jGIJw9kcIvjA/proAfU0IeU7WlMXW7rs= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/mroth/weightedrand/v2 v2.0.1 h1:zrEVDIaau/E4QLOKu02kpg8T8myweFlMGikIgbIdrRA= -github.com/mroth/weightedrand/v2 v2.0.1/go.mod h1:f2faGsfOGOwc1p94wzHKKZyTpcJUW7OJ/9U4yfiNAOU= +github.com/mroth/weightedrand/v2 v2.0.2 h1:A8wJRUBcfguGl6oOQHI8fy5P4ViGRT9hdQdlG/7RiXo= +github.com/mroth/weightedrand/v2 v2.0.2/go.mod h1:f2faGsfOGOwc1p94wzHKKZyTpcJUW7OJ/9U4yfiNAOU= github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 h1:1102pQc2SEPp5+xrS26wEaeb26sZy6k9/ZXlZN+eXE4= github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7/go.mod h1:UqoUn6cHESlliMhOnKLWr+CBH+e3bazUPvFj1XZwAjs= -github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI= -github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= -github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= +github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= +github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/openacid/errors v0.8.1/go.mod h1:GUQEJJOJE3W9skHm8E8Y4phdl2LLEN8iD7c5gcGgdx0= github.com/openacid/low v0.1.21 h1:Tr2GNu4N/+rGRYdOsEHOE89cxUIaDViZbVmKz29uKGo= github.com/openacid/low v0.1.21/go.mod h1:q+MsKI6Pz2xsCkzV4BLj7NR5M4EX0sGz5AqotpZDVh0= @@ -130,10 +133,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -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/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs= +github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY= github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE= github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -144,10 +145,8 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= -github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= -github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= +github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA= github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms= @@ -155,14 +154,12 @@ github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6E github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk= -github.com/sagernet/sing v0.2.5-0.20230530114415-221f066dba7c h1:OAwuwvyjPPsCCdSxqZA7T+ABNezeNbF68sRbcMkKT7M= -github.com/sagernet/sing v0.2.5-0.20230530114415-221f066dba7c/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= -github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646 h1:X3ADfMqeGns1Q1FlXc9kaL9FwW1UM6D6tEQo8jFstpc= -github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646/go.mod h1:pF+RnLvCAOhECrvauy6LYOpBakJ/vuaF1Wm4lPsWryI= -github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3 h1:PNwJs1F+3e/iZguYQR7YzxsH8Sm0Eu7vVuHawD89r34= -github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3/go.mod h1:oG8bPerYI6cZ74KquY3DvA7ynECyrILPBnce6wtBqeI= -github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 h1:BHOnxrbC929JonuKqFdJ7ZbDp7zs4oTlH5KFvKtWu9U= -github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3/go.mod h1:yKrAr+dqZd64DxBXCHWrYicp+n4qbqO73mtwv3dck8U= +github.com/sagernet/sing v0.2.9 h1:3wsTz+JG5Wzy65eZnh6AuCrD2QqcRF6Iq6f7ttmJsAo= +github.com/sagernet/sing v0.2.9/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= +github.com/sagernet/sing-mux v0.1.2 h1:av2/m6e+Gh+ECTuJZqYCjJz55BNkot0VyRMkREqyF/g= +github.com/sagernet/sing-mux v0.1.2/go.mod h1:r2V8AlOzXaRCHXK7fILCUGzuI2iILweTaG8C5xlpHxo= +github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k= +github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0= github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 h1:2ItpW1nMNkPzmBTxV0/eClCklHrFSQMnUGcpUmJxVeE= @@ -175,8 +172,8 @@ github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 h1:rc/CcqLH3lh8n+csdOuDfP+NuykE0U6AeYSJJHKDgSg= github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9/go.mod h1:a/83NAfUXvEuLpmxDssAXxgUgrEy12MId3Wd7OTs76s= -github.com/shirou/gopsutil/v3 v3.23.5 h1:5SgDCeQ0KW0S4N0znjeM/eFHXXOKyv2dVNgRq/c9P6Y= -github.com/shirou/gopsutil/v3 v3.23.5/go.mod h1:Ng3Maa27Q2KARVJ0SPZF5NdrQSC3XHKP8IIWrHgMeLY= +github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4= +github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -187,19 +184,18 @@ github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c h1:DjKMC30y6y github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c/go.mod h1:NV/a66PhhWYVmUMaotlXJ8fIEFB98u+c8l/CQIEFLrU= github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e h1:ur8uMsPIFG3i4Gi093BQITvwH9znsz2VUZmnmwHvpIo= github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e/go.mod h1:+e5fBW3bpPyo+3uLo513gIUblc03egGjMM0+5GKbzK8= -github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= -github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 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.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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= @@ -211,8 +207,6 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/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-20230107031059-4610f88d00f3 h1:a3Y4WVjCxwoyO4E2xdNvq577tW8lkSBgyrA8E9+2NtM= -github.com/xtls/go v0.0.0-20230107031059-4610f88d00f3/go.mod h1:YJTRELIWrGxR1s8xcEBgxcxBfwQfMGjdvNLTjN9XFgY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -227,30 +221,30 @@ go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI= +golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -269,33 +263,33 @@ golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= 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= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/transport/hysteria/acl/engine.go b/transport/hysteria/acl/engine.go deleted file mode 100644 index adff5690..00000000 --- a/transport/hysteria/acl/engine.go +++ /dev/null @@ -1,100 +0,0 @@ -package acl - -import ( - "github.com/Dreamacro/clash/transport/hysteria/utils" - lru "github.com/hashicorp/golang-lru" - "github.com/oschwald/geoip2-golang" - "net" -) - -const entryCacheSize = 1024 - -type Engine struct { - DefaultAction Action - Entries []Entry - Cache *lru.ARCCache - ResolveIPAddr func(string) (*net.IPAddr, error) - GeoIPReader *geoip2.Reader -} - -type cacheKey struct { - Host string - Port uint16 - IsUDP bool -} - -type cacheValue struct { - Action Action - Arg string -} - -// action, arg, isDomain, resolvedIP, error -func (e *Engine) ResolveAndMatch(host string, port uint16, isUDP bool) (Action, string, bool, *net.IPAddr, error) { - ip, zone := utils.ParseIPZone(host) - if ip == nil { - // Domain - ipAddr, err := e.ResolveIPAddr(host) - if v, ok := e.Cache.Get(cacheKey{host, port, isUDP}); ok { - // Cache hit - ce := v.(cacheValue) - return ce.Action, ce.Arg, true, ipAddr, err - } - for _, entry := range e.Entries { - mReq := MatchRequest{ - Domain: host, - Port: port, - DB: e.GeoIPReader, - } - if ipAddr != nil { - mReq.IP = ipAddr.IP - } - if isUDP { - mReq.Protocol = ProtocolUDP - } else { - mReq.Protocol = ProtocolTCP - } - if entry.Match(mReq) { - e.Cache.Add(cacheKey{host, port, isUDP}, - cacheValue{entry.Action, entry.ActionArg}) - return entry.Action, entry.ActionArg, true, ipAddr, err - } - } - e.Cache.Add(cacheKey{host, port, isUDP}, cacheValue{e.DefaultAction, ""}) - return e.DefaultAction, "", true, ipAddr, err - } else { - // IP - if v, ok := e.Cache.Get(cacheKey{ip.String(), port, isUDP}); ok { - // Cache hit - ce := v.(cacheValue) - return ce.Action, ce.Arg, false, &net.IPAddr{ - IP: ip, - Zone: zone, - }, nil - } - for _, entry := range e.Entries { - mReq := MatchRequest{ - IP: ip, - Port: port, - DB: e.GeoIPReader, - } - if isUDP { - mReq.Protocol = ProtocolUDP - } else { - mReq.Protocol = ProtocolTCP - } - if entry.Match(mReq) { - e.Cache.Add(cacheKey{ip.String(), port, isUDP}, - cacheValue{entry.Action, entry.ActionArg}) - return entry.Action, entry.ActionArg, false, &net.IPAddr{ - IP: ip, - Zone: zone, - }, nil - } - } - e.Cache.Add(cacheKey{ip.String(), port, isUDP}, cacheValue{e.DefaultAction, ""}) - return e.DefaultAction, "", false, &net.IPAddr{ - IP: ip, - Zone: zone, - }, nil - } -} diff --git a/transport/hysteria/acl/engine_test.go b/transport/hysteria/acl/engine_test.go deleted file mode 100644 index 4c30884d..00000000 --- a/transport/hysteria/acl/engine_test.go +++ /dev/null @@ -1,154 +0,0 @@ -package acl - -import ( - "errors" - lru "github.com/hashicorp/golang-lru" - "net" - "strings" - "testing" -) - -func TestEngine_ResolveAndMatch(t *testing.T) { - cache, _ := lru.NewARC(16) - e := &Engine{ - DefaultAction: ActionDirect, - Entries: []Entry{ - { - Action: ActionProxy, - ActionArg: "", - Matcher: &domainMatcher{ - matcherBase: matcherBase{ - Protocol: ProtocolTCP, - Port: 443, - }, - Domain: "google.com", - Suffix: false, - }, - }, - { - Action: ActionHijack, - ActionArg: "good.org", - Matcher: &domainMatcher{ - matcherBase: matcherBase{}, - Domain: "evil.corp", - Suffix: true, - }, - }, - { - Action: ActionProxy, - ActionArg: "", - Matcher: &netMatcher{ - matcherBase: matcherBase{}, - Net: &net.IPNet{ - IP: net.ParseIP("10.0.0.0"), - Mask: net.CIDRMask(8, 32), - }, - }, - }, - { - Action: ActionBlock, - ActionArg: "", - Matcher: &allMatcher{}, - }, - }, - Cache: cache, - ResolveIPAddr: func(s string) (*net.IPAddr, error) { - if strings.Contains(s, "evil.corp") { - return nil, errors.New("resolve error") - } - return net.ResolveIPAddr("ip", s) - }, - } - tests := []struct { - name string - host string - port uint16 - isUDP bool - wantAction Action - wantArg string - wantErr bool - }{ - { - name: "domain proxy", - host: "google.com", - port: 443, - isUDP: false, - wantAction: ActionProxy, - wantArg: "", - }, - { - name: "domain block", - host: "google.com", - port: 80, - isUDP: false, - wantAction: ActionBlock, - wantArg: "", - }, - { - name: "domain suffix 1", - host: "evil.corp", - port: 8899, - isUDP: true, - wantAction: ActionHijack, - wantArg: "good.org", - wantErr: true, - }, - { - name: "domain suffix 2", - host: "notevil.corp", - port: 22, - isUDP: false, - wantAction: ActionBlock, - wantArg: "", - wantErr: true, - }, - { - name: "domain suffix 3", - host: "im.real.evil.corp", - port: 443, - isUDP: true, - wantAction: ActionHijack, - wantArg: "good.org", - wantErr: true, - }, - { - name: "ip match", - host: "10.2.3.4", - port: 80, - isUDP: false, - wantAction: ActionProxy, - wantArg: "", - }, - { - name: "ip mismatch", - host: "100.5.6.0", - port: 1234, - isUDP: false, - wantAction: ActionBlock, - wantArg: "", - }, - { - name: "domain proxy cache", - host: "google.com", - port: 443, - isUDP: false, - wantAction: ActionProxy, - wantArg: "", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotAction, gotArg, _, _, err := e.ResolveAndMatch(tt.host, tt.port, tt.isUDP) - if (err != nil) != tt.wantErr { - t.Errorf("ResolveAndMatch() error = %v, wantErr %v", err, tt.wantErr) - return - } - if gotAction != tt.wantAction { - t.Errorf("ResolveAndMatch() gotAction = %v, wantAction %v", gotAction, tt.wantAction) - } - if gotArg != tt.wantArg { - t.Errorf("ResolveAndMatch() gotArg = %v, wantAction %v", gotArg, tt.wantArg) - } - }) - } -} diff --git a/transport/hysteria/acl/entry.go b/transport/hysteria/acl/entry.go deleted file mode 100644 index bc345aa1..00000000 --- a/transport/hysteria/acl/entry.go +++ /dev/null @@ -1,331 +0,0 @@ -package acl - -import ( - "errors" - "fmt" - "github.com/oschwald/geoip2-golang" - "net" - "strconv" - "strings" -) - -type Action byte -type Protocol byte - -const ( - ActionDirect = Action(iota) - ActionProxy - ActionBlock - ActionHijack -) - -const ( - ProtocolAll = Protocol(iota) - ProtocolTCP - ProtocolUDP -) - -var protocolPortAliases = map[string]string{ - "echo": "*/7", - "ftp-data": "*/20", - "ftp": "*/21", - "ssh": "*/22", - "telnet": "*/23", - "domain": "*/53", - "dns": "*/53", - "http": "*/80", - "sftp": "*/115", - "ntp": "*/123", - "https": "*/443", - "quic": "udp/443", - "socks": "*/1080", -} - -type Entry struct { - Action Action - ActionArg string - Matcher Matcher -} - -type MatchRequest struct { - IP net.IP - Domain string - - Protocol Protocol - Port uint16 - - DB *geoip2.Reader -} - -type Matcher interface { - Match(MatchRequest) bool -} - -type matcherBase struct { - Protocol Protocol - Port uint16 // 0 for all ports -} - -func (m *matcherBase) MatchProtocolPort(p Protocol, port uint16) bool { - return (m.Protocol == ProtocolAll || m.Protocol == p) && (m.Port == 0 || m.Port == port) -} - -func parseProtocolPort(s string) (Protocol, uint16, error) { - if protocolPortAliases[s] != "" { - s = protocolPortAliases[s] - } - if len(s) == 0 || s == "*" { - return ProtocolAll, 0, nil - } - parts := strings.Split(s, "/") - if len(parts) != 2 { - return ProtocolAll, 0, errors.New("invalid protocol/port syntax") - } - protocol := ProtocolAll - switch parts[0] { - case "tcp": - protocol = ProtocolTCP - case "udp": - protocol = ProtocolUDP - case "*": - protocol = ProtocolAll - default: - return ProtocolAll, 0, errors.New("invalid protocol") - } - if parts[1] == "*" { - return protocol, 0, nil - } - port, err := strconv.ParseUint(parts[1], 10, 16) - if err != nil { - return ProtocolAll, 0, errors.New("invalid port") - } - return protocol, uint16(port), nil -} - -type netMatcher struct { - matcherBase - Net *net.IPNet -} - -func (m *netMatcher) Match(r MatchRequest) bool { - if r.IP == nil { - return false - } - return m.Net.Contains(r.IP) && m.MatchProtocolPort(r.Protocol, r.Port) -} - -type domainMatcher struct { - matcherBase - Domain string - Suffix bool -} - -func (m *domainMatcher) Match(r MatchRequest) bool { - if len(r.Domain) == 0 { - return false - } - domain := strings.ToLower(r.Domain) - return (m.Domain == domain || (m.Suffix && strings.HasSuffix(domain, "."+m.Domain))) && - m.MatchProtocolPort(r.Protocol, r.Port) -} - -type countryMatcher struct { - matcherBase - Country string // ISO 3166-1 alpha-2 country code, upper case -} - -func (m *countryMatcher) Match(r MatchRequest) bool { - if r.IP == nil || r.DB == nil { - return false - } - c, err := r.DB.Country(r.IP) - if err != nil { - return false - } - return c.Country.IsoCode == m.Country && m.MatchProtocolPort(r.Protocol, r.Port) -} - -type allMatcher struct { - matcherBase -} - -func (m *allMatcher) Match(r MatchRequest) bool { - return m.MatchProtocolPort(r.Protocol, r.Port) -} - -func (e Entry) Match(r MatchRequest) bool { - return e.Matcher.Match(r) -} - -func ParseEntry(s string) (Entry, error) { - fields := strings.Fields(s) - if len(fields) < 2 { - return Entry{}, fmt.Errorf("expected at least 2 fields, got %d", len(fields)) - } - e := Entry{} - action := fields[0] - conds := fields[1:] - switch strings.ToLower(action) { - case "direct": - e.Action = ActionDirect - case "proxy": - e.Action = ActionProxy - case "block": - e.Action = ActionBlock - case "hijack": - if len(conds) < 2 { - return Entry{}, fmt.Errorf("hijack requires at least 3 fields, got %d", len(fields)) - } - e.Action = ActionHijack - e.ActionArg = conds[len(conds)-1] - conds = conds[:len(conds)-1] - default: - return Entry{}, fmt.Errorf("invalid action %s", fields[0]) - } - m, err := condsToMatcher(conds) - if err != nil { - return Entry{}, err - } - e.Matcher = m - return e, nil -} - -func condsToMatcher(conds []string) (Matcher, error) { - if len(conds) < 1 { - return nil, errors.New("no condition specified") - } - typ, args := conds[0], conds[1:] - switch strings.ToLower(typ) { - case "domain": - // domain - if len(args) == 0 || len(args) > 2 { - return nil, fmt.Errorf("invalid number of arguments for domain: %d, expected 1 or 2", len(args)) - } - mb := matcherBase{} - if len(args) == 2 { - protocol, port, err := parseProtocolPort(args[1]) - if err != nil { - return nil, err - } - mb.Protocol = protocol - mb.Port = port - } - return &domainMatcher{ - matcherBase: mb, - Domain: args[0], - Suffix: false, - }, nil - case "domain-suffix": - // domain-suffix - if len(args) == 0 || len(args) > 2 { - return nil, fmt.Errorf("invalid number of arguments for domain-suffix: %d, expected 1 or 2", len(args)) - } - mb := matcherBase{} - if len(args) == 2 { - protocol, port, err := parseProtocolPort(args[1]) - if err != nil { - return nil, err - } - mb.Protocol = protocol - mb.Port = port - } - return &domainMatcher{ - matcherBase: mb, - Domain: args[0], - Suffix: true, - }, nil - case "cidr": - // cidr - if len(args) == 0 || len(args) > 2 { - return nil, fmt.Errorf("invalid number of arguments for cidr: %d, expected 1 or 2", len(args)) - } - mb := matcherBase{} - if len(args) == 2 { - protocol, port, err := parseProtocolPort(args[1]) - if err != nil { - return nil, err - } - mb.Protocol = protocol - mb.Port = port - } - _, ipNet, err := net.ParseCIDR(args[0]) - if err != nil { - return nil, err - } - return &netMatcher{ - matcherBase: mb, - Net: ipNet, - }, nil - case "ip": - // ip - if len(args) == 0 || len(args) > 2 { - return nil, fmt.Errorf("invalid number of arguments for ip: %d, expected 1 or 2", len(args)) - } - mb := matcherBase{} - if len(args) == 2 { - protocol, port, err := parseProtocolPort(args[1]) - if err != nil { - return nil, err - } - mb.Protocol = protocol - mb.Port = port - } - ip := net.ParseIP(args[0]) - if ip == nil { - return nil, fmt.Errorf("invalid ip: %s", args[0]) - } - var ipNet *net.IPNet - if ip.To4() != nil { - ipNet = &net.IPNet{ - IP: ip, - Mask: net.CIDRMask(32, 32), - } - } else { - ipNet = &net.IPNet{ - IP: ip, - Mask: net.CIDRMask(128, 128), - } - } - return &netMatcher{ - matcherBase: mb, - Net: ipNet, - }, nil - case "country": - // country - if len(args) == 0 || len(args) > 2 { - return nil, fmt.Errorf("invalid number of arguments for country: %d, expected 1 or 2", len(args)) - } - mb := matcherBase{} - if len(args) == 2 { - protocol, port, err := parseProtocolPort(args[1]) - if err != nil { - return nil, err - } - mb.Protocol = protocol - mb.Port = port - } - return &countryMatcher{ - matcherBase: mb, - Country: strings.ToUpper(args[0]), - }, nil - case "all": - // all - if len(args) > 1 { - return nil, fmt.Errorf("invalid number of arguments for all: %d, expected 0 or 1", len(args)) - } - mb := matcherBase{} - if len(args) == 1 { - protocol, port, err := parseProtocolPort(args[0]) - if err != nil { - return nil, err - } - mb.Protocol = protocol - mb.Port = port - } - return &allMatcher{ - matcherBase: mb, - }, nil - default: - return nil, fmt.Errorf("invalid condition type: %s", typ) - } -} diff --git a/transport/hysteria/acl/entry_test.go b/transport/hysteria/acl/entry_test.go deleted file mode 100644 index 37b88071..00000000 --- a/transport/hysteria/acl/entry_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package acl - -import ( - "net" - "reflect" - "testing" -) - -func TestParseEntry(t *testing.T) { - _, ok3net, _ := net.ParseCIDR("8.8.8.0/24") - - type args struct { - s string - } - tests := []struct { - name string - args args - want Entry - wantErr bool - }{ - {name: "empty", args: args{""}, want: Entry{}, wantErr: true}, - {name: "ok 1", args: args{"direct domain-suffix google.com"}, - want: Entry{ActionDirect, "", &domainMatcher{ - matcherBase: matcherBase{}, - Domain: "google.com", - Suffix: true, - }}, - wantErr: false}, - {name: "ok 2", args: args{"proxy domain shithole"}, - want: Entry{ActionProxy, "", &domainMatcher{ - matcherBase: matcherBase{}, - Domain: "shithole", - Suffix: false, - }}, - wantErr: false}, - {name: "ok 3", args: args{"block cidr 8.8.8.0/24 */53"}, - want: Entry{ActionBlock, "", &netMatcher{ - matcherBase: matcherBase{ProtocolAll, 53}, - Net: ok3net, - }}, - wantErr: false}, - {name: "ok 4", args: args{"hijack all udp/* udpblackhole.net"}, - want: Entry{ActionHijack, "udpblackhole.net", &allMatcher{ - matcherBase: matcherBase{ProtocolUDP, 0}, - }}, - wantErr: false}, - {name: "err 1", args: args{"what the heck"}, - want: Entry{}, - wantErr: true}, - {name: "err 2", args: args{"proxy sucks ass"}, - want: Entry{}, - wantErr: true}, - {name: "err 3", args: args{"block ip 999.999.999.999"}, - want: Entry{}, - wantErr: true}, - {name: "err 4", args: args{"hijack domain google.com"}, - want: Entry{}, - wantErr: true}, - {name: "err 5", args: args{"hijack domain google.com bing.com 123"}, - want: Entry{}, - wantErr: true}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ParseEntry(tt.args.s) - if (err != nil) != tt.wantErr { - t.Errorf("ParseEntry() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ParseEntry() got = %v, wantAction %v", got, tt.want) - } - }) - } -} diff --git a/transport/hysteria/core/client.go b/transport/hysteria/core/client.go index e0f3a0dd..a219e76c 100644 --- a/transport/hysteria/core/client.go +++ b/transport/hysteria/core/client.go @@ -135,7 +135,7 @@ func (c *Client) handleControlStream(qs quic.Connection, stream quic.Stream) (bo func (c *Client) handleMessage(qs quic.Connection) { for { - msg, err := qs.ReceiveMessage() + msg, err := qs.ReceiveMessage(context.Background()) if err != nil { break } diff --git a/transport/trojan/trojan.go b/transport/trojan/trojan.go index abe21f34..710905ad 100644 --- a/transport/trojan/trojan.go +++ b/transport/trojan/trojan.go @@ -7,7 +7,6 @@ import ( "encoding/binary" "encoding/hex" "errors" - "fmt" "io" "net" "net/http" @@ -18,10 +17,7 @@ import ( tlsC "github.com/Dreamacro/clash/component/tls" C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/transport/socks5" - "github.com/Dreamacro/clash/transport/vless" "github.com/Dreamacro/clash/transport/vmess" - - xtls "github.com/xtls/go" ) const ( @@ -42,7 +38,7 @@ const ( CommandTCP byte = 1 CommandUDP byte = 3 - // for XTLS + // deprecated XTLS commands, as souvenirs commandXRD byte = 0xf0 // XTLS direct mode commandXRO byte = 0xf1 // XTLS origin mode ) @@ -53,8 +49,6 @@ type Option struct { ServerName string SkipCertVerify bool Fingerprint string - Flow string - FlowShow bool ClientFingerprint string Reality *tlsC.RealityConfig } @@ -76,78 +70,50 @@ func (t *Trojan) StreamConn(ctx context.Context, conn net.Conn) (net.Conn, error if len(t.option.ALPN) != 0 { alpn = t.option.ALPN } - switch t.option.Flow { - case vless.XRO, vless.XRD, vless.XRS: - xtlsConfig := &xtls.Config{ - NextProtos: alpn, - MinVersion: xtls.VersionTLS12, - InsecureSkipVerify: t.option.SkipCertVerify, - ServerName: t.option.ServerName, - } + tlsConfig := &tls.Config{ + NextProtos: alpn, + MinVersion: tls.VersionTLS12, + InsecureSkipVerify: t.option.SkipCertVerify, + ServerName: t.option.ServerName, + } - if len(t.option.Fingerprint) == 0 { - xtlsConfig = tlsC.GetGlobalXTLSConfig(xtlsConfig) - } else { - var err error - if xtlsConfig, err = tlsC.GetSpecifiedFingerprintXTLSConfig(xtlsConfig, t.option.Fingerprint); err != nil { - return nil, err - } - } - - xtlsConn := xtls.Client(conn, xtlsConfig) - - ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) - defer cancel() - if err := xtlsConn.HandshakeContext(ctx); err != nil { + if len(t.option.Fingerprint) == 0 { + tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig) + } else { + var err error + if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, t.option.Fingerprint); err != nil { return nil, err } - return xtlsConn, nil - default: - tlsConfig := &tls.Config{ - NextProtos: alpn, - MinVersion: tls.VersionTLS12, - InsecureSkipVerify: t.option.SkipCertVerify, - ServerName: t.option.ServerName, - } + } - if len(t.option.Fingerprint) == 0 { - tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig) - } else { - var err error - if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, t.option.Fingerprint); err != nil { - return nil, err - } - } - - if len(t.option.ClientFingerprint) != 0 { - if t.option.Reality == nil { - utlsConn, valid := vmess.GetUTLSConn(conn, t.option.ClientFingerprint, tlsConfig) - if valid { - ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) - defer cancel() - - err := utlsConn.(*tlsC.UConn).HandshakeContext(ctx) - return utlsConn, err - } - } else { + if len(t.option.ClientFingerprint) != 0 { + if t.option.Reality == nil { + utlsConn, valid := vmess.GetUTLSConn(conn, t.option.ClientFingerprint, tlsConfig) + if valid { ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) defer cancel() - return tlsC.GetRealityConn(ctx, conn, t.option.ClientFingerprint, tlsConfig, t.option.Reality) + + err := utlsConn.(*tlsC.UConn).HandshakeContext(ctx) + return utlsConn, err } + } else { + ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) + defer cancel() + return tlsC.GetRealityConn(ctx, conn, t.option.ClientFingerprint, tlsConfig, t.option.Reality) } - if t.option.Reality != nil { - return nil, errors.New("REALITY is based on uTLS, please set a client-fingerprint") - } - - tlsConn := tls.Client(conn, tlsConfig) - - // fix tls handshake not timeout - ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) - defer cancel() - - err := tlsConn.HandshakeContext(ctx) - return tlsConn, err } + if t.option.Reality != nil { + return nil, errors.New("REALITY is based on uTLS, please set a client-fingerprint") + } + + tlsConn := tls.Client(conn, tlsConfig) + + // fix tls handshake not timeout + ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) + defer cancel() + + err := tlsConn.HandshakeContext(ctx) + return tlsConn, err } func (t *Trojan) StreamWebsocketConn(ctx context.Context, conn net.Conn, wsOptions *WebsocketOption) (net.Conn, error) { @@ -174,37 +140,7 @@ func (t *Trojan) StreamWebsocketConn(ctx context.Context, conn net.Conn, wsOptio }) } -func (t *Trojan) PresetXTLSConn(conn net.Conn) (net.Conn, error) { - switch t.option.Flow { - case vless.XRO, vless.XRD, vless.XRS: - if xtlsConn, ok := conn.(*xtls.Conn); ok { - xtlsConn.RPRX = true - xtlsConn.SHOW = t.option.FlowShow - xtlsConn.MARK = "XTLS" - if t.option.Flow == vless.XRS { - t.option.Flow = vless.XRD - } - - if t.option.Flow == vless.XRD { - xtlsConn.DirectMode = true - } - } else { - return conn, fmt.Errorf("failed to use %s, maybe \"security\" is not \"xtls\"", t.option.Flow) - } - } - - return conn, nil -} - func (t *Trojan) WriteHeader(w io.Writer, command Command, socks5Addr []byte) error { - if command == CommandTCP { - if t.option.Flow == vless.XRD { - command = commandXRD - } else if t.option.Flow == vless.XRO { - command = commandXRO - } - } - buf := pool.GetBuffer() defer pool.PutBuffer(buf) @@ -398,8 +334,7 @@ func (pc *PacketConn) WaitReadFrom() (data []byte, put func(), addr net.Addr, er func hexSha224(data []byte) []byte { buf := make([]byte, 56) - hash := sha256.New224() - hash.Write(data) - hex.Encode(buf, hash.Sum(nil)) + hash := sha256.Sum224(data) + hex.Encode(buf, hash[:]) return buf } diff --git a/transport/tuic/server.go b/transport/tuic/server.go index 47850107..a6f91b88 100644 --- a/transport/tuic/server.go +++ b/transport/tuic/server.go @@ -114,7 +114,7 @@ func (s *serverHandler) handle() { func (s *serverHandler) handleMessage() (err error) { for { var message []byte - message, err = s.quicConn.ReceiveMessage() + message, err = s.quicConn.ReceiveMessage(context.Background()) if err != nil { return err } diff --git a/transport/tuic/v4/client.go b/transport/tuic/v4/client.go index e1a334e5..fd3bf54a 100644 --- a/transport/tuic/v4/client.go +++ b/transport/tuic/v4/client.go @@ -196,7 +196,7 @@ func (t *clientImpl) handleMessage(quicConn quic.Connection) (err error) { }() for { var message []byte - message, err = quicConn.ReceiveMessage() + message, err = quicConn.ReceiveMessage(context.Background()) if err != nil { return err } diff --git a/transport/tuic/v4/protocol.go b/transport/tuic/v4/protocol.go index 11ac3b4e..bbdca67c 100644 --- a/transport/tuic/v4/protocol.go +++ b/transport/tuic/v4/protocol.go @@ -457,12 +457,10 @@ func NewAddress(metadata *C.Metadata) Address { copy(addr[1:], metadata.Host) } - port, _ := strconv.ParseUint(metadata.DstPort, 10, 16) - return Address{ TYPE: addrType, ADDR: addr, - PORT: uint16(port), + PORT: metadata.DstPort, } } diff --git a/transport/tuic/v4/server.go b/transport/tuic/v4/server.go index 9513ccfd..b0012d96 100644 --- a/transport/tuic/v4/server.go +++ b/transport/tuic/v4/server.go @@ -66,10 +66,10 @@ func (s *serverHandler) HandleMessage(message []byte) (err error) { if err != nil { return } - return s.parsePacket(packet, common.NATIVE) + return s.parsePacket(&packet, common.NATIVE) } -func (s *serverHandler) parsePacket(packet Packet, udpRelayMode common.UdpRelayMode) (err error) { +func (s *serverHandler) parsePacket(packet *Packet, udpRelayMode common.UdpRelayMode) (err error) { <-s.authCh if !s.authOk.Load() { return @@ -97,7 +97,7 @@ func (s *serverHandler) parsePacket(packet Packet, udpRelayMode common.UdpRelayM return s.HandleUdpFn(packet.ADDR.SocksAddr(), &serverUDPPacket{ pc: pc, - packet: &packet, + packet: packet, rAddr: N.NewCustomAddr("tuic", fmt.Sprintf("tuic-%s-%d", s.uuid, assocId), s.quicConn.RemoteAddr()), // for tunnel's handleUDPConn }) } @@ -166,7 +166,7 @@ func (s *serverHandler) HandleUniStream(reader *bufio.Reader) (err error) { if err != nil { return } - return s.parsePacket(packet, common.QUIC) + return s.parsePacket(&packet, common.QUIC) case DissociateType: var disassociate Dissociate disassociate, err = ReadDissociateWithHead(commandHead, reader) diff --git a/transport/tuic/v5/client.go b/transport/tuic/v5/client.go index cb1d538c..74dfd581 100644 --- a/transport/tuic/v5/client.go +++ b/transport/tuic/v5/client.go @@ -195,7 +195,7 @@ func (t *clientImpl) handleMessage(quicConn quic.Connection) (err error) { }() for { var message []byte - message, err = quicConn.ReceiveMessage() + message, err = quicConn.ReceiveMessage(context.Background()) if err != nil { return err } diff --git a/transport/tuic/v5/frag.go b/transport/tuic/v5/frag.go index 30b7b3f5..ae9dbf10 100644 --- a/transport/tuic/v5/frag.go +++ b/transport/tuic/v5/frag.go @@ -2,6 +2,9 @@ package v5 import ( "bytes" + "sync" + + "github.com/Dreamacro/clash/common/cache" "github.com/metacubex/quic-go" ) @@ -39,42 +42,68 @@ func fragWriteNative(quicConn quic.Connection, packet Packet, buf *bytes.Buffer, } type deFragger struct { - pkgID uint16 - frags []*Packet - count uint8 + lru *cache.LruCache[uint16, *packetBag] + once sync.Once } -func (d *deFragger) Feed(m Packet) *Packet { +type packetBag struct { + frags []*Packet + count uint8 + mutex sync.Mutex +} + +func newPacketBag() *packetBag { + return new(packetBag) +} + +func (d *deFragger) init() { + if d.lru == nil { + d.lru = cache.New( + cache.WithAge[uint16, *packetBag](10), + cache.WithUpdateAgeOnGet[uint16, *packetBag](), + ) + } +} + +func (d *deFragger) Feed(m *Packet) *Packet { if m.FRAG_TOTAL <= 1 { - return &m + return m } if m.FRAG_ID >= m.FRAG_TOTAL { // wtf is this? return nil } - if d.count == 0 || m.PKT_ID != d.pkgID { + d.once.Do(d.init) // lazy init + bag, _ := d.lru.GetOrStore(m.PKT_ID, newPacketBag) + bag.mutex.Lock() + defer bag.mutex.Unlock() + if int(m.FRAG_TOTAL) != len(bag.frags) { // new message, clear previous state - d.pkgID = m.PKT_ID - d.frags = make([]*Packet, m.FRAG_TOTAL) - d.count = 1 - d.frags[m.FRAG_ID] = &m - } else if d.frags[m.FRAG_ID] == nil { - d.frags[m.FRAG_ID] = &m - d.count++ - if int(d.count) == len(d.frags) { - // all fragments received, assemble - var data []byte - for _, frag := range d.frags { - data = append(data, frag.DATA...) - } - p := d.frags[0] // recover from first fragment - p.SIZE = uint16(len(data)) - p.DATA = data - p.FRAG_ID = 0 - p.FRAG_TOTAL = 1 - d.count = 0 - return p - } + bag.frags = make([]*Packet, m.FRAG_TOTAL) + bag.count = 1 + bag.frags[m.FRAG_ID] = m + return nil } - return nil + if bag.frags[m.FRAG_ID] != nil { + return nil + } + bag.frags[m.FRAG_ID] = m + bag.count++ + if int(bag.count) != len(bag.frags) { + return nil + } + + // all fragments received, assemble + var data []byte + for _, frag := range bag.frags { + data = append(data, frag.DATA...) + } + p := *bag.frags[0] // recover from first fragment + p.SIZE = uint16(len(data)) + p.DATA = data + p.FRAG_ID = 0 + p.FRAG_TOTAL = 1 + bag.frags = nil + d.lru.Delete(m.PKT_ID) + return &p } diff --git a/transport/tuic/v5/packet.go b/transport/tuic/v5/packet.go index 4a11d671..cd3ed12b 100644 --- a/transport/tuic/v5/packet.go +++ b/transport/tuic/v5/packet.go @@ -103,7 +103,7 @@ func (q *quicStreamPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err err if err != nil { return } - if packetPtr := q.deFragger.Feed(packet); packetPtr != nil { + if packetPtr := q.deFragger.Feed(&packet); packetPtr != nil { n = copy(p, packet.DATA) addr = packetPtr.ADDR.UDPAddr() return @@ -123,7 +123,7 @@ func (q *quicStreamPacketConn) WaitReadFrom() (data []byte, put func(), addr net if err != nil { return } - if packetPtr := q.deFragger.Feed(packet); packetPtr != nil { + if packetPtr := q.deFragger.Feed(&packet); packetPtr != nil { data = packetPtr.DATA addr = packetPtr.ADDR.UDPAddr() return @@ -178,16 +178,14 @@ func (q *quicStreamPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err erro default: // native if len(p) > q.maxUdpRelayPacketSize { err = fragWriteNative(q.quicConn, packet, buf, q.maxUdpRelayPacketSize) + } else { + err = packet.WriteTo(buf) if err != nil { return } + data := buf.Bytes() + err = q.quicConn.SendMessage(data) } - err = packet.WriteTo(buf) - if err != nil { - return - } - data := buf.Bytes() - err = q.quicConn.SendMessage(data) var tooLarge quic.ErrMessageTooLarge if errors.As(err, &tooLarge) { diff --git a/transport/tuic/v5/protocol.go b/transport/tuic/v5/protocol.go index 83b44146..964401e1 100644 --- a/transport/tuic/v5/protocol.go +++ b/transport/tuic/v5/protocol.go @@ -436,12 +436,10 @@ func NewAddress(metadata *C.Metadata) Address { copy(addr[1:], metadata.Host) } - port, _ := strconv.ParseUint(metadata.DstPort, 10, 16) - return Address{ TYPE: addrType, ADDR: addr, - PORT: uint16(port), + PORT: metadata.DstPort, } } diff --git a/transport/tuic/v5/server.go b/transport/tuic/v5/server.go index 96b3d24f..30259583 100644 --- a/transport/tuic/v5/server.go +++ b/transport/tuic/v5/server.go @@ -73,7 +73,7 @@ func (s *serverHandler) HandleMessage(message []byte) (err error) { if err != nil { return } - return s.parsePacket(packet, common.NATIVE) + return s.parsePacket(&packet, common.NATIVE) case HeartbeatType: var heartbeat Heartbeat heartbeat, err = ReadHeartbeatWithHead(commandHead, reader) @@ -85,7 +85,7 @@ func (s *serverHandler) HandleMessage(message []byte) (err error) { return } -func (s *serverHandler) parsePacket(packet Packet, udpRelayMode common.UdpRelayMode) (err error) { +func (s *serverHandler) parsePacket(packet *Packet, udpRelayMode common.UdpRelayMode) (err error) { <-s.authCh if !s.authOk.Load() { return @@ -179,7 +179,7 @@ func (s *serverHandler) HandleUniStream(reader *bufio.Reader) (err error) { if err != nil { return } - return s.parsePacket(packet, common.QUIC) + return s.parsePacket(&packet, common.QUIC) case DissociateType: var disassociate Dissociate disassociate, err = ReadDissociateWithHead(commandHead, reader) diff --git a/transport/vless/conn.go b/transport/vless/conn.go index fb514367..33ecd97a 100644 --- a/transport/vless/conn.go +++ b/transport/vless/conn.go @@ -3,7 +3,6 @@ package vless import ( "encoding/binary" "errors" - "fmt" "io" "net" "sync" @@ -13,7 +12,6 @@ import ( "github.com/Dreamacro/clash/transport/vless/vision" "github.com/gofrs/uuid/v5" - xtls "github.com/xtls/go" "google.golang.org/protobuf/proto" ) @@ -109,9 +107,7 @@ func (vc *Conn) sendRequest(p []byte) bool { var buffer *buf.Buffer if vc.IsXTLSVisionEnabled() { - _buffer := buf.StackNew() - defer buf.KeepAlive(_buffer) - buffer = buf.Dup(_buffer) + buffer = buf.New() defer buffer.Release() } else { requestLen := 1 // protocol version @@ -126,9 +122,7 @@ func (vc *Conn) sendRequest(p []byte) bool { } requestLen += len(p) - _buffer := buf.StackNewSize(requestLen) - defer buf.KeepAlive(_buffer) - buffer = buf.Dup(_buffer) + buffer = buf.NewSize(requestLen) defer buffer.Release() } @@ -205,25 +199,6 @@ func newConn(conn net.Conn, client *Client, dst *DstAddr) (net.Conn, error) { if client.Addons != nil { switch client.Addons.Flow { - case XRO, XRD, XRS: - if !dst.UDP { - if xtlsConn, ok := conn.(*xtls.Conn); ok { - xtlsConn.RPRX = true - xtlsConn.SHOW = client.XTLSShow - xtlsConn.MARK = "XTLS" - if client.Addons.Flow == XRS { - client.Addons.Flow = XRD - } - - if client.Addons.Flow == XRD { - xtlsConn.DirectMode = true - } - c.addons = client.Addons - } else { - return nil, fmt.Errorf("failed to use %s, maybe \"security\" is not \"xtls\"", client.Addons.Flow) - } - } - case XRV: visionConn, err := vision.NewConn(c, c.id) if err != nil { diff --git a/transport/vless/vision/conn.go b/transport/vless/vision/conn.go index 23721c0b..03f524aa 100644 --- a/transport/vless/vision/conn.go +++ b/transport/vless/vision/conn.go @@ -157,9 +157,7 @@ func (vc *Conn) ReadBuffer(buffer *buf.Buffer) error { func (vc *Conn) Write(p []byte) (int, error) { if vc.writeFilterApplicationData { - _buffer := buf.StackNew() - defer buf.KeepAlive(_buffer) - buffer := buf.Dup(_buffer) + buffer := buf.New() defer buffer.Release() buffer.Write(p) err := vc.WriteBuffer(buffer) diff --git a/transport/vless/vless.go b/transport/vless/vless.go index c2066afe..6c01b839 100644 --- a/transport/vless/vless.go +++ b/transport/vless/vless.go @@ -42,9 +42,8 @@ type DstAddr struct { // Client is vless connection generator type Client struct { - uuid *uuid.UUID - Addons *Addons - XTLSShow bool + uuid *uuid.UUID + Addons *Addons } // StreamConn return a Conn with net.Conn and DstAddr @@ -53,15 +52,14 @@ func (c *Client) StreamConn(conn net.Conn, dst *DstAddr) (net.Conn, error) { } // NewClient return Client instance -func NewClient(uuidStr string, addons *Addons, xtlsShow bool) (*Client, error) { +func NewClient(uuidStr string, addons *Addons) (*Client, error) { uid, err := utils.UUIDMap(uuidStr) if err != nil { return nil, err } return &Client{ - uuid: &uid, - Addons: addons, - XTLSShow: xtlsShow, + uuid: &uid, + Addons: addons, }, nil } diff --git a/transport/vless/xtls.go b/transport/vless/xtls.go deleted file mode 100644 index 071e6e8f..00000000 --- a/transport/vless/xtls.go +++ /dev/null @@ -1,37 +0,0 @@ -package vless - -import ( - "context" - "net" - - tlsC "github.com/Dreamacro/clash/component/tls" - xtls "github.com/xtls/go" -) - -type XTLSConfig struct { - Host string - SkipCertVerify bool - Fingerprint string - NextProtos []string -} - -func StreamXTLSConn(ctx context.Context, conn net.Conn, cfg *XTLSConfig) (net.Conn, error) { - xtlsConfig := &xtls.Config{ - ServerName: cfg.Host, - InsecureSkipVerify: cfg.SkipCertVerify, - NextProtos: cfg.NextProtos, - } - if len(cfg.Fingerprint) == 0 { - xtlsConfig = tlsC.GetGlobalXTLSConfig(xtlsConfig) - } else { - var err error - if xtlsConfig, err = tlsC.GetSpecifiedFingerprintXTLSConfig(xtlsConfig, cfg.Fingerprint); err != nil { - return nil, err - } - } - - xtlsConn := xtls.Client(conn, xtlsConfig) - - err := xtlsConn.HandshakeContext(ctx) - return xtlsConn, err -} diff --git a/tunnel/connection.go b/tunnel/connection.go index 38dbfa65..2e76b86b 100644 --- a/tunnel/connection.go +++ b/tunnel/connection.go @@ -41,7 +41,13 @@ func handleUDPToLocal(writeBack C.WriteBack, pc N.EnhancePacketConn, key string, } fromUDPAddr, isUDPAddr := from.(*net.UDPAddr) - if isUDPAddr { + if !isUDPAddr { + fromUDPAddr = net.UDPAddrFromAddrPort(oAddrPort) // oAddrPort was Unmapped + log.Warnln("server return a [%T](%s) which isn't a *net.UDPAddr, force replace to (%s), this may be caused by a wrongly implemented server", from, from, oAddrPort) + } else if fromUDPAddr == nil { + fromUDPAddr = net.UDPAddrFromAddrPort(oAddrPort) // oAddrPort was Unmapped + log.Warnln("server return a nil *net.UDPAddr, force replace to (%s), this may be caused by a wrongly implemented server", oAddrPort) + } else { _fromUDPAddr := *fromUDPAddr fromUDPAddr = &_fromUDPAddr // make a copy if fromAddr, ok := netip.AddrFromSlice(fromUDPAddr.IP); ok { @@ -54,9 +60,6 @@ func handleUDPToLocal(writeBack C.WriteBack, pc N.EnhancePacketConn, key string, fromUDPAddr.Zone = "" // only ipv6 can have the zone } } - } else { - fromUDPAddr = net.UDPAddrFromAddrPort(oAddrPort) // oAddrPort was Unmapped - log.Warnln("server return a [%T](%s) which isn't a *net.UDPAddr, force replace to (%s), this may be caused by a wrongly implemented server", from, from, oAddrPort) } _, err = writeBack.WriteBack(data, fromUDPAddr) diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index e375f656..d4c15a87 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -7,7 +7,6 @@ import ( "net/netip" "path/filepath" "runtime" - "strconv" "sync" "time" @@ -566,8 +565,7 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) { if attemptProcessLookup && !findProcessMode.Off() && (findProcessMode.Always() || rule.ShouldFindProcess()) { attemptProcessLookup = false - srcPort, _ := strconv.ParseUint(metadata.SrcPort, 10, 16) - uid, path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(srcPort)) + uid, path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(metadata.SrcPort)) if err != nil { log.Debugln("[Process] find process %s: %v", metadata.String(), err) } else {