Skip to content

Commit 2acaebd

Browse files
committed
More Process
1 parent b38a412 commit 2acaebd

File tree

8 files changed

+173
-137
lines changed

8 files changed

+173
-137
lines changed

app/router/condition.go

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package router
33
import (
44
"context"
55
"os"
6+
"path/filepath"
67
"regexp"
8+
"slices"
79
"strings"
810

911
"github.com/xtls/xray-core/common/errors"
@@ -308,7 +310,41 @@ func (m *AttributeMatcher) Apply(ctx routing.Context) bool {
308310
}
309311

310312
type ProcessNameMatcher struct {
311-
names []string
313+
ProcessNames []string
314+
AbsPaths []string
315+
Folders []string
316+
MatchXraySelf bool
317+
}
318+
319+
func NewProcessNameMatcher(names []string) *ProcessNameMatcher {
320+
processNames := []string{}
321+
folders := []string{}
322+
absPaths := []string{}
323+
matchXraySelf := false
324+
for _, name := range names {
325+
if name == "self/" {
326+
matchXraySelf = true
327+
}
328+
name := filepath.ToSlash(name)
329+
// /usr/bin/
330+
if strings.HasSuffix(name, "/") {
331+
folders = append(folders, name)
332+
continue
333+
}
334+
// /usr/bin/curl
335+
if strings.Contains(name, "/") {
336+
absPaths = append(absPaths, name)
337+
continue
338+
}
339+
// curl.exe or curl
340+
processNames = append(processNames, strings.TrimSuffix(name, ".exe"))
341+
}
342+
return &ProcessNameMatcher{
343+
ProcessNames: processNames,
344+
AbsPaths: absPaths,
345+
Folders: folders,
346+
MatchXraySelf: matchXraySelf,
347+
}
312348
}
313349

314350
func (m *ProcessNameMatcher) Apply(ctx routing.Context) bool {
@@ -327,18 +363,26 @@ func (m *ProcessNameMatcher) Apply(ctx routing.Context) bool {
327363
if err != nil {
328364
return false
329365
}
330-
pid, name, err := net.FindProcess(src)
366+
pid, name, absPath, err := net.FindProcess(src)
331367
if err != nil {
332368
if err != net.ErrNotLocal {
333369
errors.LogError(context.Background(), "Unables to find local process name: ", err)
334370
}
335371
return false
336372
}
337-
for _, n := range m.names {
338-
if name == "/self" && pid == os.Getpid() {
373+
if m.MatchXraySelf {
374+
if pid == os.Getpid() {
339375
return true
340376
}
341-
if n == name {
377+
}
378+
if slices.Contains(m.ProcessNames, name) {
379+
return true
380+
}
381+
if slices.Contains(m.AbsPaths, absPath) {
382+
return true
383+
}
384+
for _, f := range m.Folders {
385+
if strings.HasPrefix(absPath, f) {
342386
return true
343387
}
344388
}

app/router/config.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,8 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
106106
conds.Add(matcher)
107107
}
108108

109-
if len(rr.ProcessName) > 0 {
110-
refinedNames := make([]string, 0, len(rr.ProcessName))
111-
for _, name := range rr.ProcessName {
112-
refinedNames = append(refinedNames, strings.TrimSuffix(name, ".exe"))
113-
}
114-
conds.Add(&ProcessNameMatcher{refinedNames})
109+
if len(rr.Process) > 0 {
110+
conds.Add(NewProcessNameMatcher(rr.Process))
115111
}
116112

117113
if conds.Len() == 0 {

app/router/config.pb.go

Lines changed: 66 additions & 66 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/router/config.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ message RoutingRule {
113113
xray.common.net.PortList local_port_list = 18;
114114

115115
xray.common.net.PortList vless_route_list = 20;
116-
repeated string process_name = 21;
116+
repeated string process = 21;
117117
}
118118

119119
message BalancingRule {

common/net/find_process_linux.go

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import (
1313
"github.com/xtls/xray-core/common/errors"
1414
)
1515

16-
func FindProcess(dest Destination) (int, string, error) {
16+
func FindProcess(dest Destination) (PID int, Name string, AbsolutePath string, err error) {
1717
isLocal, err := IsLocal(dest.Address.IP())
1818
if err != nil {
19-
return 0, "", errors.New("failed to determine if address is local: ", err)
19+
return 0, "", "", errors.New("failed to determine if address is local: ", err)
2020
}
2121
if !isLocal {
22-
return 0, "", ErrNotLocal
22+
return 0, "", "", ErrNotLocal
2323
}
2424
if dest.Network != Network_TCP && dest.Network != Network_UDP {
2525
panic("Unsupported network type for process lookup.")
@@ -51,36 +51,39 @@ func FindProcess(dest Destination) (int, string, error) {
5151

5252
targetHexAddr, err := formatLittleEndianString(dest.Address, dest.Port)
5353
if err != nil {
54-
return 0, "", errors.New("failed to format address: ", err)
54+
return 0, "", "", errors.New("failed to format address: ", err)
5555
}
5656

5757
inode, err := findInodeInFile(procFile, targetHexAddr)
5858
if err != nil {
59-
return 0, "", errors.New("could not search in ", procFile).Base(err)
59+
return 0, "", "", errors.New("could not search in ", procFile).Base(err)
6060
}
6161
if inode == "" {
62-
return 0, "", errors.New("connection for ", dest.Address, ":", dest.Port, " not found in ", procFile)
62+
return 0, "", "", errors.New("connection for ", dest.Address, ":", dest.Port, " not found in ", procFile)
6363
}
6464

6565
pidStr, err := findPidByInode(inode)
6666
if err != nil {
67-
return 0, "", errors.New("could not find PID for inode ", inode, ": ", err)
67+
return 0, "", "", errors.New("could not find PID for inode ", inode, ": ", err)
6868
}
6969
if pidStr == "" {
70-
return 0, "", errors.New("no process found for inode ", inode)
70+
return 0, "", "", errors.New("no process found for inode ", inode)
7171
}
7272

73-
procName, err := getProcessName(pidStr)
73+
absPath, err := getAbsPath(pidStr)
7474
if err != nil {
75-
return 0, "", fmt.Errorf("could not get process name for PID %s: %w", pidStr, err)
75+
return 0, "", "", errors.New("could not get process name for PID ", pidStr, ":", err)
7676
}
7777

78+
nameSplit := strings.Split(absPath, "/")
79+
procName := nameSplit[len(nameSplit)-1]
80+
7881
pid, err := strconv.Atoi(pidStr)
7982
if err != nil {
80-
return 0, "", errors.New("failed to parse PID: ", err)
83+
return 0, "", "", errors.New("failed to parse PID: ", err)
8184
}
8285

83-
return pid, procName, nil
86+
return pid, procName, absPath, nil
8487
}
8588

8689
func formatLittleEndianString(addr Address, port Port) (string, error) {
@@ -167,12 +170,7 @@ func findPidByInode(inode string) (string, error) {
167170
return "", nil
168171
}
169172

170-
func getProcessName(pid string) (string, error) {
171-
path := fmt.Sprintf("/proc/%s/comm", pid)
172-
content, err := os.ReadFile(path)
173-
if err != nil {
174-
return "", err
175-
}
176-
// remove trailing \n
177-
return strings.TrimSpace(string(content)), nil
173+
func getAbsPath(pid string) (string, error) {
174+
path := fmt.Sprintf("/proc/%s/exe", pid)
175+
return os.Readlink(path)
178176
}

common/net/find_process_others.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ import (
66
"github.com/xtls/xray-core/common/errors"
77
)
88

9-
func FindProcess(dest Destination) (int, string, error) {
10-
return 0, "", errors.New("process lookup is not supported on this platform")
9+
func FindProcess(dest Destination) (int, string, string, error) {
10+
return 0, "", "", errors.New("process lookup is not supported on this platform")
1111
}

0 commit comments

Comments
 (0)