Comments (16)
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.
That's not correct. See the sentence that I quoted, which exactly specifies when Initial keys are dropped.
from quic-go.
"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.
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.
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 {}
}
from quic-go.
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).
from quic-go.
@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.
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.
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.
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.
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.
Would you welcome a PR adding a switch to turn off this behavior?
from quic-go.
Why would you want to make this configurable? I see no advantage in not sending an ACK.
from quic-go.
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.
I see, thanks for adding some context here.
What's the reasoning behind not sending the ACK in Chrome and Firefox?
from quic-go.
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)
- The method `ListenAndServe` in package `http3` is not compatible with `http` HOT 4
- improve WASM support
- quic-go.newStream high memory usage HOT 7
- http3: response body not implemented http3.HTTPStreamer HOT 9
- Datagram no recent network activity error HOT 3
- bug: unable to connect to quiche servers HOT 5
- In some cases I have turned off Stream on the server side, but OpenStreamSync on the client side is still blocked HOT 6
- pass a context to ConnContext context, cancel it when the connection is closed
- Slow transfer speed HOT 10
- Wrong ACK numbers? HOT 1
- gquic branch usage HOT 1
- Go 1.21
- server incorrectly allows 0-RTT with reduced limits when using tls.Config.GetConfigForClient
- introduce a minimum step size of Path MTU Discovery
- Allow applications to specify MaxPacketBufferSize HOT 8
- add more metrics
- Significant Packet Delay with quic-go on iOS Due to Goroutine Handling HOT 3
- http3: RoundTripper is caching dialErr since v0.43.0 HOT 1
- Cancel retransmission of data when sending with quic Client HOT 1
- implement BBRv3 HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from quic-go.