package uot import ( "context" "net" "net/netip" "github.com/sagernet/sing-box/adapter" E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/logger" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" "github.com/sagernet/sing/common/uot" ) var _ adapter.ConnectionRouter = (*Router)(nil) type Router struct { router adapter.ConnectionRouter logger logger.ContextLogger } func NewRouter(router adapter.ConnectionRouter, logger logger.ContextLogger) *Router { return &Router{router, logger} } func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { switch metadata.Destination.Fqdn { case uot.MagicAddress: request, err := uot.ReadRequest(conn) if err != nil { return E.Cause(err, "read UoT request") } if request.IsConnect { r.logger.InfoContext(ctx, "inbound UoT connect connection to ", request.Destination) } else { r.logger.InfoContext(ctx, "inbound UoT connection to ", request.Destination) } metadata.Domain = metadata.Destination.Fqdn metadata.Destination = request.Destination return r.router.RoutePacketConnection(ctx, uot.NewConn(conn, *request), metadata) case uot.LegacyMagicAddress: r.logger.InfoContext(ctx, "inbound legacy UoT connection") metadata.Domain = metadata.Destination.Fqdn metadata.Destination = M.Socksaddr{Addr: netip.IPv4Unspecified()} return r.RoutePacketConnection(ctx, uot.NewConn(conn, uot.Request{}), metadata) } return r.router.RouteConnection(ctx, conn, metadata) } func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { return r.router.RoutePacketConnection(ctx, conn, metadata) }