-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/crypto/ssh: provide Client.DialContext method #20288
Comments
what exactly do you want controlled with deadline? The underlying TCP deadline? Or were you thinking of a SSH-level support for deadlines? |
My use case is not leaking goroutines. When my goroutine does a blocking read on an ssh.Channel it is always blocked, I can't signal that goroutine to shutdown. The usual way with a net.Conn is to set read and write deadlines, then poll for errors. So I was thinking of SSH channel level support for (both read and write) deadlines. |
My experimental fork https://github.com/glycerine/xcryptossh provides Dial with context and idle timers for Read/Write unblocking. |
Actually it's doable with user code without forking/modifying the lib.
|
This should be part of library as |
Context is a good way to handle cancelation so adding context to the Dial to allow for connection timeout is good thing. Followed the method defined at: golang/go#20288 (comment)
Change https://go.dev/cl/504735 mentions this issue: |
LGTM and the patch implementing this proposal is on Hold while the proposal is accepted. Can we add this proposal to the active column of the proposals project? Thank you cc @golang/proposal-review |
Seems unobjectionable. Adding to minutes, can probably likely accept next week. |
This proposal has been added to the active column of the proposals project |
No change in consensus, so accepted. 🎉
|
This change adds DialContext to ssh.Client, which opens a TCP-IP connection tunneled over the SSH connection. This is useful for proxying network connections, e.g. setting (net/http.Transport).DialContext. Fixes golang/go#20288. Change-Id: I110494c00962424ea803065535ebe2209364ac27 GitHub-Last-Rev: 3176984 GitHub-Pull-Request: golang#260 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/504735 Run-TryBot: Nicola Murino <[email protected]> Run-TryBot: Han-Wen Nienhuys <[email protected]> Auto-Submit: Nicola Murino <[email protected]> Reviewed-by: Han-Wen Nienhuys <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Nicola Murino <[email protected]> Commit-Queue: Nicola Murino <[email protected]>
I may be using it wrongly, but the usage is horrible. We have to stick with our wrapper for sane usability.
|
@prochac , from the first comment
Can you please share your wrapper? Maybe we can use it for a new proposal. Thank you. |
I just did 😅 Secretly, I hope someone will tell me that I'm doing something horribly wrong in my |
@prochac you’re not the first person to confuse the It’s relatively straightforward to add a top-level // DialContext starts a client connection to the given SSH server. It is a
// convenience function that connects to the given network address,
// initiates the SSH handshake, and then sets up a Client.
//
// The provided Context must be non-nil. If the context expires before the
// connection is complete, an error is returned. Once successfully connected,
// any expiration of the context will not affect the connection.
//
// See [Dial] for additional information.
func DialContext(ctx context.Context, network, addr string, config *ClientConfig) (*Client, error) {
d := net.Dialer{
Timeout: config.Timeout,
}
conn, err := d.DialContext(ctx, network, addr)
if err != nil {
return nil, err
}
type result struct {
client *Client
err error
}
ch := make(chan result)
go func() {
var client *Client
c, chans, reqs, err := NewClientConn(conn, addr, config)
if err == nil {
client = NewClient(c, chans, reqs)
}
select {
case ch <- result{client, err}:
case <-ctx.Done():
if client != nil {
client.Close()
}
}
}()
select {
case res := <-ch:
return res.client, res.err
case <-ctx.Done():
return nil, context.Cause(ctx)
}
} |
Similar to #17759, it would be useful for
ssh.Client
to provide aDialContext
method next to itsDial
method. We use SSH tunnels for connecting to domain registries that use IP allowlists.Note: per some confusion in the comments below, this does not refer to the top-level
Dial
func that opens an SSH connection. This proposal specifically refers to adding a(*ssh.Client).DialContext
method that opens a TCP/IP tunnel, (returning anet.Conn
), useful for proxying connections across an SSH connection.An implementation can be found here: CL 504735
Original context from 2017:
We’ve been progressively consolidating our timeout and deadline code to use
context.Context
throughout, implementing workarounds for dialers in APIs that lackContext
support.The text was updated successfully, but these errors were encountered: