[FIXED] assignment copies lock value for crypto/tls.Config

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/)
This commit is contained in:
Ivan Kozlovic
2016-10-20 13:49:54 -06:00
parent 8da901fcd9
commit 4997637270
4 changed files with 57 additions and 8 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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))

46
util/tls.go Normal file
View File

@@ -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
}