diff --git a/core/src/main/golang/native/app/tun.go b/core/src/main/golang/native/app/tun.go index 14c05994..5bf7b0ab 100644 --- a/core/src/main/golang/native/app/tun.go +++ b/core/src/main/golang/native/app/tun.go @@ -2,7 +2,6 @@ package app import ( "net" - "strings" "syscall" "cfa/native/platform" @@ -16,10 +15,15 @@ func MarkSocket(fd int) { } func QuerySocketUid(source, target net.Addr) int { - protocol := syscall.IPPROTO_TCP + var protocol int - if strings.HasPrefix(source.String(), "udp") { + switch source.Network() { + case "udp", "udp4", "udp6": protocol = syscall.IPPROTO_UDP + case "tcp", "tcp4", "tcp6": + protocol = syscall.IPPROTO_TCP + default: + return -1 } if PlatformVersion() < 29 { diff --git a/core/src/main/golang/native/tunnel/init.go b/core/src/main/golang/native/tunnel/init.go new file mode 100644 index 00000000..d442a238 --- /dev/null +++ b/core/src/main/golang/native/tunnel/init.go @@ -0,0 +1,43 @@ +package tunnel + +import ( + "context" + "net" + "strings" + + "github.com/Dreamacro/clash/component/dialer" + C "github.com/Dreamacro/clash/constant" + CTX "github.com/Dreamacro/clash/context" + "github.com/Dreamacro/clash/tunnel" +) + +func init() { + dialer.DefaultTunnelDialer = func(context context.Context, network, address string) (net.Conn, error) { + if !strings.HasPrefix(network, "tcp") { + return nil, net.UnknownNetworkError("unsupported network") + } + + host, port, err := net.SplitHostPort(address) + if err != nil { + return nil, err + } + + left, right := net.Pipe() + + metadata := &C.Metadata{ + NetWork: C.TCP, + Type: C.HTTPCONNECT, + SrcIP: net.ParseIP("127.0.0.1"), + SrcPort: "65535", + DstPort: port, + AddrType: C.AtypDomainName, + Host: host, + RawSrcAddr: left.RemoteAddr(), + RawDstAddr: left.LocalAddr(), + } + + tunnel.TCPIn() <- CTX.NewConnContext(right, metadata) + + return left, nil + } +}