1
0

shadowsocks_relay.go 4.3 KB

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