parent
357d2469d8
commit
f8183dd83e
14
README.md
14
README.md
|
@ -1,3 +1,15 @@
|
||||||
# goautossh
|
# goautossh
|
||||||
|
|
||||||
Autossh in Go.
|
Autossh in Go.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
```
|
||||||
|
goautossh <ssh-command>
|
||||||
|
```
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
goautossh ssh -N -L123:remote:123 x@y.com
|
||||||
|
```
|
||||||
|
|
30
goautossh.go
30
goautossh.go
|
@ -22,13 +22,13 @@ type SSHWatcher struct {
|
||||||
|
|
||||||
pingInterval time.Duration // Time between pings.
|
pingInterval time.Duration // Time between pings.
|
||||||
pingTimeout time.Duration // Fail timeout for ping loop.
|
pingTimeout time.Duration // Fail timeout for ping loop.
|
||||||
retryWait time.Duration //
|
retryWait time.Duration // Time to wait between failure and reconnect.
|
||||||
|
|
||||||
pingClientPort int
|
pingClientPort int
|
||||||
pingServerPort int
|
pingServerPort int
|
||||||
|
|
||||||
pingListener net.Listener // Server
|
pingListener net.Listener // Server. This is thread-safe.
|
||||||
pingConn net.Conn // Client
|
pingConn net.Conn // Client. This is thread-safe.
|
||||||
pingChan chan byte
|
pingChan chan byte
|
||||||
cmdStr string
|
cmdStr string
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
|
@ -39,9 +39,9 @@ func NewSSHWatcher() *SSHWatcher {
|
||||||
userCmd: strings.Join(os.Args[1:], " "),
|
userCmd: strings.Join(os.Args[1:], " "),
|
||||||
connectWait: 8 * time.Second,
|
connectWait: 8 * time.Second,
|
||||||
pingInterval: 8 * time.Second,
|
pingInterval: 8 * time.Second,
|
||||||
pingTimeout: 32 * time.Second,
|
pingTimeout: 24 * time.Second,
|
||||||
retryWait: 32 * time.Second,
|
retryWait: 16 * time.Second,
|
||||||
pingChan: make(chan byte),
|
pingChan: make(chan byte, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,15 +108,17 @@ func (w *SSHWatcher) startPingServer() StateFunc {
|
||||||
return w.sleepRetry
|
return w.sleepRetry
|
||||||
}
|
}
|
||||||
|
|
||||||
go w.runPingServer()
|
go w.runPingServer(w.pingListener)
|
||||||
|
|
||||||
time.Sleep(w.connectWait)
|
time.Sleep(w.connectWait)
|
||||||
|
|
||||||
return w.startPingClient
|
return w.startPingClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SSHWatcher) runPingServer() {
|
func (w *SSHWatcher) runPingServer(listener net.Listener) {
|
||||||
conn, err := w.pingListener.Accept()
|
defer listener.Close()
|
||||||
|
|
||||||
|
conn, err := listener.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to accept ping connection: %v", err)
|
log.Printf("Failed to accept ping connection: %v", err)
|
||||||
return
|
return
|
||||||
|
@ -152,23 +154,25 @@ func (w *SSHWatcher) startPingClient() StateFunc {
|
||||||
return w.sleepRetry
|
return w.sleepRetry
|
||||||
}
|
}
|
||||||
|
|
||||||
go w.runPingClient()
|
go w.runPingClient(w.pingConn)
|
||||||
|
|
||||||
return w.pingLoop
|
return w.pingLoop
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SSHWatcher) runPingClient() {
|
func (w *SSHWatcher) runPingClient(conn net.Conn) {
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
// Send pings.
|
// Send pings.
|
||||||
for {
|
for {
|
||||||
// Set timeout.
|
// Set timeout.
|
||||||
err := w.pingConn.SetWriteDeadline(time.Now().Add(w.pingTimeout))
|
err := conn.SetWriteDeadline(time.Now().Add(w.pingTimeout))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to set ping client write deadline: %v", err)
|
log.Printf("Failed to set ping client write deadline: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write ping data.
|
// Write ping data.
|
||||||
if _, err = w.pingConn.Write([]byte("1")); err != nil {
|
if _, err = conn.Write([]byte("1")); err != nil {
|
||||||
log.Printf("Failed to write ping data: %v", err)
|
log.Printf("Failed to write ping data: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue