Skip to content

FR: When tunneling over DERP (TCP), drop packets to manipulate the inner TCP congestion control #15522

@sfllaw

Description

@sfllaw

What are you trying to do?

DERP relays listen for their traffic over TCP on the HTTPS port, because everyone’s network allows outbound traffic to port 443. The DERP client actually generates packet loss with its magic sock:

ctx, cancel := context.WithCancel(c.connCtx)
ch := make(chan derpWriteRequest, bufferedDerpWritesBeforeDrop())

select {
case <-c.donec:
metricSendDERPErrorClosed.Add(1)
return false, errConnClosed
case ch <- derpWriteRequest{addr, pubKey, pkt, isDisco}:
metricSendDERPQueued.Add(1)
return true, nil
default:
metricSendDERPErrorQueue.Add(1)
// Too many writes queued. Drop packet.
return false, errDropDerpPacket
}

This packet loss signals to the inner TCP congestion algorithm to slow down. But it looks like there might be some head-of-line blocking that could cause TCP meltdown, where the inner TCP spends all its time retransmitting. Which coincidentally, is the Sysiphean boulder that @apenwarr keeps pushing up that hill.

How should we solve this?

TBD

What is the impact of not solving this?

The workaround is to use a totally reliable network connection between you and a DERP relay that never experiences high latency or drops packets. /s

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions