@@ -11,6 +11,7 @@ import (
1111 "os/signal"
1212 "time"
1313
14+ "github.com/pkg/errors"
1415 "golang.org/x/crypto/ssh"
1516)
1617
@@ -34,7 +35,9 @@ var help = `
3435
3536 -ls, Local HTTP server host (default: localhost)
3637
37- -lp, Local HTTP server port (default: 7500)
38+ -lp, Local HTTP server port (default: 7500)
39+
40+ -a, Keep tunnel connection alive (default: false)
3841
3942 Read more:
4043 https://github.com/bleenco/vex
4548 remotePort = flag .Int ("p" , 2200 , "" )
4649 localServer = flag .String ("ls" , "localhost" , "" )
4750 localPort = flag .Int ("lp" , 7500 , "" )
51+ keepAlive = flag .Bool ("a" , false , "" )
4852)
4953
5054func main () {
@@ -82,6 +86,16 @@ func main() {
8286 log .Fatalln (fmt .Printf ("Dial INTO remote server error: %s" , err ))
8387 }
8488
89+ connectionDone := make (chan struct {})
90+ if * keepAlive {
91+ go func () {
92+ err = keepAliveTicker (serverConn , connectionDone )
93+ if err != nil {
94+ log .Fatalln (fmt .Printf ("Cannot initialize keep alive on connection: %s" , err ))
95+ }
96+ }()
97+ }
98+
8599 go func () {
86100 session , err := serverConn .NewSession ()
87101 if err != nil {
@@ -149,6 +163,22 @@ func handleClient(client net.Conn, remote net.Conn) {
149163 <- chDone
150164}
151165
166+ func keepAliveTicker (cl * ssh.Client , done <- chan struct {}) error {
167+ t := time .NewTicker (time .Minute )
168+ defer t .Stop ()
169+ for {
170+ select {
171+ case <- t .C :
172+ _ , _ , err := cl .SendRequest ("keepalive" , true , nil )
173+ if err != nil {
174+ return errors .Wrap (err , "failed to send keep alive" )
175+ }
176+ case <- done :
177+ return nil
178+ }
179+ }
180+ }
181+
152182func randomPort (min , max int ) int {
153183 rand .Seed (time .Now ().Unix ())
154184 return rand .Intn (max - min ) + min
0 commit comments