From 5cdeb0d8a1385a92f82cf9b0d3aa0c39bec611ba Mon Sep 17 00:00:00 2001 From: James Phillips Date: Tue, 16 Aug 2016 12:39:41 -0700 Subject: [PATCH] Upgrades to Go 1.7 and fixes vet finding and TLS behavior change. --- .travis.yml | 2 +- README.md | 4 ++-- scripts/consul-builder/Dockerfile | 2 +- tlsutil/config.go | 37 +++++++++++++++++++++++++++++-- tlsutil/config_test.go | 3 +++ 5 files changed, 42 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3111b9ee1d68..41378f4ca705 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: go go: - - 1.6.3 + - 1.7.3 branches: only: diff --git a/README.md b/README.md index 793194d7bdc3..6196e79db314 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ https://www.consul.io/docs ## Developing Consul If you wish to work on Consul itself, you'll first need [Go](https://golang.org) -installed (version 1.6+ is _required_). Make sure you have Go properly installed, +installed (version 1.7+ is _required_). Make sure you have Go properly installed, including setting up your [GOPATH](https://golang.org/doc/code.html#GOPATH). Next, clone this repository into `$GOPATH/src/github.com/hashicorp/consul` and @@ -64,7 +64,7 @@ format the code according to Go standards. ### Building Consul on Windows -Make sure Go 1.6+ is installed on your system and that the Go command is in your +Make sure Go 1.7+ is installed on your system and that the Go command is in your %PATH%. For building Consul on Windows, you also need to have MinGW installed. diff --git a/scripts/consul-builder/Dockerfile b/scripts/consul-builder/Dockerfile index 3c6b90c2b866..04e20fe0886e 100644 --- a/scripts/consul-builder/Dockerfile +++ b/scripts/consul-builder/Dockerfile @@ -1,6 +1,6 @@ FROM ubuntu:trusty -ENV GOVERSION 1.6.3 +ENV GOVERSION 1.7.3 RUN apt-get update -y && \ apt-get install --no-install-recommends -y -q \ diff --git a/tlsutil/config.go b/tlsutil/config.go index 105934d3a87d..57c986748357 100644 --- a/tlsutil/config.go +++ b/tlsutil/config.go @@ -143,6 +143,39 @@ func (c *Config) OutgoingTLSConfig() (*tls.Config, error) { return tlsConfig, nil } +// Clone returns a copy of c. Only the exported fields are copied. This +// was copied from https://golang.org/src/crypto/tls/common.go since that +// isn't exported and Go 1.7's vet uncovered an unsafe copy of a mutex in +// here. +// +// TODO (slackpad) - This can be removed once we move to Go 1.8, see +// https://github.com/golang/go/commit/d24f446 for details. +func clone(c *tls.Config) *tls.Config { + return &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, + DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, + Renegotiation: c.Renegotiation, + } +} + // OutgoingTLSWrapper returns a a DCWrapper based on the OutgoingTLS // configuration. If hostname verification is on, the wrapper // will properly generate the dynamic server name for verification. @@ -164,9 +197,9 @@ func (c *Config) OutgoingTLSWrapper() (DCWrapper, error) { // Generate the wrapper based on hostname verification if c.VerifyServerHostname { wrapper := func(dc string, conn net.Conn) (net.Conn, error) { - conf := *tlsConfig + conf := clone(tlsConfig) conf.ServerName = "server." + dc + "." + domain - return WrapTLSClient(conn, &conf) + return WrapTLSClient(conn, conf) } return wrapper, nil } else { diff --git a/tlsutil/config_test.go b/tlsutil/config_test.go index cbd127ac894b..052cff2560c6 100644 --- a/tlsutil/config_test.go +++ b/tlsutil/config_test.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "net" "testing" + "time" "github.com/hashicorp/yamux" ) @@ -202,11 +203,13 @@ func startTLSServer(config *Config) (net.Conn, chan error) { serverConn, _ := serverSession.Accept() go func() { + serverConn.SetReadDeadline(time.Now().Add(time.Second)) tlsServer := tls.Server(serverConn, tlsConfigServer) if err := tlsServer.Handshake(); err != nil { errc <- err } close(errc) + // Because net.Pipe() is unbuffered, if both sides // Close() simultaneously, we will deadlock as they // both send an alert and then block. So we make the