github.com/v2fly/v2ray-core/v4@v4.45.2/app/proxyman/command/command.go (about)

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