/
hbone.go
100 lines (89 loc) · 2.71 KB
/
hbone.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package endpoint
import (
"crypto/tls"
"fmt"
"net"
"net/http"
"istio.io/istio/pkg/hbone"
)
var _ Instance = &connectInstance{}
type connectInstance struct {
Config
server *http.Server
}
func newHBONE(config Config) Instance {
return &connectInstance{
Config: config,
}
}
func (c connectInstance) Close() error {
if c.server != nil {
return c.server.Close()
}
return nil
}
func (c connectInstance) Start(onReady OnReadyFunc) error {
defer onReady()
c.server = hbone.NewServer()
var listener net.Listener
var port int
var err error
if c.Port.TLS {
cert, cerr := tls.LoadX509KeyPair(c.TLSCert, c.TLSKey)
if cerr != nil {
return fmt.Errorf("could not load TLS keys: %v", cerr)
}
config := &tls.Config{
Certificates: []tls.Certificate{cert},
NextProtos: []string{"h2"},
GetConfigForClient: func(info *tls.ClientHelloInfo) (*tls.Config, error) {
// There isn't a way to pass through all ALPNs presented by the client down to the
// HTTP server to return in the response. However, for debugging, we can at least log
// them at this level.
epLog.Infof("TLS connection with alpn: %v", info.SupportedProtos)
return nil, nil
},
MinVersion: tls.VersionTLS12,
}
// Listen on the given port and update the port if it changed from what was passed in.
listener, port, err = listenOnAddressTLS(c.ListenerIP, c.Port.Port, config)
// Store the actual listening port back to the argument.
c.Port.Port = port
} else {
// Listen on the given port and update the port if it changed from what was passed in.
listener, port, err = listenOnAddress(c.ListenerIP, c.Port.Port)
// Store the actual listening port back to the argument.
c.Port.Port = port
}
if err != nil {
return err
}
if c.Port.TLS {
c.server.Addr = fmt.Sprintf(":%d", port)
epLog.Infof("Listening HBONE on %v\n", port)
} else {
c.server.Addr = fmt.Sprintf(":%d", port)
epLog.Infof("Listening HBONE (plaintext) on %v\n", port)
}
go func() {
err := c.server.Serve(listener)
epLog.Warnf("Port %d listener terminated with error: %v", port, err)
}()
return nil
}
func (c connectInstance) GetConfig() Config {
return c.Config
}