From 4371ac28643114042cf2499a61d381bf3d6bee75 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 19:41:21 +0800 Subject: [PATCH] Add Android process finder interface for per-app routing (#182) * Initial plan * Add Android process finder interface for per-app routing Agent-Logs-Url: https://github.com/2dust/AndroidLibXrayLite/sessions/319cba61-5c38-403c-bec5-3f01d1fd70c2 Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com> * Update README.md * Add panic recovery to Android process finder callback Change the registered Android process finder callback to use named return values and add a defer/recover block that converts panics into a formatted error. This prevents panics in the Finder implementation from propagating into corenet and improves robustness while preserving the existing "process not found" error behavior. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com> --- android_process_finder.go | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 android_process_finder.go diff --git a/android_process_finder.go b/android_process_finder.go new file mode 100644 index 0000000..3943547 --- /dev/null +++ b/android_process_finder.go @@ -0,0 +1,48 @@ +//go:build android + +package libv2ray + +import ( + "fmt" + + corenet "github.com/xtls/xray-core/common/net" +) + +// ProcessFinder is an interface for Android process finding functionality. +// Apps using AndroidLibXrayLite should implement FindProcessByConnection() +// and pass the implementation to RegisterProcessFinder() before starting the core. +type ProcessFinder interface { + // FindProcessByConnection finds the UID of the process that owns the given connection. + // + // network: Protocol type: "tcp" or "udp" + // srcIP: Source IP address + // srcPort: Source port + // destIP: Destination IP address + // destPort: Destination port + // Returns the UID of the owning process, or -1 if not found. + FindProcessByConnection(network, srcIP string, srcPort int, destIP string, destPort int) int +} + +// RegisterProcessFinder registers an Android process finder with Xray-core, +// enabling per-app routing based on UID. Must be called before starting the +// core for process-based routing rules to work. +// Pass nil to unregister a previously registered finder. +func RegisterProcessFinder(finder ProcessFinder) { + if finder == nil { + corenet.RegisterAndroidProcessFinder(nil) + return + } + + corenet.RegisterAndroidProcessFinder(func(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (uid int, name string, path string, err error) { + defer func() { + if r := recover(); r != nil { + uid, name, path, err = 0, "", "", fmt.Errorf("process finder panic: %v", r) + } + }() + uid = finder.FindProcessByConnection(network, srcIP, int(srcPort), destIP, int(destPort)) + if uid < 0 { + return 0, "", "", fmt.Errorf("process not found for %s %s:%d -> %s:%d", network, srcIP, srcPort, destIP, destPort) + } + return uid, fmt.Sprintf("%d", uid), "", nil + }) +}