Skip to content

Commit 18f9020

Browse files
committed
Skip closing an initializing connection
Without this change, if a cert is updated (e.g. to add CNs) while the listener is in the middle of Accept()ing a new connection, the connection gets dropped, we'll see a message like this in the server logs: http: TLS handshake error from 127.0.0.1:51232: write tcp 127.0.7.1:8443->127.0.0.1:51232: use of closed network connection and the client (like a browser) won't necessarily reconnect. This change modifies the GetCertificate routine in the listener's tls.Config to keep track of the state of the incoming connections and only close connections that have completed GetCertificate and therefore are finished with their TLS handshake, so that only old established connections are closed.
1 parent 94e2249 commit 18f9020

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

listener.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,9 @@ func (l *listener) wrap(conn net.Conn) net.Conn {
275275

276276
type closeWrapper struct {
277277
net.Conn
278-
id int
279-
l *listener
278+
id int
279+
l *listener
280+
cert *tls.Certificate
280281
}
281282

282283
func (c *closeWrapper) close() error {
@@ -291,13 +292,14 @@ func (c *closeWrapper) Close() error {
291292
}
292293

293294
func (l *listener) getCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
295+
newConn := hello.Conn
294296
if hello.ServerName != "" {
295297
if err := l.updateCert(hello.ServerName); err != nil {
296298
return nil, err
297299
}
298300
}
299301

300-
return l.loadCert()
302+
return l.loadCert(newConn.(*closeWrapper))
301303
}
302304

303305
func (l *listener) updateCert(cn ...string) error {
@@ -339,7 +341,7 @@ func (l *listener) updateCert(cn ...string) error {
339341
return nil
340342
}
341343

342-
func (l *listener) loadCert() (*tls.Certificate, error) {
344+
func (l *listener) loadCert(currentConn *closeWrapper) (*tls.Certificate, error) {
343345
l.RLock()
344346
defer l.RUnlock()
345347

@@ -373,11 +375,17 @@ func (l *listener) loadCert() (*tls.Certificate, error) {
373375
if l.conns != nil && l.cert != nil {
374376
l.connLock.Lock()
375377
for _, conn := range l.conns {
378+
// Don't close a connection that's in the middle of completing a TLS handshake
379+
if conn.cert == nil {
380+
continue
381+
}
376382
_ = conn.close()
377383
}
378384
l.connLock.Unlock()
379385
}
380386

387+
l.conns[currentConn.id].cert = &cert
388+
381389
l.cert = &cert
382390
l.version = secret.ResourceVersion
383391
return l.cert, nil

0 commit comments

Comments
 (0)