Skip to content
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: no simple way to implement efficient keep alives #21478

Closed
nhooyr opened this issue Aug 16, 2017 · 5 comments
Closed

x/crypto/ssh: no simple way to implement efficient keep alives #21478

nhooyr opened this issue Aug 16, 2017 · 5 comments

Comments

@nhooyr
Copy link
Contributor

nhooyr commented Aug 16, 2017

In order to implement SSH Keep Alives, I'm currently doing something like this:

(conn is the net.Conn underlying the ssh client)

func keepAlive(cl *ssh.Client, conn net.Conn, done <-chan struct{}) error {
        const keepAliveInterval = time.Minute
	t := time.NewTicker(keepAliveInterval)
	defer t.Stop()
	for {
		deadline := time.Now().Add(keepAliveInterval).Add(15 * time.Second)
		err := conn.SetDeadline(deadline)
		if err != nil {
			return errors.Wrap(err, "failed to set deadline")
		}
		select {
		case <-t.C:
			_, _, err = cl.SendRequest("keepalive@golang.org", true, nil)
			if err != nil {
				return errors.Wrap(err, "failed to send keep alive")
			}
		case <-done:
			return nil
		}
	}
}

However, this is inefficient in that it will always send a request after the interval, even if some other packet was received over the connection confirming that the connection is alive. I'd like a way to send keep alives only if no data has been received over the connection in X amount of time.

I could wrap the net.Conn with my own interface to implement this (create a timer and reset it every time some data is read, and if the timer hits 0, send a keep alive) but I think this is a feature that deserves a easy to use solution as part of the library.

@gopherbot gopherbot added this to the Unreleased milestone Aug 16, 2017
@dsnet
Copy link
Member

dsnet commented Aug 16, 2017

Related to #19338.

@hanwen
Copy link
Contributor

hanwen commented Aug 30, 2017

can you point to some data that shows that the extra keepalive package is a performance problem?

@nhooyr
Copy link
Contributor Author

nhooyr commented Aug 30, 2017

Not sure if it's a significant problem, it's a matter of efficiency. I'll admit it's somewhat a premature optimization but network roundtrips are expensive and if we can easily avoid one, we should.

@hanwen
Copy link
Contributor

hanwen commented Sep 4, 2017

network roundtrips are really cheap. Did you know that every SSH read actually incurs a network roundtrip due to flow control?

@nhooyr
Copy link
Contributor Author

nhooyr commented Sep 12, 2017

Nope, I did not know that. However, I still think we should add this because SSH is often used over a very poor connection where those extra roundtrips could become significant.

I know this is all highly hypothetical and I don't have the time right now to benchmark or get data on this so if you don't find my argument convincing, feel free to close.

@hanwen hanwen closed this as completed Sep 12, 2017
@golang golang locked and limited conversation to collaborators Sep 12, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants