router.go 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package uot
  2. import (
  3. "context"
  4. "net"
  5. "net/netip"
  6. "github.com/sagernet/sing-box/adapter"
  7. E "github.com/sagernet/sing/common/exceptions"
  8. "github.com/sagernet/sing/common/logger"
  9. M "github.com/sagernet/sing/common/metadata"
  10. N "github.com/sagernet/sing/common/network"
  11. "github.com/sagernet/sing/common/uot"
  12. )
  13. var _ adapter.ConnectionRouterEx = (*Router)(nil)
  14. type Router struct {
  15. router adapter.ConnectionRouterEx
  16. logger logger.ContextLogger
  17. }
  18. func NewRouter(router adapter.ConnectionRouterEx, logger logger.ContextLogger) *Router {
  19. return &Router{router, logger}
  20. }
  21. func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  22. switch metadata.Destination.Fqdn {
  23. case uot.MagicAddress:
  24. request, err := uot.ReadRequest(conn)
  25. if err != nil {
  26. return E.Cause(err, "read UoT request")
  27. }
  28. if request.IsConnect {
  29. r.logger.InfoContext(ctx, "inbound UoT connect connection to ", request.Destination)
  30. } else {
  31. r.logger.InfoContext(ctx, "inbound UoT connection to ", request.Destination)
  32. }
  33. metadata.Domain = metadata.Destination.Fqdn
  34. metadata.Destination = request.Destination
  35. return r.router.RoutePacketConnection(ctx, uot.NewConn(conn, *request), metadata)
  36. case uot.LegacyMagicAddress:
  37. r.logger.InfoContext(ctx, "inbound legacy UoT connection")
  38. metadata.Domain = metadata.Destination.Fqdn
  39. metadata.Destination = M.Socksaddr{Addr: netip.IPv4Unspecified()}
  40. return r.RoutePacketConnection(ctx, uot.NewConn(conn, uot.Request{}), metadata)
  41. }
  42. return r.router.RouteConnection(ctx, conn, metadata)
  43. }
  44. func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  45. return r.router.RoutePacketConnection(ctx, conn, metadata)
  46. }
  47. func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
  48. switch metadata.Destination.Fqdn {
  49. case uot.MagicAddress:
  50. request, err := uot.ReadRequest(conn)
  51. if err != nil {
  52. err = E.Cause(err, "UoT read request")
  53. r.logger.ErrorContext(ctx, "process connection from ", metadata.Source, ": ", err)
  54. N.CloseOnHandshakeFailure(conn, onClose, err)
  55. return
  56. }
  57. if request.IsConnect {
  58. r.logger.InfoContext(ctx, "inbound UoT connect connection to ", request.Destination)
  59. } else {
  60. r.logger.InfoContext(ctx, "inbound UoT connection to ", request.Destination)
  61. }
  62. metadata.Domain = metadata.Destination.Fqdn
  63. metadata.Destination = request.Destination
  64. r.router.RoutePacketConnectionEx(ctx, uot.NewConn(conn, *request), metadata, onClose)
  65. return
  66. case uot.LegacyMagicAddress:
  67. r.logger.InfoContext(ctx, "inbound legacy UoT connection")
  68. metadata.Domain = metadata.Destination.Fqdn
  69. metadata.Destination = M.Socksaddr{Addr: netip.IPv4Unspecified()}
  70. r.RoutePacketConnectionEx(ctx, uot.NewConn(conn, uot.Request{}), metadata, onClose)
  71. return
  72. }
  73. r.router.RouteConnectionEx(ctx, conn, metadata, onClose)
  74. }
  75. func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
  76. r.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
  77. }