56 lines
1 KiB
Go
56 lines
1 KiB
Go
|
package ssh
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"net"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type serverConn struct {
|
||
|
net.Conn
|
||
|
|
||
|
idleTimeout time.Duration
|
||
|
maxDeadline time.Time
|
||
|
closeCanceler context.CancelFunc
|
||
|
}
|
||
|
|
||
|
func (c *serverConn) Write(p []byte) (n int, err error) {
|
||
|
c.updateDeadline()
|
||
|
n, err = c.Conn.Write(p)
|
||
|
if _, isNetErr := err.(net.Error); isNetErr && c.closeCanceler != nil {
|
||
|
c.closeCanceler()
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (c *serverConn) Read(b []byte) (n int, err error) {
|
||
|
c.updateDeadline()
|
||
|
n, err = c.Conn.Read(b)
|
||
|
if _, isNetErr := err.(net.Error); isNetErr && c.closeCanceler != nil {
|
||
|
c.closeCanceler()
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (c *serverConn) Close() (err error) {
|
||
|
err = c.Conn.Close()
|
||
|
if c.closeCanceler != nil {
|
||
|
c.closeCanceler()
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (c *serverConn) updateDeadline() {
|
||
|
switch {
|
||
|
case c.idleTimeout > 0:
|
||
|
idleDeadline := time.Now().Add(c.idleTimeout)
|
||
|
if idleDeadline.Unix() < c.maxDeadline.Unix() || c.maxDeadline.IsZero() {
|
||
|
c.Conn.SetDeadline(idleDeadline)
|
||
|
return
|
||
|
}
|
||
|
fallthrough
|
||
|
default:
|
||
|
c.Conn.SetDeadline(c.maxDeadline)
|
||
|
}
|
||
|
}
|