crypto/tls: pass argument to serverInit rather than using a field in Config.

Updates #20164.

Change-Id: Ib900095e7885f25cd779750674a712c770603ca8
Reviewed-on: https://go-review.googlesource.com/42137
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Adam Langley 2017-04-28 13:37:52 -07:00 committed by Brad Fitzpatrick
parent 20de5509db
commit b0bcb44715
2 changed files with 8 additions and 19 deletions

View File

@ -509,17 +509,13 @@ type Config struct {
serverInitOnce sync.Once // guards calling (*Config).serverInit serverInitOnce sync.Once // guards calling (*Config).serverInit
// mutex protects sessionTicketKeys and originalConfig. // mutex protects sessionTicketKeys.
mutex sync.RWMutex mutex sync.RWMutex
// sessionTicketKeys contains zero or more ticket keys. If the length // sessionTicketKeys contains zero or more ticket keys. If the length
// is zero, SessionTicketsDisabled must be true. The first key is used // is zero, SessionTicketsDisabled must be true. The first key is used
// for new tickets and any subsequent keys can be used to decrypt old // for new tickets and any subsequent keys can be used to decrypt old
// tickets. // tickets.
sessionTicketKeys []ticketKey sessionTicketKeys []ticketKey
// originalConfig is set to the Config that was passed to Server if
// this Config is returned by a GetConfigForClient callback. It's used
// by serverInit in order to copy session ticket keys if needed.
originalConfig *Config
} }
// ticketKeyNameLen is the number of bytes of identifier that is prepended to // ticketKeyNameLen is the number of bytes of identifier that is prepended to
@ -551,7 +547,7 @@ func ticketKeyFromBytes(b [32]byte) (key ticketKey) {
func (c *Config) Clone() *Config { func (c *Config) Clone() *Config {
// Running serverInit ensures that it's safe to read // Running serverInit ensures that it's safe to read
// SessionTicketsDisabled. // SessionTicketsDisabled.
c.serverInitOnce.Do(c.serverInit) c.serverInitOnce.Do(func() { c.serverInit(nil) })
var sessionTicketKeys []ticketKey var sessionTicketKeys []ticketKey
c.mutex.RLock() c.mutex.RLock()
@ -585,20 +581,17 @@ func (c *Config) Clone() *Config {
Renegotiation: c.Renegotiation, Renegotiation: c.Renegotiation,
KeyLogWriter: c.KeyLogWriter, KeyLogWriter: c.KeyLogWriter,
sessionTicketKeys: sessionTicketKeys, sessionTicketKeys: sessionTicketKeys,
// originalConfig is deliberately not duplicated.
} }
} }
func (c *Config) serverInit() { // serverInit is run under c.serverInitOnce to do initialization of c. If c was
// returned by a GetConfigForClient callback then the argument should be the
// Config that was passed to Server, otherwise it should be nil.
func (c *Config) serverInit(originalConfig *Config) {
if c.SessionTicketsDisabled || len(c.ticketKeys()) != 0 { if c.SessionTicketsDisabled || len(c.ticketKeys()) != 0 {
return return
} }
var originalConfig *Config
c.mutex.Lock()
originalConfig, c.originalConfig = c.originalConfig, nil
c.mutex.Unlock()
alreadySet := false alreadySet := false
for _, b := range c.SessionTicketKey { for _, b := range c.SessionTicketKey {
if b != 0 { if b != 0 {

View File

@ -40,7 +40,7 @@ type serverHandshakeState struct {
func (c *Conn) serverHandshake() error { func (c *Conn) serverHandshake() error {
// If this is the first server handshake, we generate a random key to // If this is the first server handshake, we generate a random key to
// encrypt the tickets with. // encrypt the tickets with.
c.config.serverInitOnce.Do(c.config.serverInit) c.config.serverInitOnce.Do(func() { c.config.serverInit(nil) })
hs := serverHandshakeState{ hs := serverHandshakeState{
c: c, c: c,
@ -129,11 +129,7 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
c.sendAlert(alertInternalError) c.sendAlert(alertInternalError)
return false, err return false, err
} else if newConfig != nil { } else if newConfig != nil {
newConfig.mutex.Lock() newConfig.serverInitOnce.Do(func() { newConfig.serverInit(c.config) })
newConfig.originalConfig = c.config
newConfig.mutex.Unlock()
newConfig.serverInitOnce.Do(newConfig.serverInit)
c.config = newConfig c.config = newConfig
} }
} }