Skip to content

x/net/quic: add QUIC implementation #58547

Open
@neild

Description

@neild

I propose adding an implementation of the QUIC transport protocol (RFC 9000) in golang.org/x/net/quic. QUIC is the protocol underlying HTTP/3, and QUIC support is a necessary prerequisite for HTTP/3 support.

The proposed API is in https://go.dev/cl/468575. This API does not include support for Early Data, but does not preclude adding that support at a later time.

RFC 9000 does not define a QUIC API, but it does define a set of operations that can be performed on a QUIC connection or stream.

A QUIC connection is shared state between a client and server.

  • open a [client] connection:

    conn, err := quic.Dial(ctx, "udp", "127.0.0.1:8000", &quic.Config{})
  • listen for incoming connections:

    l, err := quic.Listen("udp", "127.0.0.1:8000", &quic.Config{})
    conn, err := l.Accept(ctx)

A QUIC stream is an ordered, reliable byte stream. A connection may have many streams. (A QUIC stream is loosely analogous to a TCP connection.)

  • create streams:

    s, err := conn.NewStream(ctx)
  • accept streams created by the peer:

    s, err := conn.AcceptStream(ctx)
  • read from, write to, and close streams:

    n, err = s.Read(buf)
    n, err = s.Write(buf)
    s.Close()
  • stream operations also have Context-aware variants:

    n, err = s.ReadContext(ctx, buf)
    n, err = s.WriteContext(ctx, buf)
    s.CloseContext(ctx)
  • data written to streams is buffered, and may be explicitly flushed:

    // Sends one datagram, not 100.
    for i := byte(0); i < 100; i++ {
      s.Write([]byte{i})
    }
    // Data will not be sent until a datagram's worth has been accumulated or an explicit flush.
    // No Nagle's algorithm.
    s.Flush()

See https://go.dev/cl/468575 for the detailed API.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Accepted

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions