Documentation
¶
Overview ¶
Package ipc provides Unix socket pairs and typed RPC for engine-plugin communication.
Index ¶
- Constants
- func Authenticate(ctx context.Context, conn net.Conn, expectedToken string) (string, error)
- func AuthenticateWithLookup(ctx context.Context, conn net.Conn, sharedSecret string, ...) (string, error)
- func AuthenticateWithName(ctx context.Context, conn net.Conn, expectedToken, expectedName string) (string, error)
- func CertFingerprint(cert tls.Certificate) string
- func GenerateSelfSignedCert() (tls.Certificate, error)
- func ReadLineRaw(conn net.Conn, maxSize int) ([]byte, error)
- func SendAuth(_ context.Context, conn net.Conn, token, name string) error
- func StartListeners(addrs []string, cert tls.Certificate) ([]net.Listener, error)
- func TLSConfigWithFingerprint(fingerprint string) *tls.Config
- type PluginAcceptor
- func (pa *PluginAcceptor) Addr() net.Addr
- func (pa *PluginAcceptor) CertFP() string
- func (pa *PluginAcceptor) SetSecretLookup(lookup func(name string) (string, bool))
- func (pa *PluginAcceptor) Start()
- func (pa *PluginAcceptor) Stop()
- func (pa *PluginAcceptor) Token() string
- func (pa *PluginAcceptor) TokenForPlugin(name string) (string, error)
- func (pa *PluginAcceptor) WaitForPlugin(ctx context.Context, name string) (net.Conn, error)
- type PluginConn
- func (pc *PluginConn) CallBatchRPC(ctx context.Context, events [][]byte) (json.RawMessage, error)
- func (pc *PluginConn) CallRPC(ctx context.Context, method string, params any) (json.RawMessage, error)
- func (pc *PluginConn) Close() error
- func (pc *PluginConn) HasBridge() bool
- func (pc *PluginConn) ReadRequest(ctx context.Context) (*rpc.Request, error)
- func (pc *PluginConn) SendBye(ctx context.Context, reason string) error
- func (pc *PluginConn) SendCodedError(ctx context.Context, id uint64, code, message string) error
- func (pc *PluginConn) SendConfigApply(ctx context.Context, sections []rpc.ConfigDiffSection) (*rpc.ConfigApplyOutput, error)
- func (pc *PluginConn) SendConfigOperationApply(ctx context.Context, input *rpc.ConfigOperationApplyInput) (*rpc.ConfigOperationApplyOutput, error)
- func (pc *PluginConn) SendConfigOperationCommit(ctx context.Context, input *rpc.ConfigOperationCommitInput) (*rpc.ConfigOperationCommitOutput, error)
- func (pc *PluginConn) SendConfigOperationDecompose(ctx context.Context, input *rpc.ConfigOperationDecomposeInput) (*rpc.ConfigOperationDecomposeOutput, error)
- func (pc *PluginConn) SendConfigOperationRollback(ctx context.Context, input *rpc.ConfigOperationRollbackInput) (*rpc.ConfigOperationRollbackOutput, error)
- func (pc *PluginConn) SendConfigOperationVerify(ctx context.Context, input *rpc.ConfigOperationVerifyInput) (*rpc.ConfigOperationVerifyOutput, error)
- func (pc *PluginConn) SendConfigRollback(ctx context.Context, txID string) error
- func (pc *PluginConn) SendConfigVerify(ctx context.Context, sections []rpc.ConfigSection) (*rpc.ConfigVerifyOutput, error)
- func (pc *PluginConn) SendConfigure(ctx context.Context, sections []rpc.ConfigSection) error
- func (pc *PluginConn) SendDeclareCapabilities(ctx context.Context, input *rpc.DeclareCapabilitiesInput) error
- func (pc *PluginConn) SendDeclareRegistration(ctx context.Context, input *rpc.DeclareRegistrationInput) error
- func (pc *PluginConn) SendDecodeCapability(ctx context.Context, code uint8, hex string) (string, error)
- func (pc *PluginConn) SendDecodeNLRI(ctx context.Context, family, hex string) (string, error)
- func (pc *PluginConn) SendDeliverBatch(ctx context.Context, events []string) error
- func (pc *PluginConn) SendDeliverEvent(ctx context.Context, eventJSON string) error
- func (pc *PluginConn) SendDoctorCheck(ctx context.Context, name string) (*rpc.DoctorCheckOutput, error)
- func (pc *PluginConn) SendEncodeNLRI(ctx context.Context, family string, args []string) (string, error)
- func (pc *PluginConn) SendEnrichShow(ctx context.Context, input *rpc.EnrichShowInput) (*rpc.EnrichShowOutput, error)
- func (pc *PluginConn) SendError(ctx context.Context, id uint64, message string) error
- func (pc *PluginConn) SendExecuteCommand(ctx context.Context, serial, command string, args []string, peer string) (*rpc.ExecuteCommandOutput, error)
- func (pc *PluginConn) SendFilterUpdate(ctx context.Context, input *rpc.FilterUpdateInput) (*rpc.FilterUpdateOutput, error)
- func (pc *PluginConn) SendOK(ctx context.Context, id uint64) error
- func (pc *PluginConn) SendPostStartup(ctx context.Context) error
- func (pc *PluginConn) SendReady(ctx context.Context) error
- func (pc *PluginConn) SendResult(ctx context.Context, id uint64, data any) error
- func (pc *PluginConn) SendShareRegistry(ctx context.Context, commands []rpc.RegistryCommand) error
- func (pc *PluginConn) SendValidateOpen(ctx context.Context, input *rpc.ValidateOpenInput) (*rpc.ValidateOpenOutput, error)
- func (pc *PluginConn) SetBridge(b *rpc.DirectBridge)
Constants ¶
const MaxAuthFrameSize = 4096
MaxAuthFrameSize is the maximum size of an auth RPC frame (4 KB).
Variables ¶
This section is empty.
Functions ¶
func Authenticate ¶
Authenticate reads the first RPC from conn and validates the auth token. Returns the plugin name on success. The context deadline controls the auth timeout -- unauthenticated connections are closed when ctx expires. On failure, the connection is closed and an error is returned.
Uses byte-by-byte reading to avoid buffering ahead into the connection. This ensures the underlying net.Conn is clean for the caller to wrap in rpc.Conn + MuxConn without data loss from scanner buffering.
func AuthenticateWithLookup ¶
func AuthenticateWithLookup(ctx context.Context, conn net.Conn, sharedSecret string, lookup func(name string) (string, bool)) (string, error)
AuthenticateWithLookup reads the first RPC from conn and validates the auth token using a per-name secret lookup. The lookup function returns the expected secret for the given name, or false if the name is unknown. This supports per-client secrets where each managed client has its own token.
Falls back to sharedSecret if lookup returns false (plugin connections use shared secret).
func AuthenticateWithName ¶
func AuthenticateWithName(ctx context.Context, conn net.Conn, expectedToken, expectedName string) (string, error)
AuthenticateWithName reads the first RPC from conn and validates that both the auth token and the plugin name match the expected values. This enforces name binding: a plugin cannot use its token to impersonate another plugin. On failure, the connection is closed and an error is returned.
func CertFingerprint ¶
func CertFingerprint(cert tls.Certificate) string
CertFingerprint returns the hex-encoded SHA-256 fingerprint of a TLS certificate's DER-encoded bytes. Used to pass the server cert identity to plugins for pinning.
func GenerateSelfSignedCert ¶
func GenerateSelfSignedCert() (tls.Certificate, error)
GenerateSelfSignedCert creates an ephemeral self-signed TLS certificate. Used when no user-provided certificate is configured.
func ReadLineRaw ¶
ReadLineRaw reads bytes one at a time until newline or maxSize. Avoids bufio.Scanner to prevent buffering ahead into the connection.
func SendAuth ¶
SendAuth sends the auth RPC to the engine as #0 auth {"token":"...","name":"..."}. Writes directly to conn without creating rpc.Conn (avoids reader goroutine leak).
func StartListeners ¶
StartListeners creates TLS listeners on each of the given addresses. Returns all listeners on success, or an error if any address fails to bind. Returns an error if addrs is empty. On error, all successfully created listeners are closed before returning.
func TLSConfigWithFingerprint ¶
TLSConfigWithFingerprint returns a TLS client config that verifies the server certificate matches the given SHA-256 fingerprint. If fingerprint is empty, uses InsecureSkipVerify (useful during development or when fingerprint is unavailable).
Types ¶
type PluginAcceptor ¶
type PluginAcceptor struct {
// contains filtered or unexported fields
}
PluginAcceptor manages a TLS listener and routes authenticated connections to waiting plugin processes by name. The server creates one acceptor from the hub config and shares it with all external processes.
func NewPluginAcceptor ¶
func NewPluginAcceptor(listener net.Listener, secret, certFP string) *PluginAcceptor
NewPluginAcceptor creates an acceptor that authenticates connections on the given listener using the shared secret. Call Start() to begin accepting. certFP is the hex-encoded SHA-256 fingerprint of the server cert (from CertFingerprint).
func (*PluginAcceptor) Addr ¶
func (pa *PluginAcceptor) Addr() net.Addr
Addr returns the listener's address (useful when bound to port 0 in tests).
func (*PluginAcceptor) CertFP ¶
func (pa *PluginAcceptor) CertFP() string
CertFP returns the hex-encoded SHA-256 fingerprint of the server certificate.
func (*PluginAcceptor) SetSecretLookup ¶
func (pa *PluginAcceptor) SetSecretLookup(lookup func(name string) (string, bool))
SetSecretLookup sets a per-client secret lookup function. When set, auth first checks per-client secrets by name, falling back to the shared secret if the name is not found in the lookup.
func (*PluginAcceptor) Start ¶
func (pa *PluginAcceptor) Start()
Start begins the accept loop in a goroutine. Each accepted connection is authenticated and routed to the matching WaitForPlugin caller.
func (*PluginAcceptor) Stop ¶
func (pa *PluginAcceptor) Stop()
Stop closes the listener and cancels the accept loop.
func (*PluginAcceptor) Token ¶
func (pa *PluginAcceptor) Token() string
Token returns the shared auth token. Used by startExternal to pass via env var.
func (*PluginAcceptor) TokenForPlugin ¶
func (pa *PluginAcceptor) TokenForPlugin(name string) (string, error)
TokenForPlugin returns a unique random token for the given plugin name. Generates a new 32-byte token on first call for each name; subsequent calls return the same token. Safe for concurrent use.
func (*PluginAcceptor) WaitForPlugin ¶
WaitForPlugin blocks until a plugin with the given name connects and authenticates, or until ctx expires. Returns the authenticated connection.
type PluginConn ¶
PluginConn provides typed RPC communication over a plugin connection. It embeds *rpc.Conn for low-level newline-framed JSON RPC and adds typed methods for each YANG RPC in the plugin protocol.
PluginConn supports two wiring modes:
- Direct: NewPluginConn(conn, conn) -- read and write on the same connection.
- Muxed: NewMuxPluginConn(mux) -- all traffic via MuxConn (production path). ReadRequest reads from MuxConn.Requests(), CallRPC/SendResult delegate to MuxConn.
func NewMuxPluginConn ¶
func NewMuxPluginConn(mux *rpc.MuxConn) *PluginConn
NewMuxPluginConn creates a PluginConn backed by a MuxConn for single-connection mode. ReadRequest reads from MuxConn.Requests(), all outbound calls go through MuxConn.CallRPC().
func NewPluginConn ¶
func NewPluginConn(readConn, writeConn net.Conn) *PluginConn
NewPluginConn creates a PluginConn that reads from readConn and writes to writeConn. For per-socket wiring (matching SDK pattern), pass the same conn for both arguments. For cross-socket wiring (test scenarios), pass different conns.
func (*PluginConn) CallBatchRPC ¶
func (pc *PluginConn) CallBatchRPC(ctx context.Context, events [][]byte) (json.RawMessage, error)
CallBatchRPC sends a batch delivery frame. In single-conn mode, converts [][]byte events to []json.RawMessage to preserve raw JSON embedding.
func (*PluginConn) CallRPC ¶
func (pc *PluginConn) CallRPC(ctx context.Context, method string, params any) (json.RawMessage, error)
CallRPC sends an RPC and waits for the response. Routes through: bridge (if set) -> MuxConn (if set) -> direct Conn. Most typed methods call this; SendExecuteCommand has a typed bridge fast path.
func (*PluginConn) Close ¶
func (pc *PluginConn) Close() error
Close closes the underlying connection.
func (*PluginConn) HasBridge ¶
func (pc *PluginConn) HasBridge() bool
HasBridge reports whether bridge transport has been activated. When true, the SDK has closed its end of the mux (all plugin->engine RPCs flow via DirectBridge), so server-side mux readers must NOT treat mux close as a plugin-exited signal.
func (*PluginConn) ReadRequest ¶
ReadRequest reads the next plugin request. In muxed mode, reads from MuxConn.Requests() channel. In direct mode, reads from the underlying connection.
func (*PluginConn) SendBye ¶
func (pc *PluginConn) SendBye(ctx context.Context, reason string) error
SendBye sends a shutdown request to the plugin.
func (*PluginConn) SendCodedError ¶
SendCodedError sends an error RPC response with a specific error code.
func (*PluginConn) SendConfigApply ¶
func (pc *PluginConn) SendConfigApply(ctx context.Context, sections []rpc.ConfigDiffSection) (*rpc.ConfigApplyOutput, error)
SendConfigApply sends a config apply request to the plugin. Returns the plugin's apply result (status + optional error).
func (*PluginConn) SendConfigOperationApply ¶
func (pc *PluginConn) SendConfigOperationApply(ctx context.Context, input *rpc.ConfigOperationApplyInput) (*rpc.ConfigOperationApplyOutput, error)
SendConfigOperationApply sends one operation apply request.
func (*PluginConn) SendConfigOperationCommit ¶
func (pc *PluginConn) SendConfigOperationCommit(ctx context.Context, input *rpc.ConfigOperationCommitInput) (*rpc.ConfigOperationCommitOutput, error)
SendConfigOperationCommit finalizes operation journals for a transaction.
func (*PluginConn) SendConfigOperationDecompose ¶
func (pc *PluginConn) SendConfigOperationDecompose(ctx context.Context, input *rpc.ConfigOperationDecomposeInput) (*rpc.ConfigOperationDecomposeOutput, error)
SendConfigOperationDecompose sends one operation decomposition request.
func (*PluginConn) SendConfigOperationRollback ¶
func (pc *PluginConn) SendConfigOperationRollback(ctx context.Context, input *rpc.ConfigOperationRollbackInput) (*rpc.ConfigOperationRollbackOutput, error)
SendConfigOperationRollback sends operation rollback for a transaction.
func (*PluginConn) SendConfigOperationVerify ¶
func (pc *PluginConn) SendConfigOperationVerify(ctx context.Context, input *rpc.ConfigOperationVerifyInput) (*rpc.ConfigOperationVerifyOutput, error)
SendConfigOperationVerify sends one operation verification request.
func (*PluginConn) SendConfigRollback ¶
func (pc *PluginConn) SendConfigRollback(ctx context.Context, txID string) error
SendConfigRollback sends a config rollback request to the plugin. The plugin is expected to undo any changes applied under this transaction (typically via its SDK journal) and return without error. A non-nil error implies the plugin is broken and needs restart; the transaction orchestrator reports it with CodeBroken in the rollback ack.
func (*PluginConn) SendConfigVerify ¶
func (pc *PluginConn) SendConfigVerify(ctx context.Context, sections []rpc.ConfigSection) (*rpc.ConfigVerifyOutput, error)
SendConfigVerify sends a config verification request to the plugin. Returns the plugin's validation result (status + optional error).
func (*PluginConn) SendConfigure ¶
func (pc *PluginConn) SendConfigure(ctx context.Context, sections []rpc.ConfigSection) error
SendConfigure sends Stage 2: configure to the plugin.
func (*PluginConn) SendDeclareCapabilities ¶
func (pc *PluginConn) SendDeclareCapabilities(ctx context.Context, input *rpc.DeclareCapabilitiesInput) error
SendDeclareCapabilities sends Stage 3: declare-capabilities to the engine.
func (*PluginConn) SendDeclareRegistration ¶
func (pc *PluginConn) SendDeclareRegistration(ctx context.Context, input *rpc.DeclareRegistrationInput) error
SendDeclareRegistration sends Stage 1: declare-registration to the engine.
func (*PluginConn) SendDecodeCapability ¶
func (pc *PluginConn) SendDecodeCapability(ctx context.Context, code uint8, hex string) (string, error)
SendDecodeCapability requests capability decoding from the plugin. Returns JSON result.
func (*PluginConn) SendDecodeNLRI ¶
SendDecodeNLRI requests NLRI decoding from the plugin. Returns JSON result.
func (*PluginConn) SendDeliverBatch ¶
func (pc *PluginConn) SendDeliverBatch(ctx context.Context, events []string) error
SendDeliverBatch sends multiple BGP events to the plugin in a single batch. Uses a pooled buffer to construct the JSON-RPC frame directly, bypassing json.Marshal and FrameWriter.Write allocations. One write + one ack per batch.
func (*PluginConn) SendDeliverEvent ¶
func (pc *PluginConn) SendDeliverEvent(ctx context.Context, eventJSON string) error
SendDeliverEvent sends a BGP event to the plugin via callback.
func (*PluginConn) SendDoctorCheck ¶
func (pc *PluginConn) SendDoctorCheck(ctx context.Context, name string) (*rpc.DoctorCheckOutput, error)
SendDoctorCheck invokes a plugin's doctor check callback and returns diagnostics.
func (*PluginConn) SendEncodeNLRI ¶
func (pc *PluginConn) SendEncodeNLRI(ctx context.Context, family string, args []string) (string, error)
SendEncodeNLRI requests NLRI encoding from the plugin. Returns hex result.
func (*PluginConn) SendEnrichShow ¶
func (pc *PluginConn) SendEnrichShow(ctx context.Context, input *rpc.EnrichShowInput) (*rpc.EnrichShowOutput, error)
SendEnrichShow requests show enrichment from the plugin.
func (*PluginConn) SendExecuteCommand ¶
func (pc *PluginConn) SendExecuteCommand(ctx context.Context, serial, command string, args []string, peer string) (*rpc.ExecuteCommandOutput, error)
SendExecuteCommand requests command execution from the plugin.
func (*PluginConn) SendFilterUpdate ¶
func (pc *PluginConn) SendFilterUpdate(ctx context.Context, input *rpc.FilterUpdateInput) (*rpc.FilterUpdateOutput, error)
SendFilterUpdate sends a filter-update request to the plugin. The plugin evaluates the update against the named filter and returns accept/reject/modify.
func (*PluginConn) SendOK ¶
func (pc *PluginConn) SendOK(ctx context.Context, id uint64) error
SendOK sends an empty successful RPC response.
func (*PluginConn) SendPostStartup ¶
func (pc *PluginConn) SendPostStartup(ctx context.Context) error
SendPostStartup notifies the plugin that every startup phase has completed and both the plugin registry and the dispatcher command registry have been frozen. Plugins that registered a handler via OnAllPluginsReady run it on receipt; others silently no-op. Delivered best-effort: callers are expected to swallow transient errors (closed connection, timeout) rather than treat them as fatal.
func (*PluginConn) SendReady ¶
func (pc *PluginConn) SendReady(ctx context.Context) error
SendReady sends Stage 5: ready to the engine.
func (*PluginConn) SendResult ¶
SendResult sends a successful RPC response.
func (*PluginConn) SendShareRegistry ¶
func (pc *PluginConn) SendShareRegistry(ctx context.Context, commands []rpc.RegistryCommand) error
SendShareRegistry sends Stage 4: share-registry to the plugin.
func (*PluginConn) SendValidateOpen ¶
func (pc *PluginConn) SendValidateOpen(ctx context.Context, input *rpc.ValidateOpenInput) (*rpc.ValidateOpenOutput, error)
SendValidateOpen sends a validate-open request to the plugin. Returns the plugin's validation result (accept/reject with optional NOTIFICATION codes).
func (*PluginConn) SetBridge ¶
func (pc *PluginConn) SetBridge(b *rpc.DirectBridge)
SetBridge activates bridge transport for engine->plugin callbacks. After this, CallRPC routes through bridge.SendCallback instead of the pipe.