-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathprotocol.go
More file actions
137 lines (120 loc) · 3.53 KB
/
Copy pathprotocol.go
File metadata and controls
137 lines (120 loc) · 3.53 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package connection
import (
"fmt"
"github.com/rs/zerolog"
)
const (
AvailableProtocolFlagMessage = "Available protocols: 'auto' - starts with QUIC and falls back to HTTP/2 (the default and recommended option); 'quic' - based on QUIC, relying on UDP egress to Cloudflare edge; 'http2' - using Go's HTTP2 library, relying on TCP egress to Cloudflare edge"
// edgeH2muxTLSServerName is the server name to establish h2mux connection with edge (unused, but kept for legacy reference).
_ = "cftunnel.com"
// edgeH2TLSServerName is the server name to establish http2 connection with edge
edgeH2TLSServerName = "h2.cftunnel.com"
// edgeQUICServerName is the server name to establish quic connection with edge.
edgeQUICServerName = "quic.cftunnel.com"
// probeTLSServerName is the server name used for pre-flight connectivity checks.
probeTLSServerName = "probe.cftunnel.com"
quicProtos = "argotunnel"
AutoSelectFlag = "auto"
)
// ProtocolList represents the supported protocols for communication with the edge.
var ProtocolList = []Protocol{QUIC, HTTP2}
type Protocol int64
const (
// HTTP2 using golang HTTP2 library for edge connections.
HTTP2 Protocol = iota
// QUIC using quic-go for edge connections.
QUIC
)
// Fallback returns the fallback protocol and whether the protocol has a fallback
func (p Protocol) fallback() (Protocol, bool) {
switch p {
case HTTP2:
return 0, false
case QUIC:
return HTTP2, true
default:
return 0, false
}
}
func (p Protocol) String() string {
switch p {
case HTTP2:
return "http2"
case QUIC:
return "quic"
default:
return "unknown protocol"
}
}
func (p Protocol) TLSSettings() *TLSSettings {
switch p {
case HTTP2:
return &TLSSettings{
ServerName: edgeH2TLSServerName,
}
case QUIC:
return &TLSSettings{
ServerName: edgeQUICServerName,
NextProtos: []string{quicProtos},
}
default:
return nil
}
}
// ProbeTLSSettings returns TLS settings for pre-flight connectivity checks.
func (p Protocol) ProbeTLSSettings() *TLSSettings {
switch p {
case HTTP2:
return &TLSSettings{
ServerName: probeTLSServerName,
}
case QUIC:
return &TLSSettings{
ServerName: probeTLSServerName,
NextProtos: []string{quicProtos},
}
default:
return nil
}
}
type TLSSettings struct {
ServerName string
NextProtos []string
}
type ProtocolSelector interface {
Current() Protocol
Fallback() (Protocol, bool)
}
type protocolSelector struct {
current Protocol
allowFallback bool
}
func (s *protocolSelector) Current() Protocol {
return s.current
}
func (s *protocolSelector) Fallback() (Protocol, bool) {
if !s.allowFallback {
return s.current, false
}
return s.current.fallback()
}
// NewProtocolSelector selects the configured edge transport protocol.
func NewProtocolSelector(
protocolFlag string,
log *zerolog.Logger,
) (ProtocolSelector, error) {
// If the user picks a protocol, then we stick to it no matter what.
switch protocolFlag {
case "h2mux":
// Any users still requesting h2mux will be upgraded to http2 instead
log.Warn().Msg("h2mux is no longer a supported protocol: upgrading edge connection to http2. Please remove '--protocol h2mux' from runtime arguments to remove this warning.")
return &protocolSelector{current: HTTP2}, nil
case QUIC.String():
return &protocolSelector{current: QUIC}, nil
case HTTP2.String():
return &protocolSelector{current: HTTP2}, nil
case AutoSelectFlag:
return &protocolSelector{current: QUIC, allowFallback: true}, nil
}
return nil, fmt.Errorf("unknown protocol %s, %s", protocolFlag, AvailableProtocolFlagMessage)
}