diff --git a/common.go b/common.go index 7199cd9..fc898e2 100644 --- a/common.go +++ b/common.go @@ -455,9 +455,13 @@ func ticketKeyFromBytes(b [32]byte) (key ticketKey) { return key } -// Clone returns a shallow clone of c. -// Only the exported fields are copied. +// Clone returns a shallow clone of c. It is safe to clone a Config that is +// being used concurrently by a TLS client or server. func (c *Config) Clone() *Config { + // Running serverInit ensures that it's safe to read + // SessionTicketsDisabled. + c.serverInitOnce.Do(c.serverInit) + var sessionTicketKeys []ticketKey c.mutex.RLock() sessionTicketKeys = c.sessionTicketKeys diff --git a/tls_test.go b/tls_test.go index d2a674d..87cfa3f 100644 --- a/tls_test.go +++ b/tls_test.go @@ -508,6 +508,10 @@ func TestClone(t *testing.T) { } c2 := c1.Clone() + // DeepEqual also compares unexported fields, thus c2 needs to have run + // serverInit in order to be DeepEqual to c1. Cloning it and discarding + // the result is sufficient. + c2.Clone() if !reflect.DeepEqual(&c1, c2) { t.Errorf("clone failed to copy a field")