handler

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 5, 2025 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const ClientVersion = "1.2.331.1"
View Source
const DefaultTerminalHeight = 24
View Source
const DefaultTerminalWidth = 80
View Source
const TerminalWindowIntervalMilliseconds = 250

Variables

View Source
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")
)
View Source
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")
)
View Source
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")
)
View Source
var DefaultTerminalSizeFunc = TerminalSizeFunc(func() (width int, height int, err error) {
	return DefaultTerminalWidth, DefaultTerminalHeight, nil
})
View Source
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.

View Source
var MuxSupported version.FeatureFlag = "3.0.196.0"
View Source
var SmuxKeepAliveSupported version.FeatureFlag = "3.1.1511.0"

Functions

func CopyReaderToSessionWriter

func CopyReaderToSessionWriter(ctx context.Context, reader io.Reader, writer SessionWriter) error

func CopySessionReaderToWriter

func CopySessionReaderToWriter(ctx context.Context, writer io.Writer, reader SessionReader) error

func SetTerminalSize

func SetTerminalSize(ctx context.Context, writer SessionWriter, width int, height int) error

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

func (m *MuxPortForward) Dial(ctx context.Context) (net.Conn, error)

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

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

func (s *Stream) 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 TerminalSize

type TerminalSize interface {
	Size() (width int, height int, err error)
}

type TerminalSizeFunc

type TerminalSizeFunc func() (width int, height int, err error)

func (TerminalSizeFunc) Size

func (gsf TerminalSizeFunc) Size() (width int, height int, err error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL