diff options
| author | Lena <lena@omega> | 2026-07-01 00:00:00 +0000 |
|---|---|---|
| committer | Lena <lena@omega> | 2026-07-01 00:00:00 +0000 |
| commit | a6640c603b7a15d3531980116fdce15d1743c865 (patch) | |
| tree | 64559109ced762369d190105833e3294993d4d40 /rsh | |
| parent | 8141ea0b4e29644327e3ba579e2caf083c50f6f6 (diff) | |
| download | rsend-a6640c603b7a15d3531980116fdce15d1743c865.tar.gz | |
rsh: bound the SSH handshake
ssh.Dial applies its Timeout only to the TCP connect, so a host that
accepts the connection and then stalls the SSH handshake hangs the
sync forever. Dial with a timeout, run the handshake under a deadline,
and clear the deadline once the connection is established.
Diffstat (limited to 'rsh')
| -rw-r--r-- | rsh/main.go | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/rsh/main.go b/rsh/main.go index dfcea0b..68b6e49 100644 --- a/rsh/main.go +++ b/rsh/main.go @@ -203,7 +203,24 @@ func dial(user, host string, hostKey ssh.HostKeyCallback) (*ssh.Client, error) { Timeout: dialTimeout, } addr := net.JoinHostPort(host, strconv.Itoa(port)) - return ssh.Dial("tcp", addr, cfg) + conn, err := net.DialTimeout("tcp", addr, dialTimeout) + if err != nil { + return nil, err + } + if err := conn.SetDeadline(time.Now().Add(dialTimeout)); err != nil { + conn.Close() + return nil, err + } + clientConn, chans, reqs, err := ssh.NewClientConn(conn, addr, cfg) + if err != nil { + conn.Close() + return nil, err + } + if err := conn.SetDeadline(time.Time{}); err != nil { + clientConn.Close() + return nil, err + } + return ssh.NewClient(clientConn, chans, reqs), nil } // parseTransport extracts the user, host, and remote command from the argument |