inbound.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package direct
  2. import (
  3. "context"
  4. "net"
  5. "time"
  6. "github.com/sagernet/sing-box/adapter"
  7. "github.com/sagernet/sing-box/adapter/inbound"
  8. "github.com/sagernet/sing-box/common/listener"
  9. C "github.com/sagernet/sing-box/constant"
  10. "github.com/sagernet/sing-box/log"
  11. "github.com/sagernet/sing-box/option"
  12. "github.com/sagernet/sing/common/buf"
  13. "github.com/sagernet/sing/common/bufio"
  14. M "github.com/sagernet/sing/common/metadata"
  15. N "github.com/sagernet/sing/common/network"
  16. "github.com/sagernet/sing/common/udpnat2"
  17. )
  18. func RegisterInbound(registry *inbound.Registry) {
  19. inbound.Register[option.DirectInboundOptions](registry, C.TypeDirect, NewInbound)
  20. }
  21. type Inbound struct {
  22. inbound.Adapter
  23. ctx context.Context
  24. router adapter.ConnectionRouterEx
  25. logger log.ContextLogger
  26. listener *listener.Listener
  27. udpNat *udpnat.Service
  28. overrideOption int
  29. overrideDestination M.Socksaddr
  30. }
  31. func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.DirectInboundOptions) (adapter.Inbound, error) {
  32. options.UDPFragmentDefault = true
  33. inbound := &Inbound{
  34. Adapter: inbound.NewAdapter(C.TypeDirect, tag),
  35. ctx: ctx,
  36. router: router,
  37. logger: logger,
  38. }
  39. if options.OverrideAddress != "" && options.OverridePort != 0 {
  40. inbound.overrideOption = 1
  41. inbound.overrideDestination = M.ParseSocksaddrHostPort(options.OverrideAddress, options.OverridePort)
  42. } else if options.OverrideAddress != "" {
  43. inbound.overrideOption = 2
  44. inbound.overrideDestination = M.ParseSocksaddrHostPort(options.OverrideAddress, options.OverridePort)
  45. } else if options.OverridePort != 0 {
  46. inbound.overrideOption = 3
  47. inbound.overrideDestination = M.Socksaddr{Port: options.OverridePort}
  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. inbound.udpNat = udpnat.New(inbound, inbound.preparePacketConnection, udpTimeout, false)
  56. inbound.listener = listener.New(listener.Options{
  57. Context: ctx,
  58. Logger: logger,
  59. Network: options.Network.Build(),
  60. Listen: options.ListenOptions,
  61. ConnectionHandler: inbound,
  62. PacketHandler: inbound,
  63. })
  64. return inbound, nil
  65. }
  66. func (i *Inbound) Start(stage adapter.StartStage) error {
  67. if stage != adapter.StartStateStart {
  68. return nil
  69. }
  70. return i.listener.Start()
  71. }
  72. func (i *Inbound) Close() error {
  73. return i.listener.Close()
  74. }
  75. func (i *Inbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
  76. i.udpNat.NewPacket([][]byte{buffer.Bytes()}, source, i.listener.UDPAddr(), nil)
  77. }
  78. func (i *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
  79. metadata.Inbound = i.Tag()
  80. metadata.InboundType = i.Type()
  81. destination := metadata.OriginDestination
  82. switch i.overrideOption {
  83. case 1:
  84. destination = i.overrideDestination
  85. case 2:
  86. destination.Addr = i.overrideDestination.Addr
  87. case 3:
  88. destination.Port = metadata.Destination.Port
  89. }
  90. metadata.Destination = destination
  91. if i.overrideOption != 0 {
  92. i.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
  93. }
  94. i.router.RouteConnectionEx(ctx, conn, metadata, onClose)
  95. }
  96. func (i *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
  97. i.logger.InfoContext(ctx, "inbound packet connection from ", source)
  98. var metadata adapter.InboundContext
  99. metadata.Inbound = i.Tag()
  100. metadata.InboundType = i.Type()
  101. //nolint:staticcheck
  102. metadata.InboundDetour = i.listener.ListenOptions().Detour
  103. //nolint:staticcheck
  104. metadata.InboundOptions = i.listener.ListenOptions().InboundOptions
  105. metadata.Source = source
  106. destination = i.listener.UDPAddr()
  107. switch i.overrideOption {
  108. case 1:
  109. destination = i.overrideDestination
  110. case 2:
  111. destination.Addr = i.overrideDestination.Addr
  112. case 3:
  113. destination.Port = i.overrideDestination.Port
  114. default:
  115. }
  116. i.logger.InfoContext(ctx, "inbound packet connection to ", destination)
  117. metadata.Destination = destination
  118. if i.overrideOption != 0 {
  119. conn = bufio.NewDestinationNATPacketConn(bufio.NewNetPacketConn(conn), i.listener.UDPAddr(), destination)
  120. }
  121. i.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
  122. }
  123. func (i *Inbound) preparePacketConnection(source M.Socksaddr, destination M.Socksaddr, userData any) (bool, context.Context, N.PacketWriter, N.CloseHandlerFunc) {
  124. return true, log.ContextWithNewID(i.ctx), &directPacketWriter{i.listener.PacketWriter(), source}, nil
  125. }
  126. type directPacketWriter struct {
  127. writer N.PacketWriter
  128. source M.Socksaddr
  129. }
  130. func (w *directPacketWriter) WritePacket(buffer *buf.Buffer, addr M.Socksaddr) error {
  131. return w.writer.WritePacket(buffer, w.source)
  132. }