sing-box/inbound/default.go

400 lines
12 KiB
Go
Raw Normal View History

2022-07-01 11:34:02 +00:00
package inbound
import (
"context"
"net"
"net/netip"
"os"
"sync"
"time"
2022-07-08 15:03:57 +00:00
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/settings"
2022-07-08 15:03:57 +00:00
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
2022-07-11 10:44:59 +00:00
"github.com/sagernet/sing-dns"
2022-07-01 11:34:02 +00:00
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
2022-07-06 07:01:09 +00:00
"github.com/database64128/tfo-go"
2022-07-01 11:34:02 +00:00
)
var _ adapter.Inbound = (*myInboundAdapter)(nil)
type myInboundAdapter struct {
2022-07-15 00:42:02 +00:00
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
2022-07-01 11:34:02 +00:00
// http mixed
setSystemProxy bool
2022-07-01 11:34:02 +00:00
// internal
tcpListener *net.TCPListener
udpConn *net.UDPConn
packetAccess sync.RWMutex
packetOutboundClosed chan struct{}
packetOutbound chan *myInboundPacket
}
func (a *myInboundAdapter) Type() string {
return a.protocol
}
func (a *myInboundAdapter) Tag() string {
return a.tag
}
func (a *myInboundAdapter) Start() error {
2022-07-22 08:20:24 +00:00
bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort)
2022-07-29 16:29:22 +00:00
if common.Contains(a.network, N.NetworkTCP) {
2022-07-01 11:34:02 +00:00
var tcpListener *net.TCPListener
var err error
if !a.listenOptions.TCPFastOpen {
2022-07-29 16:29:22 +00:00
tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
2022-07-01 11:34:02 +00:00
} else {
2022-07-29 16:29:22 +00:00
tcpListener, err = tfo.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
2022-07-01 11:34:02 +00:00
}
if err != nil {
return err
}
a.tcpListener = tcpListener
go a.loopTCPIn()
2022-07-04 07:34:43 +00:00
a.logger.Info("tcp server started at ", tcpListener.Addr())
2022-07-01 11:34:02 +00:00
}
2022-07-29 16:29:22 +00:00
if common.Contains(a.network, N.NetworkUDP) {
udpConn, err := net.ListenUDP(M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.UDPAddr())
2022-07-01 11:34:02 +00:00
if err != nil {
return err
}
a.udpConn = udpConn
a.packetOutboundClosed = make(chan struct{})
a.packetOutbound = make(chan *myInboundPacket)
2022-07-15 00:42:02 +00:00
if a.oobPacketHandler != nil {
if _, threadUnsafeHandler := common.Cast[N.ThreadUnsafeWriter](a.packetUpstream); !threadUnsafeHandler {
go a.loopUDPOOBIn()
} else {
go a.loopUDPOOBInThreadSafe()
}
2022-07-01 11:34:02 +00:00
} else {
2022-07-15 00:42:02 +00:00
if _, threadUnsafeHandler := common.Cast[N.ThreadUnsafeWriter](a.packetUpstream); !threadUnsafeHandler {
go a.loopUDPIn()
} else {
go a.loopUDPInThreadSafe()
}
go a.loopUDPOut()
2022-07-01 11:34:02 +00:00
}
2022-07-04 07:34:43 +00:00
a.logger.Info("udp server started at ", udpConn.LocalAddr())
2022-07-01 11:34:02 +00:00
}
if a.setSystemProxy {
err := settings.SetSystemProxy(M.SocksaddrFromNet(a.tcpListener.Addr()).Port, a.protocol == C.TypeMixed)
if err != nil {
return E.Cause(err, "set system proxy")
}
}
2022-07-01 11:34:02 +00:00
return nil
}
func (a *myInboundAdapter) Close() error {
var err error
if a.setSystemProxy {
err = settings.ClearSystemProxy()
}
return E.Errors(err, common.Close(
2022-07-01 11:34:02 +00:00
common.PtrOrNil(a.tcpListener),
common.PtrOrNil(a.udpConn),
))
2022-07-01 11:34:02 +00:00
}
func (a *myInboundAdapter) upstreamHandler(metadata adapter.InboundContext) adapter.UpstreamHandlerAdapter {
2022-07-02 06:07:50 +00:00
return adapter.NewUpstreamHandler(metadata, a.newConnection, a.streamPacketConnection, a)
2022-07-01 11:34:02 +00:00
}
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 {
2022-07-12 07:17:29 +00:00
a.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
2022-07-01 11:34:02 +00:00
return a.router.RouteConnection(ctx, conn, metadata)
}
2022-07-02 06:07:50 +00:00
func (a *myInboundAdapter) streamPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
2022-07-12 07:17:29 +00:00
a.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
2022-07-02 06:07:50 +00:00
return a.router.RoutePacketConnection(ctx, conn, metadata)
}
2022-07-01 11:34:02 +00:00
func (a *myInboundAdapter) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
2022-07-12 07:17:29 +00:00
ctx = log.ContextWithNewID(ctx)
a.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
a.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
2022-07-01 11:34:02 +00:00
return a.router.RoutePacketConnection(ctx, conn, metadata)
}
func (a *myInboundAdapter) loopTCPIn() {
tcpListener := a.tcpListener
for {
2022-07-30 06:50:33 +00:00
conn, err := tcpListener.AcceptTCP()
2022-07-01 11:34:02 +00:00
if err != nil {
return
}
go func() {
2022-07-12 07:17:29 +00:00
ctx := log.ContextWithNewID(a.ctx)
2022-07-02 06:07:50 +00:00
var metadata adapter.InboundContext
metadata.Inbound = a.tag
2022-07-19 14:16:49 +00:00
metadata.InboundType = a.protocol
2022-07-06 04:39:44 +00:00
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
2022-07-11 10:44:59 +00:00
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
2022-07-29 16:29:22 +00:00
metadata.Network = N.NetworkTCP
2022-07-02 06:07:50 +00:00
metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr())
2022-07-12 07:17:29 +00:00
a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
2022-07-01 11:34:02 +00:00
hErr := a.connHandler.NewConnection(ctx, conn, metadata)
if hErr != nil {
2022-07-08 04:58:43 +00:00
conn.Close()
2022-07-02 06:07:50 +00:00
a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source))
2022-07-01 11:34:02 +00:00
}
}()
}
}
func (a *myInboundAdapter) loopUDPIn() {
defer close(a.packetOutboundClosed)
_buffer := buf.StackNewPacket()
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release()
buffer.IncRef()
defer buffer.DecRef()
packetService := (*myInboundPacketAdapter)(a)
for {
buffer.Reset()
n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
if err != nil {
return
}
buffer.Truncate(n)
2022-07-02 06:07:50 +00:00
var metadata adapter.InboundContext
metadata.Inbound = a.tag
2022-07-19 14:16:49 +00:00
metadata.InboundType = a.protocol
2022-07-06 04:39:44 +00:00
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
2022-07-11 10:44:59 +00:00
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
2022-07-29 16:29:22 +00:00
metadata.Network = N.NetworkUDP
2022-07-02 06:07:50 +00:00
metadata.Source = M.SocksaddrFromNetIP(addr)
2022-07-01 11:34:02 +00:00
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
if err != nil {
2022-07-02 06:07:50 +00:00
a.newError(E.Cause(err, "process packet from ", metadata.Source))
2022-07-01 11:34:02 +00:00
}
}
}
2022-07-15 00:42:02 +00:00
func (a *myInboundAdapter) loopUDPOOBIn() {
defer close(a.packetOutboundClosed)
_buffer := buf.StackNewPacket()
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release()
buffer.IncRef()
defer buffer.DecRef()
packetService := (*myInboundPacketAdapter)(a)
oob := make([]byte, 1024)
for {
buffer.Reset()
n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
if err != nil {
return
}
buffer.Truncate(n)
var metadata adapter.InboundContext
metadata.Inbound = a.tag
2022-07-19 14:16:49 +00:00
metadata.InboundType = a.protocol
2022-07-15 00:42:02 +00:00
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
2022-07-29 16:29:22 +00:00
metadata.Network = N.NetworkUDP
2022-07-15 00:42:02 +00:00
metadata.Source = M.SocksaddrFromNetIP(addr)
err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
if err != nil {
a.newError(E.Cause(err, "process packet from ", metadata.Source))
}
}
}
2022-07-01 11:34:02 +00:00
func (a *myInboundAdapter) loopUDPInThreadSafe() {
defer close(a.packetOutboundClosed)
packetService := (*myInboundPacketAdapter)(a)
for {
buffer := buf.NewPacket()
n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
if err != nil {
2022-07-03 05:14:49 +00:00
buffer.Release()
2022-07-01 11:34:02 +00:00
return
}
buffer.Truncate(n)
2022-07-02 06:07:50 +00:00
var metadata adapter.InboundContext
metadata.Inbound = a.tag
2022-07-19 14:16:49 +00:00
metadata.InboundType = a.protocol
2022-07-06 04:39:44 +00:00
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
2022-07-11 10:44:59 +00:00
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
2022-07-29 16:29:22 +00:00
metadata.Network = N.NetworkUDP
2022-07-02 06:07:50 +00:00
metadata.Source = M.SocksaddrFromNetIP(addr)
2022-07-01 11:34:02 +00:00
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
if err != nil {
buffer.Release()
2022-07-02 06:07:50 +00:00
a.newError(E.Cause(err, "process packet from ", metadata.Source))
2022-07-01 11:34:02 +00:00
}
}
}
2022-07-15 00:42:02 +00:00
func (a *myInboundAdapter) loopUDPOOBInThreadSafe() {
defer close(a.packetOutboundClosed)
packetService := (*myInboundPacketAdapter)(a)
oob := make([]byte, 1024)
for {
buffer := buf.NewPacket()
n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
if err != nil {
buffer.Release()
return
}
buffer.Truncate(n)
var metadata adapter.InboundContext
metadata.Inbound = a.tag
2022-07-19 14:16:49 +00:00
metadata.InboundType = a.protocol
2022-07-15 00:42:02 +00:00
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
2022-07-29 16:29:22 +00:00
metadata.Network = N.NetworkUDP
2022-07-15 00:42:02 +00:00
metadata.Source = M.SocksaddrFromNetIP(addr)
err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
if err != nil {
buffer.Release()
a.newError(E.Cause(err, "process packet from ", metadata.Source))
}
}
}
2022-07-01 11:34:02 +00:00
func (a *myInboundAdapter) loopUDPOut() {
for {
select {
case packet := <-a.packetOutbound:
err := a.writePacket(packet.buffer, packet.destination)
if err != nil && !E.IsClosed(err) {
a.newError(E.New("write back udp: ", err))
}
continue
case <-a.packetOutboundClosed:
}
for {
select {
case packet := <-a.packetOutbound:
packet.buffer.Release()
default:
return
}
}
}
}
func (a *myInboundAdapter) newError(err error) {
2022-07-02 06:07:50 +00:00
a.logger.Error(err)
2022-07-01 11:34:02 +00:00
}
func (a *myInboundAdapter) NewError(ctx context.Context, err error) {
2022-07-09 11:18:37 +00:00
NewError(a.logger, ctx, err)
}
2022-07-12 07:17:29 +00:00
func NewError(logger log.ContextLogger, ctx context.Context, err error) {
2022-07-01 11:34:02 +00:00
common.Close(err)
2022-07-20 01:41:44 +00:00
if E.IsClosedOrCanceled(err) {
2022-07-24 13:25:41 +00:00
logger.TraceContext(ctx, "connection closed: ", err)
2022-07-01 11:34:02 +00:00
return
}
2022-07-12 07:17:29 +00:00
logger.ErrorContext(ctx, err)
2022-07-01 11:34:02 +00:00
}
func (a *myInboundAdapter) writePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
defer buffer.Release()
2022-07-02 14:55:10 +00:00
if destination.IsFqdn() {
2022-07-29 16:29:22 +00:00
udpAddr, err := net.ResolveUDPAddr(N.NetworkUDP, destination.String())
2022-07-01 11:34:02 +00:00
if err != nil {
return err
}
return common.Error(a.udpConn.WriteTo(buffer.Bytes(), udpAddr))
}
return common.Error(a.udpConn.WriteToUDPAddrPort(buffer.Bytes(), destination.AddrPort()))
}
type myInboundPacketAdapter myInboundAdapter
func (s *myInboundPacketAdapter) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
n, addr, err := s.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
if err != nil {
return M.Socksaddr{}, err
}
buffer.Truncate(n)
return M.SocksaddrFromNetIP(addr), nil
}
func (s *myInboundPacketAdapter) WriteIsThreadUnsafe() {
}
type myInboundPacket struct {
buffer *buf.Buffer
destination M.Socksaddr
}
func (s *myInboundPacketAdapter) Upstream() any {
return s.udpConn
}
func (s *myInboundPacketAdapter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
s.packetAccess.RLock()
defer s.packetAccess.RUnlock()
select {
case <-s.packetOutboundClosed:
return os.ErrClosed
default:
}
s.packetOutbound <- &myInboundPacket{buffer, destination}
return nil
}
func (s *myInboundPacketAdapter) Close() error {
return s.udpConn.Close()
}
func (s *myInboundPacketAdapter) LocalAddr() net.Addr {
return s.udpConn.LocalAddr()
}
func (s *myInboundPacketAdapter) SetDeadline(t time.Time) error {
return s.udpConn.SetDeadline(t)
}
func (s *myInboundPacketAdapter) SetReadDeadline(t time.Time) error {
return s.udpConn.SetReadDeadline(t)
}
func (s *myInboundPacketAdapter) SetWriteDeadline(t time.Time) error {
return s.udpConn.SetWriteDeadline(t)
}