Documentation
¶
Overview ¶
Package ctrlchan provides multi-underlay control channel support for router-controller communication.
This package implements a priority-based messaging system over channel.MultiChannel, allowing control plane traffic to be distributed across multiple TCP connections (underlays) with different priority levels. This enables separation of time-sensitive control messages from bulk traffic like metrics.
Architecture ¶
A control channel uses channel.MultiChannel to manage multiple underlays:
- Default underlay: Carries normal control traffic (terminators, metrics, etc.)
- High-priority underlay: Reserved for time-sensitive messages (heartbeats, routing, circuit requests)
- Low-priority underlay: For bulk/background traffic (inspections, file-transfers)
Messages are routed to senders by priority level. Each underlay pulls from its designated message queue, with fallback behavior when dedicated underlays aren't available.
Usage ¶
Router side (dialing):
dialCtrlChan := ctrlchan.NewDialCtrlChannel(ctrlchan.DialCtrlChannelConfig{
Dialer: dialer,
MaxDefaultChannels: 1,
MaxHighPriorityChannels: 1, // Set to 0 if controller doesn't support multi-underlay
MaxLowPriorityChannels: 0,
UnderlayChangeCallback: changeCallback,
})
Controller side (listening):
listenerCtrlChan := ctrlchan.NewListenerCtrlChannel()
Both implementations satisfy CtrlChannelUnderlayHandler which combines CtrlChannel (for sending messages) with channel.UnderlayHandler (for MultiChannel integration).
Index ¶
- Constants
- type BaseCtrlChannel
- func (self *BaseCtrlChannel) ChannelCreated(ch channel.MultiChannel)
- func (self *BaseCtrlChannel) Close() error
- func (self *BaseCtrlChannel) GetChannel() channel.Channel
- func (self *BaseCtrlChannel) GetDefaultSender() channel.Sender
- func (self *BaseCtrlChannel) GetHighPriorityMsg(notifier *channel.CloseNotifier) (channel.Sendable, error)
- func (self *BaseCtrlChannel) GetHighPrioritySender() channel.Sender
- func (self *BaseCtrlChannel) GetLowPriorityMsg(notifier *channel.CloseNotifier) (channel.Sendable, error)
- func (self *BaseCtrlChannel) GetLowPrioritySender() channel.Sender
- func (self *BaseCtrlChannel) GetMessageSource(underlay channel.Underlay) channel.MessageSourceF
- func (self *BaseCtrlChannel) GetNextMsgDefault(notifier *channel.CloseNotifier) (channel.Sendable, error)
- func (self *BaseCtrlChannel) HandleTxFailed(_ channel.Underlay, _ channel.Sendable) bool
- func (self *BaseCtrlChannel) IsClosed() bool
- func (self *BaseCtrlChannel) PeerId() string
- type CtrlChannel
- type CtrlChannelUnderlayHandler
- type DialCtrlChannel
- func (self *DialCtrlChannel) CreateGroupedUnderlay(groupId string, groupSecret []byte, underlayType string, timeout time.Duration) (channel.Underlay, error)
- func (self *DialCtrlChannel) DialFailed(ch channel.MultiChannel, _ string, attempt int)
- func (self *DialCtrlChannel) HandleUnderlayAccepted(ch channel.MultiChannel, underlay channel.Underlay)
- func (self *DialCtrlChannel) HandleUnderlayClose(ch channel.MultiChannel, underlay channel.Underlay)
- func (self *DialCtrlChannel) IsConnected() bool
- func (self *DialCtrlChannel) Start(channel channel.MultiChannel)
- type DialCtrlChannelConfig
- type ListenerCtrlChannel
- func (self *ListenerCtrlChannel) HandleUnderlayAccepted(_ channel.MultiChannel, underlay channel.Underlay)
- func (self *ListenerCtrlChannel) HandleUnderlayClose(ch channel.MultiChannel, underlay channel.Underlay)
- func (self *ListenerCtrlChannel) IsConnected() bool
- func (self *ListenerCtrlChannel) Start(channel channel.MultiChannel)
Constants ¶
const ( ChannelTypeDefault string = "ctrl.default" ChannelTypeHighPriority string = "ctrl.high" ChannelTypeLowPriority string = "ctrl.low" )
Channel type constants identify the priority level of each underlay connection. These are used as the TypeHeader value when establishing grouped underlays.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BaseCtrlChannel ¶
type BaseCtrlChannel struct {
channel.SenderContext
// contains filtered or unexported fields
}
BaseCtrlChannel provides the core priority-based message routing for control channels. It maintains separate message queues for each priority level and routes messages to the appropriate underlay based on type.
Message flow:
- Callers send via GetDefaultSender(), GetHighPrioritySender(), or GetLowPrioritySender()
- Each underlay calls GetMessageSource() to get its message retrieval function
- The retrieval function pulls from the appropriate queue(s) based on underlay type
func NewBaseCtrlChannel ¶
func NewBaseCtrlChannel() *BaseCtrlChannel
NewBaseCtrlChannel creates the base control channel with priority message queues.
func (*BaseCtrlChannel) ChannelCreated ¶
func (self *BaseCtrlChannel) ChannelCreated(ch channel.MultiChannel)
func (*BaseCtrlChannel) Close ¶
func (self *BaseCtrlChannel) Close() error
func (*BaseCtrlChannel) GetChannel ¶
func (self *BaseCtrlChannel) GetChannel() channel.Channel
func (*BaseCtrlChannel) GetDefaultSender ¶
func (self *BaseCtrlChannel) GetDefaultSender() channel.Sender
func (*BaseCtrlChannel) GetHighPriorityMsg ¶
func (self *BaseCtrlChannel) GetHighPriorityMsg(notifier *channel.CloseNotifier) (channel.Sendable, error)
func (*BaseCtrlChannel) GetHighPrioritySender ¶
func (self *BaseCtrlChannel) GetHighPrioritySender() channel.Sender
func (*BaseCtrlChannel) GetLowPriorityMsg ¶
func (self *BaseCtrlChannel) GetLowPriorityMsg(notifier *channel.CloseNotifier) (channel.Sendable, error)
func (*BaseCtrlChannel) GetLowPrioritySender ¶
func (self *BaseCtrlChannel) GetLowPrioritySender() channel.Sender
func (*BaseCtrlChannel) GetMessageSource ¶
func (self *BaseCtrlChannel) GetMessageSource(underlay channel.Underlay) channel.MessageSourceF
func (*BaseCtrlChannel) GetNextMsgDefault ¶
func (self *BaseCtrlChannel) GetNextMsgDefault(notifier *channel.CloseNotifier) (channel.Sendable, error)
func (*BaseCtrlChannel) HandleTxFailed ¶
func (*BaseCtrlChannel) IsClosed ¶
func (self *BaseCtrlChannel) IsClosed() bool
func (*BaseCtrlChannel) PeerId ¶
func (self *BaseCtrlChannel) PeerId() string
type CtrlChannel ¶
type CtrlChannel interface {
PeerId() string
GetChannel() channel.Channel
GetDefaultSender() channel.Sender
GetHighPrioritySender() channel.Sender
GetLowPrioritySender() channel.Sender
IsConnected() bool
Close() error
IsClosed() bool
}
CtrlChannel provides access to priority-based message senders for control traffic.
type CtrlChannelUnderlayHandler ¶
type CtrlChannelUnderlayHandler interface {
CtrlChannel
channel.UnderlayHandler
}
CtrlChannelUnderlayHandler combines CtrlChannel with channel.UnderlayHandler. Implementations handle both message routing and underlay lifecycle management.
func NewDialCtrlChannel ¶
func NewDialCtrlChannel(config DialCtrlChannelConfig) CtrlChannelUnderlayHandler
NewDialCtrlChannel creates a control channel handler for the dialing side (router). The handler manages underlay constraints and automatically re-establishes connections when underlays are lost.
func NewListenerCtrlChannel ¶
func NewListenerCtrlChannel() CtrlChannelUnderlayHandler
NewListenerCtrlChannel creates a control channel handler for the listening side (controller). The controller side requires at least one default underlay to remain connected.
type DialCtrlChannel ¶
type DialCtrlChannel struct {
BaseCtrlChannel
// contains filtered or unexported fields
}
DialCtrlChannel implements CtrlChannelUnderlayHandler for the dialing side (router). It manages underlay constraints, automatically re-establishes lost connections, and notifies callers of connectivity changes via the callback.
func (*DialCtrlChannel) CreateGroupedUnderlay ¶
func (*DialCtrlChannel) DialFailed ¶
func (self *DialCtrlChannel) DialFailed(ch channel.MultiChannel, _ string, attempt int)
func (*DialCtrlChannel) HandleUnderlayAccepted ¶
func (self *DialCtrlChannel) HandleUnderlayAccepted(ch channel.MultiChannel, underlay channel.Underlay)
func (*DialCtrlChannel) HandleUnderlayClose ¶
func (self *DialCtrlChannel) HandleUnderlayClose(ch channel.MultiChannel, underlay channel.Underlay)
func (*DialCtrlChannel) IsConnected ¶
func (self *DialCtrlChannel) IsConnected() bool
IsConnected returns true if the dial-side ctrl channel has at least one active underlay.
func (*DialCtrlChannel) Start ¶
func (self *DialCtrlChannel) Start(channel channel.MultiChannel)
type DialCtrlChannelConfig ¶
type DialCtrlChannelConfig struct {
// Dialer creates new underlay connections to the controller.
Dialer channel.DialUnderlayFactory
// MaxDefaultChannels is the target number of default priority underlays (typically 1).
MaxDefaultChannels int
// MaxHighPriorityChannels is the target number of high priority underlays.
// Set to 1 if controller supports multi-underlay, 0 otherwise.
MaxHighPriorityChannels int
// MaxLowPriorityChannels is the target number of low priority underlays. Current 0, but anticipated to be used in future
MaxLowPriorityChannels int
// StartupDelay delays additional underlay establishment after the initial connection.
StartupDelay time.Duration
// UnderlayChangeCallback is invoked when the total underlay count changes.
UnderlayChangeCallback func(ch *DialCtrlChannel, oldCount, newCount uint32)
}
DialCtrlChannelConfig configures the dialing side of a control channel (router side).
type ListenerCtrlChannel ¶
type ListenerCtrlChannel struct {
BaseCtrlChannel
// contains filtered or unexported fields
}
ListenerCtrlChannel implements CtrlChannelUnderlayHandler for the listening side (controller). Unlike DialCtrlChannel, it requires at least one underlay to remain connected and will close the channel if all underlays are lost.
func (*ListenerCtrlChannel) HandleUnderlayAccepted ¶
func (self *ListenerCtrlChannel) HandleUnderlayAccepted(_ channel.MultiChannel, underlay channel.Underlay)
func (*ListenerCtrlChannel) HandleUnderlayClose ¶
func (self *ListenerCtrlChannel) HandleUnderlayClose(ch channel.MultiChannel, underlay channel.Underlay)
func (*ListenerCtrlChannel) IsConnected ¶
func (self *ListenerCtrlChannel) IsConnected() bool
IsConnected returns true if the listener-side ctrl channel has not been closed.
func (*ListenerCtrlChannel) Start ¶
func (self *ListenerCtrlChannel) Start(channel channel.MultiChannel)