github.com/EagleQL/Xray-core@v1.4.3/app/proxyman/command/command.go (about)

     1  package command
     2  
     3  import (
     4  	"context"
     5  
     6  	grpc "google.golang.org/grpc"
     7  
     8  	"github.com/xtls/xray-core/common"
     9  	"github.com/xtls/xray-core/core"
    10  	"github.com/xtls/xray-core/features/inbound"
    11  	"github.com/xtls/xray-core/features/outbound"
    12  	"github.com/xtls/xray-core/proxy"
    13  )
    14  
    15  // InboundOperation is the interface for operations that applies to inbound handlers.
    16  type InboundOperation interface {
    17  	// ApplyInbound applies this operation to the given inbound handler.
    18  	ApplyInbound(context.Context, inbound.Handler) error
    19  }
    20  
    21  // OutboundOperation is the interface for operations that applies to outbound handlers.
    22  type OutboundOperation interface {
    23  	// ApplyOutbound applies this operation to the given outbound handler.
    24  	ApplyOutbound(context.Context, outbound.Handler) error
    25  }
    26  
    27  func getInbound(handler inbound.Handler) (proxy.Inbound, error) {
    28  	gi, ok := handler.(proxy.GetInbound)
    29  	if !ok {
    30  		return nil, newError("can't get inbound proxy from handler.")
    31  	}
    32  	return gi.GetInbound(), nil
    33  }
    34  
    35  // ApplyInbound implements InboundOperation.
    36  func (op *AddUserOperation) ApplyInbound(ctx context.Context, handler inbound.Handler) error {
    37  	p, err := getInbound(handler)
    38  	if err != nil {
    39  		return err
    40  	}
    41  	um, ok := p.(proxy.UserManager)
    42  	if !ok {
    43  		return newError("proxy is not a UserManager")
    44  	}
    45  	mUser, err := op.User.ToMemoryUser()
    46  	if err != nil {
    47  		return newError("failed to parse user").Base(err)
    48  	}
    49  	return um.AddUser(ctx, mUser)
    50  }
    51  
    52  // ApplyInbound implements InboundOperation.
    53  func (op *RemoveUserOperation) ApplyInbound(ctx context.Context, handler inbound.Handler) error {
    54  	p, err := getInbound(handler)
    55  	if err != nil {
    56  		return err
    57  	}
    58  	um, ok := p.(proxy.UserManager)
    59  	if !ok {
    60  		return newError("proxy is not a UserManager")
    61  	}
    62  	return um.RemoveUser(ctx, op.Email)
    63  }
    64  
    65  type handlerServer struct {
    66  	s   *core.Instance
    67  	ihm inbound.Manager
    68  	ohm outbound.Manager
    69  }
    70  
    71  func (s *handlerServer) AddInbound(ctx context.Context, request *AddInboundRequest) (*AddInboundResponse, error) {
    72  	if err := core.AddInboundHandler(s.s, request.Inbound); err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	return &AddInboundResponse{}, nil
    77  }
    78  
    79  func (s *handlerServer) RemoveInbound(ctx context.Context, request *RemoveInboundRequest) (*RemoveInboundResponse, error) {
    80  	return &RemoveInboundResponse{}, s.ihm.RemoveHandler(ctx, request.Tag)
    81  }
    82  
    83  func (s *handlerServer) AlterInbound(ctx context.Context, request *AlterInboundRequest) (*AlterInboundResponse, error) {
    84  	rawOperation, err := request.Operation.GetInstance()
    85  	if err != nil {
    86  		return nil, newError("unknown operation").Base(err)
    87  	}
    88  	operation, ok := rawOperation.(InboundOperation)
    89  	if !ok {
    90  		return nil, newError("not an inbound operation")
    91  	}
    92  
    93  	handler, err := s.ihm.GetHandler(ctx, request.Tag)
    94  	if err != nil {
    95  		return nil, newError("failed to get handler: ", request.Tag).Base(err)
    96  	}
    97  
    98  	return &AlterInboundResponse{}, operation.ApplyInbound(ctx, handler)
    99  }
   100  
   101  func (s *handlerServer) AddOutbound(ctx context.Context, request *AddOutboundRequest) (*AddOutboundResponse, error) {
   102  	if err := core.AddOutboundHandler(s.s, request.Outbound); err != nil {
   103  		return nil, err
   104  	}
   105  	return &AddOutboundResponse{}, nil
   106  }
   107  
   108  func (s *handlerServer) RemoveOutbound(ctx context.Context, request *RemoveOutboundRequest) (*RemoveOutboundResponse, error) {
   109  	return &RemoveOutboundResponse{}, s.ohm.RemoveHandler(ctx, request.Tag)
   110  }
   111  
   112  func (s *handlerServer) AlterOutbound(ctx context.Context, request *AlterOutboundRequest) (*AlterOutboundResponse, error) {
   113  	rawOperation, err := request.Operation.GetInstance()
   114  	if err != nil {
   115  		return nil, newError("unknown operation").Base(err)
   116  	}
   117  	operation, ok := rawOperation.(OutboundOperation)
   118  	if !ok {
   119  		return nil, newError("not an outbound operation")
   120  	}
   121  
   122  	handler := s.ohm.GetHandler(request.Tag)
   123  	return &AlterOutboundResponse{}, operation.ApplyOutbound(ctx, handler)
   124  }
   125  
   126  func (s *handlerServer) mustEmbedUnimplementedHandlerServiceServer() {}
   127  
   128  type service struct {
   129  	v *core.Instance
   130  }
   131  
   132  func (s *service) Register(server *grpc.Server) {
   133  	hs := &handlerServer{
   134  		s: s.v,
   135  	}
   136  	common.Must(s.v.RequireFeatures(func(im inbound.Manager, om outbound.Manager) {
   137  		hs.ihm = im
   138  		hs.ohm = om
   139  	}))
   140  	RegisterHandlerServiceServer(server, hs)
   141  
   142  	// For compatibility purposes
   143  	vCoreDesc := HandlerService_ServiceDesc
   144  	vCoreDesc.ServiceName = "v2ray.core.app.proxyman.command.HandlerService"
   145  	server.RegisterService(&vCoreDesc, hs)
   146  }
   147  
   148  func init() {
   149  	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {
   150  		s := core.MustFromContext(ctx)
   151  		return &service{v: s}, nil
   152  	}))
   153  }