shadowsocks_relay.go 4.3 KB

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