Skip to content

Commit a47c648

Browse files
committed
Log DERP connection logic and overlarge frame head
Signed-off-by: Spike Curtis <spike@coder.com>
1 parent c821c9c commit a47c648

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

derp/derp_client.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,14 @@ func (c *Client) recvTimeout(timeout time.Duration) (m ReceivedMessage, err erro
478478
return nil, err
479479
}
480480
if n > 1<<20 {
481+
// This could be due to some middleware returning non-DERP data. Read a little more of
482+
// the stream and log for debugging before throwing an error.
483+
raw := make([]byte, 256)
484+
raw[0] = byte(t)
485+
bin.PutUint32(raw[1:5], n)
486+
k, _ := c.br.Read(raw[5:])
487+
raw = raw[:5+k]
488+
c.logf("[unexpected] large or corrupt frame; up to 256 bytes as follows: %q", raw)
481489
return nil, fmt.Errorf("unexpectedly large frame (type 0x%x) of %d bytes returned", t, n)
482490
}
483491

derp/derphttp/derphttp_client.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,9 @@ func (c *Client) connect(ctx context.Context, caller string) (client *derp.Clien
518518
// https://blog.gypsyengineer.com/en/security/how-does-tls-1-3-protect-against-downgrade-attacks.html
519519
cs := tlsConn.ConnectionState()
520520
tlsState = &cs
521+
c.logf("%s: TLS version 0x%x", caller, cs.Version)
521522
if cs.Version >= tls.VersionTLS13 {
522-
serverPub, serverProtoVersion = parseMetaCert(cs.PeerCertificates)
523+
serverPub, serverProtoVersion = parseMetaCert(c.logf, cs.PeerCertificates)
523524
}
524525
} else {
525526
httpConn = tcpConn
@@ -556,13 +557,15 @@ func (c *Client) connect(ctx context.Context, caller string) (client *derp.Clien
556557
// just to get routed into the server's HTTP Handler so it
557558
// can Hijack the request, but we signal with a special header
558559
// that we don't want to deal with its HTTP response.
560+
c.logf("%s: using fast start", caller)
559561
req.Header.Set(fastStartHeader, "1") // suppresses the server's HTTP response
560562
if err := req.Write(brw); err != nil {
561563
return nil, 0, err
562564
}
563565
// No need to flush the HTTP request. the derp.Client's initial
564566
// client auth frame will flush it.
565567
} else {
568+
c.logf("%s: not using fast start", caller)
566569
if err := req.Write(brw); err != nil {
567570
return nil, 0, err
568571
}
@@ -574,6 +577,7 @@ func (c *Client) connect(ctx context.Context, caller string) (client *derp.Clien
574577
if err != nil {
575578
return nil, 0, err
576579
}
580+
c.logf("%s: DERP server returned status %d", caller, resp.StatusCode)
577581
if resp.StatusCode != http.StatusSwitchingProtocols {
578582
b, _ := io.ReadAll(resp.Body)
579583
resp.Body.Close()
@@ -1206,8 +1210,9 @@ func (c *Client) closeForReconnect(brokenClient *derp.Client) {
12061210

12071211
var ErrClientClosed = errors.New("derphttp.Client closed")
12081212

1209-
func parseMetaCert(certs []*x509.Certificate) (serverPub key.NodePublic, serverProtoVersion int) {
1213+
func parseMetaCert(logf logger.Logf, certs []*x509.Certificate) (serverPub key.NodePublic, serverProtoVersion int) {
12101214
for _, cert := range certs {
1215+
logf("derpclient: got cert %s", cert.Subject.CommonName)
12111216
// Look for derpkey prefix added by initMetacert() on the server side.
12121217
if pubHex, ok := strings.CutPrefix(cert.Subject.CommonName, "derpkey"); ok {
12131218
var err error

0 commit comments

Comments
 (0)