Skip to content

Commit f27edc3

Browse files
Routing: process supports UID on Android (#5915)
Example: #5915 (comment) --------- Co-authored-by: 风扇滑翔翼 <Fangliding.fshxy@outlook.com>
1 parent c93478b commit f27edc3

5 files changed

Lines changed: 70 additions & 43 deletions

File tree

app/router/condition.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,10 @@ func (m *ProcessNameMatcher) Apply(ctx routing.Context) bool {
390390
if len(ctx.GetSourceIPs()) == 0 {
391391
return false
392392
}
393-
srcPort := ctx.GetSourcePort().String()
393+
394+
srcPort := uint16(ctx.GetSourcePort())
394395
srcIP := ctx.GetSourceIPs()[0].String()
396+
395397
var network string
396398
switch ctx.GetNetwork() {
397399
case net.Network_TCP:
@@ -401,11 +403,15 @@ func (m *ProcessNameMatcher) Apply(ctx routing.Context) bool {
401403
default:
402404
return false
403405
}
404-
src, err := net.ParseDestination(strings.Join([]string{network, srcIP, srcPort}, ":"))
405-
if err != nil {
406-
return false
406+
407+
var dstIP string
408+
var dstPort uint16 = 0
409+
if len(ctx.GetTargetIPs()) > 0 {
410+
dstIP = ctx.GetTargetIPs()[0].String()
411+
dstPort = uint16(ctx.GetTargetPort())
407412
}
408-
pid, name, absPath, err := net.FindProcess(src)
413+
414+
pid, name, absPath, err := net.FindProcess(network, srcIP, uint16(srcPort), dstIP, uint16(dstPort))
409415
if err != nil {
410416
if err != net.ErrNotLocal {
411417
errors.LogError(context.Background(), "Unables to find local process name: ", err)

common/net/find_process_android.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//go:build android
2+
3+
package net
4+
5+
import (
6+
"github.com/xtls/xray-core/common/errors"
7+
)
8+
9+
var androidProcessFinder func(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error)
10+
11+
func RegisterAndroidProcessFinder(f func(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error)) {
12+
androidProcessFinder = f
13+
}
14+
15+
func FindProcess(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error) {
16+
if androidProcessFinder != nil {
17+
return androidProcessFinder(network, srcIP, srcPort, destIP, destPort)
18+
}
19+
return 0, "", "", errors.New("android process lookup must be registered before use")
20+
}

common/net/find_process_linux.go

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,51 @@
1-
//go:build linux
1+
//go:build linux && !android
22

33
package net
44

55
import (
66
"bufio"
77
"encoding/hex"
88
"fmt"
9+
"net"
910
"os"
1011
"strconv"
1112
"strings"
1213

1314
"github.com/xtls/xray-core/common/errors"
1415
)
1516

16-
func FindProcess(dest Destination) (PID int, Name string, AbsolutePath string, err error) {
17-
isLocal, err := IsLocal(dest.Address.IP())
17+
func FindProcess(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (PID int, Name string, AbsolutePath string, err error) {
18+
isLocal, err := IsLocal(net.ParseIP(srcIP))
1819
if err != nil {
1920
return 0, "", "", errors.New("failed to determine if address is local: ", err)
2021
}
2122
if !isLocal {
2223
return 0, "", "", ErrNotLocal
2324
}
24-
if dest.Network != Network_TCP && dest.Network != Network_UDP {
25+
if network != "tcp" && network != "udp" {
2526
panic("Unsupported network type for process lookup.")
2627
}
27-
// the core should never has a domain as source(?
28-
if dest.Address.Family() == AddressFamilyDomain {
29-
panic("Domain addresses are not supported for process lookup.")
30-
}
28+
3129
var procFile string
3230

33-
switch dest.Network {
34-
case Network_TCP:
35-
if dest.Address.Family() == AddressFamilyIPv4 {
31+
switch network {
32+
case "tcp":
33+
if net.ParseIP(srcIP).To4() != nil {
3634
procFile = "/proc/net/tcp"
37-
}
38-
if dest.Address.Family() == AddressFamilyIPv6 {
35+
} else {
3936
procFile = "/proc/net/tcp6"
4037
}
41-
case Network_UDP:
42-
if dest.Address.Family() == AddressFamilyIPv4 {
38+
case "udp":
39+
if net.ParseIP(srcIP).To4() != nil {
4340
procFile = "/proc/net/udp"
44-
}
45-
if dest.Address.Family() == AddressFamilyIPv6 {
41+
} else {
4642
procFile = "/proc/net/udp6"
4743
}
4844
default:
4945
panic("Unsupported network type for process lookup.")
5046
}
5147

52-
targetHexAddr, err := formatLittleEndianString(dest.Address, dest.Port)
48+
targetHexAddr, err := formatLittleEndianString(net.ParseIP(srcIP), Port(srcPort))
5349
if err != nil {
5450
return 0, "", "", errors.New("failed to format address: ", err)
5551
}
@@ -59,7 +55,7 @@ func FindProcess(dest Destination) (PID int, Name string, AbsolutePath string, e
5955
return 0, "", "", errors.New("could not search in ", procFile).Base(err)
6056
}
6157
if inode == "" {
62-
return 0, "", "", errors.New("connection for ", dest.Address, ":", dest.Port, " not found in ", procFile)
58+
return 0, "", "", errors.New("connection for ", srcIP, ":", srcPort, " not found in ", procFile)
6359
}
6460

6561
pidStr, err := findPidByInode(inode)
@@ -86,16 +82,16 @@ func FindProcess(dest Destination) (PID int, Name string, AbsolutePath string, e
8682
return pid, procName, absPath, nil
8783
}
8884

89-
func formatLittleEndianString(addr Address, port Port) (string, error) {
90-
ip := addr.IP()
85+
func formatLittleEndianString(addr net.IP, port Port) (string, error) {
86+
ip := addr
9187
var ipBytes []byte
92-
if addr.Family() == AddressFamilyIPv4 {
88+
if ip.To4() != nil {
9389
ipBytes = ip.To4()
9490
} else {
9591
ipBytes = ip.To16()
9692
}
9793
if ipBytes == nil {
98-
return "", errors.New("invalid IP format for ", addr.Family(), ": ", ip)
94+
return "", errors.New("invalid IP format for ", addr, ": ", ip)
9995
}
10096

10197
for i, j := 0, len(ipBytes)-1; i < j; i, j = i+1, j-1 {

common/net/find_process_others.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
//go:build !windows && !linux
1+
//go:build !windows && !linux && !android
22

33
package net
44

55
import (
66
"github.com/xtls/xray-core/common/errors"
77
)
88

9-
func FindProcess(dest Destination) (int, string, string, error) {
9+
func FindProcess(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error) {
1010
return 0, "", "", errors.New("process lookup is not supported on this platform")
1111
}

common/net/find_process_windows.go

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package net
44

55
import (
6+
"net"
67
"net/netip"
78
"path/filepath"
89
"strings"
@@ -49,41 +50,37 @@ func initWin32API() error {
4950
return nil
5051
}
5152

52-
func FindProcess(dest Destination) (PID int, Name string, AbsolutePath string, err error) {
53+
func FindProcess(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (PID int, Name string, AbsolutePath string, err error) {
5354
once.Do(func() {
5455
initErr = initWin32API()
5556
})
5657
if initErr != nil {
5758
return 0, "", "", initErr
5859
}
59-
isLocal, err := IsLocal(dest.Address.IP())
60+
isLocal, err := IsLocal(net.ParseIP(srcIP))
6061
if err != nil {
6162
return 0, "", "", errors.New("failed to determine if address is local: ", err)
6263
}
6364
if !isLocal {
6465
return 0, "", "", ErrNotLocal
6566
}
66-
if dest.Network != Network_TCP && dest.Network != Network_UDP {
67+
if network != "tcp" && network != "udp" {
6768
panic("Unsupported network type for process lookup.")
6869
}
69-
// the core should never has a domain as source(?
70-
if dest.Address.Family() == AddressFamilyDomain {
71-
panic("Domain addresses are not supported for process lookup.")
72-
}
7370
var class int
7471
var fn uintptr
75-
switch dest.Network {
76-
case Network_TCP:
72+
switch network {
73+
case "tcp":
7774
fn = getExTCPTable
7875
class = tcpTablePidConn
79-
case Network_UDP:
76+
case "udp":
8077
fn = getExUDPTable
8178
class = udpTablePid
8279
default:
8380
panic("Unsupported network type for process lookup.")
8481
}
85-
ip := dest.Address.IP()
86-
port := int(dest.Port)
82+
ip := net.ParseIP(srcIP)
83+
port := int(srcPort)
8784

8885
addr, ok := netip.AddrFromSlice(ip)
8986
if !ok {
@@ -101,7 +98,15 @@ func FindProcess(dest Destination) (PID int, Name string, AbsolutePath string, e
10198
return 0, "", "", err
10299
}
103100

104-
s := newSearcher(dest.Network, dest.Address.Family())
101+
networkType := Network_TCP
102+
if network == "udp" {
103+
networkType = Network_UDP
104+
}
105+
familyType := AddressFamilyIPv4
106+
if addr.Is6() {
107+
familyType = AddressFamilyIPv6
108+
}
109+
s := newSearcher(networkType, familyType)
105110

106111
pid, err := s.Search(buf, addr, uint16(port))
107112
if err != nil {

0 commit comments

Comments
 (0)