diff --git a/core/src/main/golang/go.mod b/core/src/main/golang/go.mod index 9786cb705..2f5970182 100644 --- a/core/src/main/golang/go.mod +++ b/core/src/main/golang/go.mod @@ -3,10 +3,8 @@ module cfa go 1.20 require ( - github.com/Kr328/tun2socket v0.0.0-20220414050025-d07c78d06d34 github.com/dlclark/regexp2 v1.11.4 github.com/metacubex/mihomo v1.7.0 - github.com/miekg/dns v1.1.62 github.com/oschwald/maxminddb-golang v1.12.0 golang.org/x/sync v0.8.0 gopkg.in/yaml.v3 v3.0.1 @@ -68,6 +66,7 @@ require ( github.com/metacubex/sing-wireguard v0.0.0-20240826061955-1e4e67afe5cd // indirect github.com/metacubex/tfo-go v0.0.0-20240830120620-c5e019b67785 // indirect github.com/metacubex/utls v1.6.6 // indirect + github.com/miekg/dns v1.1.62 // indirect github.com/mroth/weightedrand/v2 v2.1.0 // indirect github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 // indirect github.com/onsi/ginkgo/v2 v2.9.5 // indirect diff --git a/core/src/main/golang/go.sum b/core/src/main/golang/go.sum index edb7b0ae3..d11991400 100644 --- a/core/src/main/golang/go.sum +++ b/core/src/main/golang/go.sum @@ -1,7 +1,5 @@ github.com/3andne/restls-client-go v0.1.6 h1:tRx/YilqW7iHpgmEL4E1D8dAsuB0tFF3uvncS+B6I08= github.com/3andne/restls-client-go v0.1.6/go.mod h1:iEdTZNt9kzPIxjIGSMScUFSBrUH6bFRNg0BWlP4orEY= -github.com/Kr328/tun2socket v0.0.0-20220414050025-d07c78d06d34 h1:USCTqih5d1bUXUxWNS9ZD5Tx/lb0jXHEtRIIx/F9dMc= -github.com/Kr328/tun2socket v0.0.0-20220414050025-d07c78d06d34/go.mod h1:YR9wK13TgI5ww8iKWm91MHiSoHC7Oz0U4beCCmtXqLw= github.com/RyuaNerin/elliptic2 v1.0.0/go.mod h1:wWB8fWrJI/6EPJkyV/r1Rj0hxUgrusmqSj8JN6yNf/A= github.com/RyuaNerin/go-krypto v1.2.4 h1:mXuNdK6M317aPV0llW6Xpjbo4moOlPF7Yxz4tb4b4Go= github.com/RyuaNerin/go-krypto v1.2.4/go.mod h1:QqCYkoutU3yInyD9INt2PGolVRsc3W4oraQadVGXJ/8= diff --git a/core/src/main/golang/native/config/process.go b/core/src/main/golang/native/config/process.go index 545f12770..df0192144 100644 --- a/core/src/main/golang/native/config/process.go +++ b/core/src/main/golang/native/config/process.go @@ -9,6 +9,7 @@ import ( "github.com/dlclark/regexp2" "cfa/native/common" + C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/log" @@ -21,6 +22,7 @@ var processors = []processor{ patchGeneral, patchProfile, patchDns, + patchTun, patchProviders, validConfig, } @@ -74,6 +76,12 @@ func patchDns(cfg *config.RawConfig, _ string) error { return nil } +func patchTun(cfg *config.RawConfig, _ string) error { + cfg.Tun.Enable = false + + return nil +} + func patchProviders(cfg *config.RawConfig, profileDir string) error { forEachProviders(cfg, func(index int, total int, key string, provider map[string]any) { if path, ok := provider["path"].(string); ok { diff --git a/core/src/main/golang/native/tun/dns.go b/core/src/main/golang/native/tun/dns.go deleted file mode 100644 index e51c72757..000000000 --- a/core/src/main/golang/native/tun/dns.go +++ /dev/null @@ -1,33 +0,0 @@ -package tun - -import ( - "net" - - "github.com/metacubex/mihomo/dns" - - D "github.com/miekg/dns" -) - -func shouldHijackDns(dns net.IP, target net.IP, targetPort int) bool { - if targetPort != 53 { - return false - } - - return net.IPv4zero.Equal(dns) || target.Equal(dns) -} - -func relayDns(payload []byte) ([]byte, error) { - msg := &D.Msg{} - if err := msg.Unpack(payload); err != nil { - return nil, err - } - - r, err := dns.ServeDNSWithDefaultServer(msg) - if err != nil { - return nil, err - } - - r.SetRcode(msg, r.Rcode) - - return r.Pack() -} diff --git a/core/src/main/golang/native/tun/metadata.go b/core/src/main/golang/native/tun/metadata.go deleted file mode 100644 index a2141abd1..000000000 --- a/core/src/main/golang/native/tun/metadata.go +++ /dev/null @@ -1,21 +0,0 @@ -package tun - -import ( - "net" - - C "github.com/metacubex/mihomo/constant" -) - -func createMetadata(lAddr, rAddr *net.TCPAddr) *C.Metadata { - return &C.Metadata{ - NetWork: C.TCP, - Type: C.SOCKS5, - SrcIP: lAddr.AddrPort().Addr(), - DstIP: rAddr.AddrPort().Addr(), - SrcPort: uint16(lAddr.Port), - DstPort: uint16(rAddr.Port), - Host: "", - RawSrcAddr: lAddr, - RawDstAddr: rAddr, - } -} diff --git a/core/src/main/golang/native/tun/tun.go b/core/src/main/golang/native/tun/tun.go index bb44e38e8..1ac7c2e00 100644 --- a/core/src/main/golang/native/tun/tun.go +++ b/core/src/main/golang/native/tun/tun.go @@ -1,161 +1,34 @@ package tun import ( - "encoding/binary" "io" - "net" - "os" - "time" + "net/netip" - "github.com/Kr328/tun2socket" - - "github.com/metacubex/mihomo/adapter/inbound" - "github.com/metacubex/mihomo/common/pool" C "github.com/metacubex/mihomo/constant" + LC "github.com/metacubex/mihomo/listener/config" + "github.com/metacubex/mihomo/listener/sing_tun" "github.com/metacubex/mihomo/log" - "github.com/metacubex/mihomo/transport/socks5" "github.com/metacubex/mihomo/tunnel" ) -var _, ipv4LoopBack, _ = net.ParseCIDR("127.0.0.0/8") - func Start(fd int, gateway, portal, dns string) (io.Closer, error) { log.Debugln("TUN: fd = %d, gateway = %s, portal = %s, dns = %s", fd, gateway, portal, dns) - device := os.NewFile(uintptr(fd), "/dev/tun") - - ip, network, err := net.ParseCIDR(gateway) - if err != nil { - panic(err.Error()) - } else { - network.IP = ip + options := LC.Tun{ + Enable: true, + Device: sing_tun.InterfaceName, + Stack: C.TunSystem, + DNSHijack: []string{dns}, // "172.19.0.2" or "0.0.0.0" + Inet4Address: []netip.Prefix{netip.MustParsePrefix(gateway)}, // "172.19.0.1/30" + MTU: 9000, // private const val TUN_MTU = 9000 in TunService.kt + FileDescriptor: fd, } - stack, err := tun2socket.StartTun2Socket(device, network, net.ParseIP(portal)) + listener, err := sing_tun.New(options, tunnel.Tunnel) if err != nil { - _ = device.Close() - + log.Errorln("TUN:", err) return nil, err } - dnsAddr := net.ParseIP(dns) - - tcp := func() { - defer stack.TCP().Close() - defer log.Debugln("TCP: closed") - - for stack.TCP().SetDeadline(time.Time{}) == nil { - conn, err := stack.TCP().Accept() - if err != nil { - log.Debugln("Accept connection: %v", err) - - continue - } - - lAddr := conn.LocalAddr().(*net.TCPAddr) - rAddr := conn.RemoteAddr().(*net.TCPAddr) - - if ipv4LoopBack.Contains(rAddr.IP) { - conn.Close() - - continue - } - - if shouldHijackDns(dnsAddr, rAddr.IP, rAddr.Port) { - go func() { - defer conn.Close() - - buf := pool.Get(pool.UDPBufferSize) - defer pool.Put(buf) - - for { - conn.SetReadDeadline(time.Now().Add(C.DefaultTCPTimeout)) - - length := uint16(0) - if err := binary.Read(conn, binary.BigEndian, &length); err != nil { - return - } - - if int(length) > len(buf) { - return - } - - n, err := conn.Read(buf[:length]) - if err != nil { - return - } - - msg, err := relayDns(buf[:n]) - if err != nil { - return - } - - _, _ = conn.Write(msg) - } - }() - - continue - } - - go tunnel.Tunnel.HandleTCPConn(conn, createMetadata(lAddr, rAddr)) - } - } - - udp := func() { - defer stack.UDP().Close() - defer log.Debugln("UDP: closed") - - for { - buf := pool.Get(pool.UDPBufferSize) - - n, lRAddr, rRAddr, err := stack.UDP().ReadFrom(buf) - if err != nil { - return - } - - raw := buf[:n] - lAddr := lRAddr.(*net.UDPAddr) - rAddr := rRAddr.(*net.UDPAddr) - - if ipv4LoopBack.Contains(rAddr.IP) { - pool.Put(buf) - - continue - } - - if shouldHijackDns(dnsAddr, rAddr.IP, rAddr.Port) { - go func() { - defer pool.Put(buf) - - msg, err := relayDns(raw) - if err != nil { - return - } - - _, _ = stack.UDP().WriteTo(msg, rAddr, lAddr) - }() - - continue - } - - pkt := &packet{ - local: lAddr, - data: raw, - writeBack: func(b []byte, addr net.Addr) (int, error) { - return stack.UDP().WriteTo(b, addr, lAddr) - }, - drop: func() { - pool.Put(buf) - }, - } - - tunnel.Tunnel.HandleUDPPacket(inbound.NewPacket(socks5.ParseAddrToSocksAddr(rAddr), pkt, C.SOCKS5)) - } - } - - go tcp() - go udp() - go udp() - - return stack, nil + return listener, nil } diff --git a/core/src/main/golang/native/tun/udp.go b/core/src/main/golang/native/tun/udp.go deleted file mode 100644 index 386bca8d8..000000000 --- a/core/src/main/golang/native/tun/udp.go +++ /dev/null @@ -1,28 +0,0 @@ -package tun - -import ( - "net" -) - -type packet struct { - local *net.UDPAddr - data []byte - writeBack func(b []byte, addr net.Addr) (int, error) - drop func() -} - -func (pkt *packet) Data() []byte { - return pkt.data -} - -func (pkt *packet) WriteBack(b []byte, addr net.Addr) (n int, err error) { - return pkt.writeBack(b, addr) -} - -func (pkt *packet) Drop() { - pkt.drop() -} - -func (pkt *packet) LocalAddr() net.Addr { - return pkt.local -}