github quic-go/quic-go v0.35.0

latest releases: v0.47.0, v0.46.0, v0.45.2...
16 months ago

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 that context.Context wasn't in existence when quic-go was launched eight years ago.
  • quic.Listener and quic.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](https://github.com/quic-go/quic-go/blob/v0.34.0/multiplexer.go#L82-L90).

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:

  1. Substitute calls to DialContext with calls to Dial.
  2. Replace all instances of Listener with *Listener (and similarly for EarlyListener).

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 implements CloseIdleConnections method, allowing the use of http.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). Using SO_RCVBUFFORCE call will only succeed when the process has CAP_NET_ADMIN permissions, but in these cases no manual configuration will be necessary any more. Thanks to @MarcoPolo!

Full Changelog

New Contributors

Full Changelog: v0.34.0...v0.35.0

Don't miss a new quic-go release

NewReleases is sending notifications on new releases.