Documentation
¶
Overview ¶
Minimum Go Version
We require Go 1.11 in order to support deadlines: This package uses two *os.File (stdin, stdout) to implement a net.Conn interface. As such, we need to support deadlines, and Go 1.10 introduced deadlines for certain types of *os.File (https://golang.org/doc/go1.10#os). However, apart from OS/FS constraints, deadlines on *os.File only work if the underlying FD can be added to Go's event pool mechanism, which generally requires the FD to be non-blocking at the time the *os.File is created. This is the case for os.Open and so on, but not for os.Std{in,out,err}, which are created using os.NewFile from the existing FDs 0, 1 and 2. Those are blocking by default, and Go does not change them to non-blocking because the parent process might be a terminal and not expect the tty to change to non-blocking mode after the Go process exits.
Hence, in Go 1.10, deadline operations on os.Std{in,out,err} fail with os.ErrDeadline. Go 1.11 improves the behavior of os.NewFile such that iff the FD passed to os.NewFile is already non-blocking, the *os.File / FD is part of the event loop, which makes deadlines work iff the OS supports it at all (this is the case for stdin, stdout, stderr, which are pipes in our specific use case). See https://github.com/golang/go/issues/24842#issuecomment-381268558
How do we deal with this issue in package netssh? We require Go 1.11 via build tag to get the os.NewFile behavior described above and set os.Std{in,out} to non-blocking before sending it over the unix control socket. See usage of github.com/ftrvxmtrx/fd in functions Proxy and Listener.Accept.
Index ¶
- func ContextWithLog(ctx context.Context, log Logger) context.Context
- func Proxy(ctx context.Context, server string) (err error)
- type Endpoint
- type IOError
- type Listener
- type Logger
- type ProtocolError
- type SSHConn
- func (conn *SSHConn) Close() error
- func (conn *SSHConn) CloseWrite() error
- func (conn *SSHConn) Cmd() *exec.Cmd
- func (conn *SSHConn) CmdCancel()
- func (conn *SSHConn) LocalAddr() net.Addr
- func (conn *SSHConn) Read(p []byte) (int, error)
- func (conn *SSHConn) RemoteAddr() net.Addr
- func (conn *SSHConn) SetDeadline(t time.Time) error
- func (conn *SSHConn) SetReadDeadline(t time.Time) error
- func (conn *SSHConn) SetWriteDeadline(t time.Time) error
- func (conn *SSHConn) Write(p []byte) (int, error)
- type SSHError
- type ServeConn
- func (f *ServeConn) Close() (err error)
- func (f *ServeConn) CloseWrite() error
- func (f *ServeConn) LocalAddr() net.Addr
- func (f *ServeConn) Read(p []byte) (n int, err error)
- func (f *ServeConn) RemoteAddr() net.Addr
- func (f *ServeConn) SetDeadline(t time.Time) error
- func (f *ServeConn) SetReadDeadline(t time.Time) error
- func (f *ServeConn) SetWriteDeadline(t time.Time) error
- func (f *ServeConn) Write(p []byte) (n int, err error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Endpoint ¶
type ProtocolError ¶
type ProtocolError struct {
What string
}
func (ProtocolError) Error ¶
func (e ProtocolError) Error() string
type SSHConn ¶
type SSHConn struct {
// contains filtered or unexported fields
}
func Dial ¶
Dial connects to the remote endpoint where it expects a command executing Proxy(). Dial performs a handshake consisting of the exchange of banner messages before returning the connection. If the handshake cannot be completed before dialCtx is Done(), the underlying ssh command is killed and the dialCtx.Err() returned. If the handshake completes, dialCtx's deadline does not affect the returned connection.
Errors returned are either dialCtx.Err(), or intances of ProtocolError or *SSHError
func (*SSHConn) CloseWrite ¶
func (*SSHConn) Cmd ¶
Cmd returns the underlying *exec.Cmd (the ssh client process) Use read-only, should not be necessary for regular users.
func (*SSHConn) CmdCancel ¶
func (conn *SSHConn) CmdCancel()
CmdCancel bypasses the normal shutdown mechanism of SSHConn (that is, calling Close) and cancels the process's context, which usually results in SIGKILL being sent to the process. Intended for integration tests, regular users shouldn't use it.
func (*SSHConn) Read ¶
Read implements io.Reader. It returns *IOError for any non-nil error that is != io.EOF.
func (*SSHConn) RemoteAddr ¶
type ServeConn ¶
type ServeConn struct {
// contains filtered or unexported fields
}
func (*ServeConn) CloseWrite ¶
func (*ServeConn) Read ¶
Read implements io.Reader. It returns *IOError for any non-nil error that is != io.EOF.