From a0f6eb9d5eb17b7ffc3ef33ef1553ef1b0b7af59 Mon Sep 17 00:00:00 2001 From: Nuno Diegues Date: Tue, 5 Apr 2022 23:07:10 +0100 Subject: [PATCH] TUN-5992: Use QUIC protocol for remotely managed tunnels when protocol is unspecified --- cmd/cloudflared/tunnel/configuration.go | 10 ++++++++-- cmd/cloudflared/tunnel/subcommands.go | 2 +- connection/protocol.go | 6 +++--- connection/protocol_test.go | 24 ++++++++++++------------ 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/cmd/cloudflared/tunnel/configuration.go b/cmd/cloudflared/tunnel/configuration.go index 1ff02c93..0226a87e 100644 --- a/cmd/cloudflared/tunnel/configuration.go +++ b/cmd/cloudflared/tunnel/configuration.go @@ -214,6 +214,9 @@ func prepareTunnelConfig( ingressRules ingress.Ingress classicTunnel *connection.ClassicTunnelProperties ) + + transportProtocol := c.String("protocol") + cfg := config.GetConfiguration() if isNamedTunnel { clientUUID, err := uuid.NewRandom() @@ -223,8 +226,11 @@ func prepareTunnelConfig( log.Info().Msgf("Generated Connector ID: %s", clientUUID) features := append(c.StringSlice("features"), supervisor.FeatureSerializedHeaders) if c.IsSet(TunnelTokenFlag) { + if transportProtocol == connection.AutoSelectFlag { + transportProtocol = connection.QUIC.String() + } features = append(features, supervisor.FeatureAllowRemoteConfig) - log.Info().Msg("Will be fetching remotely managed configuration from Cloudflare API") + log.Info().Msg("Will be fetching remotely managed configuration from Cloudflare API. Defaulting to protocol: quic") } namedTunnel.Client = tunnelpogs.ClientInfo{ ClientID: clientUUID[:], @@ -268,7 +274,7 @@ func prepareTunnelConfig( } warpRoutingEnabled := isWarpRoutingEnabled(cfg.WarpRouting, isNamedTunnel) - protocolSelector, err := connection.NewProtocolSelector(c.String("protocol"), warpRoutingEnabled, namedTunnel, edgediscovery.ProtocolPercentage, supervisor.ResolveTTL, log) + protocolSelector, err := connection.NewProtocolSelector(transportProtocol, warpRoutingEnabled, namedTunnel, edgediscovery.ProtocolPercentage, supervisor.ResolveTTL, log) if err != nil { return nil, nil, err } diff --git a/cmd/cloudflared/tunnel/subcommands.go b/cmd/cloudflared/tunnel/subcommands.go index 70c16545..e9825654 100644 --- a/cmd/cloudflared/tunnel/subcommands.go +++ b/cmd/cloudflared/tunnel/subcommands.go @@ -134,7 +134,7 @@ var ( } selectProtocolFlag = altsrc.NewStringFlag(&cli.StringFlag{ Name: "protocol", - Value: "auto", + Value: connection.AutoSelectFlag, Aliases: []string{"p"}, Usage: fmt.Sprintf("Protocol implementation to connect with Cloudflare's edge network. %s", connection.AvailableProtocolFlagMessage), EnvVars: []string{"TUNNEL_TRANSPORT_PROTOCOL"}, diff --git a/connection/protocol.go b/connection/protocol.go index b94bb80e..ce97bffc 100644 --- a/connection/protocol.go +++ b/connection/protocol.go @@ -19,7 +19,7 @@ const ( edgeH2TLSServerName = "h2.cftunnel.com" // edgeQUICServerName is the server name to establish quic connection with edge. edgeQUICServerName = "quic.cftunnel.com" - autoSelectFlag = "auto" + AutoSelectFlag = "auto" ) var ( @@ -247,7 +247,7 @@ func selectNamedTunnelProtocols( // If the user does not pick (hopefully the majority) then we use the one derived from the TXT DNS record and // fallback on failures. - if protocolFlag == autoSelectFlag { + if protocolFlag == AutoSelectFlag { return newAutoProtocolSelector(protocol, []Protocol{QUIC, HTTP2, H2mux}, threshold, fetchFunc, ttl, log), nil } @@ -272,7 +272,7 @@ func selectWarpRoutingProtocols( // If the user does not pick (hopefully the majority) then we use the one derived from the TXT DNS record and // fallback on failures. - if protocolFlag == autoSelectFlag { + if protocolFlag == AutoSelectFlag { return newAutoProtocolSelector(protocol, []Protocol{QUICWarp, HTTP2Warp}, threshold, fetchFunc, ttl, log), nil } diff --git a/connection/protocol_test.go b/connection/protocol_test.go index 9ab5aae3..9eef7b6c 100644 --- a/connection/protocol_test.go +++ b/connection/protocol_test.go @@ -91,14 +91,14 @@ func TestNewProtocolSelector(t *testing.T) { }, { name: "named tunnel quic and http2 disabled", - protocol: "auto", + protocol: AutoSelectFlag, expectedProtocol: H2mux, fetchFunc: mockFetcher(false, edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: -1}, edgediscovery.ProtocolPercent{Protocol: "quic", Percentage: -1}), namedTunnelConfig: testNamedTunnelProperties, }, { name: "named tunnel quic disabled", - protocol: "auto", + protocol: AutoSelectFlag, expectedProtocol: HTTP2, // Hasfallback true is because if http2 fails, then we further fallback to h2mux. hasFallback: true, @@ -108,21 +108,21 @@ func TestNewProtocolSelector(t *testing.T) { }, { name: "named tunnel auto all http2 disabled", - protocol: "auto", + protocol: AutoSelectFlag, expectedProtocol: H2mux, fetchFunc: mockFetcher(false, edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: -1}), namedTunnelConfig: testNamedTunnelProperties, }, { name: "named tunnel auto to h2mux", - protocol: "auto", + protocol: AutoSelectFlag, expectedProtocol: H2mux, fetchFunc: mockFetcher(false, edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 0}), namedTunnelConfig: testNamedTunnelProperties, }, { name: "named tunnel auto to http2", - protocol: "auto", + protocol: AutoSelectFlag, expectedProtocol: HTTP2, hasFallback: true, expectedFallback: H2mux, @@ -131,7 +131,7 @@ func TestNewProtocolSelector(t *testing.T) { }, { name: "named tunnel auto to quic", - protocol: "auto", + protocol: AutoSelectFlag, expectedProtocol: QUIC, hasFallback: true, expectedFallback: HTTP2, @@ -167,7 +167,7 @@ func TestNewProtocolSelector(t *testing.T) { }, { name: "warp routing quic", - protocol: "auto", + protocol: AutoSelectFlag, expectedProtocol: QUICWarp, hasFallback: true, expectedFallback: HTTP2Warp, @@ -177,7 +177,7 @@ func TestNewProtocolSelector(t *testing.T) { }, { name: "warp routing auto", - protocol: "auto", + protocol: AutoSelectFlag, expectedProtocol: HTTP2Warp, hasFallback: false, fetchFunc: mockFetcher(false, edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 100}), @@ -186,7 +186,7 @@ func TestNewProtocolSelector(t *testing.T) { }, { name: "warp routing auto- quic", - protocol: "auto", + protocol: AutoSelectFlag, expectedProtocol: QUICWarp, hasFallback: true, expectedFallback: HTTP2Warp, @@ -209,7 +209,7 @@ func TestNewProtocolSelector(t *testing.T) { }, { name: "named tunnel fetch error", - protocol: "auto", + protocol: AutoSelectFlag, fetchFunc: mockFetcher(true), namedTunnelConfig: testNamedTunnelProperties, expectedProtocol: HTTP2, @@ -237,7 +237,7 @@ func TestNewProtocolSelector(t *testing.T) { func TestAutoProtocolSelectorRefresh(t *testing.T) { fetcher := dynamicMockFetcher{} - selector, err := NewProtocolSelector("auto", noWarpRoutingEnabled, testNamedTunnelProperties, fetcher.fetch(), testNoTTL, &log) + selector, err := NewProtocolSelector(AutoSelectFlag, noWarpRoutingEnabled, testNamedTunnelProperties, fetcher.fetch(), testNoTTL, &log) assert.NoError(t, err) assert.Equal(t, H2mux, selector.Current()) @@ -297,7 +297,7 @@ func TestHTTP2ProtocolSelectorRefresh(t *testing.T) { func TestProtocolSelectorRefreshTTL(t *testing.T) { fetcher := dynamicMockFetcher{} fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "quic", Percentage: 100}} - selector, err := NewProtocolSelector("auto", noWarpRoutingEnabled, testNamedTunnelProperties, fetcher.fetch(), time.Hour, &log) + selector, err := NewProtocolSelector(AutoSelectFlag, noWarpRoutingEnabled, testNamedTunnelProperties, fetcher.fetch(), time.Hour, &log) assert.NoError(t, err) assert.Equal(t, QUIC, selector.Current())