command.go 4.4 KB

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