shadowsocks_multi.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package inbound
  2. import (
  3. "context"
  4. "net"
  5. "os"
  6. "github.com/sagernet/sing-box/adapter"
  7. C "github.com/sagernet/sing-box/constant"
  8. "github.com/sagernet/sing-box/log"
  9. "github.com/sagernet/sing-box/option"
  10. "github.com/sagernet/sing-shadowsocks/shadowaead_2022"
  11. "github.com/sagernet/sing/common"
  12. "github.com/sagernet/sing/common/auth"
  13. "github.com/sagernet/sing/common/buf"
  14. E "github.com/sagernet/sing/common/exceptions"
  15. F "github.com/sagernet/sing/common/format"
  16. N "github.com/sagernet/sing/common/network"
  17. )
  18. var (
  19. _ adapter.Inbound = (*ShadowsocksMulti)(nil)
  20. _ adapter.InjectableInbound = (*ShadowsocksMulti)(nil)
  21. )
  22. type ShadowsocksMulti struct {
  23. myInboundAdapter
  24. service *shadowaead_2022.MultiService[int]
  25. users []option.ShadowsocksUser
  26. }
  27. func newShadowsocksMulti(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksInboundOptions) (*ShadowsocksMulti, error) {
  28. inbound := &ShadowsocksMulti{
  29. myInboundAdapter: myInboundAdapter{
  30. protocol: C.TypeShadowsocks,
  31. network: options.Network.Build(),
  32. ctx: ctx,
  33. router: router,
  34. logger: logger,
  35. tag: tag,
  36. listenOptions: options.ListenOptions,
  37. },
  38. }
  39. inbound.connHandler = inbound
  40. inbound.packetHandler = inbound
  41. var udpTimeout int64
  42. if options.UDPTimeout != 0 {
  43. udpTimeout = options.UDPTimeout
  44. } else {
  45. udpTimeout = int64(C.UDPTimeout.Seconds())
  46. }
  47. if !common.Contains(shadowaead_2022.List, options.Method) {
  48. return nil, E.New("unsupported method: " + options.Method)
  49. }
  50. service, err := shadowaead_2022.NewMultiServiceWithPassword[int](
  51. options.Method,
  52. options.Password,
  53. udpTimeout,
  54. adapter.NewUpstreamContextHandler(inbound.newConnection, inbound.newPacketConnection, inbound),
  55. router.TimeFunc(),
  56. )
  57. if err != nil {
  58. return nil, err
  59. }
  60. err = service.UpdateUsersWithPasswords(common.MapIndexed(options.Users, func(index int, user option.ShadowsocksUser) int {
  61. return index
  62. }), common.Map(options.Users, func(user option.ShadowsocksUser) string {
  63. return user.Password
  64. }))
  65. if err != nil {
  66. return nil, err
  67. }
  68. inbound.service = service
  69. inbound.packetUpstream = service
  70. inbound.users = options.Users
  71. return inbound, err
  72. }
  73. func (h *ShadowsocksMulti) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  74. return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata))
  75. }
  76. func (h *ShadowsocksMulti) NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext) error {
  77. return h.service.NewPacket(adapter.WithContext(ctx, &metadata), conn, buffer, adapter.UpstreamMetadata(metadata))
  78. }
  79. func (h *ShadowsocksMulti) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  80. return os.ErrInvalid
  81. }
  82. func (h *ShadowsocksMulti) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  83. userIndex, loaded := auth.UserFromContext[int](ctx)
  84. if !loaded {
  85. return os.ErrInvalid
  86. }
  87. user := h.users[userIndex].Name
  88. if user == "" {
  89. user = F.ToString(userIndex)
  90. } else {
  91. metadata.User = user
  92. }
  93. h.logger.InfoContext(ctx, "[", user, "] inbound connection to ", metadata.Destination)
  94. return h.router.RouteConnection(ctx, conn, metadata)
  95. }
  96. func (h *ShadowsocksMulti) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  97. userIndex, loaded := auth.UserFromContext[int](ctx)
  98. if !loaded {
  99. return os.ErrInvalid
  100. }
  101. user := h.users[userIndex].Name
  102. if user == "" {
  103. user = F.ToString(userIndex)
  104. } else {
  105. metadata.User = user
  106. }
  107. ctx = log.ContextWithNewID(ctx)
  108. h.logger.InfoContext(ctx, "[", user, "] inbound packet connection from ", metadata.Source)
  109. h.logger.InfoContext(ctx, "[", user, "] inbound packet connection to ", metadata.Destination)
  110. return h.router.RoutePacketConnection(ctx, conn, metadata)
  111. }