command.go 4.5 KB

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