Skip to content
This repository was archived by the owner on May 28, 2022. It is now read-only.

Commit 3aebaaa

Browse files
committed
TUN-5836: QUIC transport no longer sets body to nil in any condition
Setting the body to nil was rendering cloudflared to crashing with a SIGSEGV in the odd case where the hostname accessed maps to a TCP origin (e.g. SSH/RDP/...) but the eyeball sends a plain HTTP request that does not go through cloudflared access (thus not wrapped in websocket as it should). Instead, QUIC transport now sets http.noBody in that condition, which deals with the situation gracefully.
1 parent 9d9627f commit 3aebaaa

3 files changed

Lines changed: 27 additions & 4 deletions

File tree

connection/quic.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ func buildHTTPRequest(connectRequest *quicpogs.ConnectRequest, body io.ReadClose
342342
// * there is no transfer-encoding=chunked already set.
343343
// So, if transfer cannot be chunked and content length is 0, we dont set a request body.
344344
if !isWebsocket && !isTransferEncodingChunked(req) && req.ContentLength == 0 {
345-
req.Body = nil
345+
req.Body = http.NoBody
346346
}
347347
stripWebsocketUpgradeHeader(req)
348348
return req, err

connection/quic_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ func TestBuildHTTPRequest(t *testing.T) {
345345
},
346346
ContentLength: 0,
347347
Host: "cf.host",
348-
Body: nil,
348+
Body: http.NoBody,
349349
},
350350
body: io.NopCloser(&bytes.Buffer{}),
351351
},

proxy/proxy_test.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ func (w *mockHTTPRespWriter) Read(data []byte) (int, error) {
6060
return 0, fmt.Errorf("mockHTTPRespWriter doesn't implement io.Reader")
6161
}
6262

63+
// respHeaders is a test function to read respHeaders
64+
func (w *mockHTTPRespWriter) headers() http.Header {
65+
return w.Header()
66+
}
67+
6368
type mockWSRespWriter struct {
6469
*mockHTTPRespWriter
6570
writeNotification chan []byte
@@ -554,6 +559,24 @@ func TestConnections(t *testing.T) {
554559
},
555560
},
556561
},
562+
{
563+
// Send (unexpected) HTTP when origin expects WS (to unwrap for raw TCP)
564+
name: "http-(ws)tcp proxy",
565+
args: args{
566+
ingressServiceScheme: "tcp://",
567+
originService: runEchoTCPService,
568+
eyeballResponseWriter: newMockHTTPRespWriter(),
569+
eyeballRequestBody: http.NoBody,
570+
connectionType: connection.TypeHTTP,
571+
requestHeaders: map[string][]string{
572+
"Cf-Cloudflared-Proxy-Src": {"non-blank-value"},
573+
},
574+
},
575+
want: want{
576+
message: []byte{},
577+
headers: map[string][]string{},
578+
},
579+
},
557580
{
558581
name: "tcp-tcp proxy without warpRoutingService enabled",
559582
args: args{
@@ -650,8 +673,8 @@ func TestConnections(t *testing.T) {
650673
}()
651674
}
652675
if test.args.connectionType == connection.TypeTCP {
653-
rws := connection.NewHTTPResponseReadWriterAcker(respWriter, req)
654-
err = proxy.ProxyTCP(ctx, rws, &connection.TCPRequest{Dest: dest})
676+
rwa := connection.NewHTTPResponseReadWriterAcker(respWriter, req)
677+
err = proxy.ProxyTCP(ctx, rwa, &connection.TCPRequest{Dest: dest})
655678
} else {
656679
err = proxy.ProxyHTTP(respWriter, req, test.args.connectionType == connection.TypeWebsocket)
657680
}

0 commit comments

Comments
 (0)