From fa4a9aaca9a7dbac2b5cef89d1cd5ee3bebd8106 Mon Sep 17 00:00:00 2001 From: Julien Schmidt Date: Sat, 10 Jun 2017 05:25:39 +0800 Subject: [PATCH 1/2] utils: guard tlsConfigRegister by a lock Fixes #610 --- dsn.go | 3 +++ utils.go | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/dsn.go b/dsn.go index 199c9b177..5d9a84ad2 100644 --- a/dsn.go +++ b/dsn.go @@ -528,8 +528,10 @@ func parseDSNParams(cfg *Config, params string) (err error) { return fmt.Errorf("invalid value for TLS config name: %v", err) } + tlsConfigLock.RLock() if tlsConfig, ok := tlsConfigRegister[name]; ok { tlsConfig = cloneTLSConfig(tlsConfig) + tlsConfigLock.RUnlock() if len(tlsConfig.ServerName) == 0 && !tlsConfig.InsecureSkipVerify { host, _, err := net.SplitHostPort(cfg.Addr) @@ -541,6 +543,7 @@ func parseDSNParams(cfg *Config, params string) (err error) { cfg.TLSConfig = name cfg.tls = tlsConfig } else { + tlsConfigLock.RUnlock() return errors.New("invalid value / unknown config name: " + name) } } diff --git a/utils.go b/utils.go index bd11c6975..680747d3b 100644 --- a/utils.go +++ b/utils.go @@ -16,10 +16,12 @@ import ( "fmt" "io" "strings" + "sync" "time" ) var ( + tlsConfigLock sync.RWMutex tlsConfigRegister map[string]*tls.Config // Register for custom tls.Configs ) @@ -53,19 +55,23 @@ 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() } // Returns the bool value of the input. From 808c9b4883bb6139ec2cfd1fc4b310f9d531c307 Mon Sep 17 00:00:00 2001 From: Julien Schmidt Date: Sat, 10 Jun 2017 05:35:44 +0800 Subject: [PATCH 2/2] utils: move TLSConfig lock and clone logic to helper func --- dsn.go | 7 +------ utils.go | 9 +++++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/dsn.go b/dsn.go index 5d9a84ad2..ca1f2bf14 100644 --- a/dsn.go +++ b/dsn.go @@ -528,11 +528,7 @@ func parseDSNParams(cfg *Config, params string) (err error) { return fmt.Errorf("invalid value for TLS config name: %v", err) } - tlsConfigLock.RLock() - if tlsConfig, ok := tlsConfigRegister[name]; ok { - tlsConfig = cloneTLSConfig(tlsConfig) - tlsConfigLock.RUnlock() - + if tlsConfig := getTLSConfigClone(name); tlsConfig != nil { if len(tlsConfig.ServerName) == 0 && !tlsConfig.InsecureSkipVerify { host, _, err := net.SplitHostPort(cfg.Addr) if err == nil { @@ -543,7 +539,6 @@ func parseDSNParams(cfg *Config, params string) (err error) { cfg.TLSConfig = name cfg.tls = tlsConfig } else { - tlsConfigLock.RUnlock() return errors.New("invalid value / unknown config name: " + name) } } diff --git a/utils.go b/utils.go index 680747d3b..0c3729d15 100644 --- a/utils.go +++ b/utils.go @@ -74,6 +74,15 @@ func DeregisterTLSConfig(key string) { 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. // The 2nd return value indicates if the input was a valid bool value func readBool(input string) (value bool, valid bool) {