| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 | 
							- package inbound
 
- import (
 
- 	"context"
 
- 	"net"
 
- 	"github.com/sagernet/sing-box/adapter"
 
- 	"github.com/sagernet/sing-box/common/settings"
 
- 	C "github.com/sagernet/sing-box/constant"
 
- 	"github.com/sagernet/sing-box/log"
 
- 	"github.com/sagernet/sing-box/option"
 
- 	"github.com/sagernet/sing/common"
 
- 	"github.com/sagernet/sing/common/atomic"
 
- 	E "github.com/sagernet/sing/common/exceptions"
 
- 	M "github.com/sagernet/sing/common/metadata"
 
- 	N "github.com/sagernet/sing/common/network"
 
- )
 
- var _ adapter.Inbound = (*myInboundAdapter)(nil)
 
- type myInboundAdapter struct {
 
- 	protocol         string
 
- 	network          []string
 
- 	ctx              context.Context
 
- 	router           adapter.Router
 
- 	logger           log.ContextLogger
 
- 	tag              string
 
- 	listenOptions    option.ListenOptions
 
- 	connHandler      adapter.ConnectionHandler
 
- 	packetHandler    adapter.PacketHandler
 
- 	oobPacketHandler adapter.OOBPacketHandler
 
- 	packetUpstream   any
 
- 	// http mixed
 
- 	setSystemProxy bool
 
- 	systemProxy    settings.SystemProxy
 
- 	// internal
 
- 	tcpListener          net.Listener
 
- 	udpConn              *net.UDPConn
 
- 	udpAddr              M.Socksaddr
 
- 	packetOutboundClosed chan struct{}
 
- 	packetOutbound       chan *myInboundPacket
 
- 	inShutdown atomic.Bool
 
- }
 
- func (a *myInboundAdapter) Type() string {
 
- 	return a.protocol
 
- }
 
- func (a *myInboundAdapter) Tag() string {
 
- 	return a.tag
 
- }
 
- func (a *myInboundAdapter) Network() []string {
 
- 	return a.network
 
- }
 
- func (a *myInboundAdapter) Start() error {
 
- 	var err error
 
- 	if common.Contains(a.network, N.NetworkTCP) {
 
- 		_, err = a.ListenTCP()
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		go a.loopTCPIn()
 
- 	}
 
- 	if common.Contains(a.network, N.NetworkUDP) {
 
- 		_, err = a.ListenUDP()
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		a.packetOutboundClosed = make(chan struct{})
 
- 		a.packetOutbound = make(chan *myInboundPacket)
 
- 		if a.oobPacketHandler != nil {
 
- 			if _, threadUnsafeHandler := common.Cast[N.ThreadUnsafeWriter](a.packetUpstream); !threadUnsafeHandler {
 
- 				go a.loopUDPOOBIn()
 
- 			} else {
 
- 				go a.loopUDPOOBInThreadSafe()
 
- 			}
 
- 		} else {
 
- 			if _, threadUnsafeHandler := common.Cast[N.ThreadUnsafeWriter](a.packetUpstream); !threadUnsafeHandler {
 
- 				go a.loopUDPIn()
 
- 			} else {
 
- 				go a.loopUDPInThreadSafe()
 
- 			}
 
- 			go a.loopUDPOut()
 
- 		}
 
- 	}
 
- 	if a.setSystemProxy {
 
- 		listenPort := M.SocksaddrFromNet(a.tcpListener.Addr()).Port
 
- 		var listenAddrString string
 
- 		listenAddr := a.listenOptions.Listen.Build()
 
- 		if listenAddr.IsUnspecified() {
 
- 			listenAddrString = "127.0.0.1"
 
- 		} else {
 
- 			listenAddrString = listenAddr.String()
 
- 		}
 
- 		var systemProxy settings.SystemProxy
 
- 		systemProxy, err = settings.NewSystemProxy(a.ctx, M.ParseSocksaddrHostPort(listenAddrString, listenPort), a.protocol == C.TypeMixed)
 
- 		if err != nil {
 
- 			return E.Cause(err, "initialize system proxy")
 
- 		}
 
- 		err = systemProxy.Enable()
 
- 		if err != nil {
 
- 			return E.Cause(err, "set system proxy")
 
- 		}
 
- 		a.systemProxy = systemProxy
 
- 	}
 
- 	return nil
 
- }
 
- func (a *myInboundAdapter) Close() error {
 
- 	a.inShutdown.Store(true)
 
- 	var err error
 
- 	if a.systemProxy != nil && a.systemProxy.IsEnabled() {
 
- 		err = a.systemProxy.Disable()
 
- 	}
 
- 	return E.Errors(err, common.Close(
 
- 		a.tcpListener,
 
- 		common.PtrOrNil(a.udpConn),
 
- 	))
 
- }
 
- func (a *myInboundAdapter) upstreamHandler(metadata adapter.InboundContext) adapter.UpstreamHandlerAdapter {
 
- 	return adapter.NewUpstreamHandler(metadata, a.newConnection, a.streamPacketConnection, a)
 
- }
 
- func (a *myInboundAdapter) upstreamContextHandler() adapter.UpstreamHandlerAdapter {
 
- 	return adapter.NewUpstreamContextHandler(a.newConnection, a.newPacketConnection, a)
 
- }
 
- func (a *myInboundAdapter) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
 
- 	a.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
 
- 	return a.router.RouteConnection(ctx, conn, metadata)
 
- }
 
- func (a *myInboundAdapter) streamPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
 
- 	a.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
 
- 	return a.router.RoutePacketConnection(ctx, conn, metadata)
 
- }
 
- func (a *myInboundAdapter) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
 
- 	ctx = log.ContextWithNewID(ctx)
 
- 	a.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
 
- 	a.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
 
- 	return a.router.RoutePacketConnection(ctx, conn, metadata)
 
- }
 
- func (a *myInboundAdapter) createMetadata(conn net.Conn, metadata adapter.InboundContext) adapter.InboundContext {
 
- 	metadata.Inbound = a.tag
 
- 	metadata.InboundType = a.protocol
 
- 	metadata.InboundDetour = a.listenOptions.Detour
 
- 	metadata.InboundOptions = a.listenOptions.InboundOptions
 
- 	if !metadata.Source.IsValid() {
 
- 		metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap()
 
- 	}
 
- 	if !metadata.Destination.IsValid() {
 
- 		metadata.Destination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap()
 
- 	}
 
- 	if tcpConn, isTCP := common.Cast[*net.TCPConn](conn); isTCP {
 
- 		metadata.OriginDestination = M.SocksaddrFromNet(tcpConn.LocalAddr()).Unwrap()
 
- 	}
 
- 	return metadata
 
- }
 
- func (a *myInboundAdapter) createPacketMetadata(conn N.PacketConn, metadata adapter.InboundContext) adapter.InboundContext {
 
- 	metadata.Inbound = a.tag
 
- 	metadata.InboundType = a.protocol
 
- 	metadata.InboundDetour = a.listenOptions.Detour
 
- 	metadata.InboundOptions = a.listenOptions.InboundOptions
 
- 	if !metadata.Destination.IsValid() {
 
- 		metadata.Destination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap()
 
- 	}
 
- 	return metadata
 
- }
 
- func (a *myInboundAdapter) newError(err error) {
 
- 	a.logger.Error(err)
 
- }
 
- func (a *myInboundAdapter) NewError(ctx context.Context, err error) {
 
- 	NewError(a.logger, ctx, err)
 
- }
 
- func NewError(logger log.ContextLogger, ctx context.Context, err error) {
 
- 	common.Close(err)
 
- 	if E.IsClosedOrCanceled(err) {
 
- 		logger.DebugContext(ctx, "connection closed: ", err)
 
- 		return
 
- 	}
 
- 	logger.ErrorContext(ctx, err)
 
- }
 
 
  |