Documentation
¶
Index ¶
- Constants
- Variables
- func CopyReaderToSessionWriter(ctx context.Context, reader io.Reader, writer SessionWriter) error
- func CopySessionReaderToWriter(ctx context.Context, writer io.Writer, reader SessionReader) error
- func SetTerminalSize(ctx context.Context, writer SessionWriter, width int, height int) error
- type HandshakeResult
- type MuxPortForward
- type SessionReader
- type SessionReaderFunc
- type SessionReaderWriter
- type SessionWriter
- type SessionWriterFunc
- type Stream
- type TerminalSize
- type TerminalSizeFunc
Constants ¶
const ClientVersion = "1.2.331.1"
const DefaultTerminalHeight = 24
const DefaultTerminalWidth = 80
const TerminalWindowIntervalMilliseconds = 250
Variables ¶
var ( ErrSessionHandshake = errors.New("failed to do session handshake") ErrUnmarshalHandshake = errors.New("failed to unmarshal handshake request") ErrCreateHandshakeResp = errors.New("failed to create handshake response") ErrSendHandshakeResp = errors.New("failed to send handshake response to session") )
var ( ErrGetSessionMessage = errors.New("failed to get message from session") ErrWriteData = errors.New("failed to write data to writer") ErrWriteSessionMessage = errors.New("failed to write message to session") ErrReadData = errors.New("failed to read data from reader") ErrCreateSizeMessage = errors.New("failed to create size message") ErrWriteSizeMessage = errors.New("failed to write size message to session") )
var ( ErrHandshakeFailed = errors.New("handshake failed") ErrRemoteVersionNotSupported = errors.New("the remote ssm agent version does not support mux") ErrCreateSmuxClientFailed = errors.New("failed to create smux client") ErrFailedGetDialRequest = errors.New("failed to get dial request, context cancelled") ErrFailedGetDialResponse = errors.New("failed to get dial response") ErrFailedRequestDial = errors.New("failed to request dial") ErrFailedDial = errors.New("failed to dial") )
var DefaultTerminalSizeFunc = TerminalSizeFunc(func() (width int, height int, err error) { return DefaultTerminalWidth, DefaultTerminalHeight, nil })
var DiscardHandler slog.Handler = discardHandler{}
Backported from go1.24 to support earlier versions. DiscardHandler discards all log output. DiscardHandler.Enabled returns false for all Levels.
var MuxSupported version.FeatureFlag = "3.0.196.0"
var SmuxKeepAliveSupported version.FeatureFlag = "3.1.1511.0"
Functions ¶
func SetTerminalSize ¶
Types ¶
type HandshakeResult ¶
type HandshakeResult struct {
RemoteVersion string
}
func PerformHandshake ¶
func PerformHandshake(ctx context.Context, log *slog.Logger, session SessionReaderWriter) (HandshakeResult, error)
type MuxPortForward ¶
type MuxPortForward struct {
// Log provides structured logging for multiplexing events
Log *slog.Logger
// contains filtered or unexported fields
}
MuxPortForward provides multiplexed port forwarding over an SSM session using smux. It performs a handshake with the remote SSM agent to establish multiplexing capabilities, then creates a smux session over the SSM data stream. This allows multiple concurrent connections to be tunneled through a single SSM session.
The handler verifies that the remote SSM agent supports multiplexing before proceeding. If multiplexing is not supported, Start() will return an error.
func (*MuxPortForward) Dial ¶
Dial creates a new multiplexed connection over the SSM session. This method requests a new smux stream from the multiplexing session and returns it as a net.Conn. The connection can be used for bidirectional communication and will be automatically cleaned up when closed.
This method blocks until a connection is established, the context is cancelled, or the handler has stopped. Multiple concurrent calls to Dial are supported.
Returns ErrFailedDial if the connection cannot be established.
func (*MuxPortForward) Start ¶
func (m *MuxPortForward) Start(ctx context.Context, session SessionReaderWriter) error
Start initializes the multiplexed port forwarding handler. It performs a handshake with the remote SSM agent to verify multiplexing support, creates a smux session over the SSM data stream, and starts background goroutines to handle data copying and dial requests. The method returns after all background processing has been started.
Parameters:
- ctx: Context for the startup process (not used for handler lifetime)
- session: The SSM session to multiplex over
Returns ErrRemoteVersionNotSupported if the remote agent doesn't support multiplexing.
func (*MuxPortForward) Stop ¶
func (m *MuxPortForward) Stop()
Stop initiates a graceful shutdown of the multiplexed port forwarding handler. This method does NOT wait for the handler to fully shutdown - it only signals the shutdown request. The handler and its background goroutines may continue running after Stop() returns. Use Wait() to block until the handler has completely stopped.
Stop() is safe to call multiple times and from multiple goroutines.
func (*MuxPortForward) Wait ¶
func (m *MuxPortForward) Wait(ctx context.Context) error
Wait blocks until the handler has completely stopped or the context is cancelled. If the context is cancelled, Wait returns immediately with the context error, but the handler and its background goroutines may still be running. This means that if the context cancels, the handler could still be active.
Wait should be called after Start() to block until the handler terminates. It returns nil if the handler stopped gracefully, or an error if it stopped due to a failure.
type SessionReader ¶
type SessionReader interface {
Read(ctx context.Context) (*messages.AgentMessage, error)
}
type SessionReaderFunc ¶
type SessionReaderFunc func(ctx context.Context) (*messages.AgentMessage, error)
func (SessionReaderFunc) Read ¶
func (srf SessionReaderFunc) Read(ctx context.Context) (*messages.AgentMessage, error)
type SessionReaderWriter ¶
type SessionReaderWriter interface {
SessionReader
SessionWriter
}
type SessionWriter ¶
type SessionWriter interface {
Write(ctx context.Context, message *messages.AgentMessage) error
}
type SessionWriterFunc ¶
type SessionWriterFunc func(ctx context.Context, message *messages.AgentMessage) error
Adapters
func (SessionWriterFunc) Write ¶
func (swf SessionWriterFunc) Write(ctx context.Context, message *messages.AgentMessage) error
type Stream ¶
type Stream struct {
// Reader provides input data to send to the remote session (default os.Stdin)
Reader io.Reader
// Writer receives output data from the remote session (default os.Stdout)
Writer io.Writer
// TerminalSize provides terminal dimensions for the remote session
TerminalSize TerminalSize
// Log provides structured logging for stream events
Log *slog.Logger
// contains filtered or unexported fields
}
Stream provides bidirectional streaming over an SSM session, typically used for interactive shell sessions. It copies data between local Reader/Writer interfaces and the SSM session, while also managing terminal size updates for proper display formatting on the remote system.
The Stream handler automatically detects terminal capabilities and periodically sends terminal size updates to ensure proper formatting of interactive applications.
func (*Stream) Start ¶
func (s *Stream) Start(ctx context.Context, session SessionReaderWriter) error
Start initializes the streaming handler and begins bidirectional data copying. It starts background goroutines to copy data between the local Reader/Writer and the SSM session, and also starts a goroutine to periodically update the terminal size on the remote system. The method returns after all background processing has been started.
Parameters:
- ctx: Context for the startup process (not used for handler lifetime)
- session: The SSM session to stream data through
func (*Stream) Stop ¶
func (s *Stream) Stop()
Stop initiates a graceful shutdown of the streaming handler. This method does NOT wait for the handler to fully shutdown - it only signals the shutdown request. The handler and its background goroutines may continue running after Stop() returns. Use Wait() to block until the handler has completely stopped.
Stop() is safe to call multiple times and from multiple goroutines.
func (*Stream) Wait ¶
Wait blocks until the handler has completely stopped or the context is cancelled. If the context is cancelled, Wait returns immediately with the context error, but the handler and its background goroutines may still be running. This means that if the context cancels, the handler could still be active.
Wait should be called after Start() to block until the handler terminates. It returns nil if the handler stopped gracefully, or an error if it stopped due to a failure.