Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions android_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ type DialerController interface {
ProtectFd(int) bool
}

// ProcessFinder is an interface for Android process finding functionality.
// Apps 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
}

func InitDns(controller DialerController, server string) {
dns.InitDns(server, func(fd uintptr) {
controller.ProtectFd(int(fd))
Expand All @@ -32,3 +47,18 @@ func RegisterListenerController(controller DialerController) {
controller.ProtectFd(int(fd))
})
}

// 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 {
c.RegisterProcessFinder(nil)
return
}

c.RegisterProcessFinder(func(network, srcIP string, srcPort int, destIP string, destPort int) int {
return finder.FindProcessByConnection(network, srcIP, srcPort, destIP, destPort)
})
}
22 changes: 22 additions & 0 deletions controller/controller_android.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
package controller

import (
"fmt"
"syscall"

corenet "github.com/xtls/xray-core/common/net"
xinternet "github.com/xtls/xray-core/transport/internet"
)

Expand All @@ -23,3 +25,23 @@ func RegisterListenerController(controller func(fd uintptr)) {
return conn.Control(controller)
})
}

// 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 func(network, srcIP string, srcPort int, destIP string, destPort int) int) {
if finder == nil {
corenet.RegisterAndroidProcessFinder(nil)
return
}

corenet.RegisterAndroidProcessFinder(func(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error) {
if destPort == 0 || destIP == "" {
return 0, "", "", fmt.Errorf("process finder: no destination for %s %s:%d", network, srcIP, srcPort)
}

uid := finder(network, srcIP, int(srcPort), destIP, int(destPort))
return uid, fmt.Sprintf("%d", uid), "", nil
})
}