platform: Improve interface
This commit is contained in:
@@ -62,6 +62,16 @@ type LogIterator interface {
|
||||
Next() *LogEntry
|
||||
}
|
||||
|
||||
type XPCDialer interface {
|
||||
DialXPC() (int32, error)
|
||||
}
|
||||
|
||||
var sXPCDialer XPCDialer
|
||||
|
||||
func SetXPCDialer(dialer XPCDialer) {
|
||||
sXPCDialer = dialer
|
||||
}
|
||||
|
||||
func NewStandaloneCommandClient() *CommandClient {
|
||||
return new(CommandClient)
|
||||
}
|
||||
@@ -117,13 +127,113 @@ func (c *CommandClient) Connect() error {
|
||||
c.clientMutex.Lock()
|
||||
common.Close(common.PtrOrNil(c.grpcConn))
|
||||
|
||||
conn, err := c.grpcDial()
|
||||
if sXPCDialer != nil {
|
||||
fd, err := sXPCDialer.DialXPC()
|
||||
if err != nil {
|
||||
c.clientMutex.Unlock()
|
||||
return err
|
||||
}
|
||||
file := os.NewFile(uintptr(fd), "xpc-command-socket")
|
||||
if file == nil {
|
||||
c.clientMutex.Unlock()
|
||||
return E.New("invalid file descriptor")
|
||||
}
|
||||
netConn, err := net.FileConn(file)
|
||||
if err != nil {
|
||||
file.Close()
|
||||
c.clientMutex.Unlock()
|
||||
return E.Cause(err, "create connection from fd")
|
||||
}
|
||||
file.Close()
|
||||
|
||||
clientOptions := []grpc.DialOption{
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) {
|
||||
return netConn, nil
|
||||
}),
|
||||
grpc.WithUnaryInterceptor(unaryClientAuthInterceptor),
|
||||
grpc.WithStreamInterceptor(streamClientAuthInterceptor),
|
||||
}
|
||||
|
||||
grpcConn, err := grpc.NewClient("passthrough:///xpc", clientOptions...)
|
||||
if err != nil {
|
||||
netConn.Close()
|
||||
c.clientMutex.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
c.grpcConn = grpcConn
|
||||
c.grpcClient = daemon.NewStartedServiceClient(grpcConn)
|
||||
c.ctx, c.cancel = context.WithCancel(context.Background())
|
||||
c.clientMutex.Unlock()
|
||||
} else {
|
||||
conn, err := c.grpcDial()
|
||||
if err != nil {
|
||||
c.clientMutex.Unlock()
|
||||
return err
|
||||
}
|
||||
c.grpcConn = conn
|
||||
c.grpcClient = daemon.NewStartedServiceClient(conn)
|
||||
c.ctx, c.cancel = context.WithCancel(context.Background())
|
||||
c.clientMutex.Unlock()
|
||||
}
|
||||
|
||||
c.handler.Connected()
|
||||
for _, command := range c.options.commands {
|
||||
switch command {
|
||||
case CommandLog:
|
||||
go c.handleLogStream()
|
||||
case CommandStatus:
|
||||
go c.handleStatusStream()
|
||||
case CommandGroup:
|
||||
go c.handleGroupStream()
|
||||
case CommandClashMode:
|
||||
go c.handleClashModeStream()
|
||||
case CommandConnections:
|
||||
go c.handleConnectionsStream()
|
||||
default:
|
||||
return E.New("unknown command: ", command)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CommandClient) ConnectWithFD(fd int32) error {
|
||||
c.clientMutex.Lock()
|
||||
common.Close(common.PtrOrNil(c.grpcConn))
|
||||
|
||||
file := os.NewFile(uintptr(fd), "xpc-command-socket")
|
||||
if file == nil {
|
||||
c.clientMutex.Unlock()
|
||||
return E.New("invalid file descriptor")
|
||||
}
|
||||
|
||||
netConn, err := net.FileConn(file)
|
||||
if err != nil {
|
||||
file.Close()
|
||||
c.clientMutex.Unlock()
|
||||
return E.Cause(err, "create connection from fd")
|
||||
}
|
||||
file.Close()
|
||||
|
||||
clientOptions := []grpc.DialOption{
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) {
|
||||
return netConn, nil
|
||||
}),
|
||||
grpc.WithUnaryInterceptor(unaryClientAuthInterceptor),
|
||||
grpc.WithStreamInterceptor(streamClientAuthInterceptor),
|
||||
}
|
||||
|
||||
grpcConn, err := grpc.NewClient("passthrough:///xpc", clientOptions...)
|
||||
if err != nil {
|
||||
netConn.Close()
|
||||
c.clientMutex.Unlock()
|
||||
return err
|
||||
}
|
||||
c.grpcConn = conn
|
||||
c.grpcClient = daemon.NewStartedServiceClient(conn)
|
||||
|
||||
c.grpcConn = grpcConn
|
||||
c.grpcClient = daemon.NewStartedServiceClient(grpcConn)
|
||||
c.ctx, c.cancel = context.WithCancel(context.Background())
|
||||
c.clientMutex.Unlock()
|
||||
|
||||
@@ -171,6 +281,45 @@ func (c *CommandClient) getClientForCall() (daemon.StartedServiceClient, error)
|
||||
return c.grpcClient, nil
|
||||
}
|
||||
|
||||
if sXPCDialer != nil {
|
||||
fd, err := sXPCDialer.DialXPC()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
file := os.NewFile(uintptr(fd), "xpc-command-socket")
|
||||
if file == nil {
|
||||
return nil, E.New("invalid file descriptor")
|
||||
}
|
||||
netConn, err := net.FileConn(file)
|
||||
if err != nil {
|
||||
file.Close()
|
||||
return nil, E.Cause(err, "create connection from fd")
|
||||
}
|
||||
file.Close()
|
||||
|
||||
clientOptions := []grpc.DialOption{
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) {
|
||||
return netConn, nil
|
||||
}),
|
||||
grpc.WithUnaryInterceptor(unaryClientAuthInterceptor),
|
||||
grpc.WithStreamInterceptor(streamClientAuthInterceptor),
|
||||
}
|
||||
|
||||
grpcConn, err := grpc.NewClient("passthrough:///xpc", clientOptions...)
|
||||
if err != nil {
|
||||
netConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.grpcConn = grpcConn
|
||||
c.grpcClient = daemon.NewStartedServiceClient(grpcConn)
|
||||
if c.ctx == nil {
|
||||
c.ctx, c.cancel = context.WithCancel(context.Background())
|
||||
}
|
||||
return c.grpcClient, nil
|
||||
}
|
||||
|
||||
conn, err := c.grpcDial()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -195,6 +195,14 @@ func (s *CommandServer) NeedWIFIState() bool {
|
||||
return instance.Box().Network().NeedWIFIState()
|
||||
}
|
||||
|
||||
func (s *CommandServer) NeedFindProcess() bool {
|
||||
instance := s.StartedService.Instance()
|
||||
if instance == nil || instance.Box() == nil {
|
||||
return false
|
||||
}
|
||||
return instance.Box().Router().NeedFindProcess()
|
||||
}
|
||||
|
||||
func (s *CommandServer) Pause() {
|
||||
instance := s.StartedService.Instance()
|
||||
if instance == nil || instance.PauseManager() == nil {
|
||||
|
||||
@@ -11,9 +11,7 @@ type PlatformInterface interface {
|
||||
AutoDetectInterfaceControl(fd int32) error
|
||||
OpenTun(options TunOptions) (int32, error)
|
||||
UseProcFS() bool
|
||||
FindConnectionOwner(ipProtocol int32, sourceAddress string, sourcePort int32, destinationAddress string, destinationPort int32) (int32, error)
|
||||
PackageNameByUid(uid int32) (string, error)
|
||||
UIDByPackageName(packageName string) (int32, error)
|
||||
FindConnectionOwner(ipProtocol int32, sourceAddress string, sourcePort int32, destinationAddress string, destinationPort int32) (*ConnectionOwner, error)
|
||||
StartDefaultInterfaceMonitor(listener InterfaceUpdateListener) error
|
||||
CloseDefaultInterfaceMonitor(listener InterfaceUpdateListener) error
|
||||
GetInterfaces() (NetworkInterfaceIterator, error)
|
||||
@@ -25,6 +23,13 @@ type PlatformInterface interface {
|
||||
SendNotification(notification *Notification) error
|
||||
}
|
||||
|
||||
type ConnectionOwner struct {
|
||||
UserId int32
|
||||
UserName string
|
||||
ProcessPath string
|
||||
AndroidPackageName string
|
||||
}
|
||||
|
||||
type InterfaceUpdateListener interface {
|
||||
UpdateDefaultInterface(interfaceName string, interfaceIndex int32, isExpensive bool, isConstrained bool)
|
||||
}
|
||||
|
||||
@@ -166,7 +166,6 @@ func (w *platformInterfaceWrapper) UsePlatformConnectionOwnerFinder() bool {
|
||||
}
|
||||
|
||||
func (w *platformInterfaceWrapper) FindConnectionOwner(request *adapter.FindConnectionOwnerRequest) (*adapter.ConnectionOwner, error) {
|
||||
var uid int32
|
||||
if w.useProcFS {
|
||||
var source netip.AddrPort
|
||||
var destination netip.AddrPort
|
||||
@@ -185,21 +184,24 @@ func (w *platformInterfaceWrapper) FindConnectionOwner(request *adapter.FindConn
|
||||
return nil, E.New("unknown protocol: ", request.IpProtocol)
|
||||
}
|
||||
|
||||
uid = procfs.ResolveSocketByProcSearch(network, source, destination)
|
||||
uid := procfs.ResolveSocketByProcSearch(network, source, destination)
|
||||
if uid == -1 {
|
||||
return nil, E.New("procfs: not found")
|
||||
}
|
||||
} else {
|
||||
var err error
|
||||
uid, err = w.iif.FindConnectionOwner(request.IpProtocol, request.SourceAddress, request.SourcePort, request.DestinationAddress, request.DestinationPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &adapter.ConnectionOwner{
|
||||
UserId: uid,
|
||||
}, nil
|
||||
}
|
||||
|
||||
result, err := w.iif.FindConnectionOwner(request.IpProtocol, request.SourceAddress, request.SourcePort, request.DestinationAddress, request.DestinationPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
packageName, _ := w.iif.PackageNameByUid(uid)
|
||||
return &adapter.ConnectionOwner{
|
||||
UserId: uid,
|
||||
AndroidPackageName: packageName,
|
||||
UserId: result.UserId,
|
||||
UserName: result.UserName,
|
||||
ProcessPath: result.ProcessPath,
|
||||
AndroidPackageName: result.AndroidPackageName,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user