forked from gliderlabs/ssh
-
Notifications
You must be signed in to change notification settings - Fork 4
feat: Support keep-alive messages #3
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
Merged
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
5b53eed
feat: Add basic support for keep-alive messages
mtojek c82f559
WIP
mtojek 31b06a2
Server can keep connection alive
mtojek 4429de6
Support ServerAliveInterval on the client side
mtojek d39537c
KeepAliveCallback in ctx
mtojek cb4acdc
ClientAliveCountMax
mtojek 732401c
Example
mtojek 9593f2f
Address PR comments
mtojek c10a012
Fix: wantReply
mtojek 30ba47e
Use mutex
mtojek 17709ba
Use keepAliveCh
mtojek 6dbb85e
keepAliveRequestInProgress
mtojek 798e7d3
WIP
mtojek 6d96366
Metrics
mtojek 486b08a
Fix
mtojek 498552a
WIP
mtojek 63242bb
WIP
mtojek a30820a
Refactor: SessionKeepAlive
mtojek aeb836d
Fix
mtojek 3f79a58
Switch to 82
mtojek d8ccb1c
sess.Close
mtojek 9bf8356
KeepAliveMetrics as struct
mtojek bb3a84a
guard against keepAlive == nil
mtojek d09cb4d
remote sess.Exit
mtojek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"time" | ||
|
||
"github.com/gliderlabs/ssh" | ||
) | ||
|
||
var ( | ||
keepAliveInterval = 3 * time.Second | ||
keepAliveCountMax = 3 | ||
) | ||
|
||
func main() { | ||
ssh.Handle(func(s ssh.Session) { | ||
log.Println("new connection") | ||
i := 0 | ||
for { | ||
i += 1 | ||
log.Println("active seconds:", i) | ||
select { | ||
case <-time.After(time.Second): | ||
continue | ||
case <-s.Context().Done(): | ||
log.Println("connection closed") | ||
return | ||
} | ||
} | ||
}) | ||
|
||
log.Println("starting ssh server on port 2222...") | ||
log.Printf("keep-alive mode is on: %s\n", keepAliveInterval) | ||
server := &ssh.Server{ | ||
Addr: ":2222", | ||
ClientAliveInterval: keepAliveInterval, | ||
ClientAliveCountMax: keepAliveCountMax, | ||
} | ||
log.Fatal(server.ListenAndServe()) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package ssh | ||
|
||
import ( | ||
"sync" | ||
"time" | ||
) | ||
|
||
type SessionKeepAlive struct { | ||
clientAliveInterval time.Duration | ||
clientAliveCountMax int | ||
|
||
ticker *time.Ticker | ||
tickerCh <-chan time.Time | ||
lastReceived time.Time | ||
|
||
metrics KeepAliveMetrics | ||
|
||
m sync.Mutex | ||
closed bool | ||
} | ||
|
||
func NewSessionKeepAlive(clientAliveInterval time.Duration, clientAliveCountMax int) *SessionKeepAlive { | ||
var t *time.Ticker | ||
var tickerCh <-chan time.Time | ||
if clientAliveInterval > 0 { | ||
t = time.NewTicker(clientAliveInterval) | ||
tickerCh = t.C | ||
} | ||
|
||
return &SessionKeepAlive{ | ||
clientAliveInterval: clientAliveInterval, | ||
clientAliveCountMax: clientAliveCountMax, | ||
ticker: t, | ||
tickerCh: tickerCh, | ||
lastReceived: time.Now(), | ||
} | ||
} | ||
|
||
func (ska *SessionKeepAlive) RequestHandlerCallback() { | ||
ska.m.Lock() | ||
ska.metrics.RequestHandlerCalled++ | ||
ska.m.Unlock() | ||
|
||
ska.Reset() | ||
} | ||
|
||
func (ska *SessionKeepAlive) ServerRequestedKeepAliveCallback() { | ||
ska.m.Lock() | ||
defer ska.m.Unlock() | ||
|
||
ska.metrics.ServerRequestedKeepAlive++ | ||
} | ||
|
||
func (ska *SessionKeepAlive) Reset() { | ||
ska.m.Lock() | ||
defer ska.m.Unlock() | ||
|
||
ska.metrics.KeepAliveReplyReceived++ | ||
|
||
if ska.ticker != nil && !ska.closed { | ||
ska.lastReceived = time.Now() | ||
ska.ticker.Reset(ska.clientAliveInterval) | ||
johnstcn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
func (ska *SessionKeepAlive) Ticks() <-chan time.Time { | ||
return ska.tickerCh | ||
} | ||
|
||
func (ska *SessionKeepAlive) TimeIsUp() bool { | ||
ska.m.Lock() | ||
defer ska.m.Unlock() | ||
|
||
// true: Keep-alive reply not received | ||
return ska.lastReceived.Add(time.Duration(ska.clientAliveCountMax) * ska.clientAliveInterval).Before(time.Now()) | ||
} | ||
|
||
func (ska *SessionKeepAlive) Close() { | ||
ska.m.Lock() | ||
defer ska.m.Unlock() | ||
|
||
if ska.ticker != nil { | ||
ska.ticker.Stop() | ||
} | ||
ska.closed = true | ||
} | ||
|
||
func (ska *SessionKeepAlive) Metrics() KeepAliveMetrics { | ||
ska.m.Lock() | ||
defer ska.m.Unlock() | ||
|
||
return ska.metrics | ||
} | ||
|
||
type KeepAliveMetrics struct { | ||
RequestHandlerCalled int | ||
KeepAliveReplyReceived int | ||
ServerRequestedKeepAlive int | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.