mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-05-08 14:13:22 +00:00
Routing: process supports UID on Android (#5915)
Example: https://github.com/XTLS/Xray-core/pull/5915#issuecomment-4232122895 --------- Co-authored-by: 风扇滑翔翼 <Fangliding.fshxy@outlook.com>
This commit is contained in:
@@ -390,8 +390,10 @@ func (m *ProcessNameMatcher) Apply(ctx routing.Context) bool {
|
|||||||
if len(ctx.GetSourceIPs()) == 0 {
|
if len(ctx.GetSourceIPs()) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
srcPort := ctx.GetSourcePort().String()
|
|
||||||
|
srcPort := uint16(ctx.GetSourcePort())
|
||||||
srcIP := ctx.GetSourceIPs()[0].String()
|
srcIP := ctx.GetSourceIPs()[0].String()
|
||||||
|
|
||||||
var network string
|
var network string
|
||||||
switch ctx.GetNetwork() {
|
switch ctx.GetNetwork() {
|
||||||
case net.Network_TCP:
|
case net.Network_TCP:
|
||||||
@@ -401,11 +403,15 @@ func (m *ProcessNameMatcher) Apply(ctx routing.Context) bool {
|
|||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
src, err := net.ParseDestination(strings.Join([]string{network, srcIP, srcPort}, ":"))
|
|
||||||
if err != nil {
|
var dstIP string
|
||||||
return false
|
var dstPort uint16 = 0
|
||||||
|
if len(ctx.GetTargetIPs()) > 0 {
|
||||||
|
dstIP = ctx.GetTargetIPs()[0].String()
|
||||||
|
dstPort = uint16(ctx.GetTargetPort())
|
||||||
}
|
}
|
||||||
pid, name, absPath, err := net.FindProcess(src)
|
|
||||||
|
pid, name, absPath, err := net.FindProcess(network, srcIP, uint16(srcPort), dstIP, uint16(dstPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != net.ErrNotLocal {
|
if err != net.ErrNotLocal {
|
||||||
errors.LogError(context.Background(), "Unables to find local process name: ", err)
|
errors.LogError(context.Background(), "Unables to find local process name: ", err)
|
||||||
|
|||||||
20
common/net/find_process_android.go
Normal file
20
common/net/find_process_android.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//go:build android
|
||||||
|
|
||||||
|
package net
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/xtls/xray-core/common/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var androidProcessFinder func(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error)
|
||||||
|
|
||||||
|
func RegisterAndroidProcessFinder(f func(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error)) {
|
||||||
|
androidProcessFinder = f
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindProcess(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error) {
|
||||||
|
if androidProcessFinder != nil {
|
||||||
|
return androidProcessFinder(network, srcIP, srcPort, destIP, destPort)
|
||||||
|
}
|
||||||
|
return 0, "", "", errors.New("android process lookup must be registered before use")
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
//go:build linux
|
//go:build linux && !android
|
||||||
|
|
||||||
package net
|
package net
|
||||||
|
|
||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -13,43 +14,38 @@ import (
|
|||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FindProcess(dest Destination) (PID int, Name string, AbsolutePath string, err error) {
|
func FindProcess(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (PID int, Name string, AbsolutePath string, err error) {
|
||||||
isLocal, err := IsLocal(dest.Address.IP())
|
isLocal, err := IsLocal(net.ParseIP(srcIP))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, "", "", errors.New("failed to determine if address is local: ", err)
|
return 0, "", "", errors.New("failed to determine if address is local: ", err)
|
||||||
}
|
}
|
||||||
if !isLocal {
|
if !isLocal {
|
||||||
return 0, "", "", ErrNotLocal
|
return 0, "", "", ErrNotLocal
|
||||||
}
|
}
|
||||||
if dest.Network != Network_TCP && dest.Network != Network_UDP {
|
if network != "tcp" && network != "udp" {
|
||||||
panic("Unsupported network type for process lookup.")
|
panic("Unsupported network type for process lookup.")
|
||||||
}
|
}
|
||||||
// the core should never has a domain as source(?
|
|
||||||
if dest.Address.Family() == AddressFamilyDomain {
|
|
||||||
panic("Domain addresses are not supported for process lookup.")
|
|
||||||
}
|
|
||||||
var procFile string
|
var procFile string
|
||||||
|
|
||||||
switch dest.Network {
|
switch network {
|
||||||
case Network_TCP:
|
case "tcp":
|
||||||
if dest.Address.Family() == AddressFamilyIPv4 {
|
if net.ParseIP(srcIP).To4() != nil {
|
||||||
procFile = "/proc/net/tcp"
|
procFile = "/proc/net/tcp"
|
||||||
}
|
} else {
|
||||||
if dest.Address.Family() == AddressFamilyIPv6 {
|
|
||||||
procFile = "/proc/net/tcp6"
|
procFile = "/proc/net/tcp6"
|
||||||
}
|
}
|
||||||
case Network_UDP:
|
case "udp":
|
||||||
if dest.Address.Family() == AddressFamilyIPv4 {
|
if net.ParseIP(srcIP).To4() != nil {
|
||||||
procFile = "/proc/net/udp"
|
procFile = "/proc/net/udp"
|
||||||
}
|
} else {
|
||||||
if dest.Address.Family() == AddressFamilyIPv6 {
|
|
||||||
procFile = "/proc/net/udp6"
|
procFile = "/proc/net/udp6"
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
panic("Unsupported network type for process lookup.")
|
panic("Unsupported network type for process lookup.")
|
||||||
}
|
}
|
||||||
|
|
||||||
targetHexAddr, err := formatLittleEndianString(dest.Address, dest.Port)
|
targetHexAddr, err := formatLittleEndianString(net.ParseIP(srcIP), Port(srcPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, "", "", errors.New("failed to format address: ", err)
|
return 0, "", "", errors.New("failed to format address: ", err)
|
||||||
}
|
}
|
||||||
@@ -59,7 +55,7 @@ func FindProcess(dest Destination) (PID int, Name string, AbsolutePath string, e
|
|||||||
return 0, "", "", errors.New("could not search in ", procFile).Base(err)
|
return 0, "", "", errors.New("could not search in ", procFile).Base(err)
|
||||||
}
|
}
|
||||||
if inode == "" {
|
if inode == "" {
|
||||||
return 0, "", "", errors.New("connection for ", dest.Address, ":", dest.Port, " not found in ", procFile)
|
return 0, "", "", errors.New("connection for ", srcIP, ":", srcPort, " not found in ", procFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
pidStr, err := findPidByInode(inode)
|
pidStr, err := findPidByInode(inode)
|
||||||
@@ -86,16 +82,16 @@ func FindProcess(dest Destination) (PID int, Name string, AbsolutePath string, e
|
|||||||
return pid, procName, absPath, nil
|
return pid, procName, absPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatLittleEndianString(addr Address, port Port) (string, error) {
|
func formatLittleEndianString(addr net.IP, port Port) (string, error) {
|
||||||
ip := addr.IP()
|
ip := addr
|
||||||
var ipBytes []byte
|
var ipBytes []byte
|
||||||
if addr.Family() == AddressFamilyIPv4 {
|
if ip.To4() != nil {
|
||||||
ipBytes = ip.To4()
|
ipBytes = ip.To4()
|
||||||
} else {
|
} else {
|
||||||
ipBytes = ip.To16()
|
ipBytes = ip.To16()
|
||||||
}
|
}
|
||||||
if ipBytes == nil {
|
if ipBytes == nil {
|
||||||
return "", errors.New("invalid IP format for ", addr.Family(), ": ", ip)
|
return "", errors.New("invalid IP format for ", addr, ": ", ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, j := 0, len(ipBytes)-1; i < j; i, j = i+1, j-1 {
|
for i, j := 0, len(ipBytes)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//go:build !windows && !linux
|
//go:build !windows && !linux && !android
|
||||||
|
|
||||||
package net
|
package net
|
||||||
|
|
||||||
@@ -6,6 +6,6 @@ import (
|
|||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FindProcess(dest Destination) (int, string, string, error) {
|
func FindProcess(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error) {
|
||||||
return 0, "", "", errors.New("process lookup is not supported on this platform")
|
return 0, "", "", errors.New("process lookup is not supported on this platform")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
package net
|
package net
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -49,41 +50,37 @@ func initWin32API() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindProcess(dest Destination) (PID int, Name string, AbsolutePath string, err error) {
|
func FindProcess(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (PID int, Name string, AbsolutePath string, err error) {
|
||||||
once.Do(func() {
|
once.Do(func() {
|
||||||
initErr = initWin32API()
|
initErr = initWin32API()
|
||||||
})
|
})
|
||||||
if initErr != nil {
|
if initErr != nil {
|
||||||
return 0, "", "", initErr
|
return 0, "", "", initErr
|
||||||
}
|
}
|
||||||
isLocal, err := IsLocal(dest.Address.IP())
|
isLocal, err := IsLocal(net.ParseIP(srcIP))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, "", "", errors.New("failed to determine if address is local: ", err)
|
return 0, "", "", errors.New("failed to determine if address is local: ", err)
|
||||||
}
|
}
|
||||||
if !isLocal {
|
if !isLocal {
|
||||||
return 0, "", "", ErrNotLocal
|
return 0, "", "", ErrNotLocal
|
||||||
}
|
}
|
||||||
if dest.Network != Network_TCP && dest.Network != Network_UDP {
|
if network != "tcp" && network != "udp" {
|
||||||
panic("Unsupported network type for process lookup.")
|
panic("Unsupported network type for process lookup.")
|
||||||
}
|
}
|
||||||
// the core should never has a domain as source(?
|
|
||||||
if dest.Address.Family() == AddressFamilyDomain {
|
|
||||||
panic("Domain addresses are not supported for process lookup.")
|
|
||||||
}
|
|
||||||
var class int
|
var class int
|
||||||
var fn uintptr
|
var fn uintptr
|
||||||
switch dest.Network {
|
switch network {
|
||||||
case Network_TCP:
|
case "tcp":
|
||||||
fn = getExTCPTable
|
fn = getExTCPTable
|
||||||
class = tcpTablePidConn
|
class = tcpTablePidConn
|
||||||
case Network_UDP:
|
case "udp":
|
||||||
fn = getExUDPTable
|
fn = getExUDPTable
|
||||||
class = udpTablePid
|
class = udpTablePid
|
||||||
default:
|
default:
|
||||||
panic("Unsupported network type for process lookup.")
|
panic("Unsupported network type for process lookup.")
|
||||||
}
|
}
|
||||||
ip := dest.Address.IP()
|
ip := net.ParseIP(srcIP)
|
||||||
port := int(dest.Port)
|
port := int(srcPort)
|
||||||
|
|
||||||
addr, ok := netip.AddrFromSlice(ip)
|
addr, ok := netip.AddrFromSlice(ip)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -101,7 +98,15 @@ func FindProcess(dest Destination) (PID int, Name string, AbsolutePath string, e
|
|||||||
return 0, "", "", err
|
return 0, "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
s := newSearcher(dest.Network, dest.Address.Family())
|
networkType := Network_TCP
|
||||||
|
if network == "udp" {
|
||||||
|
networkType = Network_UDP
|
||||||
|
}
|
||||||
|
familyType := AddressFamilyIPv4
|
||||||
|
if addr.Is6() {
|
||||||
|
familyType = AddressFamilyIPv6
|
||||||
|
}
|
||||||
|
s := newSearcher(networkType, familyType)
|
||||||
|
|
||||||
pid, err := s.Search(buf, addr, uint16(port))
|
pid, err := s.Search(buf, addr, uint16(port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user