github.com/xmplusdev/xray-core@v1.8.10/app/proxyman/command/command.go (about)

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