Repository: quic-go/quic-go
Pull request #4312 (2024-02-07 00:39:53)

ci: update to Go 1.22.0

marten-seemann: And of course CircleCI doesn't have the image ready yet. Maybe it's time to finally leave their subpar platform.

Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 95c258cf..194e51fa 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,15 +1,15 @@
 version: 2.1
 executors:
-  test-go121:
+  test-go122:
     docker:
-      - image: "cimg/go:1.21"
+      - image: "cimg/go:1.22"
     environment:
       runrace: true
       TIMESCALE_FACTOR: 3
  
 jobs:
   "test": &test
-    executor: test-go121
+    executor: test-go122
     steps:
       - checkout
       - run:
@@ -33,10 +33,10 @@ jobs:
       - run:
           name: "Run version negotiation tests with qlog"
           command: go run github.com/onsi/ginkgo/v2/ginkgo -v -randomize-all -trace integrationtests/versionnegotiation -- -qlog
-  go121:
+  go122:
     <<: *test
 
 workflows:
   workflow:
     jobs:
-      - go121
+      - go122
diff --git a/.clusterfuzzlite/Dockerfile b/.clusterfuzzlite/Dockerfile
index d27db151..d9fedb9a 100644
--- a/.clusterfuzzlite/Dockerfile
+++ b/.clusterfuzzlite/Dockerfile
@@ -3,7 +3,7 @@ FROM gcr.io/oss-fuzz-base/base-builder-go:v1
 ARG TARGETPLATFORM
 RUN echo "TARGETPLATFORM: ${TARGETPLATFORM}"
 
-ENV GOVERSION=1.21.5
+ENV GOVERSION=1.22.0
 
 RUN platform=$(echo ${TARGETPLATFORM} | tr '/' '-') && \
   filename="go${GOVERSION}.${platform}.tar.gz" && \
diff --git a/.github/workflows/cross-compile.yml b/.github/workflows/cross-compile.yml
index b419e998..30126dd3 100644
--- a/.github/workflows/cross-compile.yml
+++ b/.github/workflows/cross-compile.yml
@@ -4,7 +4,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        go: [ "1.21.x", "1.22.0-rc.2" ]
+        go: [ "1.21.x", "1.22.x" ]
     runs-on: ${{ fromJSON(vars['CROSS_COMPILE_RUNNER_UBUNTU'] || '"ubuntu-latest"') }}
     name: "Cross Compilation (Go ${{matrix.go}})"
     steps:
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index ece4d6b7..0c0d93a9 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -6,7 +6,7 @@ jobs:
       fail-fast: false
       matrix:
         os: [ "ubuntu" ]
-        go: [ "1.21.x", "1.22.0-rc.2" ]
+        go: [ "1.21.x", "1.22.x" ]
         include:
           - os: "windows"
             go: "1.21.x"
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index e2fdf1bd..0176c487 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -7,7 +7,7 @@ jobs:
       - uses: actions/checkout@v4
       - uses: actions/setup-go@v5
         with:
-          go-version: "1.21.x"
+          go-version: "1.22.x"
       - name: Check that no non-test files import Ginkgo or Gomega
         run: .github/workflows/no_ginkgo.sh
       - name: Check for //go:build ignore in .go files
@@ -38,7 +38,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        go: [  "1.21.x", "1.22.0-rc.2" ]
+        go: [  "1.21.x", "1.22.x" ]
     name: golangci-lint (Go ${{ matrix.go }})
     steps:
       - uses: actions/checkout@v4
diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml
index e1ee2832..f999bd5c 100644
--- a/.github/workflows/unit.yml
+++ b/.github/workflows/unit.yml
@@ -7,7 +7,7 @@ jobs:
       fail-fast: false
       matrix:
         os: [ "ubuntu", "windows", "macos" ]
-        go: [ "1.21.x", "1.22.0-rc.2" ]
+        go: [ "1.21.x", "1.22.x" ]
     runs-on: ${{ fromJSON(vars[format('UNIT_RUNNER_{0}', matrix.os)] || format('"{0}-latest"', matrix.os)) }}
     name: Unit tests (${{ matrix.os}}, Go ${{ matrix.go }})
     steps:
diff --git a/README.md b/README.md
index 93f14dd9..faba82f3 100644
--- a/README.md
+++ b/README.md
@@ -226,6 +226,7 @@ http.Client{
 | [algernon](https://github.com/xyproto/algernon)           | Small self-contained pure-Go web server with Lua, Markdown, HTTP/2, QUIC, Redis and PostgreSQL support                                                            | ![GitHub Repo stars](https://img.shields.io/github/stars/xyproto/algernon?style=flat-square)        |
 | [caddy](https://github.com/caddyserver/caddy/)            | Fast, multi-platform web server with automatic HTTPS                                                                                                              | ![GitHub Repo stars](https://img.shields.io/github/stars/caddyserver/caddy?style=flat-square)       |
 | [cloudflared](https://github.com/cloudflare/cloudflared)  | A tunneling daemon that proxies traffic from the Cloudflare network to your origins                                                                               | ![GitHub Repo stars](https://img.shields.io/github/stars/cloudflare/cloudflared?style=flat-square)  |
+| [frp](https://github.com/fatedier/frp)                    | A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet                                                                   | ![GitHub Repo stars](https://img.shields.io/github/stars/fatedier/frp?style=flat-square)            |
 | [go-libp2p](https://github.com/libp2p/go-libp2p)          | libp2p implementation in Go, powering [Kubo](https://github.com/ipfs/kubo) (IPFS) and [Lotus](https://github.com/filecoin-project/lotus) (Filecoin), among others | ![GitHub Repo stars](https://img.shields.io/github/stars/libp2p/go-libp2p?style=flat-square)     |
 | [gost](https://github.com/go-gost/gost)                   | A simple security tunnel written in Go                                                                                                                        | ![GitHub Repo stars](https://img.shields.io/github/stars/go-gost/gost?style=flat-square)            |
 | [Hysteria](https://github.com/apernet/hysteria)           | A powerful, lightning fast and censorship resistant proxy                                                                                                         | ![GitHub Repo stars](https://img.shields.io/github/stars/apernet/hysteria?style=flat-square)        |
diff --git a/internal/qtls/client_session_cache.go b/internal/qtls/client_session_cache.go
index d81eb8c3..2f459334 100644
--- a/internal/qtls/client_session_cache.go
+++ b/internal/qtls/client_session_cache.go
@@ -1,5 +1,3 @@
-//go:build go1.21
-
 package qtls
 
 import (
diff --git a/interop/Dockerfile b/interop/Dockerfile
index 636b9c59..6c34fae6 100644
--- a/interop/Dockerfile
+++ b/interop/Dockerfile
@@ -5,7 +5,7 @@ RUN echo "TARGETPLATFORM: ${TARGETPLATFORM}"
 
 RUN apt-get update && apt-get install -y wget tar git
 
-ENV GOVERSION=1.21.4
+ENV GOVERSION=1.22.0
 
 RUN platform=$(echo ${TARGETPLATFORM} | tr '/' '-') && \
   filename="go${GOVERSION}.${platform}.tar.gz" && \
diff --git a/logging/connection_tracer.go b/logging/connection_tracer.go
index 0f2cbe04..7f54d6cd 100644
--- a/logging/connection_tracer.go
+++ b/logging/connection_tracer.go
@@ -27,9 +27,9 @@ type ConnectionTracer struct {
 	UpdatedCongestionState           func(CongestionState)
 	UpdatedPTOCount                  func(value uint32)
 	UpdatedKeyFromTLS                func(EncryptionLevel, Perspective)
-	UpdatedKey                       func(generation KeyPhase, remote bool)
+	UpdatedKey                       func(keyPhase KeyPhase, remote bool)
 	DroppedEncryptionLevel           func(EncryptionLevel)
-	DroppedKey                       func(generation KeyPhase)
+	DroppedKey                       func(keyPhase KeyPhase)
 	SetLossTimer                     func(TimerType, EncryptionLevel, time.Time)
 	LossTimerExpired                 func(TimerType, EncryptionLevel)
 	LossTimerCanceled                func()
diff --git a/oss-fuzz.sh b/oss-fuzz.sh
index f72fb1b0..22a577fe 100644
--- a/oss-fuzz.sh
+++ b/oss-fuzz.sh
@@ -3,12 +3,12 @@
 # Install Go manually, since oss-fuzz ships with an outdated Go version.
 # See https://github.com/google/oss-fuzz/pull/10643.
 export CXX="${CXX} -lresolv" # required by Go 1.20
-wget https://go.dev/dl/go1.21.5.linux-amd64.tar.gz \
+wget https://go.dev/dl/go1.22.0.linux-amd64.tar.gz \
   && mkdir temp-go \
   && rm -rf /root/.go/* \
-  && tar -C temp-go/ -xzf go1.21.5.linux-amd64.tar.gz \
+  && tar -C temp-go/ -xzf go1.22.0.linux-amd64.tar.gz \
   && mv temp-go/go/* /root/.go/ \
-  && rm -rf temp-go go1.21.5.linux-amd64.tar.gz
+  && rm -rf temp-go go1.22.0.linux-amd64.tar.gz
 
 (
 # fuzz qpack
diff --git a/qlog/connection_tracer.go b/qlog/connection_tracer.go
index ae328a38..c73a3fe3 100644
--- a/qlog/connection_tracer.go
+++ b/qlog/connection_tracer.go
@@ -85,14 +85,14 @@ func NewConnectionTracer(w io.WriteCloser, p logging.Perspective, odcid protocol
 		UpdatedKeyFromTLS: func(encLevel protocol.EncryptionLevel, pers protocol.Perspective) {
 			t.UpdatedKeyFromTLS(encLevel, pers)
 		},
-		UpdatedKey: func(generation protocol.KeyPhase, remote bool) {
-			t.UpdatedKey(generation, remote)
+		UpdatedKey: func(keyPhase protocol.KeyPhase, remote bool) {
+			t.UpdatedKey(keyPhase, remote)
 		},
 		DroppedEncryptionLevel: func(encLevel protocol.EncryptionLevel) {
 			t.DroppedEncryptionLevel(encLevel)
 		},
-		DroppedKey: func(generation protocol.KeyPhase) {
-			t.DroppedKey(generation)
+		DroppedKey: func(keyPhase protocol.KeyPhase) {
+			t.DroppedKey(keyPhase)
 		},
 		SetLossTimer: func(tt logging.TimerType, encLevel protocol.EncryptionLevel, timeout time.Time) {
 			t.SetLossTimer(tt, encLevel, timeout)
@@ -389,14 +389,14 @@ func (t *connectionTracer) UpdatedKey(generation protocol.KeyPhase, remote bool)
 	}
 	now := time.Now()
 	t.recordEvent(now, &eventKeyUpdated{
-		Trigger:    trigger,
-		KeyType:    keyTypeClient1RTT,
-		Generation: generation,
+		Trigger:  trigger,
+		KeyType:  keyTypeClient1RTT,
+		KeyPhase: generation,
 	})
 	t.recordEvent(now, &eventKeyUpdated{
-		Trigger:    trigger,
-		KeyType:    keyTypeServer1RTT,
-		Generation: generation,
+		Trigger:  trigger,
+		KeyType:  keyTypeServer1RTT,
+		KeyPhase: generation,
 	})
 }
 
@@ -413,12 +413,12 @@ func (t *connectionTracer) DroppedEncryptionLevel(encLevel protocol.EncryptionLe
 func (t *connectionTracer) DroppedKey(generation protocol.KeyPhase) {
 	now := time.Now()
 	t.recordEvent(now, &eventKeyDiscarded{
-		KeyType:    encLevelToKeyType(protocol.Encryption1RTT, protocol.PerspectiveServer),
-		Generation: generation,
+		KeyType:  encLevelToKeyType(protocol.Encryption1RTT, protocol.PerspectiveServer),
+		KeyPhase: generation,
 	})
 	t.recordEvent(now, &eventKeyDiscarded{
-		KeyType:    encLevelToKeyType(protocol.Encryption1RTT, protocol.PerspectiveClient),
-		Generation: generation,
+		KeyType:  encLevelToKeyType(protocol.Encryption1RTT, protocol.PerspectiveClient),
+		KeyPhase: generation,
 	})
 }
 
diff --git a/qlog/event.go b/qlog/event.go
index e2ceca9f..d3d26601 100644
--- a/qlog/event.go
+++ b/qlog/event.go
@@ -345,9 +345,9 @@ func (e eventPacketLost) MarshalJSONObject(enc *gojay.Encoder) {
 }
 
 type eventKeyUpdated struct {
-	Trigger    keyUpdateTrigger
-	KeyType    keyType
-	Generation protocol.KeyPhase
+	Trigger  keyUpdateTrigger
+	KeyType  keyType
+	KeyPhase protocol.KeyPhase
 	// we don't log the keys here, so we don't need `old` and `new`.
 }
 
@@ -359,13 +359,13 @@ func (e eventKeyUpdated) MarshalJSONObject(enc *gojay.Encoder) {
 	enc.StringKey("trigger", e.Trigger.String())
 	enc.StringKey("key_type", e.KeyType.String())
 	if e.KeyType == keyTypeClient1RTT || e.KeyType == keyTypeServer1RTT {
-		enc.Uint64Key("generation", uint64(e.Generation))
+		enc.Uint64Key("key_phase", uint64(e.KeyPhase))
 	}
 }
 
 type eventKeyDiscarded struct {
-	KeyType    keyType
-	Generation protocol.KeyPhase
+	KeyType  keyType
+	KeyPhase protocol.KeyPhase
 }
 
 func (e eventKeyDiscarded) Category() category { return categorySecurity }
@@ -378,7 +378,7 @@ func (e eventKeyDiscarded) MarshalJSONObject(enc *gojay.Encoder) {
 	}
 	enc.StringKey("key_type", e.KeyType.String())
 	if e.KeyType == keyTypeClient1RTT || e.KeyType == keyTypeServer1RTT {
-		enc.Uint64Key("generation", uint64(e.Generation))
+		enc.Uint64Key("key_phase", uint64(e.KeyPhase))
 	}
 }
 


Test patch:
diff --git a/internal/qtls/qtls_test.go b/internal/qtls/qtls_test.go
index aadc118c..1007b82a 100644
--- a/internal/qtls/qtls_test.go
+++ b/internal/qtls/qtls_test.go
@@ -9,7 +9,7 @@ import (
 	. "github.com/onsi/gomega"
 )
 
-var _ = Describe("Go 1.21", func() {
+var _ = Describe("interface go crypto/tls", func() {
 	It("converts to tls.EncryptionLevel", func() {
 		Expect(ToTLSEncryptionLevel(protocol.EncryptionInitial)).To(Equal(tls.QUICEncryptionLevelInitial))
 		Expect(ToTLSEncryptionLevel(protocol.EncryptionHandshake)).To(Equal(tls.QUICEncryptionLevelHandshake))
diff --git a/qlog/connection_tracer_test.go b/qlog/connection_tracer_test.go
index 1e879ad9..dd4b800f 100644
--- a/qlog/connection_tracer_test.go
+++ b/qlog/connection_tracer_test.go
@@ -722,7 +722,7 @@ var _ = Describe("Tracing", func() {
 			ev := entry.Event
 			Expect(ev).To(HaveKeyWithValue("key_type", "client_handshake_secret"))
 			Expect(ev).To(HaveKeyWithValue("trigger", "tls"))
-			Expect(ev).ToNot(HaveKey("generation"))
+			Expect(ev).ToNot(HaveKey("key_phase"))
 			Expect(ev).ToNot(HaveKey("old"))
 			Expect(ev).ToNot(HaveKey("new"))
 		})
@@ -735,7 +735,7 @@ var _ = Describe("Tracing", func() {
 			ev := entry.Event
 			Expect(ev).To(HaveKeyWithValue("key_type", "server_1rtt_secret"))
 			Expect(ev).To(HaveKeyWithValue("trigger", "tls"))
-			Expect(ev).To(HaveKeyWithValue("generation", float64(0)))
+			Expect(ev).To(HaveKeyWithValue("key_phase", float64(0)))
 			Expect(ev).ToNot(HaveKey("old"))
 			Expect(ev).ToNot(HaveKey("new"))
 		})
@@ -749,7 +749,7 @@ var _ = Describe("Tracing", func() {
 				Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond)))
 				Expect(entry.Name).To(Equal("security:key_updated"))
 				ev := entry.Event
-				Expect(ev).To(HaveKeyWithValue("generation", float64(1337)))
+				Expect(ev).To(HaveKeyWithValue("key_phase", float64(1337)))
 				Expect(ev).To(HaveKeyWithValue("trigger", "remote_update"))
 				Expect(ev).To(HaveKey("key_type"))
 				keyTypes = append(keyTypes, ev["key_type"].(string))
@@ -796,7 +796,7 @@ var _ = Describe("Tracing", func() {
 				Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond)))
 				Expect(entry.Name).To(Equal("security:key_discarded"))
 				ev := entry.Event
-				Expect(ev).To(HaveKeyWithValue("generation", float64(42)))
+				Expect(ev).To(HaveKeyWithValue("key_phase", float64(42)))
 				Expect(ev).ToNot(HaveKey("trigger"))
 				Expect(ev).To(HaveKey("key_type"))
 				keyTypes = append(keyTypes, ev["key_type"].(string))