core

package
v1.7.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: GPL-3.0 Imports: 86 Imported by: 0

Documentation

Index

Constants

View Source
const IPv6IdentityPrefixBits = 64

IPv6IdentityPrefixBits is how much of an IPv6 address identifies one subscriber. This is policy rather than mechanism -- /128 lets a single SLAAC host exhaust any limit through address rotation, /48 would hold an entire site to one slot -- but unlike the ban list it cannot live in the service layer: the normalized address is the map key every later stage groups on, so it has to be decided at track time. Change the trade-off here.

Exported because anything displaying a normalized v6 address has to say which prefix it stands for: the bare masked address is one no client ever used.

Variables

This section is empty.

Functions

func Context

func Context(
	ctx context.Context,
	inboundRegistry adapter.InboundRegistry,
	outboundRegistry adapter.OutboundRegistry,
	endpointRegistry adapter.EndpointRegistry,
	dnsTransportRegistry adapter.DNSTransportRegistry,
	serviceRegistry adapter.ServiceRegistry,
) context.Context

func DNSTransportRegistry

func DNSTransportRegistry() *dns.TransportRegistry

func EndpointRegistry

func EndpointRegistry() *endpoint.Registry

func IPLimitActive added in v1.7.0

func IPLimitActive() bool

IPLimitActive reports whether lastActive is being stamped at all. Readers of IPWindow.LastSeen need it: with no limit anywhere the field never moves off the connection's creation time, so an idle test against it measures age, not inactivity.

func InboundRegistry

func InboundRegistry() *inbound.Registry

func NewDefaultFactory

func NewDefaultFactory(
	ctx context.Context,
	formatter log.Formatter,
	writer io.Writer,
	filePath string,
) log.ObservableFactory

func NewFactory

func NewFactory(options log.Options) (log.Factory, error)

func OutboundRegistry

func OutboundRegistry() *outbound.Registry

func ServiceRegistry

func ServiceRegistry() *service.Registry

func SetConnGate added in v1.7.0

func SetConnGate(gate ConnGate)

SetConnGate installs (or with a nil gate, removes) the connection gate. It is read per connection instead of captured in NewConnTracker so that installing it never has to be ordered against core startup: Box, and with it every tracker, is rebuilt from scratch on each Start.

func SetIPLimitActive added in v1.7.0

func SetIPLimitActive(active bool)

SetIPLimitActive tells the trackers whether any client currently has an IP limit. When none does, lastActive has no reader -- planIPLimit only looks at clients with limit_ip > 0 -- so stamping it on every read and write would be a clock call per packet that nothing consumes.

Switching this on leaves already-established connections reporting their creation time until their next read, so the first scan afterwards may see them as idle. That errs towards not counting a connection rather than evicting a live one, and corrects itself on the following scan.

Types

type Box

type Box struct {
	// contains filtered or unexported fields
}

func NewBox

func NewBox(options Options) (*Box, error)

func (*Box) Close

func (s *Box) Close() error

func (*Box) ConnTracker

func (s *Box) ConnTracker() *ConnTracker

func (*Box) Endpoint

func (s *Box) Endpoint() adapter.EndpointManager

func (*Box) Inbound

func (s *Box) Inbound() adapter.InboundManager

func (*Box) Network

func (s *Box) Network() adapter.NetworkManager

func (*Box) Outbound

func (s *Box) Outbound() adapter.OutboundManager

func (*Box) PreStart

func (s *Box) PreStart() error

func (*Box) Router

func (s *Box) Router() adapter.Router

func (*Box) Start

func (s *Box) Start() error

func (*Box) StatsTracker

func (s *Box) StatsTracker() *StatsTracker

func (*Box) Uptime

func (s *Box) Uptime() uint32

type CheckOutboundResult

type CheckOutboundResult struct {
	OK    bool
	Delay uint16
	Error string
}

func CheckOutbound

func CheckOutbound(ctx context.Context, tag string, link string) (result CheckOutboundResult)

type ConnGate added in v1.7.0

type ConnGate func(user string, source netip.Addr) bool

ConnGate reports whether a freshly routed connection may proceed. The panel installs one to enforce per-client IP limits; the deny state behind it is policy that has to outlive a core restart, so it lives in the service layer and is reached through the package-level gate below rather than being copied into each tracker.

type ConnTracker

type ConnTracker struct {
	// contains filtered or unexported fields
}

func NewConnTracker

func NewConnTracker() *ConnTracker

func (*ConnTracker) CloseConnByInbound

func (c *ConnTracker) CloseConnByInbound(inbound string) int

func (*ConnTracker) CloseConnByInboundUsers added in v1.6.0

func (c *ConnTracker) CloseConnByInboundUsers(inbound string, keepUsers map[string]struct{}) int

func (*ConnTracker) CloseConnByUserIPs added in v1.7.0

func (c *ConnTracker) CloseConnByUserIPs(drop map[string]map[netip.Addr]struct{}) int

CloseConnByUserIPs closes every tracked connection whose (user, source IP) pair appears in drop. Unlike CloseConnByInboundUsers this takes a drop set rather than a keep set: the caller has already decided exactly which IPs lose their slot, and inverting that would force it to enumerate everyone staying.

func (*ConnTracker) Generation added in v1.7.0

func (c *ConnTracker) Generation() uint64

Generation identifies this tracker instance. Box is rebuilt on every core Start, so a caller holding state derived from the previous tracker's clock can use this to notice that the basis changed and discard it.

func (*ConnTracker) Reset

func (c *ConnTracker) Reset()

func (*ConnTracker) RoutedConnection

func (c *ConnTracker) RoutedConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, matchedRule adapter.Rule, matchOutbound adapter.Outbound) net.Conn

Closing the connection is the only way a tracker can refuse one: sing-box hands our return value straight to the outbound handler and has no reject path, so the outbound still dials once before the copy fails. Refusing at the inbound instead would mean editing the protocol copies in core/protocol/, which have to stay verbatim against upstream.

func (*ConnTracker) RoutedPacketConnection

func (c *ConnTracker) RoutedPacketConnection(ctx context.Context, conn network.PacketConn, metadata adapter.InboundContext, matchedRule adapter.Rule, matchOutbound adapter.Outbound) network.PacketConn

func (*ConnTracker) UserIPs added in v1.7.0

func (c *ConnTracker) UserIPs(want func(user string) bool) (map[string]map[netip.Addr]IPWindow, int64)

UserIPs snapshots the live source IPs of every user want accepts, returning now in the same monotonic basis as the windows so a caller never mixes clocks. The maps are freshly built because the caller reads them on a cron goroutine, well after the tracker lock is gone.

want filters (nil means every user) because this runs under the mutex that every connection setup and teardown takes: the walk over c.connections is unavoidable, but building a nested map for each of hundreds of users when the caller wants one of them is allocation held against the data plane. Both callers know exactly which names they need.

type ConnectionInfo

type ConnectionInfo struct {
	ID         string
	Conn       net.Conn
	PacketConn network.PacketConn
	Inbound    string
	User       string
	Type       string // "tcp" or "udp"

	// Source is the normalized client address, invalid when the inbound routed
	// by domain rather than IP. CreatedAt and lastActive are nanoseconds since
	// the owning tracker's epoch: a monotonic basis, so an NTP step cannot
	// reorder who connected first.
	Source    netip.Addr
	CreatedAt int64
	// contains filtered or unexported fields
}

type Core

type Core struct {
	// contains filtered or unexported fields
}

func NewCore

func NewCore() *Core

func (*Core) AddEndpoint

func (c *Core) AddEndpoint(config []byte) error

func (*Core) AddInbound

func (c *Core) AddInbound(config []byte) error

func (*Core) AddOutbound

func (c *Core) AddOutbound(config []byte) error

func (*Core) AddService

func (c *Core) AddService(config []byte) error

func (*Core) GetCtx

func (c *Core) GetCtx() context.Context

func (*Core) GetInstance

func (c *Core) GetInstance() *Box

func (*Core) IsRunning

func (c *Core) IsRunning() bool

func (*Core) RemoveEndpoint

func (c *Core) RemoveEndpoint(tag string) error

func (*Core) RemoveInbound

func (c *Core) RemoveInbound(tag string) error

func (*Core) RemoveOutbound

func (c *Core) RemoveOutbound(tag string) error

func (*Core) RemoveService

func (c *Core) RemoveService(tag string) error

func (*Core) Start

func (c *Core) Start(sbConfig []byte) error

func (*Core) Stop

func (c *Core) Stop() error

func (*Core) UpdateInboundUsers added in v1.6.0

func (c *Core) UpdateInboundUsers(config []byte) (bool, error)

type Counter

type Counter struct {
	// contains filtered or unexported fields
}

type IPWindow added in v1.7.0

type IPWindow struct {
	FirstSeen int64
	LastSeen  int64
}

IPWindow is one source IP's liveness window for a user, expressed in the owning tracker's monotonic basis (see ConnTracker.epoch).

type Options

type Options struct {
	option.Options
	Context context.Context
}

type PlatformWriter

type PlatformWriter struct{}

func (PlatformWriter) DisableColors

func (p PlatformWriter) DisableColors() bool

func (PlatformWriter) WriteMessage

func (p PlatformWriter) WriteMessage(level log.Level, message string)

type StatsTracker

type StatsTracker struct {
	// contains filtered or unexported fields
}

func NewStatsTracker

func NewStatsTracker() *StatsTracker

func (*StatsTracker) GetStats

func (c *StatsTracker) GetStats() *[]model.Stats

func (*StatsTracker) Reset

func (c *StatsTracker) Reset()

func (*StatsTracker) RoutedConnection

func (c *StatsTracker) RoutedConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, matchedRule adapter.Rule, matchOutbound adapter.Outbound) net.Conn

func (*StatsTracker) RoutedPacketConnection

func (c *StatsTracker) RoutedPacketConnection(ctx context.Context, conn network.PacketConn, metadata adapter.InboundContext, matchedRule adapter.Rule, matchOutbound adapter.Outbound) network.PacketConn

Directories

Path Synopsis
protocol
anytls
Verbatim copy of sing-box protocol/anytls/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
Verbatim copy of sing-box protocol/anytls/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
hysteria
Verbatim copy of sing-box protocol/hysteria/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
Verbatim copy of sing-box protocol/hysteria/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
hysteria2
Verbatim copy of sing-box protocol/hysteria2/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
Verbatim copy of sing-box protocol/hysteria2/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
trojan
Verbatim copy of sing-box protocol/trojan/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
Verbatim copy of sing-box protocol/trojan/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
tuic
Verbatim copy of sing-box protocol/tuic/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
Verbatim copy of sing-box protocol/tuic/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
vless
Verbatim copy of sing-box protocol/vless/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
Verbatim copy of sing-box protocol/vless/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
vmess
Verbatim copy of sing-box protocol/vmess/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.
Verbatim copy of sing-box protocol/vmess/inbound.go, moved into this module so the panel can reach the unexported `service`/`users` fields that the sing-box Inbound type does not expose.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL