package model import ( "context" "crypto/tls" "net" ) // Runtime contracts keep protocol implementations independent of orchestration. type DialFunc func(context.Context, string, string) (net.Conn, error) func IsSSH(protocol string) bool { return protocol == "ssh" || protocol == "sftp" } type EventFunc func(category, rule string) const EventReadOnlyRejected = "readonly_rejected" const EventProtocolRejected = "protocol_rejected" type TestResult struct { Cluster *ClusterInfo `json:"cluster,omitempty"` Compression string `json:"compression,omitempty"` Version string `json:"version,omitempty"` TLS bool `json:"tls"` Role string `json:"role,omitempty"` Fingerprint string `json:"fingerprint,omitempty"` HostKey string `json:"hostKey,omitempty"` } // Handler owns protocol negotiation. Manager enforces IP limits and closes // inbound connections on stop. Implementations must close upstream on cancel. type Handler interface { Serve(context.Context, net.Conn, Proxy, DialFunc, *tls.Config, EventFunc) error Test(context.Context, Proxy, DialFunc) (TestResult, error) }