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