Интерфейсы адаптеров
Пакет adapter определяет основные интерфейсы, которые реализуют все компоненты. Эти интерфейсы формируют контракт между слоем оркестрации (Box, Router) и реализациями протоколов.
Исходный код: adapter/
Основные интерфейсы
Входящий (Inbound)
type Inbound interface {
Lifecycle
Type() string
Tag() string
}
type TCPInjectableInbound interface {
Inbound
ConnectionHandlerEx
}
type UDPInjectableInbound interface {
Inbound
PacketConnectionHandlerEx
}Входящий прослушивает соединения и декодирует заголовки протоколов. После декодирования он вызывает маршрутизатор для маршрутизации соединения. Инжектируемые входящие поддерживают получение соединений от других входящих (detour).
Исходящий (Outbound)
type Outbound interface {
Type() string
Tag() string
Network() []string // ["tcp"], ["udp"], or ["tcp", "udp"]
Dependencies() []string // tags of outbounds this depends on
N.Dialer // DialContext + ListenPacket
}Исходящий по сути является N.Dialer -- он может устанавливать TCP-соединения и прослушивать UDP-пакеты. Это означает, что исходящие компонуемы: исходящий VLESS оборачивает прямой dialer с кодированием протокола.
Конечная точка (Endpoint)
type Endpoint interface {
Lifecycle
Type() string
Tag() string
Outbound // endpoints are also outbounds
}Конечные точки -- это компоненты двойного назначения, выступающие одновременно как входящие и исходящие. WireGuard и Tailscale являются конечными точками -- они создают виртуальные сетевые интерфейсы.
Маршрутизатор (Router)
type Router interface {
Lifecycle
ConnectionRouter
ConnectionRouterEx
PreMatch(metadata InboundContext, ...) (tun.DirectRouteDestination, error)
RuleSet(tag string) (RuleSet, bool)
Rules() []Rule
NeedFindProcess() bool
NeedFindNeighbor() bool
AppendTracker(tracker ConnectionTracker)
ResetNetwork()
}
type ConnectionRouterEx interface {
ConnectionRouter
RouteConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}Маршрутизатор сопоставляет правила и направляет соединения к исходящим. RouteConnectionEx -- это неблокирующий вариант, принимающий обратный вызов onClose вместо блокировки до завершения.
Менеджер соединений (ConnectionManager)
type ConnectionManager interface {
Lifecycle
Count() int
CloseAll()
TrackConn(conn net.Conn) net.Conn
TrackPacketConn(conn net.PacketConn) net.PacketConn
NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}Менеджер соединений обрабатывает фактическое установление соединения и цикл двунаправленного копирования. Когда исходящий не реализует ConnectionHandlerEx напрямую, маршрутизатор делегирует задачу менеджеру соединений.
Менеджер сети (NetworkManager)
type NetworkManager interface {
Lifecycle
InterfaceFinder() control.InterfaceFinder
DefaultNetworkInterface() *NetworkInterface
AutoDetectInterface() bool
AutoDetectInterfaceFunc() control.Func
ProtectFunc() control.Func
DefaultOptions() NetworkOptions
NetworkMonitor() tun.NetworkUpdateMonitor
InterfaceMonitor() tun.DefaultInterfaceMonitor
PackageManager() tun.PackageManager
WIFIState() WIFIState
ResetNetwork()
}Управляет сетевым состоянием платформы: обнаружение интерфейсов, метки маршрутизации, защита сокетов (Android), мониторинг WIFI.
DNS-маршрутизатор (DNSRouter)
type DNSRouter interface {
Lifecycle
Exchange(ctx context.Context, message *dns.Msg, options DNSQueryOptions) (*dns.Msg, error)
Lookup(ctx context.Context, domain string, options DNSQueryOptions) ([]netip.Addr, error)
ClearCache()
LookupReverseMapping(ip netip.Addr) (string, bool)
ResetNetwork()
}Менеджер DNS-транспортов (DNSTransportManager)
type DNSTransportManager interface {
Lifecycle
Transports() []DNSTransport
Transport(tag string) (DNSTransport, bool)
Default() DNSTransport
FakeIP() FakeIPTransport
Remove(tag string) error
Create(ctx context.Context, ...) error
}InboundContext -- объект метаданных
InboundContext -- это центральная структура метаданных, проходящая через весь конвейер:
type InboundContext struct {
// Identity
Inbound string // inbound tag
InboundType string // inbound type (e.g., "vless")
Network string // "tcp" or "udp"
Source M.Socksaddr // client address
Destination M.Socksaddr // target address
User string // authenticated user
Outbound string // selected outbound tag
// Sniffing results
Protocol string // detected protocol (e.g., "tls", "http")
Domain string // sniffed domain name
Client string // detected client (e.g., "chrome")
SniffContext any
SniffError error
// Routing cache
IPVersion uint8
OriginDestination M.Socksaddr
RouteOriginalDestination M.Socksaddr
DestinationAddresses []netip.Addr // resolved IPs
SourceGeoIPCode string
GeoIPCode string
ProcessInfo *ConnectionOwner
SourceMACAddress net.HardwareAddr
SourceHostname string
QueryType uint16
FakeIP bool
// Route options (set by rule actions)
NetworkStrategy *C.NetworkStrategy
NetworkType []C.InterfaceType
FallbackNetworkType []C.InterfaceType
FallbackDelay time.Duration
UDPDisableDomainUnmapping bool
UDPConnect bool
UDPTimeout time.Duration
TLSFragment bool
TLSFragmentFallbackDelay time.Duration
TLSRecordFragment bool
// Rule matching cache (reset between rules)
IPCIDRMatchSource bool
IPCIDRAcceptEmpty bool
SourceAddressMatch bool
SourcePortMatch bool
DestinationAddressMatch bool
DestinationPortMatch bool
DidMatch bool
IgnoreDestinationIPCIDRMatch bool
}Передача через контекст
InboundContext хранится в контексте Go:
// Store in context
func WithContext(ctx context.Context, inboundContext *InboundContext) context.Context
// Retrieve from context
func ContextFrom(ctx context.Context) *InboundContext
// Clone and store (for sub-pipelines)
func ExtendContext(ctx context.Context) (context.Context, *InboundContext)Интерфейсы обработчиков
Обработчики обрабатывают входящие соединения:
// TCP connection handler
type ConnectionHandlerEx interface {
NewConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
// UDP packet connection handler
type PacketConnectionHandlerEx interface {
NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}Паттерн обратного вызова onClose является центральным в архитектуре sing-box -- он обеспечивает неблокирующую обработку соединений. При завершении соединения (успешном или с ошибкой) onClose вызывается ровно один раз.
Адаптеры верхнего уровня
Вспомогательные обёртки для преобразования между типами обработчиков:
// Route handler — wraps a ConnectionRouterEx to act as an upstream handler
func NewRouteHandlerEx(metadata InboundContext, router ConnectionRouterEx) UpstreamHandlerAdapterEx
// Upstream handler — wraps connection/packet handlers
func NewUpstreamHandlerEx(metadata InboundContext, connHandler, pktHandler) UpstreamHandlerAdapterExОни используются реализациями протоколов для цепочки обработчиков. Например, входящий VLESS декодирует заголовок, а затем использует NewRouteHandlerEx для передачи декодированного соединения маршрутизатору.
Паттерн менеджера
Все менеджеры следуют одному и тому же паттерну:
type XxxManager interface {
Lifecycle
Xxxs() []Xxx // list all
Get(tag string) (Xxx, bool) // get by tag
Remove(tag string) error // dynamic removal
Create(ctx, ..., tag, type, options) error // dynamic creation
}Менеджеры владеют своими реестрами и обрабатывают создание через паттерн реестра:
// Registry creates instances from type + options
type XxxRegistry interface {
Create(ctx, ..., tag, type string, options any) (Xxx, error)
}Трекер соединений
Используется Clash API и V2Ray API для мониторинга соединений:
type ConnectionTracker interface {
RoutedConnection(ctx, conn, metadata, matchedRule, matchOutbound) net.Conn
RoutedPacketConnection(ctx, conn, metadata, matchedRule, matchOutbound) N.PacketConn
}Трекер оборачивает соединения для подсчёта байтов и отслеживания активных соединений.