Releases: quic-go/quic-go
v0.35.0
Modernizing the quic-go connection API
In this release, we've completely revamped our connection establishment API, following an engaging discussion with the quic-go community (#3727).
Key modifications are as follows:
- The context variants of the dial functions, including
DialContext
, have been removed. In their place,Dial
now incorporates a context. This development stems from our drive to modernize the API, given thatcontext.Context
wasn't in existence when quic-go was launched eight years ago. quic.Listener
andquic.EarlyListener
have transitioned from interfaces to structs.
- We've introduced a
quic.Transport
. More about that below.
Introducing the Transport
The QUIC protocols demultiplexes connections based on the QUIC Connection IDs. This has interesting implications, first and foremost that multiple QUIC connections can run on the same UDP socket (and even connect to the same remote QUIC server). Interestingly, it's feasible to run a QUIC server on the same socket as outgoing QUIC connections. In fact, that's a really useful thing to do when using QUIC for holepunching through NATs.
Previously, it was possible to utilize this feature, but the API lacked clarity. When the same net.PacketConn
was passed to sequential Listen
and Dial
calls, quic-go would identify this and multiplex several QUIC connections on that net.PacketConn
. This behavior was not obvious and, additionally, it demanded that certain values of the Config
matched.
We've now made multiplexing explicit with the Transport
introduction. A Transport
manages a single net.PacketConn
. The usage is as follows:
laddr, err := net.ResolveUDPAddr("udp4", "0.0.0.0:443")
// handle err
conn, err := net.ListenUDP("udp4", laddr)
// handle err
tr := quic.Transport{
Conn: conn,
StatelessResetKey: <a key that survives reboots>,
}
// start listening for incoming QUIC connection
ln, err := tr.Listen(<tls.Config>, &quic.Config{})
// handle err
go func() {
conn, err := ln.Accept(context.Background())
if err != nil {
return
}
// handle accepted QUIC connection...
}()
// establish QUIC connections to remote nodes, on the same UDP socket
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel
conn, err := tr.Dial(ctx, <remote addr>, <tls.Config>, <quic.Config>)
// handle err
// handle dialed QUIC connection
This modification enables us to shift several configuration options logically tied to the UDP sockets from the Config
. Specifically, ConnectionIDLength
/ ConnectionIDGenerator
and StatelessResetKey
are now configured on the Transport
.
Migration Guide
To update to the new version, applications might need to:
- Substitute calls to
DialContext
with calls toDial
. - Replace all instances of
Listener
with*Listener
(and similarly forEarlyListener
).
Other Notable Changes
- The HTTP/3 response writer is now compatible with the
http.ResponseController
introduced in the Go 1.20 release (#3790). Thanks @dunglas! - The
http3.RoundTripper
now implementsCloseIdleConnections
method, allowing the use ofhttp.Client.CloseIdleConnections
. Thanks @Glonee! - DoS resiliency was improved by only using a single Go routine to send stateless reset, version negotiation and INVALID_TOKEN error packets (#3842 and #3854). Thanks @sukunrt!
- We now use the
SO_RCVBUFFORCE
syscall to attempt to increase the UDP receive buffer. Increasing the receive buffer is absolutely crucial for QUIC performance, and quic-go will print a log message if increasing the buffer size fails. Unfortunately, due to small default buffer sizes in most Linux distributions, this happened quite frequently and required manual configuration(https://github.com/quic-go/quic-go/wiki/UDP-Receive-Buffer-Size). UsingSO_RCVBUFFORCE
call will only succeed when the process hasCAP_NET_ADMIN
permissions, but in these cases no manual configuration will be necessary any more. Thanks to @MarcoPolo!
Full Changelog
- http3: add compatibility with net/http.ResponseController by @dunglas in #3790
- ci: allow changing runners through config vars by @marten-seemann in #3783
- set the version for integration tests using a command line flag by @marten-seemann in #3782
- ci: speed up the cross compilation job by parallelizing by @marten-seemann in #3784
- put a context on a dial functions, remove Dial*Context, remove host parameter by @marten-seemann in #3785
- congestion: fix overflow when calculating the pacing budget by @marten-seemann in #3796
- move 0-RTT queue handling from the packet handler map to the server by @marten-seemann in #3788
- make Listener and EarlyListener a struct by @marten-seemann in #3789
- docs: add Mercure in the list of projects using quic-go by @dunglas in #3791
- introduce a Transport by @marten-seemann in #3794
- docs: fix typo in documentation for EarlyConnection by @Zxilly in #3798
- transport: fix flaky stateless reset test by @marten-seemann in #3810
- use SO_RCVBUFFORCE to force receive buffer increase on Linux by @MarcoPolo in #3804
- increase the UDP send buffer size to 2 MB by @marten-seemann in #3812
- quicvarint: remove deprecated Write function by @marten-seemann in #3781
- change how the multiplex test is skipped on Linux by @marten-seemann in #3817
- fix flaky timeout integration test by @marten-seemann in #3818
- fix HTTP/3 connection test on draft-29 by @marten-seemann in #3819
- implement http3.RoundTripper.CloseIdleConnections by @Glonee in #3820
- ci: fix coverage report by @Glonee in #3837
- ackhandler: optimize memory layout of ackhandler.Packet by @marten-seemann in #3844
- transport: send stateless reset packets from a single Go routine by @sukunrt in #3842
- fix comment claiming ParseConnectionID reuses the data slice by @sukunrt in #3848
- rttstats: don't set initial RTT after obtaining a measurement by @marten-seemann in #3852
- wire: save ECN counts on the ACK frame by @marten-seemann in #3829
- quicproxy: increase UDP send and receive buffer sizes by @marten-seemann in #3813
- packet packer: don't try packing a 0-RTT packet with only an ACK by @marten-seemann in #3849
- server: send version negotiation and invalid token packets from a single Go routine by @sukunrt in #3854
- wire: apply the default value for the active_connection_id_limit by @marten-seemann in #3806
New Contributors
Full Changelog: v0.34.0...v0.35.0
v0.34.0
Breaking Changes
Connection.HandshakeComplete
now returns a channels instead of acontext.Context
Other notable Changes
- The QUIC version in use is now attached to the context returned from
ClientHelloInfo.Context()
intls.Config.GetConfigForClient
(#3721) - The
http3.RoundTripper
now multiplexes all connections on a singleUDPConn
(#3720)
What's Changed
- http3: use a single UDPConn in RoundTripper by @Glonee in #3720
- qlog: use version_mismatch trigger on transport:connection_closed event by @marten-seemann in #3724
- attach the QUIC version to context returned by ClientHelloInfo.Context by @marten-seemann in #3721
- use a chan instead of a context in Connection.HandshakeComplete by @marten-seemann in #3709
- add benchmark integration tests to measure allocations by @marten-seemann in #3697
- qtls: don't set the tls.Config.CipherSuites for cipher suite tests by @marten-seemann in #3726
- update golang.org/x/net from 0.4.0 to 0.7.0 by @dependabot in #3734
- add a security policy by @marten-seemann in #3733
- ci: update golangci-lint to v1.52.2, update Go version by @marten-seemann in #3740
- interop: build and publish Docker images for linux/amd64 and linux/arm64 by @marten-seemann in #3748
- http3: make error codes public and consistent with http2 package by @jfgiorgi in #3744
- http3: check scheme before host to be consistent with net/http by @jfgiorgi in #3774
- wire: correctly parse multi-byte frame types by @marten-seemann in #3736
- ci: update golangci-lint config, increase timeout by @marten-seemann in #3771
- add missing tracing for dropped 0-RTT packets by @marten-seemann in #3762
- wire: speed up identification of 0-RTT packets by @marten-seemann in #3761
- offer only TLS 1.3 cipher suites in ClientHello by @marten-seemann in #3749
- wire: use constants for frame types by @marten-seemann in #3739
- add a handshake test for post-quantum-size ClientHellos by @marten-seemann in #3759
- ci: remove special casing for AppVeyor by @marten-seemann in #3753
- githooks: add check that go.mod in integrationtests/gomodvendor is tidy by @marten-seemann in #3750
- qlog: move the quic-go version to the configuration field by @marten-seemann in #3735
- protocol: remove VersionWhatever, previously used for testing by @marten-seemann in #3763
- wire: use a dedicated rand.Rand for greasing transport parameters by @marten-seemann in #3758
- avoid copying when detecting stateless resets by @marten-seemann in #3767
- interop: fix setting of cipher suite for the ChaCha20 test by @marten-seemann in #3747
- protocol: remove VersionTLS, used during the gQUIC -> TLS 1.3 transition by @marten-seemann in #3764
- qtls: fix cipher suite selection for ClientHellos by @marten-seemann in #3751
- initiate the first key update after sending / receiving 100 packets by @marten-seemann in #3745
- simplify mockgen usage for private interfaces by @marten-seemann in #3769
- use larger range to draw greased value for post-quantum test from by @marten-seemann in #3780
New Contributors
- @dependabot made their first contribution in #3734
- @jfgiorgi made their first contribution in #3744
Full Changelog: v0.33.0...v0.34.0
v0.33.0
Breaking Changes
Very minimal breaking changes this time. We've deprecated quicvarint.Write
(use quicvarint.Append
instead). We've also removed support for Go 1.18 (we now only support Go 1.19 and 1.20).
Notable Improvements
- HTTP/3: Content Type Sniffing: #3715
- QUIC v2: fix code point of the TLS extension: #3710
- HTTP/3: fix race when accessing the client's connection: #3696
- reduce the size of the message channel in the crypto setup (from 100 to 1): #3664
- refactor the datagram queue to not use a channel (of capacity 100): #3664
Changelog
- docs: Go 1.20 is now supported by @dunglas in #3693
- fix flaky send stream test by @marten-seemann in #3678
- drop support for Go 1.18, use atomic.Bool by @marten-seemann in #3689
- fix logging of sent Version Negotiation Packets by @marten-seemann in #3691
- fix logging of coalesced packets that don't contain long header packets by @marten-seemann in #3705
- deprecate quicvarint.Write in favor of quicvarint.Append by @marten-seemann in #3690
- reduce the size of messageChan channel in the crypto setup by @marten-seemann in #3664
- remove unneeded tracking variables from streams, optimize memory layout by @marten-seemann in #3699
- http3: fix race condition when accessing the client's connection by @marten-seemann in #3696
- don't apply invalid transport parameters by @marten-seemann in #3700
- only allocate datagram receive queue when receiving datagrams by @marten-seemann in #3702
- ci: update GitHub action workflow versions by @giddygoatgaming in #3677
- quicv2: fix TLS extension type by @zoltan-kiss-cujo in #3710
- interop: fix server configuration for the 0-RTT test case by @marten-seemann in #3713
- ci: fix interop Docker builder by @marten-seemann in #3712
- update qtls to include the Go 1.20.1 / 1.19.6 changes to crypto/tls by @marten-seemann in #3711
- http3: sniff HTTP Content Type by @Glonee in #3715
New Contributors
- @giddygoatgaming made their first contribution in #3677
- @zoltan-kiss-cujo made their first contribution in #3710
- @Glonee made their first contribution in #3715
Full Changelog: v0.32.0...v0.33.0
v0.32.0
Breaking Changes
quic-go has moved from the private GitHub account of lucas-clemente
to a dedicated org, quic-go
. Now all the QUIC-related repositories (the various qtls forks of crypto/tls, our QPACK implementation, webtransport-go etc.) are now all located under this org. Note that this will require users to update the import path in go.mod
as well as in Go files. The new import path is github.com/quic-go/quic-go
.
Notable Changes
- We now have support for Go 1.20, which was released earlier today.
- This release dramatically reduces the number of allocations that happen when transferring large amount of data on a stream. This is the result of a large effort to reduce and amortize allocations across the entire code base. See the linked PRs in #3526 for a list of related changes.
- We have (finally!) resolved a very old issue (#765) that made using HTTP/3 clients quite cumbersome: #3684.
- The
ConnectionState
method on theConnection
can now be called at any time. It doesn't block until completion of the TLS handshake any more: #3636. - QUIC v2 support was updated to the current IETF draft: #3631
- It is now possible to accept connections right after receiving the ClientHello on the server side, i.e. 0.5 RTTs after the client started the handshake using
ListenEarly
. UsingListenEarly
does not enable 0-RTT support any more, instead, 0-RTT is controlled via theAllow0RTT
callback in theConfig
: #3635.
Changelog
- http3: simplify if condition in roundtripper by @aviscode in #3658
- update golang.org/x packages to tagged versions by @marten-seemann in #3628
- use the generic linked list for the token store by @marten-seemann in #3654
- fix flaky datagram queue test by @marten-seemann in #3650
- use ed25519 instead of RSA keys in integration tests by @marten-seemann in #3661
- update QUIC v2 support to draft-ietf-quic-v2-08 by @marten-seemann in #3631
- only call tls.CipherSuiteName if logging is on, reducing allocations by @marten-seemann in #3632
- add Allow0RTT opt in the quic.Config to control 0-RTT on the server side by @marten-seemann in #3635
- fix flaky counting of 0-RTT packets in integration test by @marten-seemann in #3669
- fix flaky send queue test by @marten-seemann in #3668
- use a sync.Pool to reduce allocation of linked list elements by @marten-seemann in #3655
- use a separate code path for handling short header packets by @marten-seemann in #3644
- refactor header writing to append to a byte slice by @marten-seemann in #3646
- avoid allocating a shortHeaderPacket struct in the PackPacket path by @marten-seemann in #3647
- make ConnectionState usable during the handshake by @marten-seemann in #3636
- pass payload around by value in the packet packer by @marten-seemann in #3648
- use a sync.Pool for ackhandler.Frames by @marten-seemann in #3656
- add support for Go 1.20 by @marten-seemann in #3641
- remove version parameter from constructors where they are not needed by @marten-seemann in #3639
- update imports to use qtls and qpack from quic-go GitHub organization by @marten-seemann in #3676
- rename module, adjust import paths to quic-go/quic-go by @marten-seemann in #3680
- http3: use HTTP/2 as the default protocol in ListenAndServe by @mstmdev in #3673
- README: add AdGuard Home to project list by @bt90 in #3574
- README: replace go-ipfs with go-libp2p by @marten-seemann in #3682
- return StreamErrors for all kinds of stream cancelations by @marten-seemann in #3681
- http3: change status codes to const by @aviscode in #3683
- http3: correctly handle closed clients by @marten-seemann in #3684
- reject invalid active_connection_id_limit transport parameter values by @marten-seemann in #3687
- update for Go 1.20 by @marten-seemann in #3688
New Contributors
Full Changelog: v0.31.1...v0.32.0
v0.31.1
What's Changed
- qerr: include role (remote / local) in error string representations by @marten-seemann in #3629
Full Changelog: v0.31.0...v0.31.1
v0.31.0
Noteworthy Changes
QUIC:
- We now expose a function,
quic.ConnectionIDFromBytes
, to convert a byte slice to a QUIC connection ID (#3614). Without this function, thequic.Config.ConnectionIDGenerator
was not usable. - The QUIC version is not exposed on the
quic.Connection.ConnectionState
: #3620 - The stateless reset key is now strongly typed, and needs to have a length of exactly 32 bytes: #3621
- Parsing control messages (which happens for every UDP packet read from the socket) is now allocation-free: #3609
HTTP/3:
- Add functions to write and parse HTTP/3 capsules: #3607
Changelog
- http3: add request to response by @Davincible in #3608
- http3: add support for parsing and writing HTTP/3 capsules by @marten-seemann in #3607
- use the new zero-allocation control message parsing function from x/sys by @marten-seemann in #3609
- chore: fix multiple typos in comments by @tobyxdd in #3612
- fix client SNI handling by @tobyxdd in #3613
- use
go run
for mockgen, goimports and ginkgo by @kixelated in #3616 - expose function to convert byte slice to a connection ID by @hf in #3614
- expose the QUIC version of a connection by @MarcoPolo in #3620
- limit the exponential PTO backoff to 60s by @cliffc-spirent in #3595
- introduce a type for the stateless reset key by @marten-seemann in #3621
New Contributors
- @Davincible made their first contribution in #3608
- @kixelated made their first contribution in #3616
- @hf made their first contribution in #3614
- @MarcoPolo made their first contribution in #3620
- @cliffc-spirent made their first contribution in #3595
Full Changelog: v0.30.0...v0.31.0
v0.30.0
Highlights
This release speeds up quic-go by reducing allocations all over the library (see #3526).
In the http3
package, the Server
now exposes a ServeQUICConn
method, allowing users to serve HTTP on a single QUIC connection (#3587).
What's Changed
- use the null tracers in the tracer integration tests by @marten-seemann in #3528
- add DPLPMTUD (RFC 8899) to list of supported RFCs in README by @marten-seemann in #3520
- fix datagram RFC number in documentation for quic.Config by @marten-seemann in #3523
- serialize frames by appending to a byte slice, not to a bytes.Buffer by @marten-seemann in #3530
- reduce allocations of ackhandler.Packet by @marten-seemann in #3525
- use a struct containing an array to represent Connection IDs by @marten-seemann in #3529
- speed up marshaling of transport parameters by @marten-seemann in #3531
- return an error when parsing a too long connection ID from a header by @marten-seemann in #3533
- fix usage of ackhandler.Packet pool for non-ack-eliciting packets by @marten-seemann in #3538
- introduce a separate code paths for Short Header packet handling by @marten-seemann in #3534
- preallocate the message buffers of the ipv4.Message passed to ReadBatch by @marten-seemann in #3541
- remove the wire.ShortHeader in favor of more return values by @marten-seemann in #3535
- split code paths for packing 0-RTT and 1-RTT packets in packet packer by @marten-seemann in #3540
- use a single bytes.Reader for frame parsing by @marten-seemann in #3536
- http3: reduce usage of bytes.Buffer by @marten-seemann in #3539
- prioritize sending ACKs over sending new DATAGRAM frames by @marten-seemann in #3544
- use a sync.Pool for ACK frames by @marten-seemann in #3547
- simplify packing of ACK-only packets by @marten-seemann in #3545
- rename qlog event key_retired to key_discarded by @marten-seemann in #3463
- http3: fix double close of chan when using DontCloseRequestStream by @marten-seemann in #3561
- http3: handle ErrAbortHandler when the handler panics by @shade34321 in #3575
- use a Peek / Pop API for the datagram queue by @marten-seemann in #3582
- reduce max DATAGRAM frame size, so that DATAGRAMs fit in IPv6 packets by @marten-seemann in #3581
- update qtls to versions that include the ec_point_formats fix by @marten-seemann in #3583
- ackhandler: reject duplicate packets in ReceivedPacket by @marten-seemann in #3568
- log the size of buffered packets by @marten-seemann in #3571
- http3: expose ALPN values by @marten-seemann in #3580
- http3: add http3.Server.ServeQUICConn to serve a single QUIC connection by @marten-seemann in #3587
- use a monotonous timer by @marten-seemann in #3570
- don't drop more than 10 consecutive packets in drop test by @marten-seemann in #3584
- migrate to Ginkgo v2, remove benchmark test by @marten-seemann in #3589
- fix version of Ginkgo installed on CI by @marten-seemann in #3591
- update qpack to v0.3.0 by @marten-seemann in #3593
- rename the variable in quic.Config.AllowConnectionWindowIncrease by @marten-seemann in #3602
- http3: add a Context method to the StreamCreator interface by @marten-seemann in #3601
- http3: add a ConnectionState method to the StreamCreator interface by @marten-seemann in #3600
- fix availability signaling of the send queue by @marten-seemann in #3597
New Contributors
- @shade34321 made their first contribution in #3575
Full Changelog: v0.29.0...v0.30.0
v0.29.2
This patch release contains two patches (cherry-picked from these PRs):
- include the standard library
crypto/tls
fix for standard library fix for golang/go#49126: #3583 - prevent busy-looping by using a monotonous timer: #3570
v0.29.1
Full Changelog: v0.29.0...v0.29.1
v0.29.0
Breaking Changes
- The API to control address validation during connection establishment using Retry packets (see Section 8.1 of RFC 9000) has been simplified: see #3494 for the design discussion
- It's now possible to specify a custom Connection ID generator: #3452
Changelog
- optimize FirstOutstanding in the sent packet history by @tobyxdd in #3467
- drop support for Go 1.16 and 1.17 by @marten-seemann in #3482
- use a generic linked list by @marten-seemann in #3487
- update golangci-lint action to v3, golangci-lint to v1.48.0 by @marten-seemann in #3499
- update the Go 1.19 qtls to v0.1.0 by @marten-seemann in #3490
- use a generic streams map for outgoing streams by @marten-seemann in #3488
- add a function to distinguish between long and short header packets by @marten-seemann in #3498
- add QPACK (RFC 9204) to the list of supported RFCs by @marten-seemann in #3485
- use generic Min and Max functions by @marten-seemann in #3483
- fix unreachable code after log.Fatal in fuzzing corpus generator by @Abirdcfly in #3496
- use a generic streams map for incoming streams by @marten-seemann in #3489
- implement a new API to let servers control client address verification by @marten-seemann in #3501
- Disable anti-amplification limit by address validation token by @birneee in #3326
- http3: fix listening on both QUIC and TCP by @mojatter in #3465
- docs: add YoMo to list of projects in README by @fanweixiao in #3513
- use a single Go routine to send copies of CONNECTION_CLOSE packets by @marten-seemann in #3514
- fix datagram support detection by @KevinZonda in #3511
- add support for providing a custom Connection ID generator via Config by @joliveirinha in #3452
- add a logging.NullTracer and logging.NullConnectionTracer by @marten-seemann in #3512
New Contributors
- @Abirdcfly made their first contribution in #3496
- @mojatter made their first contribution in #3465
- @fanweixiao made their first contribution in #3513
- @KevinZonda made their first contribution in #3511
- @joliveirinha made their first contribution in #3452
Full Changelog: v0.28.1...v0.29.0