From ae6cc1d67d3a12f514eff7f08b5a9f78370f970f Mon Sep 17 00:00:00 2001 From: yaling888 <73897884+yaling888@users.noreply.github.com> Date: Fri, 1 Jul 2022 18:34:36 +0800 Subject: [PATCH] Chore: cleanup code --- adapter/outboundgroup/loadbalance.go | 6 +- adapter/outboundgroup/urltest.go | 6 +- adapter/parser.go | 4 +- adapter/provider/fetcher.go | 15 +++++ adapter/provider/provider.go | 5 +- adapter/provider/vehicle.go | 2 +- common/cert/storage.go | 7 +++ component/dialer/mark_linux.go | 14 ++--- component/process/process.go | 53 ----------------- component/process/process_darwin.go | 6 +- component/process/process_freebsd_amd64.go | 5 +- component/process/process_windows.go | 3 +- config/config.go | 17 +++--- hub/executor/executor.go | 6 +- listener/listener.go | 27 +++------ listener/tproxy/udp.go | 5 ++ listener/tun/device/fdbased/fd_unix.go | 4 ++ listener/tun/device/fdbased/fd_windows.go | 42 +++++++++++++- listener/tun/device/tun/tun_wireguard.go | 11 +++- listener/tun/ipstack/system/mars/nat/nat.go | 33 ++++++++--- listener/tun/ipstack/system/mars/nat/table.go | 58 +++---------------- listener/tun/ipstack/system/mars/nat/tcp.go | 6 -- listener/tun/ipstack/system/mars/nat/udp.go | 2 +- listener/tun/tun_adapter.go | 9 +-- tunnel/tunnel.go | 2 +- 25 files changed, 159 insertions(+), 189 deletions(-) diff --git a/adapter/outboundgroup/loadbalance.go b/adapter/outboundgroup/loadbalance.go index 7c9f20d7..934d6551 100644 --- a/adapter/outboundgroup/loadbalance.go +++ b/adapter/outboundgroup/loadbalance.go @@ -30,10 +30,8 @@ type LoadBalance struct { var errStrategy = errors.New("unsupported strategy") func parseStrategy(config map[string]any) string { - if elm, ok := config["strategy"]; ok { - if strategy, ok := elm.(string); ok { - return strategy - } + if strategy, ok := config["strategy"].(string); ok { + return strategy } return "consistent-hashing" } diff --git a/adapter/outboundgroup/urltest.go b/adapter/outboundgroup/urltest.go index bd507e51..77aced19 100644 --- a/adapter/outboundgroup/urltest.go +++ b/adapter/outboundgroup/urltest.go @@ -125,10 +125,8 @@ func parseURLTestOption(config map[string]any) []urlTestOption { opts := []urlTestOption{} // tolerance - if elm, ok := config["tolerance"]; ok { - if tolerance, ok := elm.(int); ok { - opts = append(opts, urlTestWithTolerance(uint16(tolerance))) - } + if tolerance, ok := config["tolerance"].(int); ok { + opts = append(opts, urlTestWithTolerance(uint16(tolerance))) } return opts diff --git a/adapter/parser.go b/adapter/parser.go index 3fe87713..1c4bfa39 100644 --- a/adapter/parser.go +++ b/adapter/parser.go @@ -10,7 +10,7 @@ import ( func ParseProxy(mapping map[string]any, forceCertVerify bool) (C.Proxy, error) { decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true}) - proxyType, existType := mapping["type"] + proxyType, existType := mapping["type"].(string) if !existType { return nil, fmt.Errorf("missing type") } @@ -19,7 +19,7 @@ func ParseProxy(mapping map[string]any, forceCertVerify bool) (C.Proxy, error) { proxy C.ProxyAdapter err error ) - switch proxyType.(string) { + switch proxyType { case "ss": ssOption := &outbound.ShadowSocksOption{} err = decoder.Decode(mapping, ssOption) diff --git a/adapter/provider/fetcher.go b/adapter/provider/fetcher.go index 0426ecc2..24cc73b1 100644 --- a/adapter/provider/fetcher.go +++ b/adapter/provider/fetcher.go @@ -5,6 +5,7 @@ import ( "crypto/md5" "os" "path/filepath" + "regexp" "time" types "github.com/Dreamacro/clash/constant/provider" @@ -14,6 +15,8 @@ import ( var ( fileMode os.FileMode = 0o666 dirMode os.FileMode = 0o755 + + commentRegx = regexp.MustCompile(`(.*#.*\n)`) ) type parser[V any] func([]byte) (V, error) @@ -168,6 +171,18 @@ func safeWrite(path string, buf []byte) error { return os.WriteFile(path, buf, fileMode) } +func removeComment(buf []byte) []byte { + arr := commentRegx.FindAllSubmatch(buf, -1) + for _, subs := range arr { + sub := subs[0] + if !bytes.HasPrefix(bytes.TrimLeft(sub, " "), []byte("#")) { + continue + } + buf = bytes.Replace(buf, sub, []byte(""), 1) + } + return buf +} + func newFetcher[V any](name string, interval time.Duration, vehicle types.Vehicle, parser parser[V], onUpdate func(V)) *fetcher[V] { var ticker *time.Ticker if interval != 0 { diff --git a/adapter/provider/provider.go b/adapter/provider/provider.go index 42cc4295..ebb409cc 100644 --- a/adapter/provider/provider.go +++ b/adapter/provider/provider.go @@ -321,12 +321,13 @@ func proxiesParseAndFilter(filter string, filterReg *regexp.Regexp, forceCertVer proxies := []C.Proxy{} for idx, mapping := range schema.Proxies { - if name, ok := mapping["name"]; ok && len(filter) > 0 && !filterReg.MatchString(name.(string)) { + name, ok := mapping["name"].(string) + if ok && len(filter) > 0 && !filterReg.MatchString(name) { continue } if prefixName != "" { - mapping["name"] = prefixName + mapping["name"].(string) + mapping["name"] = prefixName + name } proxy, err := adapter.ParseProxy(mapping, forceCertVerify) diff --git a/adapter/provider/vehicle.go b/adapter/provider/vehicle.go index f48d60b5..52ff39d8 100644 --- a/adapter/provider/vehicle.go +++ b/adapter/provider/vehicle.go @@ -103,7 +103,7 @@ func (h *HTTPVehicle) Read() ([]byte, error) { return nil, err } - return buf, nil + return removeComment(buf), nil } func NewHTTPVehicle(url string, path string, header http.Header) *HTTPVehicle { diff --git a/common/cert/storage.go b/common/cert/storage.go index a55d065c..8dfa368d 100644 --- a/common/cert/storage.go +++ b/common/cert/storage.go @@ -2,6 +2,7 @@ package cert import ( "crypto/tls" + "sync" "github.com/Dreamacro/clash/component/trie" ) @@ -9,10 +10,14 @@ import ( // DomainTrieCertsStorage cache wildcard certificates type DomainTrieCertsStorage struct { certsCache *trie.DomainTrie[*tls.Certificate] + lock sync.RWMutex } // Get gets the certificate from the storage func (c *DomainTrieCertsStorage) Get(key string) (*tls.Certificate, bool) { + c.lock.RLock() + defer c.lock.RUnlock() + ca := c.certsCache.Search(key) if ca == nil { return nil, false @@ -22,7 +27,9 @@ func (c *DomainTrieCertsStorage) Get(key string) (*tls.Certificate, bool) { // Set saves the certificate to the storage func (c *DomainTrieCertsStorage) Set(key string, cert *tls.Certificate) { + c.lock.Lock() _ = c.certsCache.Insert(key, cert) + c.lock.Unlock() } func NewDomainTrieCertsStorage() *DomainTrieCertsStorage { diff --git a/component/dialer/mark_linux.go b/component/dialer/mark_linux.go index 41b61863..942a9f51 100644 --- a/component/dialer/mark_linux.go +++ b/component/dialer/mark_linux.go @@ -29,13 +29,13 @@ func bindMarkToControl(mark int, chain controlFn) controlFn { return } - return c.Control(func(fd uintptr) { - switch network { - case "tcp4", "udp4": - _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, mark) - case "tcp6", "udp6": - _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, mark) - } + var innerErr error + err = c.Control(func(fd uintptr) { + innerErr = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, mark) }) + if err == nil && innerErr != nil { + err = innerErr + } + return } } diff --git a/component/process/process.go b/component/process/process.go index 2f004d0f..09d59886 100644 --- a/component/process/process.go +++ b/component/process/process.go @@ -2,11 +2,7 @@ package process import ( "errors" - "net" "net/netip" - - "github.com/Dreamacro/clash/common/nnip" - C "github.com/Dreamacro/clash/constant" ) var ( @@ -23,52 +19,3 @@ const ( func FindProcessName(network string, srcIP netip.Addr, srcPort int) (string, error) { return findProcessName(network, srcIP, srcPort) } - -func ShouldFindProcess(metadata *C.Metadata) bool { - if metadata.Process != "" { - return false - } - if metadata.SrcIP.IsUnspecified() { - return true - } - for _, ip := range localIPs { - if ip == metadata.SrcIP { - return true - } - } - return false -} - -func AppendLocalIPs(ip ...netip.Addr) { - localIPs = append(ip, localIPs...) -} - -func getLocalIPs() []netip.Addr { - var ips []netip.Addr - - netInterfaces, err := net.Interfaces() - if err != nil { - ips = append(ips, netip.AddrFrom4([4]byte{127, 0, 0, 1}), nnip.IpToAddr(net.IPv6loopback)) - return ips - } - - for i := 0; i < len(netInterfaces); i++ { - if (netInterfaces[i].Flags & net.FlagUp) != 0 { - adds, _ := netInterfaces[i].Addrs() - - for _, address := range adds { - if ipNet, ok := address.(*net.IPNet); ok { - ips = append(ips, nnip.IpToAddr(ipNet.IP)) - } - } - } - } - - return ips -} - -var localIPs []netip.Addr - -func init() { - localIPs = getLocalIPs() -} diff --git a/component/process/process_darwin.go b/component/process/process_darwin.go index 2368f239..94ceb403 100644 --- a/component/process/process_darwin.go +++ b/component/process/process_darwin.go @@ -6,8 +6,6 @@ import ( "syscall" "unsafe" - "github.com/Dreamacro/clash/common/nnip" - "golang.org/x/sys/unix" ) @@ -63,10 +61,10 @@ func findProcessName(network string, ip netip.Addr, port int) (string, error) { switch { case flag&0x1 > 0 && isIPv4: // ipv4 - srcIP = nnip.IpToAddr(buf[inp+76 : inp+80]) + srcIP, _ = netip.AddrFromSlice(buf[inp+76 : inp+80]) case flag&0x2 > 0 && !isIPv4: // ipv6 - srcIP = nnip.IpToAddr(buf[inp+64 : inp+80]) + srcIP, _ = netip.AddrFromSlice(buf[inp+64 : inp+80]) default: continue } diff --git a/component/process/process_freebsd_amd64.go b/component/process/process_freebsd_amd64.go index 466cd249..0ce2b340 100644 --- a/component/process/process_freebsd_amd64.go +++ b/component/process/process_freebsd_amd64.go @@ -10,7 +10,6 @@ import ( "syscall" "unsafe" - "github.com/Dreamacro/clash/common/nnip" "github.com/Dreamacro/clash/log" ) @@ -135,10 +134,10 @@ func (s *searcher) Search(buf []byte, ip netip.Addr, port uint16, isTCP bool) (u switch { case flag&0x1 > 0 && isIPv4: // ipv4 - srcIP = nnip.IpToAddr(buf[inp+s.ip : inp+s.ip+4]) + srcIP, _ = netip.AddrFromSlice(buf[inp+s.ip : inp+s.ip+4]) case flag&0x2 > 0 && !isIPv4: // ipv6 - srcIP = nnip.IpToAddr(buf[inp+s.ip-12 : inp+s.ip+4]) + srcIP, _ = netip.AddrFromSlice(buf[inp+s.ip-12 : inp+s.ip+4]) default: continue } diff --git a/component/process/process_windows.go b/component/process/process_windows.go index 778675d4..86692858 100644 --- a/component/process/process_windows.go +++ b/component/process/process_windows.go @@ -7,7 +7,6 @@ import ( "syscall" "unsafe" - "github.com/Dreamacro/clash/common/nnip" "github.com/Dreamacro/clash/log" "golang.org/x/sys/windows" @@ -132,7 +131,7 @@ func (s *searcher) Search(b []byte, ip netip.Addr, port uint16) (uint32, error) continue } - srcIP := nnip.IpToAddr(row[s.ip : s.ip+s.ipSize]) + srcIP, _ := netip.AddrFromSlice(row[s.ip : s.ip+s.ipSize]) // windows binds an unbound udp socket to 0.0.0.0/[::] while first sendto if ip != srcIP && (!srcIP.IsUnspecified() || s.tcpState != -1) { continue diff --git a/config/config.go b/config/config.go index be290006..2f7cdcfc 100644 --- a/config/config.go +++ b/config/config.go @@ -99,12 +99,13 @@ type Profile struct { // Tun config type Tun struct { - Enable bool `yaml:"enable" json:"enable"` - Device string `yaml:"device" json:"device"` - Stack C.TUNStack `yaml:"stack" json:"stack"` - DNSHijack []C.DNSUrl `yaml:"dns-hijack" json:"dns-hijack"` - AutoRoute bool `yaml:"auto-route" json:"auto-route"` - AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"` + Enable bool `yaml:"enable" json:"enable"` + Device string `yaml:"device" json:"device"` + Stack C.TUNStack `yaml:"stack" json:"stack"` + DNSHijack []C.DNSUrl `yaml:"dns-hijack" json:"dns-hijack"` + AutoRoute bool `yaml:"auto-route" json:"auto-route"` + AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"` + TunAddressPrefix *netip.Prefix `yaml:"_" json:"_"` } // IPTables config @@ -415,11 +416,11 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[ // keep the original order of ProxyGroups in config file for idx, mapping := range groupsConfig { - groupName, existName := mapping["name"] + groupName, existName := mapping["name"].(string) if !existName { return nil, nil, fmt.Errorf("proxy group %d: missing name", idx) } - proxyList = append(proxyList, groupName.(string)) + proxyList = append(proxyList, groupName) } // check if any loop exists and sort the ProxyGroups diff --git a/hub/executor/executor.go b/hub/executor/executor.go index c69b9543..f95a3ef2 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -82,7 +82,7 @@ func ApplyConfig(cfg *config.Config, force bool) { updateHosts(cfg.Hosts) updateMitm(cfg.Mitm) updateProfile(cfg) - updateDNS(cfg.DNS, cfg.General.Tun) + updateDNS(cfg.DNS, &cfg.General.Tun) updateGeneral(cfg.General, force) updateIPTables(cfg) updateExperimental(cfg) @@ -121,7 +121,7 @@ func GetGeneral() *config.General { func updateExperimental(_ *config.Config) {} -func updateDNS(c *config.DNS, t config.Tun) { +func updateDNS(c *config.DNS, t *config.Tun) { cfg := dns.Config{ Main: c.NameServer, Fallback: c.Fallback, @@ -179,7 +179,7 @@ func updateDNS(c *config.DNS, t config.Tun) { } if cfg.Pool != nil { - P.SetTunAddressPrefix(cfg.Pool.IPNet()) + t.TunAddressPrefix = cfg.Pool.IPNet() } } diff --git a/listener/listener.go b/listener/listener.go index bb6484c5..a6c4be36 100644 --- a/listener/listener.go +++ b/listener/listener.go @@ -31,11 +31,9 @@ import ( ) var ( - allowLan = false - bindAddress = "*" - lastTunConf *config.Tun - lastTunAddressPrefix *netip.Prefix - tunAddressPrefix *netip.Prefix + allowLan = false + bindAddress = "*" + lastTunConf *config.Tun socksListener *socks.Listener socksUDPListener *socks.UDPListener @@ -109,10 +107,6 @@ func SetBindAddress(host string) { bindAddress = host } -func SetTunAddressPrefix(tunAddress *netip.Prefix) { - tunAddressPrefix = tunAddress -} - func ReCreateHTTP(port int, tcpIn chan<- C.ConnContext) { httpMux.Lock() defer httpMux.Unlock() @@ -363,14 +357,10 @@ func ReCreateTun(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- * } }() - if tunAddressPrefix == nil { - tunAddressPrefix = lastTunAddressPrefix - } - tunConf.DNSHijack = C.RemoveDuplicateDNSUrl(tunConf.DNSHijack) if tunStackListener != nil { - if !hasTunConfigChange(tunConf, tunAddressPrefix) { + if !hasTunConfigChange(tunConf) { return } @@ -379,7 +369,6 @@ func ReCreateTun(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- * } lastTunConf = tunConf - lastTunAddressPrefix = tunAddressPrefix if !tunConf.Enable { return @@ -391,7 +380,7 @@ func ReCreateTun(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- * udpIn: udpIn, } - tunStackListener, err = tun.New(tunConf, tunAddressPrefix, tcpIn, udpIn, callback) + tunStackListener, err = tun.New(tunConf, tcpIn, udpIn, callback) if err != nil { return } @@ -535,7 +524,7 @@ func genAddr(host string, port int, allowLan bool) string { return fmt.Sprintf("127.0.0.1:%d", port) } -func hasTunConfigChange(tunConf *config.Tun, tunAddressPrefix *netip.Prefix) bool { +func hasTunConfigChange(tunConf *config.Tun) bool { if lastTunConf == nil { return true } @@ -558,11 +547,11 @@ func hasTunConfigChange(tunConf *config.Tun, tunAddressPrefix *netip.Prefix) boo return true } - if (tunAddressPrefix != nil && lastTunAddressPrefix == nil) || (tunAddressPrefix == nil && lastTunAddressPrefix != nil) { + if (lastTunConf.TunAddressPrefix != nil && tunConf.TunAddressPrefix == nil) || (lastTunConf.TunAddressPrefix == nil && tunConf.TunAddressPrefix != nil) { return true } - if tunAddressPrefix != nil && lastTunAddressPrefix != nil && *tunAddressPrefix != *lastTunAddressPrefix { + if lastTunConf.TunAddressPrefix != nil && tunConf.TunAddressPrefix != nil && *lastTunConf.TunAddressPrefix != *tunConf.TunAddressPrefix { return true } diff --git a/listener/tproxy/udp.go b/listener/tproxy/udp.go index cf8bbd92..d851fc05 100644 --- a/listener/tproxy/udp.go +++ b/listener/tproxy/udp.go @@ -72,6 +72,11 @@ func NewUDP(addr string, in chan<- *inbound.PacketAdapter) (*UDPListener, error) if err != nil { continue } + + if rAddr.Addr().Is4() { + // try to unmap 4in6 address + lAddr = netip.AddrPortFrom(lAddr.Addr().Unmap(), lAddr.Port()) + } handlePacketConn(in, buf[:n], lAddr, rAddr) } }() diff --git a/listener/tun/device/fdbased/fd_unix.go b/listener/tun/device/fdbased/fd_unix.go index 23474a5a..336f8692 100644 --- a/listener/tun/device/fdbased/fd_unix.go +++ b/listener/tun/device/fdbased/fd_unix.go @@ -41,6 +41,10 @@ func (f *FD) Name() string { return strconv.Itoa(f.fd) } +func (f *FD) MTU() uint32 { + return f.mtu +} + func (f *FD) Close() error { err := unix.Close(f.fd) if f.file != nil { diff --git a/listener/tun/device/fdbased/fd_windows.go b/listener/tun/device/fdbased/fd_windows.go index a04f3356..260f69cd 100644 --- a/listener/tun/device/fdbased/fd_windows.go +++ b/listener/tun/device/fdbased/fd_windows.go @@ -4,8 +4,48 @@ import ( "errors" "github.com/Dreamacro/clash/listener/tun/device" + + "gvisor.dev/gvisor/pkg/tcpip/stack" ) -func Open(name string, mtu uint32) (device.Device, error) { +type FD struct { + stack.LinkEndpoint +} + +func Open(_ string, _ uint32) (device.Device, error) { return nil, errors.New("not supported") } + +func (f *FD) Name() string { + return "" +} + +func (f *FD) Type() string { + return Driver +} + +func (f *FD) Read(_ []byte) (int, error) { + return 0, nil +} + +func (f *FD) Write(_ []byte) (int, error) { + return 0, nil +} + +func (f *FD) Close() error { + return nil +} + +func (f *FD) UseEndpoint() error { + return nil +} + +func (f *FD) UseIOBased() error { + return nil +} + +func (f *FD) MTU() uint32 { + return 0 +} + +var _ device.Device = (*FD)(nil) diff --git a/listener/tun/device/tun/tun_wireguard.go b/listener/tun/device/tun/tun_wireguard.go index 04f86d4b..2436e930 100644 --- a/listener/tun/device/tun/tun_wireguard.go +++ b/listener/tun/device/tun/tun_wireguard.go @@ -59,10 +59,13 @@ func Open(name string, mtu uint32) (_ device.Device, err error) { if err != nil { return nil, fmt.Errorf("get mtu: %w", err) } - t.mtu = uint32(tunMTU) + + if t.mtu == 0 { + t.mtu = uint32(tunMTU) + } if t.offset > 0 { - t.cache = make([]byte, 65535) + t.cache = make([]byte, int(t.mtu)+t.offset) } return t, nil @@ -108,6 +111,10 @@ func (t *TUN) Name() string { return name } +func (t *TUN) MTU() uint32 { + return t.mtu +} + func (t *TUN) UseEndpoint() error { ep, err := iobased.New(t, t.mtu, t.offset) if err != nil { diff --git a/listener/tun/ipstack/system/mars/nat/nat.go b/listener/tun/ipstack/system/mars/nat/nat.go index b597ff70..9b9fa0d8 100644 --- a/listener/tun/ipstack/system/mars/nat/nat.go +++ b/listener/tun/ipstack/system/mars/nat/nat.go @@ -5,8 +5,10 @@ import ( "net" "net/netip" + dev "github.com/Dreamacro/clash/listener/tun/device" + "github.com/Dreamacro/clash/listener/tun/device/fdbased" + "github.com/Dreamacro/clash/listener/tun/device/tun" "github.com/Dreamacro/clash/listener/tun/ipstack/system/mars/tcpip" - "github.com/Dreamacro/clash/log" ) func Start(device io.ReadWriter, gateway, portal, broadcast netip.Addr) (*TCP, *UDP, error) { @@ -19,10 +21,27 @@ func Start(device io.ReadWriter, gateway, portal, broadcast netip.Addr) (*TCP, * return nil, nil, err } + var ( + t dev.Device + mtu uint32 + ok bool + ) + if t, ok = device.(*tun.TUN); ok { + mtu = t.MTU() + } else if t, ok = device.(*fdbased.FD); ok { + mtu = t.MTU() + } + + bufferSize := int(mtu) + + if bufferSize == 0 { + bufferSize = 64 * 1024 + } + tab := newTable() udp := &UDP{ device: device, - buf: [0xffff]byte{}, + buf: make([]byte, bufferSize), } tcp := &TCP{ listener: listener, @@ -38,7 +57,7 @@ func Start(device io.ReadWriter, gateway, portal, broadcast netip.Addr) (*TCP, * _ = udp.Close() }() - buf := make([]byte, 0xffff) + buf := make([]byte, bufferSize) for { n, err := device.Read(buf) @@ -133,11 +152,7 @@ func Start(device io.ReadWriter, gateway, portal, broadcast netip.Addr) (*TCP, * continue } - port, err = tab.newConn(tup) - if err != nil { - log.Warnln("[STACK] drop tcp packet by system stack: %v", err) - continue - } + port = tab.newConn(tup) } ip.SetSourceIP(portal) @@ -156,7 +171,7 @@ func Start(device io.ReadWriter, gateway, portal, broadcast netip.Addr) (*TCP, * continue } - go udp.handleUDPPacket(ip, u) + udp.handleUDPPacket(ip, u) case tcpip.ICMP: i := tcpip.ICMPPacket(ip.Payload()) diff --git a/listener/tun/ipstack/system/mars/nat/table.go b/listener/tun/ipstack/system/mars/nat/table.go index 21d07b93..38b7d6c6 100644 --- a/listener/tun/ipstack/system/mars/nat/table.go +++ b/listener/tun/ipstack/system/mars/nat/table.go @@ -1,13 +1,9 @@ package nat import ( - "fmt" "net/netip" - "sync" "github.com/Dreamacro/clash/common/generics/list" - - "golang.org/x/exp/maps" ) const ( @@ -31,8 +27,6 @@ type table struct { tuples map[tuple]*list.Element[*binding] ports [portLength]*list.Element[*binding] available *list.List[*binding] - mux sync.Mutex - count uint16 } func (t *table) tupleOf(port uint16) tuple { @@ -49,64 +43,27 @@ func (t *table) tupleOf(port uint16) tuple { } func (t *table) portOf(tuple tuple) uint16 { - t.mux.Lock() elm := t.tuples[tuple] if elm == nil { - t.mux.Unlock() return 0 } - t.mux.Unlock() t.available.MoveToFront(elm) return portBegin + elm.Value.offset } -func (t *table) newConn(tuple tuple) (uint16, error) { - t.mux.Lock() - elm, err := t.availableConn() - if err != nil { - t.mux.Unlock() - return 0, err - } +func (t *table) newConn(tuple tuple) uint16 { + elm := t.available.Back() + b := elm.Value - elm.Value.tuple = tuple + delete(t.tuples, b.tuple) t.tuples[tuple] = elm - t.mux.Unlock() + b.tuple = tuple - return portBegin + elm.Value.offset, nil -} + t.available.MoveToFront(elm) -func (t *table) availableConn() (*list.Element[*binding], error) { - var elm *list.Element[*binding] - - for i := 0; i < portLength; i++ { - elm = t.available.Back() - t.available.MoveToFront(elm) - - offset := elm.Value.offset - tup := t.ports[offset].Value.tuple - if t.tuples[tup] != nil && tup.SourceAddr.IsValid() { - continue - } - - if t.count == portLength { // resize - tuples := make(map[tuple]*list.Element[*binding], portLength) - maps.Copy(tuples, t.tuples) - t.tuples = tuples - t.count = 1 - } - return elm, nil - } - - return nil, fmt.Errorf("too many open files, limits [%d, %d]", portLength, len(t.tuples)) -} - -func (t *table) closeConn(tuple tuple) { - t.mux.Lock() - delete(t.tuples, tuple) - t.count++ - t.mux.Unlock() + return portBegin + b.offset } func newTable() *table { @@ -114,7 +71,6 @@ func newTable() *table { tuples: make(map[tuple]*list.Element[*binding], portLength), ports: [portLength]*list.Element[*binding]{}, available: list.New[*binding](), - count: 1, } for idx := range result.ports { diff --git a/listener/tun/ipstack/system/mars/nat/tcp.go b/listener/tun/ipstack/system/mars/nat/tcp.go index 2ad9c025..a6faf2d1 100644 --- a/listener/tun/ipstack/system/mars/nat/tcp.go +++ b/listener/tun/ipstack/system/mars/nat/tcp.go @@ -16,8 +16,6 @@ type conn struct { net.Conn tuple tuple - - close func() } func (t *TCP) Accept() (net.Conn, error) { @@ -41,9 +39,6 @@ func (t *TCP) Accept() (net.Conn, error) { return &conn{ Conn: c, tuple: tup, - close: func() { - t.table.closeConn(tup) - }, }, nil } @@ -60,7 +55,6 @@ func (t *TCP) SetDeadline(time time.Time) error { } func (c *conn) Close() error { - c.close() return c.Conn.Close() } diff --git a/listener/tun/ipstack/system/mars/nat/udp.go b/listener/tun/ipstack/system/mars/nat/udp.go index 4489ddaf..663711f2 100644 --- a/listener/tun/ipstack/system/mars/nat/udp.go +++ b/listener/tun/ipstack/system/mars/nat/udp.go @@ -24,7 +24,7 @@ type UDP struct { queueLock sync.Mutex queue []*call bufLock sync.Mutex - buf [0xffff]byte + buf []byte } func (u *UDP) ReadFrom(buf []byte) (int, netip.AddrPort, netip.AddrPort, error) { diff --git a/listener/tun/tun_adapter.go b/listener/tun/tun_adapter.go index a03a2e81..9dc33e10 100644 --- a/listener/tun/tun_adapter.go +++ b/listener/tun/tun_adapter.go @@ -9,7 +9,6 @@ import ( "github.com/Dreamacro/clash/adapter/inbound" "github.com/Dreamacro/clash/common/cmd" - "github.com/Dreamacro/clash/component/process" "github.com/Dreamacro/clash/config" C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/listener/tun/device" @@ -24,7 +23,7 @@ import ( ) // New TunAdapter -func New(tunConf *config.Tun, tunAddressPrefix *netip.Prefix, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter, tunChangeCallback C.TUNChangeCallback) (ipstack.Stack, error) { +func New(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter, tunChangeCallback C.TUNChangeCallback) (ipstack.Stack, error) { var ( tunAddress = netip.Prefix{} devName = tunConf.Device @@ -48,16 +47,14 @@ func New(tunConf *config.Tun, tunAddressPrefix *netip.Prefix, tcpIn chan<- C.Con devName = generateDeviceName() } - if tunAddressPrefix != nil { - tunAddress = *tunAddressPrefix + if tunConf.TunAddressPrefix != nil { + tunAddress = *tunConf.TunAddressPrefix } if !tunAddress.IsValid() || !tunAddress.Addr().Is4() { tunAddress = netip.MustParsePrefix("198.18.0.1/16") } - process.AppendLocalIPs(tunAddress.Masked().Addr().Next()) - // open tun device tunDevice, err = parseDevice(devName, uint32(mtu)) if err != nil { diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index 559270df..7328bc9c 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -394,7 +394,7 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) { resolved = true } - if !processFound && rule.ShouldFindProcess() && P.ShouldFindProcess(metadata) { + if !processFound && rule.ShouldFindProcess() { processFound = true srcPort, err := strconv.ParseUint(metadata.SrcPort, 10, 16)