mirror of
https://github.com/shazow/ssh-chat.git
synced 2025-09-24 03:42:32 -04:00
Added keepalive feature to keep clients connected
This commit is contained in:
parent
838f58e648
commit
e5b344f4eb
32
sshd/net.go
32
sshd/net.go
@ -2,6 +2,7 @@ package sshd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/shazow/rateio"
|
"github.com/shazow/rateio"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
@ -24,7 +25,7 @@ func ListenSSH(laddr string, config *ssh.ServerConfig) (*SSHListener, error) {
|
|||||||
return &l, nil
|
return &l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *SSHListener) handleConn(conn net.Conn) (*Terminal, error) {
|
func (l *SSHListener) handleConn(conn net.Conn, stop <-chan bool) (*Terminal, error) {
|
||||||
if l.RateLimit != nil {
|
if l.RateLimit != nil {
|
||||||
// TODO: Configurable Limiter?
|
// TODO: Configurable Limiter?
|
||||||
conn = ReadLimitConn(conn, l.RateLimit())
|
conn = ReadLimitConn(conn, l.RateLimit())
|
||||||
@ -38,11 +39,17 @@ func (l *SSHListener) handleConn(conn net.Conn) (*Terminal, error) {
|
|||||||
|
|
||||||
// FIXME: Disconnect if too many faulty requests? (Avoid DoS.)
|
// FIXME: Disconnect if too many faulty requests? (Avoid DoS.)
|
||||||
go ssh.DiscardRequests(requests)
|
go ssh.DiscardRequests(requests)
|
||||||
return NewSession(sshConn, channels)
|
terminal, err := NewSession(sshConn, channels)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
go KeepAlive(terminal, 2, stop)
|
||||||
|
return terminal, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accept incoming connections as terminal requests and yield them
|
// Accept incoming connections as terminal requests and yield them
|
||||||
func (l *SSHListener) ServeTerminal() <-chan *Terminal {
|
func (l *SSHListener) ServeTerminal() <-chan *Terminal {
|
||||||
|
stop := make(chan bool)
|
||||||
ch := make(chan *Terminal)
|
ch := make(chan *Terminal)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@ -59,7 +66,7 @@ func (l *SSHListener) ServeTerminal() <-chan *Terminal {
|
|||||||
|
|
||||||
// Goroutineify to resume accepting sockets early
|
// Goroutineify to resume accepting sockets early
|
||||||
go func() {
|
go func() {
|
||||||
term, err := l.handleConn(conn)
|
term, err := l.handleConn(conn, stop)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Printf("Failed to handshake: %v", err)
|
logger.Printf("Failed to handshake: %v", err)
|
||||||
return
|
return
|
||||||
@ -71,3 +78,22 @@ func (l *SSHListener) ServeTerminal() <-chan *Terminal {
|
|||||||
|
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KeepAlive Setup a new keepalive goroutine
|
||||||
|
func KeepAlive(t *Terminal, interval time.Duration, stop <-chan bool) {
|
||||||
|
// this sends keepalive packets every 2 seconds
|
||||||
|
// there's no useful response from these, so we can just abort if there's an error
|
||||||
|
tick := time.NewTicker(interval * time.Second)
|
||||||
|
defer tick.Stop()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-tick.C:
|
||||||
|
_, err := t.Channel.SendRequest("keepalive", true, nil)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case <-stop:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user