Skip to content

Canceling an SSH dial does not interrupt a stalled handshake #62

Description

@DivyamTalwar

Problem

dialSSH uses DialContext for TCP, but the following ssh.NewClientConn handshake has no context cancellation hook. A peer that accepts TCP without completing SSH leaves a canceled request blocked. Setting the original context deadline on the socket does not handle cancellation before that deadline or a context without a deadline.

Reproduction

Base: a1e6561e366455756c45a16a46647f882b3b6a1c.
Use the existing isolated SSH test fixture and point its alias at a loopback listener that accepts TCP but never sends its SSH identification. Begin dialSSH with context.WithCancel, read the client's SSH- identification at the peer to prove the handshake has started, and cancel. The dial remains blocked until the peer is closed. The same happens when explicitly canceling a context whose deadline is still 30 seconds away.

Expected behavior

Cancellation promptly interrupts the in-progress handshake and returns an error wrapping context.Canceled. After a successful handshake, canceling the original dial context must not close the established shared SSH client or force later requests to reconnect.

Proposed fix and validation

Close the raw connection via a context callback during the handshake, then stop/join the callback before publishing a successful shared client. Regression tests cover cancellation without a deadline, cancellation before a deadline, and a real SSH echo round-trip proving the completed shared tunnel outlives the dial context.
I would like to take this focused lifecycle fix because canceled diagnostics should not remain stuck in SSH setup. Host-key verification, authentication policy and server-side DNS behavior from #47 remain unchanged.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions