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>
This commit is contained in:
Copilotand2dust authored and GitHub committed 2026-04-14 19:41:21 +08:00
1 parent 2bac664bb9
commit 4371ac2864
1 file changed
+48
+48
View File
@@ -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
})
}