github.com/sagernet/sing-box@v1.2.7/inbound/default.go (about) 1 package inbound 2 3 import ( 4 "context" 5 "net" 6 7 "github.com/sagernet/sing-box/adapter" 8 "github.com/sagernet/sing-box/common/settings" 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" 13 "github.com/sagernet/sing/common/atomic" 14 E "github.com/sagernet/sing/common/exceptions" 15 M "github.com/sagernet/sing/common/metadata" 16 N "github.com/sagernet/sing/common/network" 17 ) 18 19 var _ adapter.Inbound = (*myInboundAdapter)(nil) 20 21 type myInboundAdapter struct { 22 protocol string 23 network []string 24 ctx context.Context 25 router adapter.Router 26 logger log.ContextLogger 27 tag string 28 listenOptions option.ListenOptions 29 connHandler adapter.ConnectionHandler 30 packetHandler adapter.PacketHandler 31 oobPacketHandler adapter.OOBPacketHandler 32 packetUpstream any 33 34 // http mixed 35 36 setSystemProxy bool 37 clearSystemProxy func() error 38 39 // internal 40 41 tcpListener net.Listener 42 udpConn *net.UDPConn 43 udpAddr M.Socksaddr 44 packetOutboundClosed chan struct{} 45 packetOutbound chan *myInboundPacket 46 47 inShutdown atomic.Bool 48 } 49 50 func (a *myInboundAdapter) Type() string { 51 return a.protocol 52 } 53 54 func (a *myInboundAdapter) Tag() string { 55 return a.tag 56 } 57 58 func (a *myInboundAdapter) Network() []string { 59 return a.network 60 } 61 62 func (a *myInboundAdapter) Start() error { 63 var err error 64 if common.Contains(a.network, N.NetworkTCP) { 65 _, err = a.ListenTCP() 66 if err != nil { 67 return err 68 } 69 go a.loopTCPIn() 70 } 71 if common.Contains(a.network, N.NetworkUDP) { 72 _, err = a.ListenUDP() 73 if err != nil { 74 return err 75 } 76 a.packetOutboundClosed = make(chan struct{}) 77 a.packetOutbound = make(chan *myInboundPacket) 78 if a.oobPacketHandler != nil { 79 if _, threadUnsafeHandler := common.Cast[N.ThreadUnsafeWriter](a.packetUpstream); !threadUnsafeHandler { 80 go a.loopUDPOOBIn() 81 } else { 82 go a.loopUDPOOBInThreadSafe() 83 } 84 } else { 85 if _, threadUnsafeHandler := common.Cast[N.ThreadUnsafeWriter](a.packetUpstream); !threadUnsafeHandler { 86 go a.loopUDPIn() 87 } else { 88 go a.loopUDPInThreadSafe() 89 } 90 go a.loopUDPOut() 91 } 92 } 93 if a.setSystemProxy { 94 a.clearSystemProxy, err = settings.SetSystemProxy(a.router, M.SocksaddrFromNet(a.tcpListener.Addr()).Port, a.protocol == C.TypeMixed) 95 if err != nil { 96 return E.Cause(err, "set system proxy") 97 } 98 } 99 return nil 100 } 101 102 func (a *myInboundAdapter) Close() error { 103 a.inShutdown.Store(true) 104 var err error 105 if a.clearSystemProxy != nil { 106 err = a.clearSystemProxy() 107 } 108 return E.Errors(err, common.Close( 109 a.tcpListener, 110 common.PtrOrNil(a.udpConn), 111 )) 112 } 113 114 func (a *myInboundAdapter) upstreamHandler(metadata adapter.InboundContext) adapter.UpstreamHandlerAdapter { 115 return adapter.NewUpstreamHandler(metadata, a.newConnection, a.streamPacketConnection, a) 116 } 117 118 func (a *myInboundAdapter) upstreamContextHandler() adapter.UpstreamHandlerAdapter { 119 return adapter.NewUpstreamContextHandler(a.newConnection, a.newPacketConnection, a) 120 } 121 122 func (a *myInboundAdapter) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { 123 a.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination) 124 return a.router.RouteConnection(ctx, conn, metadata) 125 } 126 127 func (a *myInboundAdapter) streamPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { 128 a.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination) 129 return a.router.RoutePacketConnection(ctx, conn, metadata) 130 } 131 132 func (a *myInboundAdapter) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { 133 ctx = log.ContextWithNewID(ctx) 134 a.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source) 135 a.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination) 136 return a.router.RoutePacketConnection(ctx, conn, metadata) 137 } 138 139 func (a *myInboundAdapter) createMetadata(conn net.Conn, metadata adapter.InboundContext) adapter.InboundContext { 140 metadata.Inbound = a.tag 141 metadata.InboundType = a.protocol 142 metadata.InboundDetour = a.listenOptions.Detour 143 metadata.InboundOptions = a.listenOptions.InboundOptions 144 if !metadata.Source.IsValid() { 145 metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap() 146 } 147 if !metadata.Destination.IsValid() { 148 metadata.Destination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap() 149 } 150 if tcpConn, isTCP := common.Cast[*net.TCPConn](conn); isTCP { 151 metadata.OriginDestination = M.SocksaddrFromNet(tcpConn.LocalAddr()).Unwrap() 152 } 153 return metadata 154 } 155 156 func (a *myInboundAdapter) newError(err error) { 157 a.logger.Error(err) 158 } 159 160 func (a *myInboundAdapter) NewError(ctx context.Context, err error) { 161 NewError(a.logger, ctx, err) 162 } 163 164 func NewError(logger log.ContextLogger, ctx context.Context, err error) { 165 common.Close(err) 166 if E.IsClosedOrCanceled(err) { 167 logger.DebugContext(ctx, "connection closed: ", err) 168 return 169 } 170 logger.ErrorContext(ctx, err) 171 }