1package daemon
2
3import (
4 "context"
5 "net"
6 "time"
7)
8
9type serverConn struct {
10 net.Conn
11
12 idleTimeout time.Duration
13 maxDeadline time.Time
14 closeCanceler context.CancelFunc
15}
16
17func (c *serverConn) Write(p []byte) (n int, err error) {
18 c.updateDeadline()
19 n, err = c.Conn.Write(p)
20 if _, isNetErr := err.(net.Error); isNetErr && c.closeCanceler != nil {
21 c.closeCanceler()
22 }
23 return
24}
25
26func (c *serverConn) Read(b []byte) (n int, err error) {
27 c.updateDeadline()
28 n, err = c.Conn.Read(b)
29 if _, isNetErr := err.(net.Error); isNetErr && c.closeCanceler != nil {
30 c.closeCanceler()
31 }
32 return
33}
34
35func (c *serverConn) Close() (err error) {
36 err = c.Conn.Close()
37 if c.closeCanceler != nil {
38 c.closeCanceler()
39 }
40 return
41}
42
43func (c *serverConn) updateDeadline() {
44 switch {
45 case c.idleTimeout > 0:
46 idleDeadline := time.Now().Add(c.idleTimeout)
47 if idleDeadline.Unix() < c.maxDeadline.Unix() || c.maxDeadline.IsZero() {
48 c.Conn.SetDeadline(idleDeadline)
49 return
50 }
51 fallthrough
52 default:
53 c.Conn.SetDeadline(c.maxDeadline)
54 }
55}