mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 20:39:57 +00:00
TUN-6617: Dont fallback to http2 if QUIC conn was successful.
cloudflared falls back aggressively to HTTP/2 protocol if a connection attempt with QUIC failed. This was done to ensure that machines with UDP egress disabled did not stop clients from connecting to the cloudlfare edge. This PR improves on that experience by having cloudflared remember if a QUIC connection was successful which implies UDP egress works. In this case, cloudflared does not fallback to HTTP/2 and keeps trying to connect to the edge with QUIC.
This commit is contained in:
@@ -2,6 +2,7 @@ package connection
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
@@ -21,6 +22,7 @@ type controlStream struct {
|
||||
namedTunnelProperties *NamedTunnelProperties
|
||||
connIndex uint8
|
||||
edgeAddress net.IP
|
||||
protocol Protocol
|
||||
|
||||
newRPCClientFunc RPCClientFunc
|
||||
|
||||
@@ -51,6 +53,7 @@ func NewControlStream(
|
||||
newRPCClientFunc RPCClientFunc,
|
||||
gracefulShutdownC <-chan struct{},
|
||||
gracePeriod time.Duration,
|
||||
protocol Protocol,
|
||||
) ControlStreamHandler {
|
||||
if newRPCClientFunc == nil {
|
||||
newRPCClientFunc = newRegistrationRPCClient
|
||||
@@ -64,6 +67,7 @@ func NewControlStream(
|
||||
edgeAddress: edgeAddress,
|
||||
gracefulShutdownC: gracefulShutdownC,
|
||||
gracePeriod: gracePeriod,
|
||||
protocol: protocol,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +84,9 @@ func (c *controlStream) ServeControlStream(
|
||||
rpcClient.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
c.observer.logServerInfo(c.connIndex, registrationDetails.Location, c.edgeAddress, fmt.Sprintf("Connection %s registered", registrationDetails.UUID))
|
||||
c.observer.sendConnectedEvent(c.connIndex, c.protocol, registrationDetails.Location)
|
||||
c.connectedFuse.Connected()
|
||||
|
||||
// if conn index is 0 and tunnel is not remotely managed, then send local ingress rules configuration
|
||||
|
@@ -5,6 +5,7 @@ type Event struct {
|
||||
Index uint8
|
||||
EventType Status
|
||||
Location string
|
||||
Protocol Protocol
|
||||
URL string
|
||||
}
|
||||
|
||||
|
@@ -43,6 +43,7 @@ func newTestHTTP2Connection() (*HTTP2Connection, net.Conn) {
|
||||
nil,
|
||||
nil,
|
||||
1*time.Second,
|
||||
HTTP2,
|
||||
)
|
||||
return NewHTTP2Connection(
|
||||
cfdConn,
|
||||
@@ -366,6 +367,7 @@ func TestServeControlStream(t *testing.T) {
|
||||
rpcClientFactory.newMockRPCClient,
|
||||
nil,
|
||||
1*time.Second,
|
||||
HTTP2,
|
||||
)
|
||||
http2Conn.controlStreamHandler = controlStream
|
||||
|
||||
@@ -417,6 +419,7 @@ func TestFailRegistration(t *testing.T) {
|
||||
rpcClientFactory.newMockRPCClient,
|
||||
nil,
|
||||
1*time.Second,
|
||||
HTTP2,
|
||||
)
|
||||
http2Conn.controlStreamHandler = controlStream
|
||||
|
||||
@@ -464,6 +467,7 @@ func TestGracefulShutdownHTTP2(t *testing.T) {
|
||||
rpcClientFactory.newMockRPCClient,
|
||||
shutdownC,
|
||||
1*time.Second,
|
||||
HTTP2,
|
||||
)
|
||||
|
||||
http2Conn.controlStreamHandler = controlStream
|
||||
|
@@ -55,8 +55,8 @@ func (o *Observer) sendRegisteringEvent(connIndex uint8) {
|
||||
o.sendEvent(Event{Index: connIndex, EventType: RegisteringTunnel})
|
||||
}
|
||||
|
||||
func (o *Observer) sendConnectedEvent(connIndex uint8, location string) {
|
||||
o.sendEvent(Event{Index: connIndex, EventType: Connected, Location: location})
|
||||
func (o *Observer) sendConnectedEvent(connIndex uint8, protocol Protocol, location string) {
|
||||
o.sendEvent(Event{Index: connIndex, EventType: Connected, Protocol: protocol, Location: location})
|
||||
}
|
||||
|
||||
func (o *Observer) SendURL(url string) {
|
||||
|
@@ -81,63 +81,63 @@ func TestQUICServer(t *testing.T) {
|
||||
},
|
||||
expectedResponse: []byte("OK"),
|
||||
},
|
||||
//{
|
||||
// desc: "test http body request streaming",
|
||||
// dest: "/slow_echo_body",
|
||||
// connectionType: quicpogs.ConnectionTypeHTTP,
|
||||
// metadata: []quicpogs.Metadata{
|
||||
// {
|
||||
// Key: "HttpHeader:Cf-Ray",
|
||||
// Val: "123123123",
|
||||
// },
|
||||
// {
|
||||
// Key: "HttpHost",
|
||||
// Val: "cf.host",
|
||||
// },
|
||||
// {
|
||||
// Key: "HttpMethod",
|
||||
// Val: "POST",
|
||||
// },
|
||||
// {
|
||||
// Key: "HttpHeader:Content-Length",
|
||||
// Val: "24",
|
||||
// },
|
||||
// },
|
||||
// message: []byte("This is the message body"),
|
||||
// expectedResponse: []byte("This is the message body"),
|
||||
//},
|
||||
//{
|
||||
// desc: "test ws proxy",
|
||||
// dest: "/ws/echo",
|
||||
// connectionType: quicpogs.ConnectionTypeWebsocket,
|
||||
// metadata: []quicpogs.Metadata{
|
||||
// {
|
||||
// Key: "HttpHeader:Cf-Cloudflared-Proxy-Connection-Upgrade",
|
||||
// Val: "Websocket",
|
||||
// },
|
||||
// {
|
||||
// Key: "HttpHeader:Another-Header",
|
||||
// Val: "Misc",
|
||||
// },
|
||||
// {
|
||||
// Key: "HttpHost",
|
||||
// Val: "cf.host",
|
||||
// },
|
||||
// {
|
||||
// Key: "HttpMethod",
|
||||
// Val: "get",
|
||||
// },
|
||||
// },
|
||||
// message: wsBuf.Bytes(),
|
||||
// expectedResponse: []byte{0x82, 0x5, 0x48, 0x65, 0x6c, 0x6c, 0x6f},
|
||||
//},
|
||||
//{
|
||||
// desc: "test tcp proxy",
|
||||
// connectionType: quicpogs.ConnectionTypeTCP,
|
||||
// metadata: []quicpogs.Metadata{},
|
||||
// message: []byte("Here is some tcp data"),
|
||||
// expectedResponse: []byte("Here is some tcp data"),
|
||||
//},
|
||||
{
|
||||
desc: "test http body request streaming",
|
||||
dest: "/slow_echo_body",
|
||||
connectionType: quicpogs.ConnectionTypeHTTP,
|
||||
metadata: []quicpogs.Metadata{
|
||||
{
|
||||
Key: "HttpHeader:Cf-Ray",
|
||||
Val: "123123123",
|
||||
},
|
||||
{
|
||||
Key: "HttpHost",
|
||||
Val: "cf.host",
|
||||
},
|
||||
{
|
||||
Key: "HttpMethod",
|
||||
Val: "POST",
|
||||
},
|
||||
{
|
||||
Key: "HttpHeader:Content-Length",
|
||||
Val: "24",
|
||||
},
|
||||
},
|
||||
message: []byte("This is the message body"),
|
||||
expectedResponse: []byte("This is the message body"),
|
||||
},
|
||||
{
|
||||
desc: "test ws proxy",
|
||||
dest: "/ws/echo",
|
||||
connectionType: quicpogs.ConnectionTypeWebsocket,
|
||||
metadata: []quicpogs.Metadata{
|
||||
{
|
||||
Key: "HttpHeader:Cf-Cloudflared-Proxy-Connection-Upgrade",
|
||||
Val: "Websocket",
|
||||
},
|
||||
{
|
||||
Key: "HttpHeader:Another-Header",
|
||||
Val: "Misc",
|
||||
},
|
||||
{
|
||||
Key: "HttpHost",
|
||||
Val: "cf.host",
|
||||
},
|
||||
{
|
||||
Key: "HttpMethod",
|
||||
Val: "get",
|
||||
},
|
||||
},
|
||||
message: wsBuf.Bytes(),
|
||||
expectedResponse: []byte{0x82, 0x5, 0x48, 0x65, 0x6c, 0x6c, 0x6f},
|
||||
},
|
||||
{
|
||||
desc: "test tcp proxy",
|
||||
connectionType: quicpogs.ConnectionTypeTCP,
|
||||
metadata: []quicpogs.Metadata{},
|
||||
message: []byte("Here is some tcp data"),
|
||||
expectedResponse: []byte("Here is some tcp data"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@@ -2,7 +2,6 @@ package connection
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
@@ -117,9 +116,6 @@ func (rsc *registrationServerClient) RegisterConnection(
|
||||
|
||||
observer.metrics.regSuccess.WithLabelValues("registerConnection").Inc()
|
||||
|
||||
observer.logServerInfo(connIndex, conn.Location, edgeAddress, fmt.Sprintf("Connection %s registered", conn.UUID))
|
||||
observer.sendConnectedEvent(connIndex, conn.Location)
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user