ietf-wg-masque / draft-ietf-masque-quic-proxy

Other
12 stars 7 forks source link

Happy Eyeballs? #59

Open DavidSchinazi opened 2 years ago

DavidSchinazi commented 2 years ago

CONNECT-UDP can't perform Happy Eyeballs because UDP doesn't have an equivalent of the TCP SYN-ACK. However, QUIC has such an equivalent. This extension could recommend performing Happy Eyeballs when target_host is a DNS host name.

LPardue commented 2 years ago

How would that work, the proxy duplicating the Client initial over a v4 and a v6 path? That doesn't sound good

gloinul commented 2 years ago

Have to agree with @LPardue here. I don't see how this can work. A UDP Proxy can clearly run happy eyeball and race the quick connection between the masque client and the masque server (proxy) over IPv4 and IPv6 and in this case it would be the MASQUE used HTTP establishment that is raced. For the end-to-end connection that is being tunnelled, that require the application above the QUIC connection(s) to perform happy eyeballs. If you want to enable this, then you need to have the end-to-end application open two QUIC connection over the same proxy and race these and thus indicate a preference for IPv4 or IPv6 when doing the request for proxying.

I don't believe in the proxy duplicating what it thinks is a QUIC handshake packet for the E2E quic connection and send it over both IPv4 and IPv6 for domains that have both A and AAAA DNS records. If you one would do that and then select which to use based on the response. Then first you are impacting when the response can be sent. So any attempt in this direction would need an extension and explicit signalling about it.

tfpauly commented 2 years ago

Yeah, the client would need to be involved in order to run proper happy eyeballs, I think.

The proxy could certainly learn for commonly accessed targets that a particular address actually doesn't work — like if the DNS entry had IPv6 addresses, but never responded, for future requests the proxy could prefer IPv4.

LPardue commented 2 years ago

Proxy heuristics seem fine but then that seems common to any type of HTTP CONNECT proxy. Is there anything special to say here?

tfpauly commented 2 years ago

I'm not sure there's something specific to say here, no, but David may have ideas.

DavidSchinazi commented 2 years ago

(For the sake of simplicity, I'm assuming there's only one v4 address and one v6 address below, but this generalizes)

My initial thought was to have the proxy send the INITIAL to both the v4 and v6 target addresses (staggered as in HEv2, not all at once) and then pick the first target address that replies as its target, and forward the reply to the client. If the proxy receives a reply from the other address, there are two scenarios:

  1. the second reply has packet number 0: this means that it came from a different target server - the proxy drops the reply and generates a fake INITIAL CONNECTION_CLOSE and sends it to the second target address to tell that server to give up
  2. the second reply has packet number > 0: this means that it was the same target server as the first reply - the proxy forwards the reply to the client and picks the best target address as its future target address to send to

Of course we'd need something a bit more smart to handle packet loss but I think the general idea would work.

If folks think this is too complicated I'm happy to take that to an extension, but since we haven't adopted this yet I thought it might be worth thinking about since we're not delaying progress.

LPardue commented 2 years ago

My concerns stem from implications of reuse of connection IDs and tokens, e.g.

An endpoint MUST NOT reuse a connection ID when sending from more than one local address -- for example, when initiating connection migration

Maybe we could make this more of explicit behaviour? E.g. the client gives a proxy multiple SCIDS to use for this and then just returns packets with the selected one

DavidSchinazi commented 2 years ago

That MUST NOT is post-handshake though. The client not allowed to switch its SCID during the handshake (except to the one the server gives it)

LPardue commented 2 years ago

Right, but duplication of CiDS in initial across paths could still provide some form of linkability?

Do clients already do this kind of happy eyeballs copying behaviour without any proxy in the mix?

DavidSchinazi commented 2 years ago

Right, but duplication of CiDS in initial across paths could still provide some form of linkability?

You'd be linking the public IPv4 and IPv6 addresses of the proxy together. I don't think the proxy cares.

Do clients already do this kind of happy eyeballs copying behaviour without any proxy in the mix?

Our client does Happy Eyeballs across protocols in the sense that it tries QUIC on the first address and if that's sad it falls back to TCP, but that's because our client only does h3. But if I were to implement a QUIC-only client today I would create two separate QUIC connections so there wouldn't be duplication of initials. You could definitely do that through the proxy, but you'd save on CPU costs and latency by doing it from the proxy with duplication. Definitely a tradeoff.

LPardue commented 2 years ago

Yeah agree it's a tradeoff.

Thinking aloud. It seems like in an era of HTTPS records, happy eyeballs for QUIC could be useful for non-proxy clients. And guidance on how to close an uneeded connection seems useful. The decision whether to duplicate Initials could be part of guidance around tradeoffs. A proxy could then take that and use it. A CONNECT-UDP proxy that snoops could even employ the approach ypu outline