Skip to content

Releases: quic-go/quic-go

v0.57.1

26 Nov 05:45
Immutable release. Only release title and notes can be modified.
4b0ab7e

Choose a tag to compare

This release resolves a panic during the server handshake when using the upcoming Go 1.26 toolchain, specifically occurring with TLS session tickets disabled (#5462). This issue does not impact builds on Go 1.25 or earlier versions.

v0.57.0

21 Nov 10:56
Immutable release. Only release title and notes can be modified.
5b2d212

Choose a tag to compare

This release reworks the HTTP/3 header processing logic:

  • Both client and server now send their respective header size constraints using the SETTINGS_MAX_FIELD_SECTION_SIZE setting: #5431
  • For any QPACK-related errors, the correct error code (QPACK_DECOMPRESSION_FAILED) is now used: #5439
  • QPACK header parsing is now incremental (instead of parsing all headers at once), which is ~5-10% faster and reduces allocations: #5435 (and quic-go/qpack#67)
  • The server now sends a 431 status code (Request Header Fields Too Large) when encountering HTTP header fields exceeding the size constraint: #5452

 

Breaking Changes

  • http3: Transport.MaxResponseBytes is now an int (before: int64): #5433
     

Notable Fixes

  • qlogwriter: fix storing of event schemas (this prevented qlog event logging from working for HTTP/3): #5430
  • http3: errors sending the request are now ignored, instead, the response from the server is read (thereby allowing the client to read the status code, for example): #5432

What's Changed

New Contributors

Full Changelog: v0.56.0...v0.57.0

v0.56.0

08 Nov 05:03
Immutable release. Only release title and notes can be modified.
eb7fcf5

Choose a tag to compare

This release introduces qlog support for HTTP/3 (#5367, #5372, #5374, #5375, #5376, #5381, #5383).

For this, we completely changed how connection tracing works. Instead of a general-purpose logging.ConnectionTracer (which we removed entirely), we now have a qlog-specific tracer (#5356, #5417). quic-go users can now implement their own qlog events.

It also removes the Prometheus-based metrics collection. Please comment on the tracking issue (#5294) if you rely on metrics and are interested in seeing metrics brought back in a future release.

Notable Changes

  • replaced the unmaintained gojay with a custom, performance-optimized JSON encoder (#5353, #5371)
  • quicvarint: improved panic message for numbers larger than 2^62 (#5410)

Behind the Scenes

Go 1.25 introduced support for testing concurrent code using testing/synctest. We've been working on transitioning tests to use synctest (#5357, #5391, #5393, #5397, #5398, #5403, #5414, #5415), using @MarcoPolo's simnet package to simulate a network in memory.

Using synctest makes test execution more reliable (reducing flakiness). The use of a synthetic clock leads to a massive speedup; the execution time of some integration tests was reduced from 20s to less than 1ms. The work will continue for the next release (see tracking issue: #5386).

Changelog

New Contributors

  • @kriztalz made their first contribution in #5377
  • @Copilot made their first contribution in #5382

Full Changelog: v0.55.0...v0.56.0

v0.55.0

03 Oct 08:25
Immutable release. Only release title and notes can be modified.
7c1ce0e

Choose a tag to compare

This release contains a number of improvements and fixes, and it updates the supported Go versions to 1.24 and 1.25.

Optimizations

When sending packets on a QUIC connection, RFC 9002 requires us to save the timestamp for every packet sent. In #5344, we implemented a memory-optimized drop-in replacement for time.Time, which reduces the memory required from 24 to 8 bytes, and vastly speeds up timer calculations (which happen very frequently).

New Features

  • Basic connection statistics are now exposed via Conn.ConnectionStats, thanks to @MarcoPolo
  • On some links, packet reordering can lead to spurious detections of packet loss when using the loss detection logic specified in RFC 9002. #5355 adds logic detect when packet loss is detected spuriously.

Notable Fixes

  • http3: don't allow usage of closed Transport: #5324, thanks to @Glonee
  • http3: fix race in concurrent Transport.Roundtrip calls: #5323, thanks to @Glonee
  • improve and fix connection timer logic: #5339, thanks to @sukunrt for a very comprehensive code review

Behind the Scenes

We have started transitioning tests to make use of the new synctest package that was added in Go 1.25 (and was available as a GOEXPERIMENT in Go 1.24): #5291, #5296, #5298, #5299, #5302, #5304, #5305, #5306, #5317. This is a lot of work, but it makes the test execution both faster and more reliable.

Changelog

New Contributors

Full Changelog: v0.54.0...v0.55.0

v0.54.0

20 Jul 21:00
c2e784a

Choose a tag to compare

This release adds support for QUIC Stream Resets with Partial Delivery, a QUIC extension that allows resetting a stream, while guaranteeing delivery of stream data up to a certain byte offset (#5155, #5158, #5160, #5235, #5242, #5243). This extension is a requirement of newer versions of WebTransport over HTTP/3.

Other Notable Changes

  • http3: the package now doesn't depend on any internal quic-go packages: #5256
  • wire: return concrete structs (instead of a wire.Frame) for common frame types (STREAM, DATAGRAM, ACK), speeding up STREAM frame parsing by ~18%: #5253, #5227, thanks to @jannis-seemann

Fixes

  • fix retransmission logic for path probing packets: #5241
  • close the Transport when DialAddr fails: #5259, thanks to @rbqvq

Changelog

New Contributors

Full Changelog: v0.53.0...v0.54.0

v0.53.0

25 Jun 03:26
b94fc4d

Choose a tag to compare

This release introduces a massive overhaul of the quic-go API. See this blog post for more details about the motivation. Most users will need to make some changes when upgrading to this version.

  • The Connection interface was removed in favor of a Conn struct (#5195).
  • The ReceiveStream, SendStream and Stream interfaces were replaced with structs of the same name (#5149, #5172, #5173, #5214).

In most cases, migrating downstream code should be fairly straightforward. For example, a method that used to accept a quic.Connection as a parameter now needs to accept a *quic.Conn, and a function handling a quic.Stream now needs to handle a *quic.Stream. Of course, consumers of quic-go are free to define their own interfaces.

Similarly, on the HTTP/3 layer:

  • The Connection interface was replaced with a Conn struct (#5204).
  • The RequestStream interface was converted to a struct (#5153, #5216).
  • The Stream interface was converted to a struct (#5154).

We expect that most HTTP/3 users won't need to adjust their code, if they use the package to run an HTTP/3 server and dial HTTP/3 connection. More advanced use cases, such as WebTransport and the various MASQUE protocols, will require updates. We have already released new versions of webtransport-go and masque-go to support these changes.

Other Breaking Changes

  • http3: the deprecated SingleDestinationRoundTripper was removed (#5217)

Notable Fixes and Improvements

  • fix Goroutine leak when receiving a Version Negotiation packets race with dial context cancellation (#5203)
  • drain the server accept queue when closing the transport (#5237), thanks to @sukunrt
  • fix a race condition when closing transport (#5220), thanks to @sukunrt
  • quicvarint: speed up parsing of 1, 2 and 4-byte varints (~12.5% for 1 and 2 bytes, ~1% for 4 bytes) (#5229), thanks to @jannis-seemann
  • http3: expose ClientConn.Context, CloseWithError and Conn: #5219
  • http3: RequestStream could be misused in many different ways, that's why we tightened the error checks (#5231)

Behind The Scenes

We've completed the migration of the entire test suite away from Ginkgo (#3652) and towards standard Go tests (#5084, #5150, #5151, #5193, #5194, #5196, #5198). This was a major undertaking, spanning roughly 9 months and resulting in a complete rewrite of quic-go's test suite (> 40,000 lines of code!). Users will now benefit from a significantly slimmed-down dependency tree when upgrading.

Changelog

New Contributors

Full Changelog: v0.52.0...v0.53.0

v0.52.0

20 May 07:24
04eab22

Choose a tag to compare

This release focus on HTTP/3 graceful shutdown using the GOAWAY mechnism.

On the server side graceful shutdown is initiated by calling the http3.Server.Shutdown method:

  • A single GOAWAY frame is sent, instructing the client to not issue any new requests (#5114).
  • New requests are rejected by resetting the streams using the H3_REQUEST_REJECTED reset error code: #5116.
  • QUIC listeners created by the HTTP/3 server (i.e. when using http3.Server.ListenAndServe and ListenAndServeTLS) are immediately closed (#5101). QUIC listeners created by the application (i.e. when using http3.Server.ServeListener) are left running, it is the application's responsibility to close them, or use them in a new server instance (#5129).
  • Note that the during the graceful shutdown period, the server does not close existing connections, as this is racy in the presence of packet reordering.

On the client side, when receiving a GOAWAY frame:

  • No new streams will be opened on the new connection. Requests to the same origin will be sent on a freshly established QUIC connection.
  • Once all requests have completed / were cancelled, the underlying QUIC connection is closed: #5143 and #5145.

Breaking Changes

  • Transport.ConnContext now passes the ClientInfo to the callback, and allows rejecting handshakes by introducing an error return value: #5122. This allows applications to build more sophisticated DoS defenses. Thanks to @sukunrt!
  • Connections accepted from a Listener using the Listen and ListenAddr convenience functions now aren't closed when the listener is closed. This makes the shutdown behavior consistent with listeners created from a Transport, and the standard library's net.Listener: #5108.

Other Notable Changes

  • The TLS ClientHello is now fragmented into multiple pieces, complicating Deep Packet Inspection of the handshake by middlebox: #5107. This behavior can be disabled by setting the QUIC_GO_DISABLE_CLIENTHELLO_SCRAMBLING environment variable.
  • Kernel control messages for ECN and for picking the correct network interface now work on big-endian platforms such as s390x: #5094 and #5105. Thanks to @Zxilly!
  • The RTT estimate is now stored in the resumption token (and not in the TLS session ticket): #5065. Thanks to @tanghaowillow!

Fixes

  • http3: The Alt-Svc entry is now removed when http3.Server.Serve returns: #5093.
  • http3: http3.Server.ServeQUICConn now returns http.ErrServerClosed when called on a closed server: #5095.
  • http3: The datagram receive loop now doesn't prematurely return when receiving a datagram for an unknown stream: #5136.
  • http3: Requests are now only retried when it can be guaranteed that the server didn't process the request: #5141.
  • http3: Prevent a stream leak when the server sends too many 1xx responses: #5144.

Behind The Scenes

As in the last couple of releases, we continued our ongoing effort to migrate away from the Ginkgo test suite (tracking issue #3652), mostly in the HTTP/3 package: #5068, #5069, #5070, #5073, #5075, #5078, #5067, #5081, #5085, #5096, #5133. There are still ~1400 LOC of Ginkgo tests to clean up, scattered across the code base.

Changelog

New Contributors

Full Changelog: v0.51.0...v0.52.0

v0.51.0

20 Apr 06:34
d35b5ac

Choose a tag to compare

This release introduces client-side support for QUIC Connection Migration (server-side support was added in the last release). Clients can now probe multiple paths and switch between them mid-connection. For example, this enables seamless migration from Wi-Fi to a cellular connection when Wi-Fi connectivity deteriorates.

For details on using the new Connection Migration API, please refer to the documentation.

Breaking Changes

  • The error returned from Connection.OpenStream, OpenUniStream, OpenStreamSync and OpenUniStreamSync doesn't implement net.Error anymore. Use error assertion on StreamLimitReachedError instead: #5060
  • ClientHelloInfo was renamed to ClientInfo: #5016

Other Notable Changes

  • Documentation improvements: #4955 (thanks to @mark-rushakoff!), #5047, #5061
  • http3: reject duplicate pseudo headers: #4993 (thanks to @pittgi!)
  • Correctly handle undefined IPv4 / IPv6 preferred address values: #4985, #4986
  • Fix potential deadlock when OpenStreamSync context is cancelled: #5037 (thanks to @sukunrt for a very helpful review!)
  • Stateless resets are now properly detected when zero-length Connection IDs are used: #5027

Behind The Scenes

  • As in the last couple of releases, we continued our ongoing effort to migrate away from the Ginkgo test suite (tracking issue #3652). The quic package is now fully migrated (#4957, #4969, #5033, #5040, #5054). There are still ~5300 LOC of Ginkgo tests to clean up, mainly in the congestion and the http3 package.
  • We've fully migrated from math/rand and golang.org/x/exp/rand to the new math/rand/v2 package: #5044, #5045, #5046

v0.50.1

21 Mar 05:49
b90058a

Choose a tag to compare

This patch release contains a backported fix for a remote-triggered panic in the probe packet loss detection logic: #4998.

Full Changelog: v0.50.0...v0.50.1

v0.50.0

20 Feb 08:53
d726a79

Choose a tag to compare

This release implements server-side path-probing (as described in section 9 of RFC 9000): #4932, #4933, #4935, #4938, #4939, #4940, #4941, #4944, #4947, #4959.

When the server receives a packet for an existing connection from a different IP address / port, it first needs to probe the new path before it can send packets on that path. This happens when the client experiences a NAT rebinding, and when the client attempts to migrate to a new connection. Previous versions of quic-go would accept the packets from the new path, but never switch to the new path.

Note that the client side connection migration logic (#234) is not yet implemented in quic-go (but we're working on it!).

Major Changes

  • use the new crypto/tls 0-RTT API that we helped design in 2023: #4953
  • use a ringbuffer to store received packets, significantly reducing memory consumption: #4929
  • according to our Go version policy, we removed support for Go 1.22. quic-go now requires Go 1.23 or Go 1.24: #4880
  • the connection timer logic was refactored, enabling future changes to this code path: #4927

Other Fixes

  • fix busy-looping when pacing packets and the send queue blocks: #4943
  • don't drop undecryptable packets when deriving 2 sets of keys at the same time (i.e. when resuming a 0-RTT connection): #4950

Go 1.24 FIPS 140-3 Caveats

Go 1.24 made several changes related to FIPS 140-3 compliance. Among others, it introduced a fips-only mode (enabled by setting GODEBUG="fips140=only").

It is not possible to use quic-go in fips-only mode, since the QUIC RFC requires initializing an AES GCM cipher with a fixed nonce, which is considered unsafe according to FIPS 140-3, or at least the Go team's interpretation thereof. See #4894 and the discussion on Go issue #69536.

Before v0.50.0, quic-go would initialize the AES cipher on init, leading to a panic when using fips-only mode. For v0.50.0 we changed this behavior to lazy initialization (#4916). Note that this still means it's not possible to use QUIC in fips-only mode.

Changelog

Full Changelog: v0.49.0...v0.50.0