From 4997637270c4a8ee83ca78801c0832ceb96833a2 Mon Sep 17 00:00:00 2001 From: Ivan Kozlovic Date: Thu, 20 Oct 2016 13:49:54 -0600 Subject: [PATCH] [FIXED] assignment copies lock value for crypto/tls.Config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Running `go vet ./...` with `go 1.7.3` would report the following: ``` server/route.go:342: assignment copies lock value to tlsConfig: crypto/tls.Config contains sync.Once contains sync.Mutex server/server.go:479: assignment copies lock value to config: crypto/tls.Config contains sync.Once contains sync.Mutex ``` Add a “clone” function while waiting for this to be addressed by the language itself (https://go-review.googlesource.com/#/c/28075/) --- .travis.yml | 6 +++--- server/route.go | 8 +++++--- server/server.go | 5 +++-- util/tls.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 util/tls.go diff --git a/.travis.yml b/.travis.yml index cef0231d8f1..961817c9d71 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: go go: -- 1.5.4 - 1.6.3 +- 1.7.3 env: global: - GO15VENDOREXPERIMENT=1 @@ -16,5 +16,5 @@ script: - go test -i -race ./... - go test -v -race ./... after_script: -- if [ "$TRAVIS_GO_VERSION" = "1.6.3" ]; then ./scripts/cov.sh TRAVIS; fi -- if [ "$TRAVIS_GO_VERSION" = "1.6.3" ] && [ "$TRAVIS_TAG" != "" ]; then ./scripts/cross_compile.sh $TRAVIS_TAG; ghr --username nats-io --token $GITHUB_TOKEN --replace $TRAVIS_TAG pkg/; fi +- if [ "$TRAVIS_GO_VERSION" = "1.7.3" ]; then ./scripts/cov.sh TRAVIS; fi +- if [ "$TRAVIS_GO_VERSION" = "1.7.3" ] && [ "$TRAVIS_TAG" != "" ]; then ./scripts/cross_compile.sh $TRAVIS_TAG; ghr --username nats-io --token $GITHUB_TOKEN --replace $TRAVIS_TAG pkg/; fi diff --git a/server/route.go b/server/route.go index ffb3ca8bc84..bb34d565db8 100644 --- a/server/route.go +++ b/server/route.go @@ -15,6 +15,8 @@ import ( "strings" "sync/atomic" "time" + + "github.com/nats-io/gnatsd/util" ) // RouteType designates the router type @@ -339,7 +341,7 @@ func (s *Server) createRoute(conn net.Conn, rURL *url.URL) *client { // Check for TLS if tlsRequired { // Copy off the config to add in ServerName if we - tlsConfig := *s.opts.ClusterTLSConfig + tlsConfig := util.CloneTLSConfig(s.opts.ClusterTLSConfig) // If we solicited, we will act like the client, otherwise the server. if didSolicit { @@ -347,10 +349,10 @@ func (s *Server) createRoute(conn net.Conn, rURL *url.URL) *client { // Specify the ServerName we are expecting. host, _, _ := net.SplitHostPort(rURL.Host) tlsConfig.ServerName = host - c.nc = tls.Client(c.nc, &tlsConfig) + c.nc = tls.Client(c.nc, tlsConfig) } else { c.Debugf("Starting TLS route server handshake") - c.nc = tls.Server(c.nc, &tlsConfig) + c.nc = tls.Server(c.nc, tlsConfig) } conn := c.nc.(*tls.Conn) diff --git a/server/server.go b/server/server.go index fcdef7efb44..c2badf9785f 100644 --- a/server/server.go +++ b/server/server.go @@ -18,6 +18,7 @@ import ( "time" // Allow dynamic profiling. + "github.com/nats-io/gnatsd/util" _ "net/http/pprof" ) @@ -476,9 +477,9 @@ func (s *Server) startMonitoring(secure bool) { if secure { hp = net.JoinHostPort(s.opts.HTTPHost, strconv.Itoa(s.opts.HTTPSPort)) Noticef("Starting https monitor on %s", hp) - config := *s.opts.TLSConfig + config := util.CloneTLSConfig(s.opts.TLSConfig) config.ClientAuth = tls.NoClientCert - s.http, err = tls.Listen("tcp", hp, &config) + s.http, err = tls.Listen("tcp", hp, config) } else { hp = net.JoinHostPort(s.opts.HTTPHost, strconv.Itoa(s.opts.HTTPPort)) diff --git a/util/tls.go b/util/tls.go new file mode 100644 index 00000000000..cafa02faeb1 --- /dev/null +++ b/util/tls.go @@ -0,0 +1,46 @@ +// Copyright 2016 Apcera Inc. All rights reserved. + +package util + +import ( + "crypto/tls" + "reflect" +) + +// CloneTLSConfig returns a copy of c. Only the exported fields are copied. +// This is temporary, until this is provided by the language. +// https://go-review.googlesource.com/#/c/28075/ +func CloneTLSConfig(c *tls.Config) *tls.Config { + newConfig := &tls.Config{ + Rand: c.Rand, + Time: c.Time, + Certificates: c.Certificates, + NameToCertificate: c.NameToCertificate, + GetCertificate: c.GetCertificate, + RootCAs: c.RootCAs, + NextProtos: c.NextProtos, + ServerName: c.ServerName, + ClientAuth: c.ClientAuth, + ClientCAs: c.ClientCAs, + InsecureSkipVerify: c.InsecureSkipVerify, + CipherSuites: c.CipherSuites, + PreferServerCipherSuites: c.PreferServerCipherSuites, + SessionTicketsDisabled: c.SessionTicketsDisabled, + SessionTicketKey: c.SessionTicketKey, + ClientSessionCache: c.ClientSessionCache, + MinVersion: c.MinVersion, + MaxVersion: c.MaxVersion, + CurvePreferences: c.CurvePreferences, + } + fieldName := "DynamicRecordSizingDisabled" + if cField := reflect.ValueOf(c).Elem().FieldByName(fieldName); cField.IsValid() { + newField := reflect.ValueOf(newConfig).Elem().FieldByName(fieldName) + newField.SetBool(cField.Bool()) + + fieldName = "Renegotiation" + cField = reflect.ValueOf(c).Elem().FieldByName(fieldName) + newField = reflect.ValueOf(newConfig).Elem().FieldByName(fieldName) + newField.SetInt(cField.Int()) + } + return newConfig +}