mirror of
https://github.com/MetaCubeX/ClashMetaForAndroid.git
synced 2024-11-16 13:32:37 +08:00
using sing-tun instead of tun2socket
This commit is contained in:
parent
4df39342a2
commit
158e47b372
|
@ -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
|
||||
|
|
|
@ -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=
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
}
|
|
@ -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 + ":53"}, // "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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user