Skip to content

Commit 48f3a2f

Browse files
Fix panic when perIPConn.Close is called multiple times (#1993)
This happens when a perIPConn is idle and closed during Server.Shutdown() and then again closed by the WorkerFunc returning.
1 parent e380d34 commit 48f3a2f

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

peripconn.go

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,17 @@ type perIPConn struct {
4343

4444
perIPConnCounter *perIPConnCounter
4545

46-
ip uint32
46+
ip uint32
47+
lock sync.Mutex
4748
}
4849

4950
type perIPTLSConn struct {
5051
*tls.Conn
5152

5253
perIPConnCounter *perIPConnCounter
5354

54-
ip uint32
55+
ip uint32
56+
lock sync.Mutex
5557
}
5658

5759
func acquirePerIPConn(conn net.Conn, ip uint32, counter *perIPConnCounter) net.Conn {
@@ -85,17 +87,33 @@ func acquirePerIPConn(conn net.Conn, ip uint32, counter *perIPConnCounter) net.C
8587
}
8688

8789
func (c *perIPConn) Close() error {
88-
err := c.Conn.Close()
89-
c.perIPConnCounter.Unregister(c.ip)
90+
c.lock.Lock()
91+
cc := c.Conn
9092
c.Conn = nil
93+
c.lock.Unlock()
94+
95+
if cc == nil {
96+
return nil
97+
}
98+
99+
err := cc.Close()
100+
c.perIPConnCounter.Unregister(c.ip)
91101
c.perIPConnCounter.perIPConnPool.Put(c)
92102
return err
93103
}
94104

95105
func (c *perIPTLSConn) Close() error {
96-
err := c.Conn.Close()
97-
c.perIPConnCounter.Unregister(c.ip)
106+
c.lock.Lock()
107+
cc := c.Conn
98108
c.Conn = nil
109+
c.lock.Unlock()
110+
111+
if cc == nil {
112+
return nil
113+
}
114+
115+
err := cc.Close()
116+
c.perIPConnCounter.Unregister(c.ip)
99117
c.perIPConnCounter.perIPTLSConnPool.Put(c)
100118
return err
101119
}

0 commit comments

Comments
 (0)