shadowsocks_multi.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. N "github.com/sagernet/sing/common/network"
  22. "github.com/sagernet/sing/common/ntp"
  23. )
  24. var (
  25. _ adapter.Inbound = (*ShadowsocksMulti)(nil)
  26. _ adapter.InjectableInbound = (*ShadowsocksMulti)(nil)
  27. )
  28. type ShadowsocksMulti struct {
  29. myInboundAdapter
  30. service shadowsocks.MultiService[int]
  31. users []option.ShadowsocksUser
  32. }
  33. func newShadowsocksMulti(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksInboundOptions) (*ShadowsocksMulti, error) {
  34. inbound := &ShadowsocksMulti{
  35. myInboundAdapter: myInboundAdapter{
  36. protocol: C.TypeShadowsocks,
  37. network: options.Network.Build(),
  38. ctx: ctx,
  39. router: uot.NewRouter(router, logger),
  40. logger: logger,
  41. tag: tag,
  42. listenOptions: options.ListenOptions,
  43. },
  44. }
  45. inbound.connHandler = inbound
  46. inbound.packetHandler = inbound
  47. var err error
  48. inbound.router, err = mux.NewRouterWithOptions(inbound.router, logger, common.PtrValueOrDefault(options.Multiplex))
  49. if err != nil {
  50. return nil, err
  51. }
  52. var udpTimeout time.Duration
  53. if options.UDPTimeout != 0 {
  54. udpTimeout = time.Duration(options.UDPTimeout)
  55. } else {
  56. udpTimeout = C.UDPTimeout
  57. }
  58. var service shadowsocks.MultiService[int]
  59. if common.Contains(shadowaead_2022.List, options.Method) {
  60. service, err = shadowaead_2022.NewMultiServiceWithPassword[int](
  61. options.Method,
  62. options.Password,
  63. int64(udpTimeout.Seconds()),
  64. adapter.NewUpstreamContextHandler(inbound.newConnection, inbound.newPacketConnection, inbound),
  65. ntp.TimeFuncFromContext(ctx),
  66. )
  67. } else if common.Contains(shadowaead.List, options.Method) {
  68. service, err = shadowaead.NewMultiService[int](
  69. options.Method,
  70. int64(udpTimeout.Seconds()),
  71. adapter.NewUpstreamContextHandler(inbound.newConnection, inbound.newPacketConnection, inbound))
  72. } else {
  73. return nil, E.New("unsupported method: " + options.Method)
  74. }
  75. if err != nil {
  76. return nil, err
  77. }
  78. err = service.UpdateUsersWithPasswords(common.MapIndexed(options.Users, func(index int, user option.ShadowsocksUser) int {
  79. return index
  80. }), common.Map(options.Users, func(user option.ShadowsocksUser) string {
  81. return user.Password
  82. }))
  83. if err != nil {
  84. return nil, err
  85. }
  86. inbound.service = service
  87. inbound.packetUpstream = service
  88. inbound.users = options.Users
  89. return inbound, err
  90. }
  91. func (h *ShadowsocksMulti) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  92. return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata))
  93. }
  94. func (h *ShadowsocksMulti) NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext) error {
  95. return h.service.NewPacket(adapter.WithContext(ctx, &metadata), conn, buffer, adapter.UpstreamMetadata(metadata))
  96. }
  97. func (h *ShadowsocksMulti) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  98. return os.ErrInvalid
  99. }
  100. func (h *ShadowsocksMulti) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  101. userIndex, loaded := auth.UserFromContext[int](ctx)
  102. if !loaded {
  103. return os.ErrInvalid
  104. }
  105. user := h.users[userIndex].Name
  106. if user == "" {
  107. user = F.ToString(userIndex)
  108. } else {
  109. metadata.User = user
  110. }
  111. h.logger.InfoContext(ctx, "[", user, "] inbound connection to ", metadata.Destination)
  112. return h.router.RouteConnection(ctx, conn, metadata)
  113. }
  114. func (h *ShadowsocksMulti) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  115. userIndex, loaded := auth.UserFromContext[int](ctx)
  116. if !loaded {
  117. return os.ErrInvalid
  118. }
  119. user := h.users[userIndex].Name
  120. if user == "" {
  121. user = F.ToString(userIndex)
  122. } else {
  123. metadata.User = user
  124. }
  125. ctx = log.ContextWithNewID(ctx)
  126. h.logger.InfoContext(ctx, "[", user, "] inbound packet connection from ", metadata.Source)
  127. h.logger.InfoContext(ctx, "[", user, "] inbound packet connection to ", metadata.Destination)
  128. return h.router.RoutePacketConnection(ctx, conn, metadata)
  129. }