github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/proxy/dial.go (about) 1 /* 2 Copyright 2015 The Kubernetes Authors All rights reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package proxy 18 19 import ( 20 "crypto/tls" 21 "fmt" 22 "net" 23 "net/http" 24 "net/url" 25 26 "github.com/golang/glog" 27 28 "k8s.io/kubernetes/pkg/util" 29 "k8s.io/kubernetes/third_party/golang/netutil" 30 ) 31 32 func DialURL(url *url.URL, transport http.RoundTripper) (net.Conn, error) { 33 dialAddr := netutil.CanonicalAddr(url) 34 35 dialer, _ := util.Dialer(transport) 36 37 switch url.Scheme { 38 case "http": 39 if dialer != nil { 40 return dialer("tcp", dialAddr) 41 } 42 return net.Dial("tcp", dialAddr) 43 case "https": 44 // Get the tls config from the transport if we recognize it 45 var tlsConfig *tls.Config 46 var tlsConn *tls.Conn 47 var err error 48 tlsConfig, _ = util.TLSClientConfig(transport) 49 50 if dialer != nil { 51 // We have a dialer; use it to open the connection, then 52 // create a tls client using the connection. 53 netConn, err := dialer("tcp", dialAddr) 54 if err != nil { 55 return nil, err 56 } 57 if tlsConfig == nil { 58 // tls.Client requires non-nil config 59 glog.Warningf("using custom dialer with no TLSClientConfig. Defaulting to InsecureSkipVerify") 60 // tls.Handshake() requires ServerName or InsecureSkipVerify 61 tlsConfig = &tls.Config{ 62 InsecureSkipVerify: true, 63 } 64 } else if len(tlsConfig.ServerName) == 0 && !tlsConfig.InsecureSkipVerify { 65 // tls.Handshake() requires ServerName or InsecureSkipVerify 66 // infer the ServerName from the hostname we're connecting to. 67 inferredHost := dialAddr 68 if host, _, err := net.SplitHostPort(dialAddr); err == nil { 69 inferredHost = host 70 } 71 // Make a copy to avoid polluting the provided config 72 tlsConfigCopy := *tlsConfig 73 tlsConfigCopy.ServerName = inferredHost 74 tlsConfig = &tlsConfigCopy 75 } 76 tlsConn = tls.Client(netConn, tlsConfig) 77 if err := tlsConn.Handshake(); err != nil { 78 netConn.Close() 79 return nil, err 80 } 81 82 } else { 83 // Dial 84 tlsConn, err = tls.Dial("tcp", dialAddr, tlsConfig) 85 if err != nil { 86 return nil, err 87 } 88 } 89 90 // Return if we were configured to skip validation 91 if tlsConfig != nil && tlsConfig.InsecureSkipVerify { 92 return tlsConn, nil 93 } 94 95 // Verify 96 host, _, _ := net.SplitHostPort(dialAddr) 97 if err := tlsConn.VerifyHostname(host); err != nil { 98 tlsConn.Close() 99 return nil, err 100 } 101 102 return tlsConn, nil 103 default: 104 return nil, fmt.Errorf("Unknown scheme: %s", url.Scheme) 105 } 106 }