From 89b3058c458af202a4c057d2542d5ac0333e39f0 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 29 May 2024 12:25:23 +0800 Subject: [PATCH] explain how to use the new Transport.ConnContext callback --- content/docs/quic/connection.md | 37 +++++++++++++++++++++++++++++++++ content/docs/quic/qlog.md | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/content/docs/quic/connection.md b/content/docs/quic/connection.md index 64a8065..1c266e9 100644 --- a/content/docs/quic/connection.md +++ b/content/docs/quic/connection.md @@ -7,6 +7,43 @@ weight: 4 The `quic.Connection` is the central object to send and receive application data. Data is not sent directly on the connection, but either on [streams]({{< relref "streams.md" >}}), or (optionally) in so-called [datagrams]({{< relref "datagrams.md" >}}). +## Using the Connection Context {#conn-context} + +When a new QUIC connection is established, a number of callbacks might be called during the different stages of the QUIC handshake. Among those are: +* TLS configuration callbacks, e.g. `tls.Config.GetConfigForClient`, `tls.Config.GetCertificate` and `tls.Config.GetClientCertificate` +* QUIC connection tracer configuration (using `quic.Config.Tracer`), used for configuring [qlog event logging]({{< relref "qlog.md" >}}), among others + +Applications can identify which QUIC connection these callbacks are called for by attaching values to the context using `Transport.ConnContext` (for incoming connections) and the context passed to `Dial` (for outgoing connections). + +For example: +```go +tr := quic.Transport{ + ConnContext: func(ctx context.Context) context.Context { + // In practice, generate an identifier that's unique to this one connection, + // for example by incrementing a counter. + return context.WithValue(ctx, "foo", "bar") + } +} + +ln, err := tr.Listen(&tls.Config{ + GetConfigForClient: func(info *tls.ClientHelloInfo) *tls.Config { + // this context has a key "foo" with value "bar" + _ = info.Context() + return + } +}, nil) +// ... error handling +conn, err := ln.Accept() +// ... error handling + +// this context has a key "foo" with value "bar" +_ = conn.Context() +``` + +The context passed to `ConnContext` is closed once the QUIC connection is closed, or if the handshake fails for any reason. +This allows applications to clean up state that might they might have created in the `ConnContext` callback (e.g. by using `context.AfterFunc`). + + ## Closing a Connection {#closing} At any point during the connection, a `quic.Connection` can be closed by calling `CloseWithError`: diff --git a/content/docs/quic/qlog.md b/content/docs/quic/qlog.md index 7a102b1..265c6a5 100644 --- a/content/docs/quic/qlog.md +++ b/content/docs/quic/qlog.md @@ -32,7 +32,7 @@ quic.Config{ } ``` -The `context.Context` passed to this callback is never closed, but it carries a `quic.ConnectionTracingKey` value. This value is also set on the context returned from `Connection.Context`. +The `context.Context` passed to this callback is never closed, and is derived from the context returned from [`quic.Config.ConnContext`]({{< relref path="connection.md#conn-context" >}}). It is valid to return `nil` for the `*logging.ConnectionTracer` from this callback. In this case, qlogging will be disabled for this connection.