Chore: add more details to process resolving (#2017)

This commit is contained in:
Kr328 2022-03-09 13:41:50 +08:00 committed by GitHub
parent f6c7281bb7
commit 9683c297a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"io"
"net" "net"
"os" "os"
"path" "path"
@ -27,17 +26,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 +33,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,7 +64,7 @@ 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)
@ -94,7 +82,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 +90,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 +148,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
@ -217,7 +208,7 @@ func resolveProcessNameByProcSearch(inode, uid int) (string, error) {
} }
} }
return "", syscall.ESRCH return "", fmt.Errorf("process of uid(%d),inode(%d) not found", uid, inode)
} }
func splitCmdline(cmdline []byte) string { func splitCmdline(cmdline []byte) string {