diff --git a/dsn.go b/dsn.go index 199c9b177..ca1f2bf14 100644 --- a/dsn.go +++ b/dsn.go @@ -528,9 +528,7 @@ func parseDSNParams(cfg *Config, params string) (err error) { return fmt.Errorf("invalid value for TLS config name: %v", err) } - if tlsConfig, ok := tlsConfigRegister[name]; ok { - tlsConfig = cloneTLSConfig(tlsConfig) - + if tlsConfig := getTLSConfigClone(name); tlsConfig != nil { if len(tlsConfig.ServerName) == 0 && !tlsConfig.InsecureSkipVerify { host, _, err := net.SplitHostPort(cfg.Addr) if err == nil { diff --git a/utils.go b/utils.go index de117479d..82da83099 100644 --- a/utils.go +++ b/utils.go @@ -16,11 +16,13 @@ import ( "fmt" "io" "strings" + "sync" "sync/atomic" "time" ) var ( + tlsConfigLock sync.RWMutex tlsConfigRegister map[string]*tls.Config // Register for custom tls.Configs ) @@ -54,19 +56,32 @@ func RegisterTLSConfig(key string, config *tls.Config) error { return fmt.Errorf("key '%s' is reserved", key) } + tlsConfigLock.Lock() if tlsConfigRegister == nil { tlsConfigRegister = make(map[string]*tls.Config) } tlsConfigRegister[key] = config + tlsConfigLock.Unlock() return nil } // DeregisterTLSConfig removes the tls.Config associated with key. func DeregisterTLSConfig(key string) { + tlsConfigLock.Lock() if tlsConfigRegister != nil { delete(tlsConfigRegister, key) } + tlsConfigLock.Unlock() +} + +func getTLSConfigClone(key string) (config *tls.Config) { + tlsConfigLock.RLock() + if v, ok := tlsConfigRegister[key]; ok { + config = cloneTLSConfig(v) + } + tlsConfigLock.RUnlock() + return } // Returns the bool value of the input. @@ -745,6 +760,7 @@ func escapeStringQuotes(buf []byte, v string) []byte { /****************************************************************************** * Sync utils * ******************************************************************************/ + // noCopy may be embedded into structs which must not be copied // after the first use. //