Documentation
¶
Index ¶
- Constants
- func Context(ctx context.Context, inboundRegistry adapter.InboundRegistry, ...) context.Context
- func DNSTransportRegistry() *dns.TransportRegistry
- func EndpointRegistry() *endpoint.Registry
- func IPLimitActive() bool
- func InboundRegistry() *inbound.Registry
- func NewDefaultFactory(ctx context.Context, formatter log.Formatter, writer io.Writer, ...) log.ObservableFactory
- func NewFactory(options log.Options) (log.Factory, error)
- func OutboundRegistry() *outbound.Registry
- func ServiceRegistry() *service.Registry
- func SetConnGate(gate ConnGate)
- func SetIPLimitActive(active bool)
- type Box
- func (s *Box) Close() error
- func (s *Box) ConnTracker() *ConnTracker
- func (s *Box) Endpoint() adapter.EndpointManager
- func (s *Box) Inbound() adapter.InboundManager
- func (s *Box) Network() adapter.NetworkManager
- func (s *Box) Outbound() adapter.OutboundManager
- func (s *Box) PreStart() error
- func (s *Box) Router() adapter.Router
- func (s *Box) Start() error
- func (s *Box) StatsTracker() *StatsTracker
- func (s *Box) Uptime() uint32
- type CheckOutboundResult
- type ConnGate
- type ConnTracker
- func (c *ConnTracker) CloseConnByInbound(inbound string) int
- func (c *ConnTracker) CloseConnByInboundUsers(inbound string, keepUsers map[string]struct{}) int
- func (c *ConnTracker) CloseConnByUserIPs(drop map[string]map[netip.Addr]struct{}) int
- func (c *ConnTracker) Generation() uint64
- func (c *ConnTracker) Reset()
- func (c *ConnTracker) RoutedConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, ...) net.Conn
- func (c *ConnTracker) RoutedPacketConnection(ctx context.Context, conn network.PacketConn, metadata adapter.InboundContext, ...) network.PacketConn
- func (c *ConnTracker) UserIPs(want func(user string) bool) (map[string]map[netip.Addr]IPWindow, int64)
- type ConnectionInfo
- type Core
- func (c *Core) AddEndpoint(config []byte) error
- func (c *Core) AddInbound(config []byte) error
- func (c *Core) AddOutbound(config []byte) error
- func (c *Core) AddService(config []byte) error
- func (c *Core) GetCtx() context.Context
- func (c *Core) GetInstance() *Box
- func (c *Core) IsRunning() bool
- func (c *Core) RemoveEndpoint(tag string) error
- func (c *Core) RemoveInbound(tag string) error
- func (c *Core) RemoveOutbound(tag string) error
- func (c *Core) RemoveService(tag string) error
- func (c *Core) Start(sbConfig []byte) error
- func (c *Core) Stop() error
- func (c *Core) UpdateInboundUsers(config []byte) (bool, error)
- type Counter
- type IPWindow
- type Options
- type PlatformWriter
- type StatsTracker
- func (c *StatsTracker) GetStats() *[]model.Stats
- func (c *StatsTracker) Reset()
- func (c *StatsTracker) RoutedConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, ...) net.Conn
- func (c *StatsTracker) RoutedPacketConnection(ctx context.Context, conn network.PacketConn, metadata adapter.InboundContext, ...) network.PacketConn
Constants ¶
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 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 NewDefaultFactory ¶
func OutboundRegistry ¶
func ServiceRegistry ¶
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 (*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) StatsTracker ¶
func (s *Box) StatsTracker() *StatsTracker
type CheckOutboundResult ¶
func CheckOutbound ¶
func CheckOutbound(ctx context.Context, tag string, link string) (result CheckOutboundResult)
type ConnGate ¶ added in v1.7.0
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 (*Core) AddEndpoint ¶
func (*Core) AddInbound ¶
func (*Core) AddOutbound ¶
func (*Core) AddService ¶
func (*Core) GetInstance ¶
func (*Core) RemoveEndpoint ¶
func (*Core) RemoveInbound ¶
func (*Core) RemoveOutbound ¶
func (*Core) RemoveService ¶
type IPWindow ¶ added in v1.7.0
IPWindow is one source IP's liveness window for a user, expressed in the owning tracker's monotonic basis (see ConnTracker.epoch).
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 (*StatsTracker) RoutedPacketConnection ¶
func (c *StatsTracker) RoutedPacketConnection(ctx context.Context, conn network.PacketConn, metadata adapter.InboundContext, matchedRule adapter.Rule, matchOutbound adapter.Outbound) network.PacketConn
Source Files
¶
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. |