1 // Copyright 2014 go-dockerclient authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // The content is borrowed from Docker's own source code to provide a simple
18 type tlsClientCon struct {
23 func (c *tlsClientCon) CloseWrite() error {
24 // Go standard tls.Conn doesn't provide the CloseWrite() method so we do it
25 // on its underlying connection.
26 if cwc, ok := c.rawConn.(interface {
29 return cwc.CloseWrite()
34 func tlsDialWithDialer(dialer *net.Dialer, network, addr string, config *tls.Config) (net.Conn, error) {
35 // We want the Timeout and Deadline values from dialer to cover the
36 // whole process: TCP connection and TLS handshake. This means that we
37 // also need to start our own timers now.
38 timeout := dialer.Timeout
40 if !dialer.Deadline.IsZero() {
41 deadlineTimeout := dialer.Deadline.Sub(time.Now())
42 if timeout == 0 || deadlineTimeout < timeout {
43 timeout = deadlineTimeout
47 var errChannel chan error
50 errChannel = make(chan error, 2)
51 time.AfterFunc(timeout, func() {
52 errChannel <- errors.New("")
56 rawConn, err := dialer.Dial(network, addr)
61 colonPos := strings.LastIndex(addr, ":")
65 hostname := addr[:colonPos]
67 // If no ServerName is set, infer the ServerName
68 // from the hostname we're connecting to.
69 if config.ServerName == "" {
70 // Make a copy to avoid polluting argument or default.
71 config = copyTLSConfig(config)
72 config.ServerName = hostname
75 conn := tls.Client(rawConn, config)
78 err = conn.Handshake()
81 errChannel <- conn.Handshake()
92 // This is Docker difference with standard's crypto/tls package: returned a
93 // wrapper which holds both the TLS and raw connections.
94 return &tlsClientCon{conn, rawConn}, nil
97 // this exists to silent an error message in go vet
98 func copyTLSConfig(cfg *tls.Config) *tls.Config {
100 Certificates: cfg.Certificates,
101 CipherSuites: cfg.CipherSuites,
102 ClientAuth: cfg.ClientAuth,
103 ClientCAs: cfg.ClientCAs,
104 ClientSessionCache: cfg.ClientSessionCache,
105 CurvePreferences: cfg.CurvePreferences,
106 InsecureSkipVerify: cfg.InsecureSkipVerify,
107 MaxVersion: cfg.MaxVersion,
108 MinVersion: cfg.MinVersion,
109 NameToCertificate: cfg.NameToCertificate,
110 NextProtos: cfg.NextProtos,
111 PreferServerCipherSuites: cfg.PreferServerCipherSuites,
113 RootCAs: cfg.RootCAs,
114 ServerName: cfg.ServerName,
115 SessionTicketKey: cfg.SessionTicketKey,
116 SessionTicketsDisabled: cfg.SessionTicketsDisabled,