Skip to content

Commit

Permalink
fix: always relisten local address when ssh connect closed
Browse files Browse the repository at this point in the history
  • Loading branch information
ashertz-dev committed Jul 6, 2022
1 parent 978199b commit ce5f9b2
Showing 1 changed file with 46 additions and 35 deletions.
81 changes: 46 additions & 35 deletions ssh/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,52 +290,63 @@ func (c *Client) run(ctx context.Context, conn *ssh.Client) {
break
}
} else {
for {
listen, err := net.Listen("tcp", rule.Local)
if err != nil {
tempDelay = c.getCurrentTempDelay(tempDelay)
go c.listenLocal(ctx, conn, rule)
}
}
}

c.Logger.Error(err, "listen",
"status", "retry",
"host", c.Host,
"user", c.User,
"local", rule.Local,
"reverse", rule.Reverse,
"retry_in", tempDelay,
)
func (c Client) listenLocal(ctx context.Context, conn *ssh.Client, rule Rule) {
var tempDelay time.Duration // how long to sleep on accept failure
ListenLocal:
for {
listen, err := net.Listen("tcp", rule.Local)
if err != nil {
tempDelay = c.getCurrentTempDelay(tempDelay)

select {
case <-ctx.Done():
c.Logger.V(2).Info("listen",
"status", "canceled",
"host", c.Host,
"user", c.User,
"local", rule.Local,
"reverse", rule.Reverse,
)
return
case <-time.After(tempDelay):
continue
}
}
tempDelay = 0
c.Logger.Error(err, "listen",
"status", "retry",
"host", c.Host,
"user", c.User,
"local", rule.Local,
"reverse", rule.Reverse,
"retry_in", tempDelay,
)

c.Logger.V(1).Info("listen",
"status", "ok",
select {
case <-ctx.Done():
c.Logger.V(2).Info("listen",
"status", "canceled",
"host", c.Host,
"user", c.User,
"local", rule.Local,
"reverse", rule.Reverse,
)
// accept message and proxy
go c.proxy(ctx, listen, rule.Remote, rule, func(ctx context.Context, network, address string) (net.Conn, error) {
return conn.Dial(network, address)
})
break
return
case <-time.After(tempDelay):
continue
}
}
}
tempDelay = 0

c.Logger.V(1).Info("listen",
"status", "ok",
"host", c.Host,
"user", c.User,
"local", rule.Local,
"reverse", rule.Reverse,
)

// accept message and proxy
go c.proxy(ctx, listen, rule.Remote, rule, func(ctx context.Context, network, address string) (net.Conn, error) {
return conn.Dial(network, address)
})

select {
case <-ctx.Done():
listen.Close()
break ListenLocal
}
}
}

func (c *Client) proxy(ctx context.Context, source net.Listener, destination string, rule Rule, dialFunc func(ctx context.Context, network, address string) (net.Conn, error)) {
Expand Down

0 comments on commit ce5f9b2

Please sign in to comment.