(ctx context.Context, conn net.Conn, address string, config *ssh.ClientConfig)
| 348 | } |
| 349 | |
| 350 | func handshakeSSHClient(ctx context.Context, conn net.Conn, address string, config *ssh.ClientConfig) (*SSHClient, error) { |
| 351 | _ = conn.SetDeadline(time.Now().Add(sshHandshakeTimeout)) |
| 352 | |
| 353 | connChan := make(chan sshHandshakeResult, 1) |
| 354 | go func() { |
| 355 | cc, chans, reqs, err := ssh.NewClientConn(conn, address, config) |
| 356 | connChan <- sshHandshakeResult{cc: cc, chans: chans, reqs: reqs, err: err} |
| 357 | }() |
| 358 | |
| 359 | select { |
| 360 | case <-ctx.Done(): |
| 361 | conn.Close() |
| 362 | return nil, errSSHConnectionCancelled |
| 363 | case result := <-connChan: |
| 364 | if result.err != nil { |
| 365 | conn.Close() |
| 366 | return nil, result.err |
| 367 | } |
| 368 | _ = conn.SetDeadline(time.Time{}) |
| 369 | return &SSHClient{client: ssh.NewClient(result.cc, result.chans, result.reqs)}, nil |
| 370 | } |
| 371 | } |
| 372 | |
| 373 | func minDuration(a, b time.Duration) time.Duration { |
| 374 | if a < b { |
no test coverage detected