Git Product home page Git Product logo

Comments (16)

marten-seemann avatar marten-seemann commented on September 22, 2024 1

Are you sure the server didn't send an Initial packet as part of a coalesced packet? It's not possible to send an ACK if there's nothing to acknowledge.

from quic-go.

marten-seemann avatar marten-seemann commented on September 22, 2024 1

That's not correct. See the sentence that I quoted, which exactly specifies when Initial keys are dropped.

from quic-go.

marten-seemann avatar marten-seemann commented on September 22, 2024 1

"you MAY, but you don't have to exchange any initial packets".

That's correct, and exactly what we're doing. As I mentioned above, giving the server the chance to generate an RTT measurement has value, which is why we send this ACK.

from quic-go.

gaukas avatar gaukas commented on September 22, 2024

In the case where this Initial packet is considered unexpected, it neither breaks the quic connection nor is essential to the quic connection. The communication could be established normally with or without this packet.

Essentially this Initial ACK has no effect when a server responded a coalesced packet with Initial ServerHello and Handshake EncryptedExtensions.

from quic-go.

gaukas avatar gaukas commented on September 22, 2024

Code to replicate this behavior is attached.

package main

import (
	"context"
	"crypto/tls"
	"net"
	"time"

	"github.com/quic-go/quic-go"
)

func main() {
	udpLaddr, err := net.ResolveUDPAddr("udp4", ":0")
	if err != nil {
		panic(err)
	}

	udpConn, err := net.ListenUDP("udp4", udpLaddr)
	if err != nil {
		panic(err)
	}

	udpRaddr, err := net.ResolveUDPAddr("udp4", "quic.tlsfingerprint.io:443")
	if err != nil {
		panic(err)
	}

	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) // 3s handshake timeout
	defer cancel()
	_, err = quic.Dial(ctx, udpConn, udpRaddr, &tls.Config{
		ServerName: "quic.tlsfingerprint.io",
	}, &quic.Config{})
	if err != nil {
		panic(err)
	}

	select {}
}

image

from quic-go.

gaukas avatar gaukas commented on September 22, 2024

Some quick experiments showed that neither Firefox nor Google Chrome (presumably Chromium) sends this Initial ACK frame, unless the server sends its ServerHello in Initial packet space without coalesced with a Handshake packet (www.google.com does this).

image
image

from quic-go.

gaukas avatar gaukas commented on September 22, 2024

@marten-seemann I think you are right. The server DOES send an Initial Packet as part of the coalesced packet.

Are you aware of any compelling reason for these well-known implementations to be not ACKing to the Initial ServerHello in that case?


I updated the description in my issue to better reflect the observation, thanks for the heads up!

from quic-go.

gaukas avatar gaukas commented on September 22, 2024

For your reference: The first packet received from the server is made of two packets, one in Initial with ServerHello and one in Handshake with EncryptedExtensions.

And thank you for responding so quickly!

from quic-go.

marten-seemann avatar marten-seemann commented on September 22, 2024

RFC 9001 says:

a client MUST discard Initial keys when it first sends a Handshake packet and a server MUST discard Initial keys when it first successfully processes a Handshake packet

The only purpose of this ACK is therefore to allow the server to generate an RTT measurement.

from quic-go.

gaukas avatar gaukas commented on September 22, 2024

Just before this line:

The successful use of Handshake packets indicates that no more Initial packets need to be exchanged, as these keys can only be produced after receiving all CRYPTO frames from Initial packets.

I would interpret this as "once client sees a Handshake packet from the server, no more Initial packet needs to be sent (and therefore dropping the ACK)". Perhaps we could make this an optional configurable feature?

What's your opinion on this?

from quic-go.

gaukas avatar gaukas commented on September 22, 2024

I understand what you were saying, the initial keys are dropped (so no more Initial Keys CAN be sent) exactly after successfully sending a Handshake packet.

However, I would interpret "no more Initial packets need to be exchanged" as "you MAY, but you don't have to exchange any initial packets". It is weaker than "a client MUST discard Initial keys". And this also aligns with what we see from modern web browsers.

FYI, it seems Safari is sending Initial ACK on seeing coalesced Initial ServerHello + Handshake EncryptedExtensions. So big techs are having divergent opinions on how to interpret this.

from quic-go.

gaukas avatar gaukas commented on September 22, 2024

Would you welcome a PR adding a switch to turn off this behavior?

from quic-go.

marten-seemann avatar marten-seemann commented on September 22, 2024

Why would you want to make this configurable? I see no advantage in not sending an ACK.

from quic-go.

gaukas avatar gaukas commented on September 22, 2024

It is more of a fingerprint-ability issue. Like uTLS, we are also creating an experimental uQUIC which is based on quic-go to prevent QUIC fingerprinting as demanded by censorship circumvention community.

Therefore we would like to be able to at least replicate all plaintext communications of other well-known QUIC clients, i.e., everything sent in Initial packet space.

If you don't feel it would be a useful addition, we would keep this feature solely in uQUIC.

from quic-go.

marten-seemann avatar marten-seemann commented on September 22, 2024

I see, thanks for adding some context here.

What's the reasoning behind not sending the ACK in Chrome and Firefox?

from quic-go.

gaukas avatar gaukas commented on September 22, 2024

reasoning behind not sending the ACK in Chrome and Firefox?

Unfortunately I don't have an answer for that, it could be just one of their standard-compliant nuances which contributes to their special fingerprints.

And it is exactly these nuances which make QUIC parroting more complicated than its TLS counterpart -- at least that's what we have learned with our preliminary results.

from quic-go.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.