mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-02-23 20:52:15 +08:00
Chore: Merge branch 'ogn-dev' into with-tun
This commit is contained in:
commit
8fbf93ccc8
@ -3,7 +3,6 @@ package process
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"net"
|
"net"
|
||||||
"path/filepath"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -96,7 +95,7 @@ func getExecPathFromPID(pid uint32) (string, error) {
|
|||||||
return "", errno
|
return "", errno
|
||||||
}
|
}
|
||||||
|
|
||||||
return filepath.Base(unix.ByteSliceToString(buf)), nil
|
return unix.ByteSliceToString(buf), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readNativeUint32(b []byte) uint32 {
|
func readNativeUint32(b []byte) uint32 {
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -77,7 +76,7 @@ func getExecPathFromPID(pid uint32) (string, error) {
|
|||||||
return "", errno
|
return "", errno
|
||||||
}
|
}
|
||||||
|
|
||||||
return filepath.Base(string(buf[:size-1])), nil
|
return string(buf[:size-1]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readNativeUint32(b []byte) uint32 {
|
func readNativeUint32(b []byte) uint32 {
|
||||||
|
@ -4,11 +4,9 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unicode"
|
"unicode"
|
||||||
@ -27,17 +25,6 @@ var nativeEndian = func() binary.ByteOrder {
|
|||||||
return binary.LittleEndian
|
return binary.LittleEndian
|
||||||
}()
|
}()
|
||||||
|
|
||||||
type (
|
|
||||||
SocketResolver func(network string, ip net.IP, srcPort int) (inode, uid int, err error)
|
|
||||||
ProcessNameResolver func(inode, uid int) (name string, err error)
|
|
||||||
)
|
|
||||||
|
|
||||||
// export for android
|
|
||||||
var (
|
|
||||||
DefaultSocketResolver SocketResolver = resolveSocketByNetlink
|
|
||||||
DefaultProcessNameResolver ProcessNameResolver = resolveProcessNameByProcSearch
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sizeOfSocketDiagRequest = syscall.SizeofNlMsghdr + 8 + 48
|
sizeOfSocketDiagRequest = syscall.SizeofNlMsghdr + 8 + 48
|
||||||
socketDiagByFamily = 20
|
socketDiagByFamily = 20
|
||||||
@ -45,15 +32,15 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func findProcessName(network string, ip net.IP, srcPort int) (string, error) {
|
func findProcessName(network string, ip net.IP, srcPort int) (string, error) {
|
||||||
inode, uid, err := DefaultSocketResolver(network, ip, srcPort)
|
inode, uid, err := resolveSocketByNetlink(network, ip, srcPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefaultProcessNameResolver(inode, uid)
|
return resolveProcessNameByProcSearch(inode, uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveSocketByNetlink(network string, ip net.IP, srcPort int) (int, int, error) {
|
func resolveSocketByNetlink(network string, ip net.IP, srcPort int) (int32, int32, error) {
|
||||||
var family byte
|
var family byte
|
||||||
var protocol byte
|
var protocol byte
|
||||||
|
|
||||||
@ -76,13 +63,12 @@ func resolveSocketByNetlink(network string, ip net.IP, srcPort int) (int, int, e
|
|||||||
|
|
||||||
socket, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_DGRAM, syscall.NETLINK_INET_DIAG)
|
socket, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_DGRAM, syscall.NETLINK_INET_DIAG)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, fmt.Errorf("dial netlink: %w", err)
|
||||||
}
|
}
|
||||||
defer syscall.Close(socket)
|
defer syscall.Close(socket)
|
||||||
|
|
||||||
syscall.SetNonblock(socket, true)
|
syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, &syscall.Timeval{Usec: 100})
|
||||||
syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, &syscall.Timeval{Usec: 50})
|
syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &syscall.Timeval{Usec: 100})
|
||||||
syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &syscall.Timeval{Usec: 50})
|
|
||||||
|
|
||||||
if err := syscall.Connect(socket, &syscall.SockaddrNetlink{
|
if err := syscall.Connect(socket, &syscall.SockaddrNetlink{
|
||||||
Family: syscall.AF_NETLINK,
|
Family: syscall.AF_NETLINK,
|
||||||
@ -94,7 +80,7 @@ func resolveSocketByNetlink(network string, ip net.IP, srcPort int) (int, int, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, err := syscall.Write(socket, req); err != nil {
|
if _, err := syscall.Write(socket, req); err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, fmt.Errorf("write request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rb := pool.Get(pool.RelayBufferSize)
|
rb := pool.Get(pool.RelayBufferSize)
|
||||||
@ -102,24 +88,27 @@ func resolveSocketByNetlink(network string, ip net.IP, srcPort int) (int, int, e
|
|||||||
|
|
||||||
n, err := syscall.Read(socket, rb)
|
n, err := syscall.Read(socket, rb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, fmt.Errorf("read response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
messages, err := syscall.ParseNetlinkMessage(rb[:n])
|
messages, err := syscall.ParseNetlinkMessage(rb[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, fmt.Errorf("parse netlink message: %w", err)
|
||||||
} else if len(messages) == 0 {
|
} else if len(messages) == 0 {
|
||||||
return 0, 0, io.ErrUnexpectedEOF
|
return 0, 0, fmt.Errorf("unexcepted netlink response")
|
||||||
}
|
}
|
||||||
|
|
||||||
message := messages[0]
|
message := messages[0]
|
||||||
if message.Header.Type&syscall.NLMSG_ERROR != 0 {
|
if message.Header.Type&syscall.NLMSG_ERROR != 0 {
|
||||||
return 0, 0, syscall.ESRCH
|
return 0, 0, fmt.Errorf("netlink message: NLMSG_ERROR")
|
||||||
}
|
}
|
||||||
|
|
||||||
uid, inode := unpackSocketDiagResponse(&messages[0])
|
uid, inode := unpackSocketDiagResponse(&messages[0])
|
||||||
|
if uid < 0 || inode < 0 {
|
||||||
|
return 0, 0, fmt.Errorf("invalid uid(%d) or inode(%d)", uid, inode)
|
||||||
|
}
|
||||||
|
|
||||||
return int(uid), int(inode), nil
|
return uid, inode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func packSocketDiagRequest(family, protocol byte, source net.IP, sourcePort uint16) []byte {
|
func packSocketDiagRequest(family, protocol byte, source net.IP, sourcePort uint16) []byte {
|
||||||
@ -157,20 +146,20 @@ func packSocketDiagRequest(family, protocol byte, source net.IP, sourcePort uint
|
|||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackSocketDiagResponse(msg *syscall.NetlinkMessage) (inode, uid uint32) {
|
func unpackSocketDiagResponse(msg *syscall.NetlinkMessage) (inode, uid int32) {
|
||||||
if len(msg.Data) < 72 {
|
if len(msg.Data) < 72 {
|
||||||
return 0, 0
|
return 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
data := msg.Data
|
data := msg.Data
|
||||||
|
|
||||||
uid = nativeEndian.Uint32(data[64:68])
|
uid = int32(nativeEndian.Uint32(data[64:68]))
|
||||||
inode = nativeEndian.Uint32(data[68:72])
|
inode = int32(nativeEndian.Uint32(data[68:72]))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveProcessNameByProcSearch(inode, uid int) (string, error) {
|
func resolveProcessNameByProcSearch(inode, uid int32) (string, error) {
|
||||||
files, err := os.ReadDir(pathProc)
|
files, err := os.ReadDir(pathProc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -207,25 +196,12 @@ func resolveProcessNameByProcSearch(inode, uid int) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if bytes.Equal(buffer[:n], socket) {
|
if bytes.Equal(buffer[:n], socket) {
|
||||||
cmdline, err := os.ReadFile(path.Join(processPath, "cmdline"))
|
return os.Readlink(path.Join(processPath, "exe"))
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return splitCmdline(cmdline), nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", syscall.ESRCH
|
return "", fmt.Errorf("process of uid(%d),inode(%d) not found", uid, inode)
|
||||||
}
|
|
||||||
|
|
||||||
func splitCmdline(cmdline []byte) string {
|
|
||||||
idx := bytes.IndexFunc(cmdline, func(r rune) bool {
|
|
||||||
return unicode.IsControl(r) || unicode.IsSpace(r)
|
|
||||||
})
|
|
||||||
|
|
||||||
return filepath.Base(string(cmdline[:idx]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isPid(s string) bool {
|
func isPid(s string) bool {
|
||||||
|
@ -3,7 +3,6 @@ package process
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"path/filepath"
|
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@ -220,5 +219,5 @@ func getExecPathFromPID(pid uint32) (string, error) {
|
|||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return filepath.Base(syscall.UTF16ToString(buf[:size])), nil
|
return syscall.UTF16ToString(buf[:size]), nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user