shadowsocks_multi.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package inbound
  2. import (
  3. "context"
  4. "net"
  5. "os"
  6. "time"
  7. "github.com/sagernet/sing-box/adapter"
  8. "github.com/sagernet/sing-box/common/mux"
  9. "github.com/sagernet/sing-box/common/uot"
  10. C "github.com/sagernet/sing-box/constant"
  11. "github.com/sagernet/sing-box/log"
  12. "github.com/sagernet/sing-box/option"
  13. "github.com/sagernet/sing-shadowsocks"
  14. "github.com/sagernet/sing-shadowsocks/shadowaead"
  15. "github.com/sagernet/sing-shadowsocks/shadowaead_2022"
  16. "github.com/sagernet/sing/common"
  17. "github.com/sagernet/sing/common/auth"
  18. "github.com/sagernet/sing/common/buf"
  19. E "github.com/sagernet/sing/common/exceptions"
  20. F "github.com/sagernet/sing/common/format"
  21. M "github.com/sagernet/sing/common/metadata"
  22. N "github.com/sagernet/sing/common/network"
  23. "github.com/sagernet/sing/common/ntp"
  24. )
  25. var (
  26. _ adapter.Inbound = (*ShadowsocksMulti)(nil)
  27. _ adapter.TCPInjectableInbound = (*ShadowsocksMulti)(nil)
  28. )
  29. type ShadowsocksMulti struct {
  30. myInboundAdapter
  31. service shadowsocks.MultiService[int]
  32. users []option.ShadowsocksUser
  33. }
  34. func newShadowsocksMulti(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksInboundOptions) (*ShadowsocksMulti, error) {
  35. inbound := &ShadowsocksMulti{
  36. myInboundAdapter: myInboundAdapter{
  37. protocol: C.TypeShadowsocks,
  38. network: options.Network.Build(),
  39. ctx: ctx,
  40. router: uot.NewRouter(router, logger),
  41. logger: logger,
  42. tag: tag,
  43. listenOptions: options.ListenOptions,
  44. },
  45. }
  46. inbound.connHandler = inbound
  47. inbound.packetHandler = inbound
  48. var err error
  49. inbound.router, err = mux.NewRouterWithOptions(inbound.router, logger, common.PtrValueOrDefault(options.Multiplex))
  50. if err != nil {
  51. return nil, err
  52. }
  53. var udpTimeout time.Duration
  54. if options.UDPTimeout != 0 {
  55. udpTimeout = time.Duration(options.UDPTimeout)
  56. } else {
  57. udpTimeout = C.UDPTimeout
  58. }
  59. var service shadowsocks.MultiService[int]
  60. if common.Contains(shadowaead_2022.List, options.Method) {
  61. service, err = shadowaead_2022.NewMultiServiceWithPassword[int](
  62. options.Method,
  63. options.Password,
  64. int64(udpTimeout.Seconds()),
  65. adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound),
  66. ntp.TimeFuncFromContext(ctx),
  67. )
  68. } else if common.Contains(shadowaead.List, options.Method) {
  69. service, err = shadowaead.NewMultiService[int](
  70. options.Method,
  71. int64(udpTimeout.Seconds()),
  72. adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound),
  73. )
  74. } else {
  75. return nil, E.New("unsupported method: " + options.Method)
  76. }
  77. if err != nil {
  78. return nil, err
  79. }
  80. err = service.UpdateUsersWithPasswords(common.MapIndexed(options.Users, func(index int, user option.ShadowsocksUser) int {
  81. return index
  82. }), common.Map(options.Users, func(user option.ShadowsocksUser) string {
  83. return user.Password
  84. }))
  85. if err != nil {
  86. return nil, err
  87. }
  88. inbound.service = service
  89. inbound.packetUpstream = service
  90. inbound.users = options.Users
  91. return inbound, err
  92. }
  93. func (h *ShadowsocksMulti) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
  94. err := h.service.NewConnection(ctx, conn, adapter.UpstreamMetadata(metadata))
  95. N.CloseOnHandshakeFailure(conn, onClose, err)
  96. if err != nil {
  97. h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
  98. }
  99. }
  100. func (h *ShadowsocksMulti) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
  101. err := h.service.NewPacket(h.ctx, h.packetConn(), buffer, M.Metadata{Source: source})
  102. if err != nil {
  103. h.logger.Error(E.Cause(err, "process packet from ", source))
  104. }
  105. }
  106. func (h *ShadowsocksMulti) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  107. userIndex, loaded := auth.UserFromContext[int](ctx)
  108. if !loaded {
  109. return os.ErrInvalid
  110. }
  111. user := h.users[userIndex].Name
  112. if user == "" {
  113. user = F.ToString(userIndex)
  114. } else {
  115. metadata.User = user
  116. }
  117. h.logger.InfoContext(ctx, "[", user, "] inbound connection to ", metadata.Destination)
  118. return h.router.RouteConnection(ctx, conn, h.createMetadata(conn, metadata))
  119. }
  120. func (h *ShadowsocksMulti) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  121. userIndex, loaded := auth.UserFromContext[int](ctx)
  122. if !loaded {
  123. return os.ErrInvalid
  124. }
  125. user := h.users[userIndex].Name
  126. if user == "" {
  127. user = F.ToString(userIndex)
  128. } else {
  129. metadata.User = user
  130. }
  131. ctx = log.ContextWithNewID(ctx)
  132. h.logger.InfoContext(ctx, "[", user, "] inbound packet connection from ", metadata.Source)
  133. h.logger.InfoContext(ctx, "[", user, "] inbound packet connection to ", metadata.Destination)
  134. return h.router.RoutePacketConnection(ctx, conn, h.createPacketMetadata(conn, metadata))
  135. }