github.com/sagernet/sing-box@v1.2.7/inbound/direct.go (about) 1 package inbound 2 3 import ( 4 "context" 5 "net" 6 "net/netip" 7 8 "github.com/sagernet/sing-box/adapter" 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 M "github.com/sagernet/sing/common/metadata" 14 N "github.com/sagernet/sing/common/network" 15 "github.com/sagernet/sing/common/udpnat" 16 ) 17 18 var _ adapter.Inbound = (*Direct)(nil) 19 20 type Direct struct { 21 myInboundAdapter 22 udpNat *udpnat.Service[netip.AddrPort] 23 overrideOption int 24 overrideDestination M.Socksaddr 25 } 26 27 func NewDirect(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.DirectInboundOptions) *Direct { 28 options.UDPFragmentDefault = true 29 inbound := &Direct{ 30 myInboundAdapter: myInboundAdapter{ 31 protocol: C.TypeDirect, 32 network: options.Network.Build(), 33 ctx: ctx, 34 router: router, 35 logger: logger, 36 tag: tag, 37 listenOptions: options.ListenOptions, 38 }, 39 } 40 if options.OverrideAddress != "" && options.OverridePort != 0 { 41 inbound.overrideOption = 1 42 inbound.overrideDestination = M.ParseSocksaddrHostPort(options.OverrideAddress, options.OverridePort) 43 } else if options.OverrideAddress != "" { 44 inbound.overrideOption = 2 45 inbound.overrideDestination = M.ParseSocksaddrHostPort(options.OverrideAddress, options.OverridePort) 46 } else if options.OverridePort != 0 { 47 inbound.overrideOption = 3 48 inbound.overrideDestination = M.Socksaddr{Port: options.OverridePort} 49 } 50 var udpTimeout int64 51 if options.UDPTimeout != 0 { 52 udpTimeout = options.UDPTimeout 53 } else { 54 udpTimeout = int64(C.UDPTimeout.Seconds()) 55 } 56 inbound.udpNat = udpnat.New[netip.AddrPort](udpTimeout, adapter.NewUpstreamContextHandler(inbound.newConnection, inbound.newPacketConnection, inbound)) 57 inbound.connHandler = inbound 58 inbound.packetHandler = inbound 59 inbound.packetUpstream = inbound.udpNat 60 return inbound 61 } 62 63 func (d *Direct) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { 64 switch d.overrideOption { 65 case 1: 66 metadata.Destination = d.overrideDestination 67 case 2: 68 destination := d.overrideDestination 69 destination.Port = metadata.Destination.Port 70 metadata.Destination = destination 71 case 3: 72 metadata.Destination.Port = d.overrideDestination.Port 73 } 74 d.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination) 75 return d.router.RouteConnection(ctx, conn, metadata) 76 } 77 78 func (d *Direct) NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext) error { 79 switch d.overrideOption { 80 case 1: 81 metadata.Destination = d.overrideDestination 82 case 2: 83 destination := d.overrideDestination 84 destination.Port = metadata.Destination.Port 85 metadata.Destination = destination 86 case 3: 87 metadata.Destination.Port = d.overrideDestination.Port 88 } 89 d.udpNat.NewContextPacket(ctx, metadata.Source.AddrPort(), buffer, adapter.UpstreamMetadata(metadata), func(natConn N.PacketConn) (context.Context, N.PacketWriter) { 90 return adapter.WithContext(log.ContextWithNewID(ctx), &metadata), &udpnat.DirectBackWriter{Source: conn, Nat: natConn} 91 }) 92 return nil 93 } 94 95 func (d *Direct) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { 96 return d.router.RouteConnection(ctx, conn, metadata) 97 } 98 99 func (d *Direct) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { 100 ctx = log.ContextWithNewID(ctx) 101 d.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source) 102 return d.router.RoutePacketConnection(ctx, conn, metadata) 103 }