Repository: quic-go/quic-go
Pull request #4764 (2024-12-18 12:17:32)

flowcontrol: reset the connection send window when 0-RTT is rejected


Patch:
diff --git a/go.mod b/go.mod
index 416f1f7b..93268311 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,7 @@ require (
 	github.com/prometheus/client_golang v1.19.1
 	github.com/quic-go/qpack v0.5.1
 	github.com/stretchr/testify v1.9.0
-	go.uber.org/mock v0.4.0
+	go.uber.org/mock v0.5.0
 	golang.org/x/crypto v0.26.0
 	golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
 	golang.org/x/net v0.28.0
diff --git a/go.sum b/go.sum
index 022aa0f4..e05c6fd8 100644
--- a/go.sum
+++ b/go.sum
@@ -139,8 +139,8 @@ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cb
 github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
 github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
 go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
-go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
-go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
+go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
+go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
 go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
 golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
 golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
diff --git a/internal/flowcontrol/connection_flow_controller.go b/internal/flowcontrol/connection_flow_controller.go
index 016ffaa9..362a9a95 100644
--- a/internal/flowcontrol/connection_flow_controller.go
+++ b/internal/flowcontrol/connection_flow_controller.go
@@ -106,5 +106,6 @@ func (c *connectionFlowController) Reset() error {
 	}
 	c.bytesSent = 0
 	c.lastBlockedAt = 0
+	c.sendWindow = 0
 	return nil
 }
diff --git a/internal/mocks/ackhandler/received_packet_handler.go b/internal/mocks/ackhandler/received_packet_handler.go
index c9c0fd57..6b9a99c4 100644
--- a/internal/mocks/ackhandler/received_packet_handler.go
+++ b/internal/mocks/ackhandler/received_packet_handler.go
@@ -22,6 +22,7 @@ import (
 type MockReceivedPacketHandler struct {
 	ctrl     *gomock.Controller
 	recorder *MockReceivedPacketHandlerMockRecorder
+	isgomock struct{}
 }
 
 // MockReceivedPacketHandlerMockRecorder is the mock recorder for MockReceivedPacketHandler.
@@ -78,17 +79,17 @@ func (c *MockReceivedPacketHandlerDropPacketsCall) DoAndReturn(f func(protocol.E
 }
 
 // GetAckFrame mocks base method.
-func (m *MockReceivedPacketHandler) GetAckFrame(arg0 protocol.EncryptionLevel, arg1 bool) *wire.AckFrame {
+func (m *MockReceivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel, onlyIfQueued bool) *wire.AckFrame {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetAckFrame", arg0, arg1)
+	ret := m.ctrl.Call(m, "GetAckFrame", encLevel, onlyIfQueued)
 	ret0, _ := ret[0].(*wire.AckFrame)
 	return ret0
 }
 
 // GetAckFrame indicates an expected call of GetAckFrame.
-func (mr *MockReceivedPacketHandlerMockRecorder) GetAckFrame(arg0, arg1 any) *MockReceivedPacketHandlerGetAckFrameCall {
+func (mr *MockReceivedPacketHandlerMockRecorder) GetAckFrame(encLevel, onlyIfQueued any) *MockReceivedPacketHandlerGetAckFrameCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAckFrame", reflect.TypeOf((*MockReceivedPacketHandler)(nil).GetAckFrame), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAckFrame", reflect.TypeOf((*MockReceivedPacketHandler)(nil).GetAckFrame), encLevel, onlyIfQueued)
 	return &MockReceivedPacketHandlerGetAckFrameCall{Call: call}
 }
 
@@ -192,17 +193,17 @@ func (c *MockReceivedPacketHandlerIsPotentiallyDuplicateCall) DoAndReturn(f func
 }
 
 // ReceivedPacket mocks base method.
-func (m *MockReceivedPacketHandler) ReceivedPacket(arg0 protocol.PacketNumber, arg1 protocol.ECN, arg2 protocol.EncryptionLevel, arg3 time.Time, arg4 bool) error {
+func (m *MockReceivedPacketHandler) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, encLevel protocol.EncryptionLevel, rcvTime time.Time, ackEliciting bool) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ReceivedPacket", arg0, arg1, arg2, arg3, arg4)
+	ret := m.ctrl.Call(m, "ReceivedPacket", pn, ecn, encLevel, rcvTime, ackEliciting)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // ReceivedPacket indicates an expected call of ReceivedPacket.
-func (mr *MockReceivedPacketHandlerMockRecorder) ReceivedPacket(arg0, arg1, arg2, arg3, arg4 any) *MockReceivedPacketHandlerReceivedPacketCall {
+func (mr *MockReceivedPacketHandlerMockRecorder) ReceivedPacket(pn, ecn, encLevel, rcvTime, ackEliciting any) *MockReceivedPacketHandlerReceivedPacketCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedPacket", reflect.TypeOf((*MockReceivedPacketHandler)(nil).ReceivedPacket), arg0, arg1, arg2, arg3, arg4)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedPacket", reflect.TypeOf((*MockReceivedPacketHandler)(nil).ReceivedPacket), pn, ecn, encLevel, rcvTime, ackEliciting)
 	return &MockReceivedPacketHandlerReceivedPacketCall{Call: call}
 }
 
diff --git a/internal/mocks/ackhandler/sent_packet_handler.go b/internal/mocks/ackhandler/sent_packet_handler.go
index 9efeb9be..84ca35ac 100644
--- a/internal/mocks/ackhandler/sent_packet_handler.go
+++ b/internal/mocks/ackhandler/sent_packet_handler.go
@@ -23,6 +23,7 @@ import (
 type MockSentPacketHandler struct {
 	ctrl     *gomock.Controller
 	recorder *MockSentPacketHandlerMockRecorder
+	isgomock struct{}
 }
 
 // MockSentPacketHandlerMockRecorder is the mock recorder for MockSentPacketHandler.
@@ -79,17 +80,17 @@ func (c *MockSentPacketHandlerDropPacketsCall) DoAndReturn(f func(protocol.Encry
 }
 
 // ECNMode mocks base method.
-func (m *MockSentPacketHandler) ECNMode(arg0 bool) protocol.ECN {
+func (m *MockSentPacketHandler) ECNMode(isShortHeaderPacket bool) protocol.ECN {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ECNMode", arg0)
+	ret := m.ctrl.Call(m, "ECNMode", isShortHeaderPacket)
 	ret0, _ := ret[0].(protocol.ECN)
 	return ret0
 }
 
 // ECNMode indicates an expected call of ECNMode.
-func (mr *MockSentPacketHandlerMockRecorder) ECNMode(arg0 any) *MockSentPacketHandlerECNModeCall {
+func (mr *MockSentPacketHandlerMockRecorder) ECNMode(isShortHeaderPacket any) *MockSentPacketHandlerECNModeCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNMode", reflect.TypeOf((*MockSentPacketHandler)(nil).ECNMode), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNMode", reflect.TypeOf((*MockSentPacketHandler)(nil).ECNMode), isShortHeaderPacket)
 	return &MockSentPacketHandlerECNModeCall{Call: call}
 }
 
@@ -308,18 +309,18 @@ func (c *MockSentPacketHandlerQueueProbePacketCall) DoAndReturn(f func(protocol.
 }
 
 // ReceivedAck mocks base method.
-func (m *MockSentPacketHandler) ReceivedAck(arg0 *wire.AckFrame, arg1 protocol.EncryptionLevel, arg2 time.Time) (bool, error) {
+func (m *MockSentPacketHandler) ReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ReceivedAck", arg0, arg1, arg2)
+	ret := m.ctrl.Call(m, "ReceivedAck", f, encLevel, rcvTime)
 	ret0, _ := ret[0].(bool)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // ReceivedAck indicates an expected call of ReceivedAck.
-func (mr *MockSentPacketHandlerMockRecorder) ReceivedAck(arg0, arg1, arg2 any) *MockSentPacketHandlerReceivedAckCall {
+func (mr *MockSentPacketHandlerMockRecorder) ReceivedAck(f, encLevel, rcvTime any) *MockSentPacketHandlerReceivedAckCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedAck", reflect.TypeOf((*MockSentPacketHandler)(nil).ReceivedAck), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedAck", reflect.TypeOf((*MockSentPacketHandler)(nil).ReceivedAck), f, encLevel, rcvTime)
 	return &MockSentPacketHandlerReceivedAckCall{Call: call}
 }
 
@@ -383,17 +384,17 @@ func (c *MockSentPacketHandlerReceivedBytesCall) DoAndReturn(f func(protocol.Byt
 }
 
 // ResetForRetry mocks base method.
-func (m *MockSentPacketHandler) ResetForRetry(arg0 time.Time) error {
+func (m *MockSentPacketHandler) ResetForRetry(rcvTime time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ResetForRetry", arg0)
+	ret := m.ctrl.Call(m, "ResetForRetry", rcvTime)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // ResetForRetry indicates an expected call of ResetForRetry.
-func (mr *MockSentPacketHandlerMockRecorder) ResetForRetry(arg0 any) *MockSentPacketHandlerResetForRetryCall {
+func (mr *MockSentPacketHandlerMockRecorder) ResetForRetry(rcvTime any) *MockSentPacketHandlerResetForRetryCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetForRetry", reflect.TypeOf((*MockSentPacketHandler)(nil).ResetForRetry), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetForRetry", reflect.TypeOf((*MockSentPacketHandler)(nil).ResetForRetry), rcvTime)
 	return &MockSentPacketHandlerResetForRetryCall{Call: call}
 }
 
@@ -421,17 +422,17 @@ func (c *MockSentPacketHandlerResetForRetryCall) DoAndReturn(f func(time.Time) e
 }
 
 // SendMode mocks base method.
-func (m *MockSentPacketHandler) SendMode(arg0 time.Time) ackhandler.SendMode {
+func (m *MockSentPacketHandler) SendMode(now time.Time) ackhandler.SendMode {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SendMode", arg0)
+	ret := m.ctrl.Call(m, "SendMode", now)
 	ret0, _ := ret[0].(ackhandler.SendMode)
 	return ret0
 }
 
 // SendMode indicates an expected call of SendMode.
-func (mr *MockSentPacketHandlerMockRecorder) SendMode(arg0 any) *MockSentPacketHandlerSendModeCall {
+func (mr *MockSentPacketHandlerMockRecorder) SendMode(now any) *MockSentPacketHandlerSendModeCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMode", reflect.TypeOf((*MockSentPacketHandler)(nil).SendMode), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMode", reflect.TypeOf((*MockSentPacketHandler)(nil).SendMode), now)
 	return &MockSentPacketHandlerSendModeCall{Call: call}
 }
 
@@ -459,15 +460,15 @@ func (c *MockSentPacketHandlerSendModeCall) DoAndReturn(f func(time.Time) ackhan
 }
 
 // SentPacket mocks base method.
-func (m *MockSentPacketHandler) SentPacket(arg0 time.Time, arg1, arg2 protocol.PacketNumber, arg3 []ackhandler.StreamFrame, arg4 []ackhandler.Frame, arg5 protocol.EncryptionLevel, arg6 protocol.ECN, arg7 protocol.ByteCount, arg8 bool) {
+func (m *MockSentPacketHandler) SentPacket(t time.Time, pn, largestAcked protocol.PacketNumber, streamFrames []ackhandler.StreamFrame, frames []ackhandler.Frame, encLevel protocol.EncryptionLevel, ecn protocol.ECN, size protocol.ByteCount, isPathMTUProbePacket bool) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "SentPacket", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
+	m.ctrl.Call(m, "SentPacket", t, pn, largestAcked, streamFrames, frames, encLevel, ecn, size, isPathMTUProbePacket)
 }
 
 // SentPacket indicates an expected call of SentPacket.
-func (mr *MockSentPacketHandlerMockRecorder) SentPacket(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 any) *MockSentPacketHandlerSentPacketCall {
+func (mr *MockSentPacketHandlerMockRecorder) SentPacket(t, pn, largestAcked, streamFrames, frames, encLevel, ecn, size, isPathMTUProbePacket any) *MockSentPacketHandlerSentPacketCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockSentPacketHandler)(nil).SentPacket), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockSentPacketHandler)(nil).SentPacket), t, pn, largestAcked, streamFrames, frames, encLevel, ecn, size, isPathMTUProbePacket)
 	return &MockSentPacketHandlerSentPacketCall{Call: call}
 }
 
@@ -531,15 +532,15 @@ func (c *MockSentPacketHandlerSetHandshakeConfirmedCall) DoAndReturn(f func()) *
 }
 
 // SetMaxDatagramSize mocks base method.
-func (m *MockSentPacketHandler) SetMaxDatagramSize(arg0 protocol.ByteCount) {
+func (m *MockSentPacketHandler) SetMaxDatagramSize(count protocol.ByteCount) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "SetMaxDatagramSize", arg0)
+	m.ctrl.Call(m, "SetMaxDatagramSize", count)
 }
 
 // SetMaxDatagramSize indicates an expected call of SetMaxDatagramSize.
-func (mr *MockSentPacketHandlerMockRecorder) SetMaxDatagramSize(arg0 any) *MockSentPacketHandlerSetMaxDatagramSizeCall {
+func (mr *MockSentPacketHandlerMockRecorder) SetMaxDatagramSize(count any) *MockSentPacketHandlerSetMaxDatagramSizeCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxDatagramSize", reflect.TypeOf((*MockSentPacketHandler)(nil).SetMaxDatagramSize), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxDatagramSize", reflect.TypeOf((*MockSentPacketHandler)(nil).SetMaxDatagramSize), count)
 	return &MockSentPacketHandlerSetMaxDatagramSizeCall{Call: call}
 }
 
diff --git a/internal/mocks/congestion.go b/internal/mocks/congestion.go
index 50654c0e..372d0824 100644
--- a/internal/mocks/congestion.go
+++ b/internal/mocks/congestion.go
@@ -21,6 +21,7 @@ import (
 type MockSendAlgorithmWithDebugInfos struct {
 	ctrl     *gomock.Controller
 	recorder *MockSendAlgorithmWithDebugInfosMockRecorder
+	isgomock struct{}
 }
 
 // MockSendAlgorithmWithDebugInfosMockRecorder is the mock recorder for MockSendAlgorithmWithDebugInfos.
@@ -41,17 +42,17 @@ func (m *MockSendAlgorithmWithDebugInfos) EXPECT() *MockSendAlgorithmWithDebugIn
 }
 
 // CanSend mocks base method.
-func (m *MockSendAlgorithmWithDebugInfos) CanSend(arg0 protocol.ByteCount) bool {
+func (m *MockSendAlgorithmWithDebugInfos) CanSend(bytesInFlight protocol.ByteCount) bool {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "CanSend", arg0)
+	ret := m.ctrl.Call(m, "CanSend", bytesInFlight)
 	ret0, _ := ret[0].(bool)
 	return ret0
 }
 
 // CanSend indicates an expected call of CanSend.
-func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) CanSend(arg0 any) *MockSendAlgorithmWithDebugInfosCanSendCall {
+func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) CanSend(bytesInFlight any) *MockSendAlgorithmWithDebugInfosCanSendCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CanSend", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).CanSend), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CanSend", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).CanSend), bytesInFlight)
 	return &MockSendAlgorithmWithDebugInfosCanSendCall{Call: call}
 }
 
@@ -117,17 +118,17 @@ func (c *MockSendAlgorithmWithDebugInfosGetCongestionWindowCall) DoAndReturn(f f
 }
 
 // HasPacingBudget mocks base method.
-func (m *MockSendAlgorithmWithDebugInfos) HasPacingBudget(arg0 time.Time) bool {
+func (m *MockSendAlgorithmWithDebugInfos) HasPacingBudget(now time.Time) bool {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "HasPacingBudget", arg0)
+	ret := m.ctrl.Call(m, "HasPacingBudget", now)
 	ret0, _ := ret[0].(bool)
 	return ret0
 }
 
 // HasPacingBudget indicates an expected call of HasPacingBudget.
-func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) HasPacingBudget(arg0 any) *MockSendAlgorithmWithDebugInfosHasPacingBudgetCall {
+func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) HasPacingBudget(now any) *MockSendAlgorithmWithDebugInfosHasPacingBudgetCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasPacingBudget", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).HasPacingBudget), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasPacingBudget", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).HasPacingBudget), now)
 	return &MockSendAlgorithmWithDebugInfosHasPacingBudgetCall{Call: call}
 }
 
@@ -267,15 +268,15 @@ func (c *MockSendAlgorithmWithDebugInfosMaybeExitSlowStartCall) DoAndReturn(f fu
 }
 
 // OnCongestionEvent mocks base method.
-func (m *MockSendAlgorithmWithDebugInfos) OnCongestionEvent(arg0 protocol.PacketNumber, arg1, arg2 protocol.ByteCount) {
+func (m *MockSendAlgorithmWithDebugInfos) OnCongestionEvent(number protocol.PacketNumber, lostBytes, priorInFlight protocol.ByteCount) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "OnCongestionEvent", arg0, arg1, arg2)
+	m.ctrl.Call(m, "OnCongestionEvent", number, lostBytes, priorInFlight)
 }
 
 // OnCongestionEvent indicates an expected call of OnCongestionEvent.
-func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnCongestionEvent(arg0, arg1, arg2 any) *MockSendAlgorithmWithDebugInfosOnCongestionEventCall {
+func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnCongestionEvent(number, lostBytes, priorInFlight any) *MockSendAlgorithmWithDebugInfosOnCongestionEventCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnCongestionEvent", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnCongestionEvent), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnCongestionEvent", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnCongestionEvent), number, lostBytes, priorInFlight)
 	return &MockSendAlgorithmWithDebugInfosOnCongestionEventCall{Call: call}
 }
 
@@ -303,15 +304,15 @@ func (c *MockSendAlgorithmWithDebugInfosOnCongestionEventCall) DoAndReturn(f fun
 }
 
 // OnPacketAcked mocks base method.
-func (m *MockSendAlgorithmWithDebugInfos) OnPacketAcked(arg0 protocol.PacketNumber, arg1, arg2 protocol.ByteCount, arg3 time.Time) {
+func (m *MockSendAlgorithmWithDebugInfos) OnPacketAcked(number protocol.PacketNumber, ackedBytes, priorInFlight protocol.ByteCount, eventTime time.Time) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "OnPacketAcked", arg0, arg1, arg2, arg3)
+	m.ctrl.Call(m, "OnPacketAcked", number, ackedBytes, priorInFlight, eventTime)
 }
 
 // OnPacketAcked indicates an expected call of OnPacketAcked.
-func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketAcked(arg0, arg1, arg2, arg3 any) *MockSendAlgorithmWithDebugInfosOnPacketAckedCall {
+func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketAcked(number, ackedBytes, priorInFlight, eventTime any) *MockSendAlgorithmWithDebugInfosOnPacketAckedCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketAcked", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketAcked), arg0, arg1, arg2, arg3)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketAcked", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketAcked), number, ackedBytes, priorInFlight, eventTime)
 	return &MockSendAlgorithmWithDebugInfosOnPacketAckedCall{Call: call}
 }
 
@@ -339,15 +340,15 @@ func (c *MockSendAlgorithmWithDebugInfosOnPacketAckedCall) DoAndReturn(f func(pr
 }
 
 // OnPacketSent mocks base method.
-func (m *MockSendAlgorithmWithDebugInfos) OnPacketSent(arg0 time.Time, arg1 protocol.ByteCount, arg2 protocol.PacketNumber, arg3 protocol.ByteCount, arg4 bool) {
+func (m *MockSendAlgorithmWithDebugInfos) OnPacketSent(sentTime time.Time, bytesInFlight protocol.ByteCount, packetNumber protocol.PacketNumber, bytes protocol.ByteCount, isRetransmittable bool) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "OnPacketSent", arg0, arg1, arg2, arg3, arg4)
+	m.ctrl.Call(m, "OnPacketSent", sentTime, bytesInFlight, packetNumber, bytes, isRetransmittable)
 }
 
 // OnPacketSent indicates an expected call of OnPacketSent.
-func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketSent(arg0, arg1, arg2, arg3, arg4 any) *MockSendAlgorithmWithDebugInfosOnPacketSentCall {
+func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnPacketSent(sentTime, bytesInFlight, packetNumber, bytes, isRetransmittable any) *MockSendAlgorithmWithDebugInfosOnPacketSentCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketSent", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketSent), arg0, arg1, arg2, arg3, arg4)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPacketSent", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnPacketSent), sentTime, bytesInFlight, packetNumber, bytes, isRetransmittable)
 	return &MockSendAlgorithmWithDebugInfosOnPacketSentCall{Call: call}
 }
 
@@ -375,15 +376,15 @@ func (c *MockSendAlgorithmWithDebugInfosOnPacketSentCall) DoAndReturn(f func(tim
 }
 
 // OnRetransmissionTimeout mocks base method.
-func (m *MockSendAlgorithmWithDebugInfos) OnRetransmissionTimeout(arg0 bool) {
+func (m *MockSendAlgorithmWithDebugInfos) OnRetransmissionTimeout(packetsRetransmitted bool) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "OnRetransmissionTimeout", arg0)
+	m.ctrl.Call(m, "OnRetransmissionTimeout", packetsRetransmitted)
 }
 
 // OnRetransmissionTimeout indicates an expected call of OnRetransmissionTimeout.
-func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnRetransmissionTimeout(arg0 any) *MockSendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall {
+func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) OnRetransmissionTimeout(packetsRetransmitted any) *MockSendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnRetransmissionTimeout", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnRetransmissionTimeout), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnRetransmissionTimeout", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).OnRetransmissionTimeout), packetsRetransmitted)
 	return &MockSendAlgorithmWithDebugInfosOnRetransmissionTimeoutCall{Call: call}
 }
 
@@ -447,17 +448,17 @@ func (c *MockSendAlgorithmWithDebugInfosSetMaxDatagramSizeCall) DoAndReturn(f fu
 }
 
 // TimeUntilSend mocks base method.
-func (m *MockSendAlgorithmWithDebugInfos) TimeUntilSend(arg0 protocol.ByteCount) time.Time {
+func (m *MockSendAlgorithmWithDebugInfos) TimeUntilSend(bytesInFlight protocol.ByteCount) time.Time {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "TimeUntilSend", arg0)
+	ret := m.ctrl.Call(m, "TimeUntilSend", bytesInFlight)
 	ret0, _ := ret[0].(time.Time)
 	return ret0
 }
 
 // TimeUntilSend indicates an expected call of TimeUntilSend.
-func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) TimeUntilSend(arg0 any) *MockSendAlgorithmWithDebugInfosTimeUntilSendCall {
+func (mr *MockSendAlgorithmWithDebugInfosMockRecorder) TimeUntilSend(bytesInFlight any) *MockSendAlgorithmWithDebugInfosTimeUntilSendCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TimeUntilSend", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).TimeUntilSend), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TimeUntilSend", reflect.TypeOf((*MockSendAlgorithmWithDebugInfos)(nil).TimeUntilSend), bytesInFlight)
 	return &MockSendAlgorithmWithDebugInfosTimeUntilSendCall{Call: call}
 }
 
diff --git a/internal/mocks/connection_flow_controller.go b/internal/mocks/connection_flow_controller.go
index e16c26d5..face2b21 100644
--- a/internal/mocks/connection_flow_controller.go
+++ b/internal/mocks/connection_flow_controller.go
@@ -21,6 +21,7 @@ import (
 type MockConnectionFlowController struct {
 	ctrl     *gomock.Controller
 	recorder *MockConnectionFlowControllerMockRecorder
+	isgomock struct{}
 }
 
 // MockConnectionFlowControllerMockRecorder is the mock recorder for MockConnectionFlowController.
@@ -286,8 +287,8 @@ type MockConnectionFlowControllerUpdateSendWindowCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockConnectionFlowControllerUpdateSendWindowCall) Return(arg0 bool) *MockConnectionFlowControllerUpdateSendWindowCall {
-	c.Call = c.Call.Return(arg0)
+func (c *MockConnectionFlowControllerUpdateSendWindowCall) Return(updated bool) *MockConnectionFlowControllerUpdateSendWindowCall {
+	c.Call = c.Call.Return(updated)
 	return c
 }
 
diff --git a/internal/mocks/crypto_setup.go b/internal/mocks/crypto_setup.go
index 407d67f2..a4feaeb8 100644
--- a/internal/mocks/crypto_setup.go
+++ b/internal/mocks/crypto_setup.go
@@ -22,6 +22,7 @@ import (
 type MockCryptoSetup struct {
 	ctrl     *gomock.Controller
 	recorder *MockCryptoSetupMockRecorder
+	isgomock struct{}
 }
 
 // MockCryptoSetupMockRecorder is the mock recorder for MockCryptoSetup.
diff --git a/internal/mocks/logging/internal/connection_tracer.go b/internal/mocks/logging/internal/connection_tracer.go
index 0bf08211..2414d236 100644
--- a/internal/mocks/logging/internal/connection_tracer.go
+++ b/internal/mocks/logging/internal/connection_tracer.go
@@ -25,6 +25,7 @@ import (
 type MockConnectionTracer struct {
 	ctrl     *gomock.Controller
 	recorder *MockConnectionTracerMockRecorder
+	isgomock struct{}
 }
 
 // MockConnectionTracerMockRecorder is the mock recorder for MockConnectionTracer.
@@ -117,15 +118,15 @@ func (c *MockConnectionTracerBufferedPacketCall) DoAndReturn(f func(logging.Pack
 }
 
 // ChoseALPN mocks base method.
-func (m *MockConnectionTracer) ChoseALPN(arg0 string) {
+func (m *MockConnectionTracer) ChoseALPN(protocol string) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "ChoseALPN", arg0)
+	m.ctrl.Call(m, "ChoseALPN", protocol)
 }
 
 // ChoseALPN indicates an expected call of ChoseALPN.
-func (mr *MockConnectionTracerMockRecorder) ChoseALPN(arg0 any) *MockConnectionTracerChoseALPNCall {
+func (mr *MockConnectionTracerMockRecorder) ChoseALPN(protocol any) *MockConnectionTracerChoseALPNCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChoseALPN", reflect.TypeOf((*MockConnectionTracer)(nil).ChoseALPN), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChoseALPN", reflect.TypeOf((*MockConnectionTracer)(nil).ChoseALPN), protocol)
 	return &MockConnectionTracerChoseALPNCall{Call: call}
 }
 
@@ -225,15 +226,15 @@ func (c *MockConnectionTracerClosedConnectionCall) DoAndReturn(f func(error)) *M
 }
 
 // Debug mocks base method.
-func (m *MockConnectionTracer) Debug(arg0, arg1 string) {
+func (m *MockConnectionTracer) Debug(name, msg string) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "Debug", arg0, arg1)
+	m.ctrl.Call(m, "Debug", name, msg)
 }
 
 // Debug indicates an expected call of Debug.
-func (mr *MockConnectionTracerMockRecorder) Debug(arg0, arg1 any) *MockConnectionTracerDebugCall {
+func (mr *MockConnectionTracerMockRecorder) Debug(name, msg any) *MockConnectionTracerDebugCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockConnectionTracer)(nil).Debug), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockConnectionTracer)(nil).Debug), name, msg)
 	return &MockConnectionTracerDebugCall{Call: call}
 }
 
@@ -297,15 +298,15 @@ func (c *MockConnectionTracerDroppedEncryptionLevelCall) DoAndReturn(f func(prot
 }
 
 // DroppedKey mocks base method.
-func (m *MockConnectionTracer) DroppedKey(arg0 protocol.KeyPhase) {
+func (m *MockConnectionTracer) DroppedKey(generation protocol.KeyPhase) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "DroppedKey", arg0)
+	m.ctrl.Call(m, "DroppedKey", generation)
 }
 
 // DroppedKey indicates an expected call of DroppedKey.
-func (mr *MockConnectionTracerMockRecorder) DroppedKey(arg0 any) *MockConnectionTracerDroppedKeyCall {
+func (mr *MockConnectionTracerMockRecorder) DroppedKey(generation any) *MockConnectionTracerDroppedKeyCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedKey", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedKey), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedKey", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedKey), generation)
 	return &MockConnectionTracerDroppedKeyCall{Call: call}
 }
 
@@ -369,15 +370,15 @@ func (c *MockConnectionTracerDroppedPacketCall) DoAndReturn(f func(logging.Packe
 }
 
 // ECNStateUpdated mocks base method.
-func (m *MockConnectionTracer) ECNStateUpdated(arg0 logging.ECNState, arg1 logging.ECNStateTrigger) {
+func (m *MockConnectionTracer) ECNStateUpdated(state logging.ECNState, trigger logging.ECNStateTrigger) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "ECNStateUpdated", arg0, arg1)
+	m.ctrl.Call(m, "ECNStateUpdated", state, trigger)
 }
 
 // ECNStateUpdated indicates an expected call of ECNStateUpdated.
-func (mr *MockConnectionTracerMockRecorder) ECNStateUpdated(arg0, arg1 any) *MockConnectionTracerECNStateUpdatedCall {
+func (mr *MockConnectionTracerMockRecorder) ECNStateUpdated(state, trigger any) *MockConnectionTracerECNStateUpdatedCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNStateUpdated", reflect.TypeOf((*MockConnectionTracer)(nil).ECNStateUpdated), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ECNStateUpdated", reflect.TypeOf((*MockConnectionTracer)(nil).ECNStateUpdated), state, trigger)
 	return &MockConnectionTracerECNStateUpdatedCall{Call: call}
 }
 
@@ -513,15 +514,15 @@ func (c *MockConnectionTracerLostPacketCall) DoAndReturn(f func(protocol.Encrypt
 }
 
 // NegotiatedVersion mocks base method.
-func (m *MockConnectionTracer) NegotiatedVersion(arg0 protocol.Version, arg1, arg2 []protocol.Version) {
+func (m *MockConnectionTracer) NegotiatedVersion(chosen protocol.Version, clientVersions, serverVersions []protocol.Version) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "NegotiatedVersion", arg0, arg1, arg2)
+	m.ctrl.Call(m, "NegotiatedVersion", chosen, clientVersions, serverVersions)
 }
 
 // NegotiatedVersion indicates an expected call of NegotiatedVersion.
-func (mr *MockConnectionTracerMockRecorder) NegotiatedVersion(arg0, arg1, arg2 any) *MockConnectionTracerNegotiatedVersionCall {
+func (mr *MockConnectionTracerMockRecorder) NegotiatedVersion(chosen, clientVersions, serverVersions any) *MockConnectionTracerNegotiatedVersionCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NegotiatedVersion", reflect.TypeOf((*MockConnectionTracer)(nil).NegotiatedVersion), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NegotiatedVersion", reflect.TypeOf((*MockConnectionTracer)(nil).NegotiatedVersion), chosen, clientVersions, serverVersions)
 	return &MockConnectionTracerNegotiatedVersionCall{Call: call}
 }
 
@@ -693,15 +694,15 @@ func (c *MockConnectionTracerReceivedTransportParametersCall) DoAndReturn(f func
 }
 
 // ReceivedVersionNegotiationPacket mocks base method.
-func (m *MockConnectionTracer) ReceivedVersionNegotiationPacket(arg0, arg1 protocol.ArbitraryLenConnectionID, arg2 []protocol.Version) {
+func (m *MockConnectionTracer) ReceivedVersionNegotiationPacket(dest, src protocol.ArbitraryLenConnectionID, arg2 []protocol.Version) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "ReceivedVersionNegotiationPacket", arg0, arg1, arg2)
+	m.ctrl.Call(m, "ReceivedVersionNegotiationPacket", dest, src, arg2)
 }
 
 // ReceivedVersionNegotiationPacket indicates an expected call of ReceivedVersionNegotiationPacket.
-func (mr *MockConnectionTracerMockRecorder) ReceivedVersionNegotiationPacket(arg0, arg1, arg2 any) *MockConnectionTracerReceivedVersionNegotiationPacketCall {
+func (mr *MockConnectionTracerMockRecorder) ReceivedVersionNegotiationPacket(dest, src, arg2 any) *MockConnectionTracerReceivedVersionNegotiationPacketCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedVersionNegotiationPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedVersionNegotiationPacket), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivedVersionNegotiationPacket", reflect.TypeOf((*MockConnectionTracer)(nil).ReceivedVersionNegotiationPacket), dest, src, arg2)
 	return &MockConnectionTracerReceivedVersionNegotiationPacketCall{Call: call}
 }
 
@@ -729,15 +730,15 @@ func (c *MockConnectionTracerReceivedVersionNegotiationPacketCall) DoAndReturn(f
 }
 
 // RestoredTransportParameters mocks base method.
-func (m *MockConnectionTracer) RestoredTransportParameters(arg0 *wire.TransportParameters) {
+func (m *MockConnectionTracer) RestoredTransportParameters(parameters *wire.TransportParameters) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "RestoredTransportParameters", arg0)
+	m.ctrl.Call(m, "RestoredTransportParameters", parameters)
 }
 
 // RestoredTransportParameters indicates an expected call of RestoredTransportParameters.
-func (mr *MockConnectionTracerMockRecorder) RestoredTransportParameters(arg0 any) *MockConnectionTracerRestoredTransportParametersCall {
+func (mr *MockConnectionTracerMockRecorder) RestoredTransportParameters(parameters any) *MockConnectionTracerRestoredTransportParametersCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestoredTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).RestoredTransportParameters), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestoredTransportParameters", reflect.TypeOf((*MockConnectionTracer)(nil).RestoredTransportParameters), parameters)
 	return &MockConnectionTracerRestoredTransportParametersCall{Call: call}
 }
 
@@ -909,15 +910,15 @@ func (c *MockConnectionTracerSetLossTimerCall) DoAndReturn(f func(logging.TimerT
 }
 
 // StartedConnection mocks base method.
-func (m *MockConnectionTracer) StartedConnection(arg0, arg1 net.Addr, arg2, arg3 protocol.ConnectionID) {
+func (m *MockConnectionTracer) StartedConnection(local, remote net.Addr, srcConnID, destConnID protocol.ConnectionID) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "StartedConnection", arg0, arg1, arg2, arg3)
+	m.ctrl.Call(m, "StartedConnection", local, remote, srcConnID, destConnID)
 }
 
 // StartedConnection indicates an expected call of StartedConnection.
-func (mr *MockConnectionTracerMockRecorder) StartedConnection(arg0, arg1, arg2, arg3 any) *MockConnectionTracerStartedConnectionCall {
+func (mr *MockConnectionTracerMockRecorder) StartedConnection(local, remote, srcConnID, destConnID any) *MockConnectionTracerStartedConnectionCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartedConnection", reflect.TypeOf((*MockConnectionTracer)(nil).StartedConnection), arg0, arg1, arg2, arg3)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartedConnection", reflect.TypeOf((*MockConnectionTracer)(nil).StartedConnection), local, remote, srcConnID, destConnID)
 	return &MockConnectionTracerStartedConnectionCall{Call: call}
 }
 
@@ -981,15 +982,15 @@ func (c *MockConnectionTracerUpdatedCongestionStateCall) DoAndReturn(f func(logg
 }
 
 // UpdatedKey mocks base method.
-func (m *MockConnectionTracer) UpdatedKey(arg0 protocol.KeyPhase, arg1 bool) {
+func (m *MockConnectionTracer) UpdatedKey(generation protocol.KeyPhase, remote bool) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "UpdatedKey", arg0, arg1)
+	m.ctrl.Call(m, "UpdatedKey", generation, remote)
 }
 
 // UpdatedKey indicates an expected call of UpdatedKey.
-func (mr *MockConnectionTracerMockRecorder) UpdatedKey(arg0, arg1 any) *MockConnectionTracerUpdatedKeyCall {
+func (mr *MockConnectionTracerMockRecorder) UpdatedKey(generation, remote any) *MockConnectionTracerUpdatedKeyCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedKey", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedKey), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedKey", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedKey), generation, remote)
 	return &MockConnectionTracerUpdatedKeyCall{Call: call}
 }
 
@@ -1053,15 +1054,15 @@ func (c *MockConnectionTracerUpdatedKeyFromTLSCall) DoAndReturn(f func(protocol.
 }
 
 // UpdatedMTU mocks base method.
-func (m *MockConnectionTracer) UpdatedMTU(arg0 protocol.ByteCount, arg1 bool) {
+func (m *MockConnectionTracer) UpdatedMTU(mtu protocol.ByteCount, done bool) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "UpdatedMTU", arg0, arg1)
+	m.ctrl.Call(m, "UpdatedMTU", mtu, done)
 }
 
 // UpdatedMTU indicates an expected call of UpdatedMTU.
-func (mr *MockConnectionTracerMockRecorder) UpdatedMTU(arg0, arg1 any) *MockConnectionTracerUpdatedMTUCall {
+func (mr *MockConnectionTracerMockRecorder) UpdatedMTU(mtu, done any) *MockConnectionTracerUpdatedMTUCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedMTU", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedMTU), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedMTU", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedMTU), mtu, done)
 	return &MockConnectionTracerUpdatedMTUCall{Call: call}
 }
 
@@ -1089,15 +1090,15 @@ func (c *MockConnectionTracerUpdatedMTUCall) DoAndReturn(f func(protocol.ByteCou
 }
 
 // UpdatedMetrics mocks base method.
-func (m *MockConnectionTracer) UpdatedMetrics(arg0 *utils.RTTStats, arg1, arg2 protocol.ByteCount, arg3 int) {
+func (m *MockConnectionTracer) UpdatedMetrics(rttStats *utils.RTTStats, cwnd, bytesInFlight protocol.ByteCount, packetsInFlight int) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "UpdatedMetrics", arg0, arg1, arg2, arg3)
+	m.ctrl.Call(m, "UpdatedMetrics", rttStats, cwnd, bytesInFlight, packetsInFlight)
 }
 
 // UpdatedMetrics indicates an expected call of UpdatedMetrics.
-func (mr *MockConnectionTracerMockRecorder) UpdatedMetrics(arg0, arg1, arg2, arg3 any) *MockConnectionTracerUpdatedMetricsCall {
+func (mr *MockConnectionTracerMockRecorder) UpdatedMetrics(rttStats, cwnd, bytesInFlight, packetsInFlight any) *MockConnectionTracerUpdatedMetricsCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedMetrics", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedMetrics), arg0, arg1, arg2, arg3)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedMetrics", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedMetrics), rttStats, cwnd, bytesInFlight, packetsInFlight)
 	return &MockConnectionTracerUpdatedMetricsCall{Call: call}
 }
 
@@ -1125,15 +1126,15 @@ func (c *MockConnectionTracerUpdatedMetricsCall) DoAndReturn(f func(*utils.RTTSt
 }
 
 // UpdatedPTOCount mocks base method.
-func (m *MockConnectionTracer) UpdatedPTOCount(arg0 uint32) {
+func (m *MockConnectionTracer) UpdatedPTOCount(value uint32) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "UpdatedPTOCount", arg0)
+	m.ctrl.Call(m, "UpdatedPTOCount", value)
 }
 
 // UpdatedPTOCount indicates an expected call of UpdatedPTOCount.
-func (mr *MockConnectionTracerMockRecorder) UpdatedPTOCount(arg0 any) *MockConnectionTracerUpdatedPTOCountCall {
+func (mr *MockConnectionTracerMockRecorder) UpdatedPTOCount(value any) *MockConnectionTracerUpdatedPTOCountCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedPTOCount", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedPTOCount), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedPTOCount", reflect.TypeOf((*MockConnectionTracer)(nil).UpdatedPTOCount), value)
 	return &MockConnectionTracerUpdatedPTOCountCall{Call: call}
 }
 
diff --git a/internal/mocks/logging/internal/tracer.go b/internal/mocks/logging/internal/tracer.go
index 2565203c..544b64b9 100644
--- a/internal/mocks/logging/internal/tracer.go
+++ b/internal/mocks/logging/internal/tracer.go
@@ -23,6 +23,7 @@ import (
 type MockTracer struct {
 	ctrl     *gomock.Controller
 	recorder *MockTracerMockRecorder
+	isgomock struct{}
 }
 
 // MockTracerMockRecorder is the mock recorder for MockTracer.
@@ -79,15 +80,15 @@ func (c *MockTracerCloseCall) DoAndReturn(f func()) *MockTracerCloseCall {
 }
 
 // Debug mocks base method.
-func (m *MockTracer) Debug(arg0, arg1 string) {
+func (m *MockTracer) Debug(name, msg string) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "Debug", arg0, arg1)
+	m.ctrl.Call(m, "Debug", name, msg)
 }
 
 // Debug indicates an expected call of Debug.
-func (mr *MockTracerMockRecorder) Debug(arg0, arg1 any) *MockTracerDebugCall {
+func (mr *MockTracerMockRecorder) Debug(name, msg any) *MockTracerDebugCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockTracer)(nil).Debug), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockTracer)(nil).Debug), name, msg)
 	return &MockTracerDebugCall{Call: call}
 }
 
@@ -187,15 +188,15 @@ func (c *MockTracerSentPacketCall) DoAndReturn(f func(net.Addr, *wire.Header, pr
 }
 
 // SentVersionNegotiationPacket mocks base method.
-func (m *MockTracer) SentVersionNegotiationPacket(arg0 net.Addr, arg1, arg2 protocol.ArbitraryLenConnectionID, arg3 []protocol.Version) {
+func (m *MockTracer) SentVersionNegotiationPacket(arg0 net.Addr, dest, src protocol.ArbitraryLenConnectionID, arg3 []protocol.Version) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "SentVersionNegotiationPacket", arg0, arg1, arg2, arg3)
+	m.ctrl.Call(m, "SentVersionNegotiationPacket", arg0, dest, src, arg3)
 }
 
 // SentVersionNegotiationPacket indicates an expected call of SentVersionNegotiationPacket.
-func (mr *MockTracerMockRecorder) SentVersionNegotiationPacket(arg0, arg1, arg2, arg3 any) *MockTracerSentVersionNegotiationPacketCall {
+func (mr *MockTracerMockRecorder) SentVersionNegotiationPacket(arg0, dest, src, arg3 any) *MockTracerSentVersionNegotiationPacketCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentVersionNegotiationPacket", reflect.TypeOf((*MockTracer)(nil).SentVersionNegotiationPacket), arg0, arg1, arg2, arg3)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentVersionNegotiationPacket", reflect.TypeOf((*MockTracer)(nil).SentVersionNegotiationPacket), arg0, dest, src, arg3)
 	return &MockTracerSentVersionNegotiationPacketCall{Call: call}
 }
 
diff --git a/internal/mocks/long_header_opener.go b/internal/mocks/long_header_opener.go
index 3473e586..d37d082c 100644
--- a/internal/mocks/long_header_opener.go
+++ b/internal/mocks/long_header_opener.go
@@ -20,6 +20,7 @@ import (
 type MockLongHeaderOpener struct {
 	ctrl     *gomock.Controller
 	recorder *MockLongHeaderOpenerMockRecorder
+	isgomock struct{}
 }
 
 // MockLongHeaderOpenerMockRecorder is the mock recorder for MockLongHeaderOpener.
@@ -40,17 +41,17 @@ func (m *MockLongHeaderOpener) EXPECT() *MockLongHeaderOpenerMockRecorder {
 }
 
 // DecodePacketNumber mocks base method.
-func (m *MockLongHeaderOpener) DecodePacketNumber(arg0 protocol.PacketNumber, arg1 protocol.PacketNumberLen) protocol.PacketNumber {
+func (m *MockLongHeaderOpener) DecodePacketNumber(wirePN protocol.PacketNumber, wirePNLen protocol.PacketNumberLen) protocol.PacketNumber {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DecodePacketNumber", arg0, arg1)
+	ret := m.ctrl.Call(m, "DecodePacketNumber", wirePN, wirePNLen)
 	ret0, _ := ret[0].(protocol.PacketNumber)
 	return ret0
 }
 
 // DecodePacketNumber indicates an expected call of DecodePacketNumber.
-func (mr *MockLongHeaderOpenerMockRecorder) DecodePacketNumber(arg0, arg1 any) *MockLongHeaderOpenerDecodePacketNumberCall {
+func (mr *MockLongHeaderOpenerMockRecorder) DecodePacketNumber(wirePN, wirePNLen any) *MockLongHeaderOpenerDecodePacketNumberCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodePacketNumber", reflect.TypeOf((*MockLongHeaderOpener)(nil).DecodePacketNumber), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodePacketNumber", reflect.TypeOf((*MockLongHeaderOpener)(nil).DecodePacketNumber), wirePN, wirePNLen)
 	return &MockLongHeaderOpenerDecodePacketNumberCall{Call: call}
 }
 
@@ -78,15 +79,15 @@ func (c *MockLongHeaderOpenerDecodePacketNumberCall) DoAndReturn(f func(protocol
 }
 
 // DecryptHeader mocks base method.
-func (m *MockLongHeaderOpener) DecryptHeader(arg0 []byte, arg1 *byte, arg2 []byte) {
+func (m *MockLongHeaderOpener) DecryptHeader(sample []byte, firstByte *byte, pnBytes []byte) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "DecryptHeader", arg0, arg1, arg2)
+	m.ctrl.Call(m, "DecryptHeader", sample, firstByte, pnBytes)
 }
 
 // DecryptHeader indicates an expected call of DecryptHeader.
-func (mr *MockLongHeaderOpenerMockRecorder) DecryptHeader(arg0, arg1, arg2 any) *MockLongHeaderOpenerDecryptHeaderCall {
+func (mr *MockLongHeaderOpenerMockRecorder) DecryptHeader(sample, firstByte, pnBytes any) *MockLongHeaderOpenerDecryptHeaderCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptHeader", reflect.TypeOf((*MockLongHeaderOpener)(nil).DecryptHeader), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptHeader", reflect.TypeOf((*MockLongHeaderOpener)(nil).DecryptHeader), sample, firstByte, pnBytes)
 	return &MockLongHeaderOpenerDecryptHeaderCall{Call: call}
 }
 
@@ -114,18 +115,18 @@ func (c *MockLongHeaderOpenerDecryptHeaderCall) DoAndReturn(f func([]byte, *byte
 }
 
 // Open mocks base method.
-func (m *MockLongHeaderOpener) Open(arg0, arg1 []byte, arg2 protocol.PacketNumber, arg3 []byte) ([]byte, error) {
+func (m *MockLongHeaderOpener) Open(dst, src []byte, pn protocol.PacketNumber, associatedData []byte) ([]byte, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "Open", arg0, arg1, arg2, arg3)
+	ret := m.ctrl.Call(m, "Open", dst, src, pn, associatedData)
 	ret0, _ := ret[0].([]byte)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // Open indicates an expected call of Open.
-func (mr *MockLongHeaderOpenerMockRecorder) Open(arg0, arg1, arg2, arg3 any) *MockLongHeaderOpenerOpenCall {
+func (mr *MockLongHeaderOpenerMockRecorder) Open(dst, src, pn, associatedData any) *MockLongHeaderOpenerOpenCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockLongHeaderOpener)(nil).Open), arg0, arg1, arg2, arg3)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockLongHeaderOpener)(nil).Open), dst, src, pn, associatedData)
 	return &MockLongHeaderOpenerOpenCall{Call: call}
 }
 
diff --git a/internal/mocks/quic/early_conn.go b/internal/mocks/quic/early_conn.go
index a6b17341..683e156c 100644
--- a/internal/mocks/quic/early_conn.go
+++ b/internal/mocks/quic/early_conn.go
@@ -23,6 +23,7 @@ import (
 type MockEarlyConnection struct {
 	ctrl     *gomock.Controller
 	recorder *MockEarlyConnectionMockRecorder
+	isgomock struct{}
 }
 
 // MockEarlyConnectionMockRecorder is the mock recorder for MockEarlyConnection.
@@ -583,17 +584,17 @@ func (c *MockEarlyConnectionRemoteAddrCall) DoAndReturn(f func() net.Addr) *Mock
 }
 
 // SendDatagram mocks base method.
-func (m *MockEarlyConnection) SendDatagram(arg0 []byte) error {
+func (m *MockEarlyConnection) SendDatagram(payload []byte) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SendDatagram", arg0)
+	ret := m.ctrl.Call(m, "SendDatagram", payload)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SendDatagram indicates an expected call of SendDatagram.
-func (mr *MockEarlyConnectionMockRecorder) SendDatagram(arg0 any) *MockEarlyConnectionSendDatagramCall {
+func (mr *MockEarlyConnectionMockRecorder) SendDatagram(payload any) *MockEarlyConnectionSendDatagramCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendDatagram", reflect.TypeOf((*MockEarlyConnection)(nil).SendDatagram), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendDatagram", reflect.TypeOf((*MockEarlyConnection)(nil).SendDatagram), payload)
 	return &MockEarlyConnectionSendDatagramCall{Call: call}
 }
 
diff --git a/internal/mocks/quic/stream.go b/internal/mocks/quic/stream.go
index 16b1f59d..32c79549 100644
--- a/internal/mocks/quic/stream.go
+++ b/internal/mocks/quic/stream.go
@@ -23,6 +23,7 @@ import (
 type MockStream struct {
 	ctrl     *gomock.Controller
 	recorder *MockStreamMockRecorder
+	isgomock struct{}
 }
 
 // MockStreamMockRecorder is the mock recorder for MockStream.
@@ -191,18 +192,18 @@ func (c *MockStreamContextCall) DoAndReturn(f func() context.Context) *MockStrea
 }
 
 // Read mocks base method.
-func (m *MockStream) Read(arg0 []byte) (int, error) {
+func (m *MockStream) Read(p []byte) (int, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "Read", arg0)
+	ret := m.ctrl.Call(m, "Read", p)
 	ret0, _ := ret[0].(int)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // Read indicates an expected call of Read.
-func (mr *MockStreamMockRecorder) Read(arg0 any) *MockStreamReadCall {
+func (mr *MockStreamMockRecorder) Read(p any) *MockStreamReadCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStream)(nil).Read), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStream)(nil).Read), p)
 	return &MockStreamReadCall{Call: call}
 }
 
@@ -212,8 +213,8 @@ type MockStreamReadCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockStreamReadCall) Return(arg0 int, arg1 error) *MockStreamReadCall {
-	c.Call = c.Call.Return(arg0, arg1)
+func (c *MockStreamReadCall) Return(n int, err error) *MockStreamReadCall {
+	c.Call = c.Call.Return(n, err)
 	return c
 }
 
@@ -230,17 +231,17 @@ func (c *MockStreamReadCall) DoAndReturn(f func([]byte) (int, error)) *MockStrea
 }
 
 // SetDeadline mocks base method.
-func (m *MockStream) SetDeadline(arg0 time.Time) error {
+func (m *MockStream) SetDeadline(t time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetDeadline", arg0)
+	ret := m.ctrl.Call(m, "SetDeadline", t)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SetDeadline indicates an expected call of SetDeadline.
-func (mr *MockStreamMockRecorder) SetDeadline(arg0 any) *MockStreamSetDeadlineCall {
+func (mr *MockStreamMockRecorder) SetDeadline(t any) *MockStreamSetDeadlineCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStream)(nil).SetDeadline), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStream)(nil).SetDeadline), t)
 	return &MockStreamSetDeadlineCall{Call: call}
 }
 
@@ -268,17 +269,17 @@ func (c *MockStreamSetDeadlineCall) DoAndReturn(f func(time.Time) error) *MockSt
 }
 
 // SetReadDeadline mocks base method.
-func (m *MockStream) SetReadDeadline(arg0 time.Time) error {
+func (m *MockStream) SetReadDeadline(t time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetReadDeadline", arg0)
+	ret := m.ctrl.Call(m, "SetReadDeadline", t)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SetReadDeadline indicates an expected call of SetReadDeadline.
-func (mr *MockStreamMockRecorder) SetReadDeadline(arg0 any) *MockStreamSetReadDeadlineCall {
+func (mr *MockStreamMockRecorder) SetReadDeadline(t any) *MockStreamSetReadDeadlineCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStream)(nil).SetReadDeadline), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStream)(nil).SetReadDeadline), t)
 	return &MockStreamSetReadDeadlineCall{Call: call}
 }
 
@@ -306,17 +307,17 @@ func (c *MockStreamSetReadDeadlineCall) DoAndReturn(f func(time.Time) error) *Mo
 }
 
 // SetWriteDeadline mocks base method.
-func (m *MockStream) SetWriteDeadline(arg0 time.Time) error {
+func (m *MockStream) SetWriteDeadline(t time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetWriteDeadline", arg0)
+	ret := m.ctrl.Call(m, "SetWriteDeadline", t)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SetWriteDeadline indicates an expected call of SetWriteDeadline.
-func (mr *MockStreamMockRecorder) SetWriteDeadline(arg0 any) *MockStreamSetWriteDeadlineCall {
+func (mr *MockStreamMockRecorder) SetWriteDeadline(t any) *MockStreamSetWriteDeadlineCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStream)(nil).SetWriteDeadline), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStream)(nil).SetWriteDeadline), t)
 	return &MockStreamSetWriteDeadlineCall{Call: call}
 }
 
@@ -382,18 +383,18 @@ func (c *MockStreamStreamIDCall) DoAndReturn(f func() protocol.StreamID) *MockSt
 }
 
 // Write mocks base method.
-func (m *MockStream) Write(arg0 []byte) (int, error) {
+func (m *MockStream) Write(p []byte) (int, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "Write", arg0)
+	ret := m.ctrl.Call(m, "Write", p)
 	ret0, _ := ret[0].(int)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // Write indicates an expected call of Write.
-func (mr *MockStreamMockRecorder) Write(arg0 any) *MockStreamWriteCall {
+func (mr *MockStreamMockRecorder) Write(p any) *MockStreamWriteCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStream)(nil).Write), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStream)(nil).Write), p)
 	return &MockStreamWriteCall{Call: call}
 }
 
@@ -403,8 +404,8 @@ type MockStreamWriteCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockStreamWriteCall) Return(arg0 int, arg1 error) *MockStreamWriteCall {
-	c.Call = c.Call.Return(arg0, arg1)
+func (c *MockStreamWriteCall) Return(n int, err error) *MockStreamWriteCall {
+	c.Call = c.Call.Return(n, err)
 	return c
 }
 
diff --git a/internal/mocks/short_header_opener.go b/internal/mocks/short_header_opener.go
index 3fb68ad1..be4ef3b6 100644
--- a/internal/mocks/short_header_opener.go
+++ b/internal/mocks/short_header_opener.go
@@ -21,6 +21,7 @@ import (
 type MockShortHeaderOpener struct {
 	ctrl     *gomock.Controller
 	recorder *MockShortHeaderOpenerMockRecorder
+	isgomock struct{}
 }
 
 // MockShortHeaderOpenerMockRecorder is the mock recorder for MockShortHeaderOpener.
@@ -41,17 +42,17 @@ func (m *MockShortHeaderOpener) EXPECT() *MockShortHeaderOpenerMockRecorder {
 }
 
 // DecodePacketNumber mocks base method.
-func (m *MockShortHeaderOpener) DecodePacketNumber(arg0 protocol.PacketNumber, arg1 protocol.PacketNumberLen) protocol.PacketNumber {
+func (m *MockShortHeaderOpener) DecodePacketNumber(wirePN protocol.PacketNumber, wirePNLen protocol.PacketNumberLen) protocol.PacketNumber {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DecodePacketNumber", arg0, arg1)
+	ret := m.ctrl.Call(m, "DecodePacketNumber", wirePN, wirePNLen)
 	ret0, _ := ret[0].(protocol.PacketNumber)
 	return ret0
 }
 
 // DecodePacketNumber indicates an expected call of DecodePacketNumber.
-func (mr *MockShortHeaderOpenerMockRecorder) DecodePacketNumber(arg0, arg1 any) *MockShortHeaderOpenerDecodePacketNumberCall {
+func (mr *MockShortHeaderOpenerMockRecorder) DecodePacketNumber(wirePN, wirePNLen any) *MockShortHeaderOpenerDecodePacketNumberCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodePacketNumber", reflect.TypeOf((*MockShortHeaderOpener)(nil).DecodePacketNumber), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodePacketNumber", reflect.TypeOf((*MockShortHeaderOpener)(nil).DecodePacketNumber), wirePN, wirePNLen)
 	return &MockShortHeaderOpenerDecodePacketNumberCall{Call: call}
 }
 
@@ -79,15 +80,15 @@ func (c *MockShortHeaderOpenerDecodePacketNumberCall) DoAndReturn(f func(protoco
 }
 
 // DecryptHeader mocks base method.
-func (m *MockShortHeaderOpener) DecryptHeader(arg0 []byte, arg1 *byte, arg2 []byte) {
+func (m *MockShortHeaderOpener) DecryptHeader(sample []byte, firstByte *byte, pnBytes []byte) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "DecryptHeader", arg0, arg1, arg2)
+	m.ctrl.Call(m, "DecryptHeader", sample, firstByte, pnBytes)
 }
 
 // DecryptHeader indicates an expected call of DecryptHeader.
-func (mr *MockShortHeaderOpenerMockRecorder) DecryptHeader(arg0, arg1, arg2 any) *MockShortHeaderOpenerDecryptHeaderCall {
+func (mr *MockShortHeaderOpenerMockRecorder) DecryptHeader(sample, firstByte, pnBytes any) *MockShortHeaderOpenerDecryptHeaderCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptHeader", reflect.TypeOf((*MockShortHeaderOpener)(nil).DecryptHeader), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptHeader", reflect.TypeOf((*MockShortHeaderOpener)(nil).DecryptHeader), sample, firstByte, pnBytes)
 	return &MockShortHeaderOpenerDecryptHeaderCall{Call: call}
 }
 
@@ -115,18 +116,18 @@ func (c *MockShortHeaderOpenerDecryptHeaderCall) DoAndReturn(f func([]byte, *byt
 }
 
 // Open mocks base method.
-func (m *MockShortHeaderOpener) Open(arg0, arg1 []byte, arg2 time.Time, arg3 protocol.PacketNumber, arg4 protocol.KeyPhaseBit, arg5 []byte) ([]byte, error) {
+func (m *MockShortHeaderOpener) Open(dst, src []byte, rcvTime time.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, associatedData []byte) ([]byte, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "Open", arg0, arg1, arg2, arg3, arg4, arg5)
+	ret := m.ctrl.Call(m, "Open", dst, src, rcvTime, pn, kp, associatedData)
 	ret0, _ := ret[0].([]byte)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // Open indicates an expected call of Open.
-func (mr *MockShortHeaderOpenerMockRecorder) Open(arg0, arg1, arg2, arg3, arg4, arg5 any) *MockShortHeaderOpenerOpenCall {
+func (mr *MockShortHeaderOpenerMockRecorder) Open(dst, src, rcvTime, pn, kp, associatedData any) *MockShortHeaderOpenerOpenCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockShortHeaderOpener)(nil).Open), arg0, arg1, arg2, arg3, arg4, arg5)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockShortHeaderOpener)(nil).Open), dst, src, rcvTime, pn, kp, associatedData)
 	return &MockShortHeaderOpenerOpenCall{Call: call}
 }
 
diff --git a/internal/mocks/short_header_sealer.go b/internal/mocks/short_header_sealer.go
index 54d15abb..9e5e09b6 100644
--- a/internal/mocks/short_header_sealer.go
+++ b/internal/mocks/short_header_sealer.go
@@ -20,6 +20,7 @@ import (
 type MockShortHeaderSealer struct {
 	ctrl     *gomock.Controller
 	recorder *MockShortHeaderSealerMockRecorder
+	isgomock struct{}
 }
 
 // MockShortHeaderSealerMockRecorder is the mock recorder for MockShortHeaderSealer.
@@ -40,15 +41,15 @@ func (m *MockShortHeaderSealer) EXPECT() *MockShortHeaderSealerMockRecorder {
 }
 
 // EncryptHeader mocks base method.
-func (m *MockShortHeaderSealer) EncryptHeader(arg0 []byte, arg1 *byte, arg2 []byte) {
+func (m *MockShortHeaderSealer) EncryptHeader(sample []byte, firstByte *byte, pnBytes []byte) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "EncryptHeader", arg0, arg1, arg2)
+	m.ctrl.Call(m, "EncryptHeader", sample, firstByte, pnBytes)
 }
 
 // EncryptHeader indicates an expected call of EncryptHeader.
-func (mr *MockShortHeaderSealerMockRecorder) EncryptHeader(arg0, arg1, arg2 any) *MockShortHeaderSealerEncryptHeaderCall {
+func (mr *MockShortHeaderSealerMockRecorder) EncryptHeader(sample, firstByte, pnBytes any) *MockShortHeaderSealerEncryptHeaderCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EncryptHeader", reflect.TypeOf((*MockShortHeaderSealer)(nil).EncryptHeader), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EncryptHeader", reflect.TypeOf((*MockShortHeaderSealer)(nil).EncryptHeader), sample, firstByte, pnBytes)
 	return &MockShortHeaderSealerEncryptHeaderCall{Call: call}
 }
 
@@ -152,17 +153,17 @@ func (c *MockShortHeaderSealerOverheadCall) DoAndReturn(f func() int) *MockShort
 }
 
 // Seal mocks base method.
-func (m *MockShortHeaderSealer) Seal(arg0, arg1 []byte, arg2 protocol.PacketNumber, arg3 []byte) []byte {
+func (m *MockShortHeaderSealer) Seal(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) []byte {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "Seal", arg0, arg1, arg2, arg3)
+	ret := m.ctrl.Call(m, "Seal", dst, src, packetNumber, associatedData)
 	ret0, _ := ret[0].([]byte)
 	return ret0
 }
 
 // Seal indicates an expected call of Seal.
-func (mr *MockShortHeaderSealerMockRecorder) Seal(arg0, arg1, arg2, arg3 any) *MockShortHeaderSealerSealCall {
+func (mr *MockShortHeaderSealerMockRecorder) Seal(dst, src, packetNumber, associatedData any) *MockShortHeaderSealerSealCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Seal", reflect.TypeOf((*MockShortHeaderSealer)(nil).Seal), arg0, arg1, arg2, arg3)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Seal", reflect.TypeOf((*MockShortHeaderSealer)(nil).Seal), dst, src, packetNumber, associatedData)
 	return &MockShortHeaderSealerSealCall{Call: call}
 }
 
diff --git a/internal/mocks/stream_flow_controller.go b/internal/mocks/stream_flow_controller.go
index 8ddc5d11..8a116787 100644
--- a/internal/mocks/stream_flow_controller.go
+++ b/internal/mocks/stream_flow_controller.go
@@ -21,6 +21,7 @@ import (
 type MockStreamFlowController struct {
 	ctrl     *gomock.Controller
 	recorder *MockStreamFlowControllerMockRecorder
+	isgomock struct{}
 }
 
 // MockStreamFlowControllerMockRecorder is the mock recorder for MockStreamFlowController.
@@ -97,8 +98,8 @@ type MockStreamFlowControllerAddBytesReadCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockStreamFlowControllerAddBytesReadCall) Return(arg0 bool) *MockStreamFlowControllerAddBytesReadCall {
-	c.Call = c.Call.Return(arg0)
+func (c *MockStreamFlowControllerAddBytesReadCall) Return(shouldQueueWindowUpdate bool) *MockStreamFlowControllerAddBytesReadCall {
+	c.Call = c.Call.Return(shouldQueueWindowUpdate)
 	return c
 }
 
@@ -265,17 +266,17 @@ func (c *MockStreamFlowControllerSendWindowSizeCall) DoAndReturn(f func() protoc
 }
 
 // UpdateHighestReceived mocks base method.
-func (m *MockStreamFlowController) UpdateHighestReceived(arg0 protocol.ByteCount, arg1 bool, arg2 time.Time) error {
+func (m *MockStreamFlowController) UpdateHighestReceived(offset protocol.ByteCount, final bool, now time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "UpdateHighestReceived", arg0, arg1, arg2)
+	ret := m.ctrl.Call(m, "UpdateHighestReceived", offset, final, now)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // UpdateHighestReceived indicates an expected call of UpdateHighestReceived.
-func (mr *MockStreamFlowControllerMockRecorder) UpdateHighestReceived(arg0, arg1, arg2 any) *MockStreamFlowControllerUpdateHighestReceivedCall {
+func (mr *MockStreamFlowControllerMockRecorder) UpdateHighestReceived(offset, final, now any) *MockStreamFlowControllerUpdateHighestReceivedCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateHighestReceived", reflect.TypeOf((*MockStreamFlowController)(nil).UpdateHighestReceived), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateHighestReceived", reflect.TypeOf((*MockStreamFlowController)(nil).UpdateHighestReceived), offset, final, now)
 	return &MockStreamFlowControllerUpdateHighestReceivedCall{Call: call}
 }
 
@@ -323,8 +324,8 @@ type MockStreamFlowControllerUpdateSendWindowCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockStreamFlowControllerUpdateSendWindowCall) Return(arg0 bool) *MockStreamFlowControllerUpdateSendWindowCall {
-	c.Call = c.Call.Return(arg0)
+func (c *MockStreamFlowControllerUpdateSendWindowCall) Return(updated bool) *MockStreamFlowControllerUpdateSendWindowCall {
+	c.Call = c.Call.Return(updated)
 	return c
 }
 


Test patch:
diff --git a/framer_test.go b/framer_test.go
index 8d767e5c..0b8801a7 100644
--- a/framer_test.go
+++ b/framer_test.go
@@ -2,6 +2,7 @@ package quic
 
 import (
 	"bytes"
+	"testing"
 	"time"
 
 	"golang.org/x/exp/rand"
@@ -10,458 +11,342 @@ import (
 	"github.com/quic-go/quic-go/internal/protocol"
 	"github.com/quic-go/quic-go/internal/wire"
 
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
+	"github.com/stretchr/testify/require"
 	"go.uber.org/mock/gomock"
 )
 
-var _ = Describe("Framer", func() {
-	const (
-		id1 = protocol.StreamID(10)
-		id2 = protocol.StreamID(11)
+func TestFramerControlFrames(t *testing.T) {
+	pc := &wire.PathChallengeFrame{Data: [8]byte{1, 2, 3, 4, 6, 7, 8}}
+	msf := &wire.MaxStreamsFrame{MaxStreamNum: 0x1337}
+
+	framer := newFramer()
+	require.False(t, framer.HasData())
+	framer.QueueControlFrame(pc)
+	require.True(t, framer.HasData())
+	framer.QueueControlFrame(msf)
+	frames, length := framer.AppendControlFrames(
+		[]ackhandler.Frame{{Frame: &wire.PingFrame{}}},
+		protocol.MaxByteCount,
+		time.Now(),
+		protocol.Version1,
 	)
-
-	var (
-		framer           *framer
-		stream1, stream2 *MockSendStreamI
-		version          protocol.Version
+	require.Len(t, frames, 3)
+	require.Contains(t, frames, ackhandler.Frame{Frame: &wire.PingFrame{}})
+	require.Contains(t, frames, ackhandler.Frame{Frame: pc})
+	require.Contains(t, frames, ackhandler.Frame{Frame: msf})
+	require.Equal(t, length, pc.Length(protocol.Version1)+msf.Length(protocol.Version1))
+	require.False(t, framer.HasData())
+}
+
+func TestFramerControlFrameSizing(t *testing.T) {
+	const maxSize = protocol.ByteCount(1000)
+	bf := &wire.DataBlockedFrame{MaximumData: 0x1337}
+	bfLen := bf.Length(protocol.Version1)
+
+	framer := newFramer()
+	numFrames := int(maxSize / bfLen) // max number of frames that fit into maxSize
+	for i := 0; i < numFrames+1; i++ {
+		framer.QueueControlFrame(bf)
+	}
+	frames, length := framer.AppendControlFrames(nil, maxSize, time.Now(), protocol.Version1)
+	require.Len(t, frames, numFrames)
+	require.Greater(t, length, maxSize-bfLen)
+	// now make sure that the last frame is also added
+	frames, length = framer.AppendControlFrames(nil, maxSize, time.Now(), protocol.Version1)
+	require.Len(t, frames, 1)
+	require.Equal(t, length, bfLen)
+}
+
+func TestFramerStreamControlFrames(t *testing.T) {
+	const streamID = protocol.StreamID(10)
+	ping := &wire.PingFrame{}
+	mdf1 := &wire.MaxStreamDataFrame{StreamID: streamID, MaximumStreamData: 1337}
+	mdf2 := &wire.MaxStreamDataFrame{StreamID: streamID, MaximumStreamData: 1338}
+
+	framer := newFramer()
+	framer.QueueControlFrame(ping)
+	str := NewMockStreamControlFrameGetter(gomock.NewController(t))
+	framer.AddStreamWithControlFrames(streamID, str)
+	now := time.Now()
+	str.EXPECT().getControlFrame(now).Return(ackhandler.Frame{Frame: mdf1}, true, true)
+	str.EXPECT().getControlFrame(now).Return(ackhandler.Frame{Frame: mdf2}, true, false)
+	frames, l := framer.AppendControlFrames(nil, protocol.MaxByteCount, now, protocol.Version1)
+	require.Len(t, frames, 3)
+	require.Equal(t, mdf1, frames[0].Frame)
+	require.Equal(t, mdf2, frames[1].Frame)
+	require.Equal(t, ping, frames[2].Frame)
+	require.Equal(t, ping.Length(protocol.Version1)+mdf1.Length(protocol.Version1)+mdf2.Length(protocol.Version1), l)
+}
+
+// If there are less than 25 bytes left, no more stream-related control frames are enqueued.
+// This avoids dequeueing a frame from the stream that would be too large to fit into the packet.
+func TestFramerStreamControlFramesSizing(t *testing.T) {
+	mdf1 := &wire.MaxStreamDataFrame{MaximumStreamData: 1337}
+
+	str := NewMockStreamControlFrameGetter(gomock.NewController(t))
+	framer := newFramer()
+	framer.AddStreamWithControlFrames(10, str)
+	str.EXPECT().getControlFrame(gomock.Any()).Return(ackhandler.Frame{Frame: mdf1}, true, true).AnyTimes()
+	frames, l := framer.AppendControlFrames(nil, 100, time.Now(), protocol.Version1)
+	require.Equal(t, protocol.ByteCount(len(frames))*mdf1.Length(protocol.Version1), l)
+	require.Greater(t, l, protocol.ByteCount(100-maxStreamControlFrameSize))
+	require.LessOrEqual(t, l, protocol.ByteCount(100))
+}
+
+func TestFramerDetectsFrameDoS(t *testing.T) {
+	framer := newFramer()
+	for i := 0; i < maxControlFrames-1; i++ {
+		framer.QueueControlFrame(&wire.PingFrame{})
+		framer.QueueControlFrame(&wire.PingFrame{})
+		require.False(t, framer.QueuedTooManyControlFrames())
+		frames, _ := framer.AppendControlFrames([]ackhandler.Frame{}, 1, time.Now(), protocol.Version1)
+		require.Len(t, frames, 1)
+		require.Len(t, framer.controlFrames, i+1)
+	}
+	framer.QueueControlFrame(&wire.PingFrame{})
+	require.False(t, framer.QueuedTooManyControlFrames())
+	require.Len(t, framer.controlFrames, maxControlFrames)
+	framer.QueueControlFrame(&wire.PingFrame{})
+	require.True(t, framer.QueuedTooManyControlFrames())
+	require.Len(t, framer.controlFrames, maxControlFrames)
+}
+
+func TestFramerDetectsFramePathResponseDoS(t *testing.T) {
+	framer := newFramer()
+	var pathResponses []*wire.PathResponseFrame
+	for i := 0; i < 2*maxPathResponses; i++ {
+		var f wire.PathResponseFrame
+		rand.Read(f.Data[:])
+		pathResponses = append(pathResponses, &f)
+		framer.QueueControlFrame(&f)
+	}
+	for i := 0; i < maxPathResponses; i++ {
+		require.True(t, framer.HasData())
+		frames, length := framer.AppendControlFrames(nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+		require.Len(t, frames, 1)
+		require.Equal(t, pathResponses[i], frames[0].Frame)
+		require.Equal(t, pathResponses[i].Length(protocol.Version1), length)
+	}
+	require.False(t, framer.HasData())
+	frames, length := framer.AppendControlFrames(nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+	require.Empty(t, frames)
+	require.Zero(t, length)
+}
+
+func TestFramerPacksSinglePathResponsePerPacket(t *testing.T) {
+	framer := newFramer()
+	f1 := &wire.PathResponseFrame{Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}}
+	f2 := &wire.PathResponseFrame{Data: [8]byte{2, 3, 4, 5, 6, 7, 8, 9}}
+	cf1 := &wire.DataBlockedFrame{MaximumData: 1337}
+	cf2 := &wire.HandshakeDoneFrame{}
+	framer.QueueControlFrame(f1)
+	framer.QueueControlFrame(f2)
+	framer.QueueControlFrame(cf1)
+	framer.QueueControlFrame(cf2)
+	// the first packet should contain a single PATH_RESPONSE frame, but all the other control frames
+	frames, _ := framer.AppendControlFrames(nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+	require.Len(t, frames, 3)
+	require.Equal(t, f1, frames[0].Frame)
+	require.Contains(t, []wire.Frame{frames[1].Frame, frames[2].Frame}, cf1)
+	require.Contains(t, []wire.Frame{frames[1].Frame, frames[2].Frame}, cf2)
+	// the second packet should contain the other PATH_RESPONSE frame
+	require.True(t, framer.HasData())
+	frames, _ = framer.AppendControlFrames(nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+	require.Len(t, frames, 1)
+	require.Equal(t, f2, frames[0].Frame)
+	require.False(t, framer.HasData())
+}
+
+func TestFramerAppendStreamFrames(t *testing.T) {
+	const (
+		str1ID = protocol.StreamID(42)
+		str2ID = protocol.StreamID(43)
 	)
-
-	BeforeEach(func() {
-		stream1 = NewMockSendStreamI(mockCtrl)
-		stream1.EXPECT().StreamID().Return(protocol.StreamID(5)).AnyTimes()
-		stream2 = NewMockSendStreamI(mockCtrl)
-		stream2.EXPECT().StreamID().Return(protocol.StreamID(6)).AnyTimes()
-		framer = newFramer()
+	f1 := &wire.StreamFrame{StreamID: str1ID, Data: []byte("foo"), DataLenPresent: true}
+	f2 := &wire.StreamFrame{StreamID: str2ID, Data: []byte("bar"), DataLenPresent: true}
+	totalLen := f1.Length(protocol.Version1) + f2.Length(protocol.Version1)
+
+	framer := newFramer()
+	require.False(t, framer.HasData())
+	// no frames added yet
+	fs, length := framer.AppendStreamFrames(nil, protocol.MaxByteCount, protocol.Version1)
+	require.Empty(t, fs)
+	require.Zero(t, length)
+
+	// add two streams
+	mockCtrl := gomock.NewController(t)
+	str1 := NewMockSendStreamI(mockCtrl)
+	str1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f1}, true, true)
+	str2 := NewMockSendStreamI(mockCtrl)
+	str2.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f2}, true, false)
+	framer.AddActiveStream(str1ID, str1)
+	framer.AddActiveStream(str1ID, str1) // duplicate calls are ok (they're no-ops)
+	framer.AddActiveStream(str2ID, str2)
+	require.True(t, framer.HasData())
+
+	// Even though the first stream claimed to have more data,
+	// we only dequeue a single STREAM frame per call of AppendStreamFrames.
+	f0 := ackhandler.StreamFrame{Frame: &wire.StreamFrame{StreamID: 9999}}
+	fs, length = framer.AppendStreamFrames([]ackhandler.StreamFrame{f0}, protocol.MaxByteCount, protocol.Version1)
+	require.Len(t, fs, 3)
+	require.Equal(t, f0, fs[0])
+	require.Equal(t, str1ID, fs[1].Frame.StreamID)
+	require.Equal(t, []byte("foo"), fs[1].Frame.Data)
+	// since two STREAM frames are sent, the DataLenPresent flag is set on the first frame
+	require.True(t, fs[1].Frame.DataLenPresent)
+	require.Equal(t, str2ID, fs[2].Frame.StreamID)
+	require.Equal(t, []byte("bar"), fs[2].Frame.Data)
+	// the last frame doesn't have the DataLenPresent flag set
+	require.False(t, fs[2].Frame.DataLenPresent)
+	require.Equal(t, fs[1].Frame.Length(protocol.Version1)+fs[2].Frame.Length(protocol.Version1), length)
+	require.Less(t, length, totalLen) // unsetting DataLenPresent on the last frame reduces the length
+	require.True(t, framer.HasData()) // the stream claimed to have more data...
+
+	// ... but it actually doesn't
+	str1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{}, false, false)
+	fs, length = framer.AppendStreamFrames(nil, protocol.MaxByteCount, protocol.Version1)
+	require.Empty(t, fs)
+	require.Zero(t, length)
+	require.False(t, framer.HasData())
+}
+
+func TestFramerRemoveActiveStream(t *testing.T) {
+	const id = protocol.StreamID(42)
+	framer := newFramer()
+	require.False(t, framer.HasData())
+	framer.AddActiveStream(id, NewMockSendStreamI(gomock.NewController(t)))
+	require.True(t, framer.HasData())
+	framer.RemoveActiveStream(id) // no calls will be issued to the mock stream
+	// we can't assert on framer.HasData here, since it's not removed from the ringbuffer
+	frames, _ := framer.AppendStreamFrames(nil, protocol.MaxByteCount, protocol.Version1)
+	require.Empty(t, frames)
+	require.False(t, framer.HasData())
+}
+
+func TestFramerMinStreamFrameSize(t *testing.T) {
+	const id = protocol.StreamID(42)
+	framer := newFramer()
+	str := NewMockSendStreamI(gomock.NewController(t))
+	framer.AddActiveStream(id, str)
+
+	require.True(t, framer.HasData())
+	// don't pop frames smaller than the minimum STREAM frame size
+	frames, _ := framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize-1, protocol.Version1)
+	require.Empty(t, frames)
+
+	// pop frames of the minimum size
+	str.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).DoAndReturn(func(size protocol.ByteCount, v protocol.Version) (ackhandler.StreamFrame, bool, bool) {
+		f := &wire.StreamFrame{StreamID: id, DataLenPresent: true}
+		f.Data = make([]byte, f.MaxDataLen(protocol.MinStreamFrameSize, v))
+		return ackhandler.StreamFrame{Frame: f}, true, false
 	})
-
-	Context("handling control frames", func() {
-		It("adds control frames", func() {
-			pc := &wire.PathChallengeFrame{Data: [8]byte{1, 2, 3, 4, 6, 7, 8}}
-			msf := &wire.MaxStreamsFrame{MaxStreamNum: 0x1337}
-			framer.QueueControlFrame(pc)
-			framer.QueueControlFrame(msf)
-			frames, length := framer.AppendControlFrames(nil, 1000, time.Now(), protocol.Version1)
-			Expect(frames).To(HaveLen(2))
-			fs := []wire.Frame{frames[0].Frame, frames[1].Frame}
-			Expect(fs).To(ContainElement(pc))
-			Expect(fs).To(ContainElement(msf))
-			Expect(length).To(Equal(pc.Length(version) + msf.Length(version)))
-		})
-
-		It("says if it has data", func() {
-			Expect(framer.HasData()).To(BeFalse())
-			f := &wire.MaxDataFrame{MaximumData: 0x42}
-			framer.QueueControlFrame(f)
-			Expect(framer.HasData()).To(BeTrue())
-			frames, _ := framer.AppendControlFrames(nil, 1000, time.Now(), protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(framer.HasData()).To(BeFalse())
-		})
-
-		It("appends to the slice given", func() {
-			ping := &wire.PingFrame{}
-			pc := &wire.PathChallengeFrame{Data: [8]byte{1, 2, 3, 4, 6, 7, 8}}
-			framer.QueueControlFrame(pc)
-			frames, length := framer.AppendControlFrames([]ackhandler.Frame{{Frame: ping}}, 1000, time.Now(), protocol.Version1)
-			Expect(frames).To(HaveLen(2))
-			Expect(frames[0].Frame).To(Equal(ping))
-			Expect(frames[1].Frame).To(Equal(pc))
-			Expect(length).To(Equal(pc.Length(version)))
-		})
-
-		It("adds stream-related control frames", func() {
-			ping := &wire.PingFrame{}
-			framer.QueueControlFrame(ping)
-			str := NewMockStreamControlFrameGetter(mockCtrl)
-			framer.AddStreamWithControlFrames(10, str)
-			mdf1 := &wire.MaxStreamDataFrame{MaximumStreamData: 1337}
-			mdf2 := &wire.MaxStreamDataFrame{MaximumStreamData: 1338}
-			now := time.Now()
-			str.EXPECT().getControlFrame(now).Return(ackhandler.Frame{Frame: mdf1}, true, true)
-			str.EXPECT().getControlFrame(now).Return(ackhandler.Frame{Frame: mdf2}, true, false)
-			frames, l := framer.AppendControlFrames(nil, protocol.MaxByteCount, now, protocol.Version1)
-			Expect(frames).To(HaveLen(3))
-			Expect(frames[0].Frame).To(Equal(mdf1))
-			Expect(frames[1].Frame).To(Equal(mdf2))
-			Expect(frames[2].Frame).To(Equal(ping))
-			Expect(l).To(Equal(ping.Length(protocol.Version1) + mdf1.Length(protocol.Version1) + mdf2.Length(protocol.Version1)))
-		})
-
-		It("doesn't enqueue more stream-related control frames if there are less than 25 bytes left", func() {
-			str := NewMockStreamControlFrameGetter(mockCtrl)
-			framer.AddStreamWithControlFrames(10, str)
-			mdf1 := &wire.MaxStreamDataFrame{MaximumStreamData: 1337}
-			str.EXPECT().getControlFrame(gomock.Any()).Return(ackhandler.Frame{Frame: mdf1}, true, true).AnyTimes()
-			frames, l := framer.AppendControlFrames(nil, 100, time.Now(), protocol.Version1)
-			Expect(l).To(Equal(protocol.ByteCount(len(frames)) * mdf1.Length(protocol.Version1)))
-			Expect(l).To(And(
-				BeNumerically(">", 100-maxStreamControlFrameSize),
-				BeNumerically("<=", 100),
-			))
-		})
-
-		It("adds the right number of frames", func() {
-			maxSize := protocol.ByteCount(1000)
-			bf := &wire.DataBlockedFrame{MaximumData: 0x1337}
-			bfLen := bf.Length(version)
-			numFrames := int(maxSize / bfLen) // max number of frames that fit into maxSize
-			for i := 0; i < numFrames+1; i++ {
-				framer.QueueControlFrame(bf)
-			}
-			frames, length := framer.AppendControlFrames(nil, maxSize, time.Now(), protocol.Version1)
-			Expect(frames).To(HaveLen(numFrames))
-			Expect(length).To(BeNumerically(">", maxSize-bfLen))
-			frames, length = framer.AppendControlFrames(nil, maxSize, time.Now(), protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(length).To(Equal(bfLen))
-		})
-
-		It("drops *_BLOCKED frames when 0-RTT is rejected", func() {
-			ping := &wire.PingFrame{}
-			ncid := &wire.NewConnectionIDFrame{
-				SequenceNumber: 10,
-				ConnectionID:   protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}),
-			}
-			frames := []wire.Frame{
-				&wire.DataBlockedFrame{MaximumData: 1337},
-				&wire.StreamDataBlockedFrame{StreamID: 42, MaximumStreamData: 1337},
-				&wire.StreamsBlockedFrame{StreamLimit: 13},
-				ping,
-				ncid,
-			}
-			rand.Shuffle(len(frames), func(i, j int) { frames[i], frames[j] = frames[j], frames[i] })
-			for _, f := range frames {
-				framer.QueueControlFrame(f)
-			}
-			framer.Handle0RTTRejection()
-			fs, length := framer.AppendControlFrames(nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
-			Expect(fs).To(HaveLen(2))
-			Expect(length).To(Equal(ping.Length(version) + ncid.Length(version)))
-		})
-
-		It("detects when too many frames are queued", func() {
-			for i := 0; i < maxControlFrames-1; i++ {
-				framer.QueueControlFrame(&wire.PingFrame{})
-				framer.QueueControlFrame(&wire.PingFrame{})
-				Expect(framer.QueuedTooManyControlFrames()).To(BeFalse())
-				frames, _ := framer.AppendControlFrames([]ackhandler.Frame{}, 1, time.Now(), protocol.Version1)
-				Expect(frames).To(HaveLen(1))
-				Expect(framer.controlFrames).To(HaveLen(i + 1))
-			}
-			framer.QueueControlFrame(&wire.PingFrame{})
-			Expect(framer.QueuedTooManyControlFrames()).To(BeFalse())
-			Expect(framer.controlFrames).To(HaveLen(maxControlFrames))
-			framer.QueueControlFrame(&wire.PingFrame{})
-			Expect(framer.QueuedTooManyControlFrames()).To(BeTrue())
-			Expect(framer.controlFrames).To(HaveLen(maxControlFrames))
-		})
-	})
-
-	Context("handling PATH_RESPONSE frames", func() {
-		It("packs a single PATH_RESPONSE per packet", func() {
-			f1 := &wire.PathResponseFrame{Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}}
-			f2 := &wire.PathResponseFrame{Data: [8]byte{2, 3, 4, 5, 6, 7, 8, 9}}
-			cf1 := &wire.DataBlockedFrame{MaximumData: 1337}
-			cf2 := &wire.HandshakeDoneFrame{}
-			framer.QueueControlFrame(f1)
-			framer.QueueControlFrame(f2)
-			framer.QueueControlFrame(cf1)
-			framer.QueueControlFrame(cf2)
-			// the first packet should contain a single PATH_RESPONSE frame, but all the other control frames
-			Expect(framer.HasData()).To(BeTrue())
-			frames, length := framer.AppendControlFrames(nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
-			Expect(frames).To(HaveLen(3))
-			Expect(frames[0].Frame).To(Equal(f1))
-			Expect([]wire.Frame{frames[1].Frame, frames[2].Frame}).To(ContainElement(cf1))
-			Expect([]wire.Frame{frames[1].Frame, frames[2].Frame}).To(ContainElement(cf2))
-			Expect(length).To(Equal(f1.Length(protocol.Version1) + cf1.Length(protocol.Version1) + cf2.Length(protocol.Version1)))
-			// the second packet should contain the other PATH_RESPONSE frame
-			Expect(framer.HasData()).To(BeTrue())
-			frames, length = framer.AppendControlFrames(nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(frames[0].Frame).To(Equal(f2))
-			Expect(length).To(Equal(f2.Length(protocol.Version1)))
-			Expect(framer.HasData()).To(BeFalse())
-		})
-
-		It("limits the number of queued PATH_RESPONSE frames", func() {
-			var pathResponses []*wire.PathResponseFrame
-			for i := 0; i < 2*maxPathResponses; i++ {
-				var f wire.PathResponseFrame
-				rand.Read(f.Data[:])
-				pathResponses = append(pathResponses, &f)
-				framer.QueueControlFrame(&f)
-			}
-			for i := 0; i < maxPathResponses; i++ {
-				Expect(framer.HasData()).To(BeTrue())
-				frames, length := framer.AppendControlFrames(nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
-				Expect(frames).To(HaveLen(1))
-				Expect(frames[0].Frame).To(Equal(pathResponses[i]))
-				Expect(length).To(Equal(pathResponses[i].Length(protocol.Version1)))
-			}
-			Expect(framer.HasData()).To(BeFalse())
-			frames, length := framer.AppendControlFrames(nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
-			Expect(frames).To(BeEmpty())
-			Expect(length).To(BeZero())
-		})
-	})
-
-	Context("popping STREAM frames", func() {
-		It("returns nil when popping an empty framer", func() {
-			Expect(framer.AppendStreamFrames(nil, 1000, protocol.Version1)).To(BeEmpty())
-		})
-
-		It("returns STREAM frames", func() {
+	frames, _ = framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize, protocol.Version1)
+	require.Len(t, frames, 1)
+	// unsetting DataLenPresent on the last frame reduced the size slightly beyond the minimum size
+	require.Equal(t, protocol.MinStreamFrameSize-2, frames[0].Frame.Length(protocol.Version1))
+}
+
+func TestFramerMinStreamFrameSizeMultipleStreamFrames(t *testing.T) {
+	const id = protocol.StreamID(42)
+	framer := newFramer()
+	str := NewMockSendStreamI(gomock.NewController(t))
+	framer.AddActiveStream(id, str)
+
+	// pop a frame such that the remaining size is one byte less than the minimum STREAM frame size
+	f := &wire.StreamFrame{
+		StreamID:       id,
+		Data:           bytes.Repeat([]byte("f"), int(500-protocol.MinStreamFrameSize)),
+		DataLenPresent: true,
+	}
+	str.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f}, true, false)
+	framer.AddActiveStream(id, str)
+	fs, length := framer.AppendStreamFrames(nil, 500, protocol.Version1)
+	require.Len(t, fs, 1)
+	require.Equal(t, f, fs[0].Frame)
+	require.Equal(t, f.Length(protocol.Version1), length)
+}
+
+func TestFramerFillPacketOneStream(t *testing.T) {
+	const id = protocol.StreamID(42)
+	str := NewMockSendStreamI(gomock.NewController(t))
+	framer := newFramer()
+
+	for i := protocol.MinStreamFrameSize; i < 2000; i++ {
+		str.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).DoAndReturn(func(size protocol.ByteCount, v protocol.Version) (ackhandler.StreamFrame, bool, bool) {
 			f := &wire.StreamFrame{
-				StreamID:       id1,
-				Data:           []byte("foobar"),
-				Offset:         42,
+				StreamID:       id,
 				DataLenPresent: true,
 			}
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f}, true, false)
-			framer.AddActiveStream(id1, stream1)
-			fs, length := framer.AppendStreamFrames(nil, 1000, protocol.Version1)
-			Expect(fs).To(HaveLen(1))
-			Expect(fs[0].Frame.DataLenPresent).To(BeFalse())
-			Expect(length).To(Equal(f.Length(version)))
-		})
-
-		It("says if it has data", func() {
-			Expect(framer.HasData()).To(BeFalse())
-			framer.AddActiveStream(id1, stream1)
-			Expect(framer.HasData()).To(BeTrue())
-			f1 := &wire.StreamFrame{StreamID: id1, Data: []byte("foo")}
-			f2 := &wire.StreamFrame{StreamID: id1, Data: []byte("bar")}
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f1}, true, true)
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f2}, true, false)
-			frames, _ := framer.AppendStreamFrames(nil, protocol.MaxByteCount, protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(frames[0].Frame).To(Equal(f1))
-			Expect(framer.HasData()).To(BeTrue())
-			frames, _ = framer.AppendStreamFrames(nil, protocol.MaxByteCount, protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(frames[0].Frame).To(Equal(f2))
-			Expect(framer.HasData()).To(BeFalse())
-			framer.AddStreamWithControlFrames(id1, nil)
-			Expect(framer.HasData()).To(BeTrue())
+			f.Data = make([]byte, f.MaxDataLen(size, v))
+			require.Equal(t, size, f.Length(protocol.Version1))
+			return ackhandler.StreamFrame{Frame: f}, true, false
 		})
-
-		It("appends to a frame slice", func() {
-			f := &wire.StreamFrame{
-				StreamID:       id1,
-				Data:           []byte("foobar"),
-				DataLenPresent: true,
-			}
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f}, true, false)
-			framer.AddActiveStream(id1, stream1)
-			f0 := ackhandler.StreamFrame{Frame: &wire.StreamFrame{StreamID: 9999}}
-			frames := []ackhandler.StreamFrame{f0}
-			fs, length := framer.AppendStreamFrames(frames, 1000, protocol.Version1)
-			Expect(fs).To(HaveLen(2))
-			Expect(fs[0]).To(Equal(f0))
-			Expect(fs[1].Frame.Data).To(Equal([]byte("foobar")))
-			Expect(fs[1].Frame.DataLenPresent).To(BeFalse())
-			Expect(length).To(Equal(f.Length(version)))
-		})
-
-		It("skips a stream that was reported active, but was completed shortly after", func() {
-			f := &wire.StreamFrame{
-				StreamID:       id2,
-				Data:           []byte("foobar"),
-				DataLenPresent: true,
-			}
-			stream2.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f}, true, false)
-			framer.AddActiveStream(id1, stream1)
-			framer.AddActiveStream(id2, stream2)
-			framer.RemoveActiveStream(id1)
-			frames, _ := framer.AppendStreamFrames(nil, 1000, protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(frames[0].Frame).To(Equal(f))
-		})
-
-		It("skips a stream that was reported active, but doesn't have any data", func() {
-			f := &wire.StreamFrame{
-				StreamID:       id2,
-				Data:           []byte("foobar"),
-				DataLenPresent: true,
-			}
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{}, false, false)
-			stream2.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f}, true, false)
-			framer.AddActiveStream(id1, stream1)
-			framer.AddActiveStream(id2, stream2)
-			frames, _ := framer.AppendStreamFrames(nil, 1000, protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(frames[0].Frame).To(Equal(f))
-		})
-
-		It("pops from a stream multiple times, if it has enough data", func() {
-			f1 := &wire.StreamFrame{StreamID: id1, Data: []byte("foobar")}
-			f2 := &wire.StreamFrame{StreamID: id1, Data: []byte("foobaz")}
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f1}, true, true)
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f2}, true, false)
-			framer.AddActiveStream(id1, stream1) // only add it once
-			frames, _ := framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize, protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(frames[0].Frame).To(Equal(f1))
-			frames, _ = framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize, protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(frames[0].Frame).To(Equal(f2))
-			// no further calls to popStreamFrame, after popStreamFrame said there's no more data
-			frames, _ = framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize, protocol.Version1)
-			Expect(frames).To(BeNil())
-		})
-
-		It("re-queues a stream at the end, if it has enough data", func() {
-			f11 := &wire.StreamFrame{StreamID: id1, Data: []byte("foobar")}
-			f12 := &wire.StreamFrame{StreamID: id1, Data: []byte("foobaz")}
-			f2 := &wire.StreamFrame{StreamID: id2, Data: []byte("raboof")}
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f11}, true, true)
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f12}, true, false)
-			stream2.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f2}, true, false)
-			framer.AddActiveStream(id1, stream1) // only add it once
-			framer.AddActiveStream(id2, stream2)
-			// first a frame from stream 1
-			frames, _ := framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize, protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(frames[0].Frame).To(Equal(f11))
-			// then a frame from stream 2
-			frames, _ = framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize, protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(frames[0].Frame).To(Equal(f2))
-			// then another frame from stream 1
-			frames, _ = framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize, protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-			Expect(frames[0].Frame).To(Equal(f12))
-		})
-
-		It("only dequeues data from each stream once per packet", func() {
-			f1 := &wire.StreamFrame{StreamID: id1, Data: []byte("foobar")}
-			f2 := &wire.StreamFrame{StreamID: id2, Data: []byte("raboof")}
-			// both streams have more data, and will be re-queued
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f1}, true, true)
-			stream2.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f2}, true, true)
-			framer.AddActiveStream(id1, stream1)
-			framer.AddActiveStream(id2, stream2)
-			frames, length := framer.AppendStreamFrames(nil, 1000, protocol.Version1)
-			Expect(frames).To(HaveLen(2))
-			Expect(frames[0].Frame).To(Equal(f1))
-			Expect(frames[1].Frame).To(Equal(f2))
-			Expect(length).To(Equal(f1.Length(version) + f2.Length(version)))
-		})
-
-		It("returns multiple normal frames in the order they were reported active", func() {
-			f1 := &wire.StreamFrame{Data: []byte("foobar")}
-			f2 := &wire.StreamFrame{Data: []byte("foobaz")}
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f1}, true, false)
-			stream2.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f2}, true, false)
-			framer.AddActiveStream(id2, stream2)
-			framer.AddActiveStream(id1, stream1)
-			frames, _ := framer.AppendStreamFrames(nil, 1000, protocol.Version1)
-			Expect(frames).To(HaveLen(2))
-			Expect(frames[0].Frame).To(Equal(f2))
-			Expect(frames[1].Frame).To(Equal(f1))
-		})
-
-		It("only asks a stream for data once, even if it was reported active multiple times", func() {
-			f := &wire.StreamFrame{Data: []byte("foobar")}
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f}, true, false) // only one call to this function
-			framer.AddActiveStream(id1, stream1)
-			framer.AddActiveStream(id1, stream1)
-			frames, _ := framer.AppendStreamFrames(nil, 1000, protocol.Version1)
-			Expect(frames).To(HaveLen(1))
-		})
-
-		It("does not pop empty frames", func() {
-			fs, length := framer.AppendStreamFrames(nil, 500, protocol.Version1)
-			Expect(fs).To(BeEmpty())
-			Expect(length).To(BeZero())
-		})
-
-		It("pops maximum size STREAM frames", func() {
-			for i := protocol.MinStreamFrameSize; i < 2000; i++ {
-				stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).DoAndReturn(func(size protocol.ByteCount, v protocol.Version) (ackhandler.StreamFrame, bool, bool) {
-					f := &wire.StreamFrame{
-						StreamID:       id1,
-						DataLenPresent: true,
-					}
-					f.Data = make([]byte, f.MaxDataLen(size, v))
-					Expect(f.Length(version)).To(Equal(size))
-					return ackhandler.StreamFrame{Frame: f}, true, false
-				})
-				framer.AddActiveStream(id1, stream1)
-				frames, _ := framer.AppendStreamFrames(nil, i, protocol.Version1)
-				Expect(frames).To(HaveLen(1))
-				f := frames[0].Frame
-				Expect(f.DataLenPresent).To(BeFalse())
-				Expect(f.Length(version)).To(Equal(i))
-			}
-		})
-
-		It("pops multiple STREAM frames", func() {
-			for i := 2 * protocol.MinStreamFrameSize; i < 2000; i++ {
-				stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).DoAndReturn(func(size protocol.ByteCount, v protocol.Version) (ackhandler.StreamFrame, bool, bool) {
-					f := &wire.StreamFrame{
-						StreamID:       id2,
-						DataLenPresent: true,
-					}
-					f.Data = make([]byte, f.MaxDataLen(protocol.MinStreamFrameSize, v))
-					return ackhandler.StreamFrame{Frame: f}, true, false
-				})
-				stream2.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).DoAndReturn(func(size protocol.ByteCount, v protocol.Version) (ackhandler.StreamFrame, bool, bool) {
-					f := &wire.StreamFrame{
-						StreamID:       id2,
-						DataLenPresent: true,
-					}
-					f.Data = make([]byte, f.MaxDataLen(size, v))
-					Expect(f.Length(version)).To(Equal(size))
-					return ackhandler.StreamFrame{Frame: f}, true, false
-				})
-				framer.AddActiveStream(id1, stream1)
-				framer.AddActiveStream(id2, stream2)
-				frames, _ := framer.AppendStreamFrames(nil, i, protocol.Version1)
-				Expect(frames).To(HaveLen(2))
-				f1 := frames[0].Frame
-				f2 := frames[1].Frame
-				Expect(f1.DataLenPresent).To(BeTrue())
-				Expect(f2.DataLenPresent).To(BeFalse())
-				Expect(f1.Length(version) + f2.Length(version)).To(Equal(i))
-			}
-		})
-
-		It("pops frames that when asked for the the minimum STREAM frame size", func() {
-			f := &wire.StreamFrame{Data: []byte("foobar")}
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f}, true, false)
-			framer.AddActiveStream(id1, stream1)
-			framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize, protocol.Version1)
-		})
-
-		It("does not pop frames smaller than the minimum size", func() {
-			// don't expect a call to PopStreamFrame()
-			framer.AppendStreamFrames(nil, protocol.MinStreamFrameSize-1, protocol.Version1)
-		})
-
-		It("stops iterating when the remaining size is smaller than the minimum STREAM frame size", func() {
-			// pop a frame such that the remaining size is one byte less than the minimum STREAM frame size
-			f := &wire.StreamFrame{
-				StreamID:       id1,
-				Data:           bytes.Repeat([]byte("f"), int(500-protocol.MinStreamFrameSize)),
-				DataLenPresent: true,
-			}
-			stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f}, true, false)
-			framer.AddActiveStream(id1, stream1)
-			fs, length := framer.AppendStreamFrames(nil, 500, protocol.Version1)
-			Expect(fs).To(HaveLen(1))
-			Expect(fs[0].Frame).To(Equal(f))
-			Expect(length).To(Equal(f.Length(version)))
+		framer.AddActiveStream(id, str)
+		frames, _ := framer.AppendStreamFrames(nil, i, protocol.Version1)
+		require.Len(t, frames, 1)
+		require.False(t, frames[0].Frame.DataLenPresent)
+		// make sure the entire space was filled up
+		require.Equal(t, i, frames[0].Frame.Length(protocol.Version1))
+	}
+}
+
+func TestFramerFillPacketMultipleStreams(t *testing.T) {
+	const (
+		id1 = protocol.StreamID(1000)
+		id2 = protocol.StreamID(11)
+	)
+	mockCtrl := gomock.NewController(t)
+	stream1 := NewMockSendStreamI(mockCtrl)
+	stream2 := NewMockSendStreamI(mockCtrl)
+	framer := newFramer()
+
+	for i := 2 * protocol.MinStreamFrameSize; i < 2000; i++ {
+		stream1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).DoAndReturn(func(size protocol.ByteCount, v protocol.Version) (ackhandler.StreamFrame, bool, bool) {
+			f := &wire.StreamFrame{StreamID: id1, DataLenPresent: true}
+			f.Data = make([]byte, f.MaxDataLen(protocol.MinStreamFrameSize, v))
+			return ackhandler.StreamFrame{Frame: f}, true, false
 		})
-
-		It("drops all STREAM frames when 0-RTT is rejected", func() {
-			framer.AddActiveStream(id1, stream1)
-			framer.Handle0RTTRejection()
-			fs, length := framer.AppendStreamFrames(nil, protocol.MaxByteCount, protocol.Version1)
-			Expect(fs).To(BeEmpty())
-			Expect(length).To(BeZero())
+		stream2.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).DoAndReturn(func(size protocol.ByteCount, v protocol.Version) (ackhandler.StreamFrame, bool, bool) {
+			f := &wire.StreamFrame{StreamID: id2, DataLenPresent: true}
+			f.Data = make([]byte, f.MaxDataLen(size, v))
+			require.Equal(t, size, f.Length(protocol.Version1))
+			return ackhandler.StreamFrame{Frame: f}, true, false
 		})
-	})
-})
+		framer.AddActiveStream(id1, stream1)
+		framer.AddActiveStream(id2, stream2)
+		frames, _ := framer.AppendStreamFrames(nil, i, protocol.Version1)
+		require.Len(t, frames, 2)
+		require.True(t, frames[0].Frame.DataLenPresent)
+		require.False(t, frames[1].Frame.DataLenPresent)
+		require.Equal(t, i, frames[0].Frame.Length(protocol.Version1)+frames[1].Frame.Length(protocol.Version1))
+	}
+}
+
+func TestFramer0RTTRejection(t *testing.T) {
+	ncid := &wire.NewConnectionIDFrame{
+		SequenceNumber: 10,
+		ConnectionID:   protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}),
+	}
+	ping := &wire.PingFrame{}
+	pc := &wire.PathChallengeFrame{Data: [8]byte{1, 2, 3, 4, 6, 7, 8}}
+
+	framer := newFramer()
+	framer.QueueControlFrame(ncid)
+	framer.QueueControlFrame(&wire.DataBlockedFrame{MaximumData: 1337})
+	framer.QueueControlFrame(&wire.StreamDataBlockedFrame{StreamID: 42, MaximumStreamData: 1337})
+	framer.QueueControlFrame(ping)
+	framer.QueueControlFrame(&wire.StreamsBlockedFrame{StreamLimit: 13})
+	framer.QueueControlFrame(pc)
+
+	framer.AddActiveStream(10, NewMockSendStreamI(gomock.NewController(t)))
+
+	framer.Handle0RTTRejection()
+	streamFrames, _ := framer.AppendStreamFrames(nil, protocol.MaxByteCount, protocol.Version1)
+	require.Empty(t, streamFrames)
+
+	controlFrames, _ := framer.AppendControlFrames(nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+	require.Len(t, controlFrames, 3)
+	require.Contains(t, controlFrames, ackhandler.Frame{Frame: pc})
+	require.Contains(t, controlFrames, ackhandler.Frame{Frame: ping})
+	require.Contains(t, controlFrames, ackhandler.Frame{Frame: ncid})
+}
diff --git a/http3/mock_quic_early_listener_test.go b/http3/mock_quic_early_listener_test.go
index bcbfa289..56e91817 100644
--- a/http3/mock_quic_early_listener_test.go
+++ b/http3/mock_quic_early_listener_test.go
@@ -22,6 +22,7 @@ import (
 type MockQUICEarlyListener struct {
 	ctrl     *gomock.Controller
 	recorder *MockQUICEarlyListenerMockRecorder
+	isgomock struct{}
 }
 
 // MockQUICEarlyListenerMockRecorder is the mock recorder for MockQUICEarlyListener.
diff --git a/http3/mock_singleroundtripper_test.go b/http3/mock_singleroundtripper_test.go
index 59dc3f53..646088b8 100644
--- a/http3/mock_singleroundtripper_test.go
+++ b/http3/mock_singleroundtripper_test.go
@@ -21,6 +21,7 @@ import (
 type MockSingleRoundTripper struct {
 	ctrl     *gomock.Controller
 	recorder *MockSingleRoundTripperMockRecorder
+	isgomock struct{}
 }
 
 // MockSingleRoundTripperMockRecorder is the mock recorder for MockSingleRoundTripper.
diff --git a/integrationtests/gomodvendor/go.mod b/integrationtests/gomodvendor/go.mod
index f3ddd4e2..a2cb938b 100644
--- a/integrationtests/gomodvendor/go.mod
+++ b/integrationtests/gomodvendor/go.mod
@@ -12,11 +12,12 @@ require (
 	github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
 	github.com/onsi/ginkgo/v2 v2.9.5 // indirect
 	github.com/quic-go/qpack v0.5.1 // indirect
-	go.uber.org/mock v0.4.0 // indirect
+	go.uber.org/mock v0.5.0 // indirect
 	golang.org/x/crypto v0.26.0 // indirect
 	golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
 	golang.org/x/mod v0.18.0 // indirect
 	golang.org/x/net v0.28.0 // indirect
+	golang.org/x/sync v0.8.0 // indirect
 	golang.org/x/sys v0.23.0 // indirect
 	golang.org/x/text v0.17.0 // indirect
 	golang.org/x/tools v0.22.0 // indirect
diff --git a/integrationtests/gomodvendor/go.sum b/integrationtests/gomodvendor/go.sum
index bf1014b0..836f14b2 100644
--- a/integrationtests/gomodvendor/go.sum
+++ b/integrationtests/gomodvendor/go.sum
@@ -27,8 +27,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
-go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
+go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
+go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
 golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
 golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
 golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
diff --git a/integrationtests/self/multiplex_test.go b/integrationtests/self/multiplex_test.go
index 91048400..2320706e 100644
--- a/integrationtests/self/multiplex_test.go
+++ b/integrationtests/self/multiplex_test.go
@@ -8,7 +8,6 @@ import (
 	"io"
 	"net"
 	"runtime"
-	"sync/atomic"
 	"testing"
 	"time"
 
@@ -187,24 +186,25 @@ func TestMultiplexingServerAndClientOnSameConn(t *testing.T) {
 }
 
 func TestMultiplexingNonQUICPackets(t *testing.T) {
+	const numPackets = 100
+
 	tr1 := &quic.Transport{Conn: newUPDConnLocalhost(t)}
 	defer tr1.Close()
 	addTracer(tr1)
+	server, err := tr1.Listen(getTLSConfig(), getQuicConfig(nil))
+	require.NoError(t, err)
+	defer server.Close()
 
 	tr2 := &quic.Transport{Conn: newUPDConnLocalhost(t)}
 	defer tr2.Close()
 	addTracer(tr2)
 
-	server, err := tr1.Listen(getTLSConfig(), getQuicConfig(nil))
-	require.NoError(t, err)
-	defer server.Close()
-
 	type nonQUICPacket struct {
 		b    []byte
 		addr net.Addr
 		err  error
 	}
-	rcvdPackets := make(chan nonQUICPacket, 1024)
+	rcvdPackets := make(chan nonQUICPacket, numPackets)
 	receiveCtx, receiveCancel := context.WithCancel(context.Background())
 	defer receiveCancel()
 	// start receiving non-QUIC packets
@@ -219,42 +219,6 @@ func TestMultiplexingNonQUICPackets(t *testing.T) {
 		}
 	}()
 
-	// send a non-QUIC packet every 100µs
-	const packetLen = 128
-	var sentPackets atomic.Int64
-	errChan := make(chan error, 1)
-	done := make(chan struct{})
-	stopSending := make(chan struct{})
-	go func() {
-		defer close(done)
-		ticker := time.NewTicker(time.Millisecond / 10)
-		defer ticker.Stop()
-
-		var wroteFirstPacket bool
-		for {
-			select {
-			case <-ticker.C:
-				b := make([]byte, packetLen)
-				rand.Read(b[1:]) // keep the first byte set to 0, so it's not classified as a QUIC packet
-				_, err := tr1.WriteTo(b, tr2.Conn.LocalAddr())
-				// The first sendmsg call on a new UDP socket sometimes errors on Linux.
-				// It's not clear why this happens.
-				// See https://github.com/golang/go/issues/63322.
-				if err != nil && !wroteFirstPacket && runtime.GOOS == "linux" && isPermissionError(err) {
-					_, err = tr1.WriteTo(b, tr2.Conn.LocalAddr())
-				}
-				if err != nil {
-					errChan <- err
-					return
-				}
-				sentPackets.Add(1)
-				wroteFirstPacket = true
-			case <-stopSending:
-				return
-			}
-		}
-	}()
-
 	ctx2, cancel2 := context.WithTimeout(context.Background(), time.Second)
 	defer cancel2()
 	conn, err := tr2.Dial(ctx2, server.Addr(), getTLSClientConfig(), getQuicConfig(nil))
@@ -265,33 +229,101 @@ func TestMultiplexingNonQUICPackets(t *testing.T) {
 	require.NoError(t, err)
 	serverStr, err := serverConn.OpenUniStream()
 	require.NoError(t, err)
+
+	// send a non-QUIC packet every 100µs
+	const packetLen = 128
+	errChanNonQUIC := make(chan error, 1)
+	sendNonQUICPacket := make(chan struct{}, 1)
 	go func() {
+		defer close(errChanNonQUIC)
+		var sentPackets int
+		for range sendNonQUICPacket {
+			b := make([]byte, packetLen)
+			rand.Read(b[1:]) // keep the first byte set to 0, so it's not classified as a QUIC packet
+			_, err := tr1.WriteTo(b, tr2.Conn.LocalAddr())
+			// The first sendmsg call on a new UDP socket sometimes errors on Linux.
+			// It's not clear why this happens.
+			// See https://github.com/golang/go/issues/63322.
+			if err != nil && sentPackets == 0 && runtime.GOOS == "linux" && isPermissionError(err) {
+				_, err = tr1.WriteTo(b, tr2.Conn.LocalAddr())
+			}
+			if err != nil {
+				errChanNonQUIC <- err
+				return
+			}
+			sentPackets++
+		}
+	}()
+
+	sendQUICPacket := make(chan struct{}, 1)
+	errChanQUIC := make(chan error, 1)
+	var dataSent []byte
+	go func() {
+		defer close(errChanQUIC)
 		defer serverStr.Close()
-		_, _ = serverStr.Write(PRData)
+		for range sendQUICPacket {
+			b := make([]byte, 1024)
+			rand.Read(b)
+			if _, err := serverStr.Write(b); err != nil {
+				errChanQUIC <- err
+				return
+			}
+			dataSent = append(dataSent, b...)
+		}
 	}()
 
-	str, err := conn.AcceptUniStream(ctx2)
-	require.NoError(t, err)
-	data, err := io.ReadAll(str)
-	require.NoError(t, err)
-	require.Equal(t, PRData, data)
+	dataChan := make(chan []byte, 1)
+	readErr := make(chan error, 1)
+	go func() {
+		str, err := conn.AcceptUniStream(ctx2)
+		if err != nil {
+			readErr <- err
+			return
+		}
+		data, err := io.ReadAll(str)
+		if err != nil {
+			readErr <- err
+			return
+		}
+		dataChan <- data
+	}()
 
-	// stop sending non-QUIC packets
-	close(stopSending)
+	ticker := time.NewTicker(scaleDuration(200 * time.Microsecond))
+	defer ticker.Stop()
+	for range numPackets {
+		sendNonQUICPacket <- struct{}{}
+		sendQUICPacket <- struct{}{}
+		<-ticker.C
+	}
+	close(sendNonQUICPacket)
+	close(sendQUICPacket)
 
 	select {
-	case err := <-errChan:
-		t.Fatalf("error sending non-QUIC packets: %v", err)
-	case <-done:
+	case err := <-errChanNonQUIC:
+		require.NoError(t, err, "error sending non-QUIC packets")
+	case <-time.After(time.Second):
+		t.Fatalf("timeout waiting for non-QUIC packets to be sent")
+	}
+	select {
+	case err := <-errChanQUIC:
+		require.NoError(t, err, "error sending QUIC packets")
+	case <-time.After(time.Second):
+		t.Fatalf("timeout waiting for QUIC packets to be sent")
+	}
+	select {
+	case err := <-readErr:
+		require.NoError(t, err, "error reading stream data")
+	case dataRcvd := <-dataChan:
+		require.Equal(t, dataSent, dataRcvd, "stream data mismatch")
+	case <-time.After(time.Second):
+		t.Fatalf("timeout waiting for stream data to be read")
 	}
 
-	sent := int(sentPackets.Load())
-	require.Greater(t, sent, 10, "not enough non-QUIC packets sent: %d", sent)
 	// make sure we don't overflow the capacity of the channel
-	require.LessOrEqual(t, sent, cap(rcvdPackets), "too many non-QUIC packets sent: %d > %d", sent, cap(rcvdPackets))
+	require.LessOrEqual(t, numPackets, cap(rcvdPackets), "too many non-QUIC packets sent: %d > %d", numPackets, cap(rcvdPackets))
 
 	// now receive these packets
-	minExpected := sent * 4 / 5
+	minExpected := numPackets * 4 / 5
 	timeout := time.After(time.Second)
 	var counter int
 	for {
diff --git a/integrationtests/self/zero_rtt_test.go b/integrationtests/self/zero_rtt_test.go
index c9316aef..ed86537b 100644
--- a/integrationtests/self/zero_rtt_test.go
+++ b/integrationtests/self/zero_rtt_test.go
@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"io"
 	"net"
+	"os"
 	"sync"
 	"sync/atomic"
 	"testing"
@@ -522,17 +523,24 @@ func Test0RTTWithIncreasedStreamLimit(t *testing.T) {
 	require.NotZero(t, counter.Load())
 }
 
-func check0RTTRejected(t *testing.T, ln *quic.EarlyListener, addr net.Addr, conf *tls.Config) quic.Connection {
+func check0RTTRejected(t *testing.T,
+	ln *quic.EarlyListener,
+	addr net.Addr,
+	conf *tls.Config,
+	sendData bool,
+) (clientConn, serverConn quic.Connection) {
 	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
 	defer cancel()
 	conn, err := quic.DialEarly(ctx, newUPDConnLocalhost(t), addr, conf, getQuicConfig(nil))
 	require.NoError(t, err)
 	require.False(t, conn.ConnectionState().TLS.HandshakeComplete)
-	str, err := conn.OpenUniStream()
-	require.NoError(t, err)
-	_, err = str.Write(make([]byte, 3000))
-	require.NoError(t, err)
-	require.NoError(t, str.Close())
+	if sendData {
+		str, err := conn.OpenUniStream()
+		require.NoError(t, err)
+		_, err = str.Write(make([]byte, 3000))
+		require.NoError(t, err)
+		require.NoError(t, str.Close())
+	}
 
 	select {
 	case <-conn.HandshakeComplete():
@@ -544,12 +552,13 @@ func check0RTTRejected(t *testing.T, ln *quic.EarlyListener, addr net.Addr, conf
 	// make sure the server doesn't process the data
 	ctx, cancel = context.WithTimeout(context.Background(), scaleDuration(50*time.Millisecond))
 	defer cancel()
-	serverConn, err := ln.Accept(ctx)
+	serverConn, err = ln.Accept(ctx)
 	require.NoError(t, err)
 	require.False(t, serverConn.ConnectionState().Used0RTT)
-	_, err = serverConn.AcceptUniStream(ctx)
-	require.Equal(t, context.DeadlineExceeded, err)
-	require.NoError(t, serverConn.CloseWithError(0, ""))
+	if sendData {
+		_, err = serverConn.AcceptUniStream(ctx)
+		require.Equal(t, context.DeadlineExceeded, err)
+	}
 
 	ctx, cancel = context.WithTimeout(context.Background(), time.Second)
 	defer cancel()
@@ -557,15 +566,7 @@ func check0RTTRejected(t *testing.T, ln *quic.EarlyListener, addr net.Addr, conf
 	require.NoError(t, err)
 	require.True(t, nextConn.ConnectionState().TLS.HandshakeComplete)
 	require.False(t, nextConn.ConnectionState().Used0RTT)
-	t.Cleanup(func() {
-		nextConn.CloseWithError(0, "")
-		select {
-		case <-serverConn.Context().Done():
-		case <-time.After(time.Second):
-			t.Fatal("server connection did not close in time")
-		}
-	})
-	return nextConn
+	return nextConn, serverConn
 }
 
 func Test0RTTRejectedOnStreamLimitDecrease(t *testing.T) {
@@ -605,13 +606,8 @@ func Test0RTTRejectedOnStreamLimitDecrease(t *testing.T) {
 	defer ln.Close()
 	proxy, num0RTT := runCountingProxyAndCount0RTTPackets(t, ln.Addr().(*net.UDPAddr).Port, rtt)
 
-	conn := check0RTTRejected(t, ln, proxy.LocalAddr(), clientConf)
-
-	// The client should send 0-RTT packets, but the server doesn't process them.
-	n := num0RTT.Load()
-	t.Logf("sent %d 0-RTT packets", n)
-	require.NotZero(t, n)
-	require.Empty(t, counter.getRcvd0RTTPacketNumbers())
+	conn, serverConn := check0RTTRejected(t, ln, proxy.LocalAddr(), clientConf, true)
+	defer conn.CloseWithError(0, "")
 
 	// It should now be possible to open new bidirectional streams up to the new limit...
 	for i := 0; i < newMaxBidiStreams; i++ {
@@ -632,6 +628,68 @@ func Test0RTTRejectedOnStreamLimitDecrease(t *testing.T) {
 	_, err = conn.OpenUniStream()
 	require.Error(t, err)
 	require.Contains(t, err.Error(), "too many open streams")
+
+	serverConn.CloseWithError(0, "")
+	// The client should send 0-RTT packets, but the server doesn't process them.
+	n := num0RTT.Load()
+	t.Logf("sent %d 0-RTT packets", n)
+	require.NotZero(t, n)
+	require.Empty(t, counter.getRcvd0RTTPacketNumbers())
+}
+
+func Test0RTTRejectedOnConnectionWindowDecrease(t *testing.T) {
+	const rtt = 5 * time.Millisecond
+
+	const (
+		connFlowControlWindow    = 100
+		newConnFlowControlWindow = connFlowControlWindow - 1
+	)
+
+	tlsConf := getTLSConfig()
+	clientConf := dialAndReceiveTicket(t,
+		rtt,
+		tlsConf,
+		getQuicConfig(&quic.Config{
+			Allow0RTT:                      true,
+			InitialConnectionReceiveWindow: connFlowControlWindow,
+		}),
+		nil,
+	)
+
+	ln, err := quic.ListenEarly(
+		newUPDConnLocalhost(t),
+		tlsConf,
+		getQuicConfig(&quic.Config{
+			Allow0RTT:                      true,
+			InitialConnectionReceiveWindow: newConnFlowControlWindow,
+		}),
+	)
+	require.NoError(t, err)
+	defer ln.Close()
+	proxy, _ := runCountingProxyAndCount0RTTPackets(t, ln.Addr().(*net.UDPAddr).Port, rtt)
+
+	conn, serverConn := check0RTTRejected(t, ln, proxy.LocalAddr(), clientConf, false)
+	defer conn.CloseWithError(0, "")
+	defer serverConn.CloseWithError(0, "")
+
+	str, err := conn.OpenStream()
+	require.NoError(t, err)
+	str.SetWriteDeadline(time.Now().Add(scaleDuration(50 * time.Millisecond)))
+	n, err := str.Write(make([]byte, 2000))
+	require.ErrorIs(t, err, os.ErrDeadlineExceeded)
+	require.Equal(t, newConnFlowControlWindow, n)
+
+	// make sure that only 99 bytes were received
+	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+	defer cancel()
+	serverStr, err := serverConn.AcceptStream(ctx)
+	require.NoError(t, err)
+	serverStr.SetReadDeadline(time.Now().Add(scaleDuration(50 * time.Millisecond)))
+	n, err = io.ReadFull(serverStr, make([]byte, newConnFlowControlWindow))
+	require.NoError(t, err)
+	require.Equal(t, newConnFlowControlWindow, n)
+	_, err = serverStr.Read([]byte{0})
+	require.ErrorIs(t, err, os.ErrDeadlineExceeded)
 }
 
 func Test0RTTRejectedOnALPNChanged(t *testing.T) {
@@ -657,9 +715,13 @@ func Test0RTTRejectedOnALPNChanged(t *testing.T) {
 	defer ln.Close()
 	proxy, num0RTTPackets := runCountingProxyAndCount0RTTPackets(t, ln.Addr().(*net.UDPAddr).Port, rtt)
 
-	conn := check0RTTRejected(t, ln, proxy.LocalAddr(), clientConf)
+	conn, serverConn := check0RTTRejected(t, ln, proxy.LocalAddr(), clientConf, true)
+	defer conn.CloseWithError(0, "")
+	defer serverConn.CloseWithError(0, "")
+
 	require.Equal(t, "new-alpn", conn.ConnectionState().TLS.NegotiatedProtocol)
 
+	serverConn.CloseWithError(0, "")
 	// The client should send 0-RTT packets, but the server doesn't process them.
 	num0RTT := num0RTTPackets.Load()
 	t.Logf("Sent %d 0-RTT packets.", num0RTT)
@@ -685,8 +747,10 @@ func Test0RTTRejectedWhenDisabled(t *testing.T) {
 	defer ln.Close()
 	proxy, num0RTTPackets := runCountingProxyAndCount0RTTPackets(t, ln.Addr().(*net.UDPAddr).Port, rtt)
 
-	check0RTTRejected(t, ln, proxy.LocalAddr(), clientConf)
+	conn, serverConn := check0RTTRejected(t, ln, proxy.LocalAddr(), clientConf, true)
+	defer conn.CloseWithError(0, "")
 
+	serverConn.CloseWithError(0, "")
 	// The client should send 0-RTT packets, but the server doesn't process them.
 	num0RTT := num0RTTPackets.Load()
 	t.Logf("Sent %d 0-RTT packets.", num0RTT)
@@ -713,9 +777,11 @@ func Test0RTTRejectedOnDatagramsDisabled(t *testing.T) {
 	defer ln.Close()
 	proxy, num0RTTPackets := runCountingProxyAndCount0RTTPackets(t, ln.Addr().(*net.UDPAddr).Port, rtt)
 
-	conn := check0RTTRejected(t, ln, proxy.LocalAddr(), clientConf)
+	conn, serverConn := check0RTTRejected(t, ln, proxy.LocalAddr(), clientConf, true)
+	defer conn.CloseWithError(0, "")
 	require.False(t, conn.ConnectionState().SupportsDatagrams)
 
+	serverConn.CloseWithError(0, "")
 	// The client should send 0-RTT packets, but the server doesn't process them.
 	num0RTT := num0RTTPackets.Load()
 	t.Logf("Sent %d 0-RTT packets.", num0RTT)
diff --git a/internal/ackhandler/mock_ecn_handler_test.go b/internal/ackhandler/mock_ecn_handler_test.go
index 42cd0ff1..850776fd 100644
--- a/internal/ackhandler/mock_ecn_handler_test.go
+++ b/internal/ackhandler/mock_ecn_handler_test.go
@@ -20,6 +20,7 @@ import (
 type MockECNHandler struct {
 	ctrl     *gomock.Controller
 	recorder *MockECNHandlerMockRecorder
+	isgomock struct{}
 }
 
 // MockECNHandlerMockRecorder is the mock recorder for MockECNHandler.
@@ -40,17 +41,17 @@ func (m *MockECNHandler) EXPECT() *MockECNHandlerMockRecorder {
 }
 
 // HandleNewlyAcked mocks base method.
-func (m *MockECNHandler) HandleNewlyAcked(arg0 []*packet, arg1, arg2, arg3 int64) bool {
+func (m *MockECNHandler) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64) bool {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "HandleNewlyAcked", arg0, arg1, arg2, arg3)
+	ret := m.ctrl.Call(m, "HandleNewlyAcked", packets, ect0, ect1, ecnce)
 	ret0, _ := ret[0].(bool)
 	return ret0
 }
 
 // HandleNewlyAcked indicates an expected call of HandleNewlyAcked.
-func (mr *MockECNHandlerMockRecorder) HandleNewlyAcked(arg0, arg1, arg2, arg3 any) *gomock.Call {
+func (mr *MockECNHandlerMockRecorder) HandleNewlyAcked(packets, ect0, ect1, ecnce any) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleNewlyAcked", reflect.TypeOf((*MockECNHandler)(nil).HandleNewlyAcked), arg0, arg1, arg2, arg3)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleNewlyAcked", reflect.TypeOf((*MockECNHandler)(nil).HandleNewlyAcked), packets, ect0, ect1, ecnce)
 }
 
 // LostPacket mocks base method.
diff --git a/internal/ackhandler/mock_sent_packet_tracker_test.go b/internal/ackhandler/mock_sent_packet_tracker_test.go
index 8c658137..dd4a91c3 100644
--- a/internal/ackhandler/mock_sent_packet_tracker_test.go
+++ b/internal/ackhandler/mock_sent_packet_tracker_test.go
@@ -20,6 +20,7 @@ import (
 type MockSentPacketTracker struct {
 	ctrl     *gomock.Controller
 	recorder *MockSentPacketTrackerMockRecorder
+	isgomock struct{}
 }
 
 // MockSentPacketTrackerMockRecorder is the mock recorder for MockSentPacketTracker.
diff --git a/internal/flowcontrol/connection_flow_controller_test.go b/internal/flowcontrol/connection_flow_controller_test.go
index 0598d1dc..1e1288b3 100644
--- a/internal/flowcontrol/connection_flow_controller_test.go
+++ b/internal/flowcontrol/connection_flow_controller_test.go
@@ -59,8 +59,16 @@ func TestConnectionFlowControlViolation(t *testing.T) {
 	require.Equal(t, qerr.FlowControlError, terr.ErrorCode)
 }
 
-// TODO (#4732): add a test for successfully resetting the flow controller
 func TestConnectionFlowControllerReset(t *testing.T) {
+	fc := NewConnectionFlowController(0, 0, nil, &utils.RTTStats{}, utils.DefaultLogger)
+	fc.UpdateSendWindow(100)
+	fc.AddBytesSent(10)
+	require.Equal(t, protocol.ByteCount(90), fc.SendWindowSize())
+	require.NoError(t, fc.Reset())
+	require.Zero(t, fc.SendWindowSize())
+}
+
+func TestConnectionFlowControllerResetAfterReading(t *testing.T) {
 	fc := NewConnectionFlowController(0, 0, nil, &utils.RTTStats{}, utils.DefaultLogger)
 	fc.AddBytesRead(1)
 	require.EqualError(t, fc.Reset(), "flow controller reset after reading data")
diff --git a/mock_ack_frame_source_test.go b/mock_ack_frame_source_test.go
index 5459c8c1..e668517f 100644
--- a/mock_ack_frame_source_test.go
+++ b/mock_ack_frame_source_test.go
@@ -21,6 +21,7 @@ import (
 type MockAckFrameSource struct {
 	ctrl     *gomock.Controller
 	recorder *MockAckFrameSourceMockRecorder
+	isgomock struct{}
 }
 
 // MockAckFrameSourceMockRecorder is the mock recorder for MockAckFrameSource.
@@ -41,17 +42,17 @@ func (m *MockAckFrameSource) EXPECT() *MockAckFrameSourceMockRecorder {
 }
 
 // GetAckFrame mocks base method.
-func (m *MockAckFrameSource) GetAckFrame(arg0 protocol.EncryptionLevel, arg1 bool) *wire.AckFrame {
+func (m *MockAckFrameSource) GetAckFrame(encLevel protocol.EncryptionLevel, onlyIfQueued bool) *wire.AckFrame {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetAckFrame", arg0, arg1)
+	ret := m.ctrl.Call(m, "GetAckFrame", encLevel, onlyIfQueued)
 	ret0, _ := ret[0].(*wire.AckFrame)
 	return ret0
 }
 
 // GetAckFrame indicates an expected call of GetAckFrame.
-func (mr *MockAckFrameSourceMockRecorder) GetAckFrame(arg0, arg1 any) *MockAckFrameSourceGetAckFrameCall {
+func (mr *MockAckFrameSourceMockRecorder) GetAckFrame(encLevel, onlyIfQueued any) *MockAckFrameSourceGetAckFrameCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAckFrame", reflect.TypeOf((*MockAckFrameSource)(nil).GetAckFrame), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAckFrame", reflect.TypeOf((*MockAckFrameSource)(nil).GetAckFrame), encLevel, onlyIfQueued)
 	return &MockAckFrameSourceGetAckFrameCall{Call: call}
 }
 
diff --git a/mock_batch_conn_test.go b/mock_batch_conn_test.go
index ea74b4e8..63f569c4 100644
--- a/mock_batch_conn_test.go
+++ b/mock_batch_conn_test.go
@@ -20,6 +20,7 @@ import (
 type MockBatchConn struct {
 	ctrl     *gomock.Controller
 	recorder *MockBatchConnMockRecorder
+	isgomock struct{}
 }
 
 // MockBatchConnMockRecorder is the mock recorder for MockBatchConn.
diff --git a/mock_conn_runner_test.go b/mock_conn_runner_test.go
index f9928165..ef1e170a 100644
--- a/mock_conn_runner_test.go
+++ b/mock_conn_runner_test.go
@@ -20,6 +20,7 @@ import (
 type MockConnRunner struct {
 	ctrl     *gomock.Controller
 	recorder *MockConnRunnerMockRecorder
+	isgomock struct{}
 }
 
 // MockConnRunnerMockRecorder is the mock recorder for MockConnRunner.
diff --git a/mock_frame_source_test.go b/mock_frame_source_test.go
index 1d53829f..906aacb2 100644
--- a/mock_frame_source_test.go
+++ b/mock_frame_source_test.go
@@ -22,6 +22,7 @@ import (
 type MockFrameSource struct {
 	ctrl     *gomock.Controller
 	recorder *MockFrameSourceMockRecorder
+	isgomock struct{}
 }
 
 // MockFrameSourceMockRecorder is the mock recorder for MockFrameSource.
diff --git a/mock_mtu_discoverer_test.go b/mock_mtu_discoverer_test.go
index 236c6a1d..4951b6d5 100644
--- a/mock_mtu_discoverer_test.go
+++ b/mock_mtu_discoverer_test.go
@@ -22,6 +22,7 @@ import (
 type MockMTUDiscoverer struct {
 	ctrl     *gomock.Controller
 	recorder *MockMTUDiscovererMockRecorder
+	isgomock struct{}
 }
 
 // MockMTUDiscovererMockRecorder is the mock recorder for MockMTUDiscoverer.
@@ -101,8 +102,8 @@ type MockMTUDiscovererGetPingCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockMTUDiscovererGetPingCall) Return(arg0 ackhandler.Frame, arg1 protocol.ByteCount) *MockMTUDiscovererGetPingCall {
-	c.Call = c.Call.Return(arg0, arg1)
+func (c *MockMTUDiscovererGetPingCall) Return(ping ackhandler.Frame, datagramSize protocol.ByteCount) *MockMTUDiscovererGetPingCall {
+	c.Call = c.Call.Return(ping, datagramSize)
 	return c
 }
 
@@ -119,17 +120,17 @@ func (c *MockMTUDiscovererGetPingCall) DoAndReturn(f func() (ackhandler.Frame, p
 }
 
 // ShouldSendProbe mocks base method.
-func (m *MockMTUDiscoverer) ShouldSendProbe(arg0 time.Time) bool {
+func (m *MockMTUDiscoverer) ShouldSendProbe(now time.Time) bool {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ShouldSendProbe", arg0)
+	ret := m.ctrl.Call(m, "ShouldSendProbe", now)
 	ret0, _ := ret[0].(bool)
 	return ret0
 }
 
 // ShouldSendProbe indicates an expected call of ShouldSendProbe.
-func (mr *MockMTUDiscovererMockRecorder) ShouldSendProbe(arg0 any) *MockMTUDiscovererShouldSendProbeCall {
+func (mr *MockMTUDiscovererMockRecorder) ShouldSendProbe(now any) *MockMTUDiscovererShouldSendProbeCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldSendProbe", reflect.TypeOf((*MockMTUDiscoverer)(nil).ShouldSendProbe), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldSendProbe", reflect.TypeOf((*MockMTUDiscoverer)(nil).ShouldSendProbe), now)
 	return &MockMTUDiscovererShouldSendProbeCall{Call: call}
 }
 
diff --git a/mock_packer_test.go b/mock_packer_test.go
index e8a2d49c..674a560e 100644
--- a/mock_packer_test.go
+++ b/mock_packer_test.go
@@ -23,6 +23,7 @@ import (
 type MockPacker struct {
 	ctrl     *gomock.Controller
 	recorder *MockPackerMockRecorder
+	isgomock struct{}
 }
 
 // MockPackerMockRecorder is the mock recorder for MockPacker.
@@ -43,18 +44,18 @@ func (m *MockPacker) EXPECT() *MockPackerMockRecorder {
 }
 
 // AppendPacket mocks base method.
-func (m *MockPacker) AppendPacket(arg0 *packetBuffer, arg1 protocol.ByteCount, arg2 time.Time, arg3 protocol.Version) (shortHeaderPacket, error) {
+func (m *MockPacker) AppendPacket(buf *packetBuffer, maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "AppendPacket", arg0, arg1, arg2, arg3)
+	ret := m.ctrl.Call(m, "AppendPacket", buf, maxPacketSize, now, v)
 	ret0, _ := ret[0].(shortHeaderPacket)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // AppendPacket indicates an expected call of AppendPacket.
-func (mr *MockPackerMockRecorder) AppendPacket(arg0, arg1, arg2, arg3 any) *MockPackerAppendPacketCall {
+func (mr *MockPackerMockRecorder) AppendPacket(buf, maxPacketSize, now, v any) *MockPackerAppendPacketCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendPacket", reflect.TypeOf((*MockPacker)(nil).AppendPacket), arg0, arg1, arg2, arg3)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendPacket", reflect.TypeOf((*MockPacker)(nil).AppendPacket), buf, maxPacketSize, now, v)
 	return &MockPackerAppendPacketCall{Call: call}
 }
 
@@ -121,9 +122,9 @@ func (c *MockPackerMaybePackProbePacketCall) DoAndReturn(f func(protocol.Encrypt
 }
 
 // PackAckOnlyPacket mocks base method.
-func (m *MockPacker) PackAckOnlyPacket(arg0 protocol.ByteCount, arg1 time.Time, arg2 protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
+func (m *MockPacker) PackAckOnlyPacket(maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "PackAckOnlyPacket", arg0, arg1, arg2)
+	ret := m.ctrl.Call(m, "PackAckOnlyPacket", maxPacketSize, now, v)
 	ret0, _ := ret[0].(shortHeaderPacket)
 	ret1, _ := ret[1].(*packetBuffer)
 	ret2, _ := ret[2].(error)
@@ -131,9 +132,9 @@ func (m *MockPacker) PackAckOnlyPacket(arg0 protocol.ByteCount, arg1 time.Time,
 }
 
 // PackAckOnlyPacket indicates an expected call of PackAckOnlyPacket.
-func (mr *MockPackerMockRecorder) PackAckOnlyPacket(arg0, arg1, arg2 any) *MockPackerPackAckOnlyPacketCall {
+func (mr *MockPackerMockRecorder) PackAckOnlyPacket(maxPacketSize, now, v any) *MockPackerPackAckOnlyPacketCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackAckOnlyPacket", reflect.TypeOf((*MockPacker)(nil).PackAckOnlyPacket), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackAckOnlyPacket", reflect.TypeOf((*MockPacker)(nil).PackAckOnlyPacket), maxPacketSize, now, v)
 	return &MockPackerPackAckOnlyPacketCall{Call: call}
 }
 
@@ -200,18 +201,18 @@ func (c *MockPackerPackApplicationCloseCall) DoAndReturn(f func(*qerr.Applicatio
 }
 
 // PackCoalescedPacket mocks base method.
-func (m *MockPacker) PackCoalescedPacket(arg0 bool, arg1 protocol.ByteCount, arg2 time.Time, arg3 protocol.Version) (*coalescedPacket, error) {
+func (m *MockPacker) PackCoalescedPacket(onlyAck bool, maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (*coalescedPacket, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "PackCoalescedPacket", arg0, arg1, arg2, arg3)
+	ret := m.ctrl.Call(m, "PackCoalescedPacket", onlyAck, maxPacketSize, now, v)
 	ret0, _ := ret[0].(*coalescedPacket)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // PackCoalescedPacket indicates an expected call of PackCoalescedPacket.
-func (mr *MockPackerMockRecorder) PackCoalescedPacket(arg0, arg1, arg2, arg3 any) *MockPackerPackCoalescedPacketCall {
+func (mr *MockPackerMockRecorder) PackCoalescedPacket(onlyAck, maxPacketSize, now, v any) *MockPackerPackCoalescedPacketCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackCoalescedPacket", reflect.TypeOf((*MockPacker)(nil).PackCoalescedPacket), arg0, arg1, arg2, arg3)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackCoalescedPacket", reflect.TypeOf((*MockPacker)(nil).PackCoalescedPacket), onlyAck, maxPacketSize, now, v)
 	return &MockPackerPackCoalescedPacketCall{Call: call}
 }
 
@@ -278,9 +279,9 @@ func (c *MockPackerPackConnectionCloseCall) DoAndReturn(f func(*qerr.TransportEr
 }
 
 // PackMTUProbePacket mocks base method.
-func (m *MockPacker) PackMTUProbePacket(arg0 ackhandler.Frame, arg1 protocol.ByteCount, arg2 protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
+func (m *MockPacker) PackMTUProbePacket(ping ackhandler.Frame, size protocol.ByteCount, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "PackMTUProbePacket", arg0, arg1, arg2)
+	ret := m.ctrl.Call(m, "PackMTUProbePacket", ping, size, v)
 	ret0, _ := ret[0].(shortHeaderPacket)
 	ret1, _ := ret[1].(*packetBuffer)
 	ret2, _ := ret[2].(error)
@@ -288,9 +289,9 @@ func (m *MockPacker) PackMTUProbePacket(arg0 ackhandler.Frame, arg1 protocol.Byt
 }
 
 // PackMTUProbePacket indicates an expected call of PackMTUProbePacket.
-func (mr *MockPackerMockRecorder) PackMTUProbePacket(arg0, arg1, arg2 any) *MockPackerPackMTUProbePacketCall {
+func (mr *MockPackerMockRecorder) PackMTUProbePacket(ping, size, v any) *MockPackerPackMTUProbePacketCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackMTUProbePacket", reflect.TypeOf((*MockPacker)(nil).PackMTUProbePacket), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackMTUProbePacket", reflect.TypeOf((*MockPacker)(nil).PackMTUProbePacket), ping, size, v)
 	return &MockPackerPackMTUProbePacketCall{Call: call}
 }
 
diff --git a/mock_packet_handler_manager_test.go b/mock_packet_handler_manager_test.go
index 465a3865..f99d909c 100644
--- a/mock_packet_handler_manager_test.go
+++ b/mock_packet_handler_manager_test.go
@@ -20,6 +20,7 @@ import (
 type MockPacketHandlerManager struct {
 	ctrl     *gomock.Controller
 	recorder *MockPacketHandlerManagerMockRecorder
+	isgomock struct{}
 }
 
 // MockPacketHandlerManagerMockRecorder is the mock recorder for MockPacketHandlerManager.
@@ -114,17 +115,17 @@ func (c *MockPacketHandlerManagerAddResetTokenCall) DoAndReturn(f func(protocol.
 }
 
 // AddWithConnID mocks base method.
-func (m *MockPacketHandlerManager) AddWithConnID(arg0, arg1 protocol.ConnectionID, arg2 packetHandler) bool {
+func (m *MockPacketHandlerManager) AddWithConnID(destConnID, newConnID protocol.ConnectionID, h packetHandler) bool {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "AddWithConnID", arg0, arg1, arg2)
+	ret := m.ctrl.Call(m, "AddWithConnID", destConnID, newConnID, h)
 	ret0, _ := ret[0].(bool)
 	return ret0
 }
 
 // AddWithConnID indicates an expected call of AddWithConnID.
-func (mr *MockPacketHandlerManagerMockRecorder) AddWithConnID(arg0, arg1, arg2 any) *MockPacketHandlerManagerAddWithConnIDCall {
+func (mr *MockPacketHandlerManagerMockRecorder) AddWithConnID(destConnID, newConnID, h any) *MockPacketHandlerManagerAddWithConnIDCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWithConnID", reflect.TypeOf((*MockPacketHandlerManager)(nil).AddWithConnID), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWithConnID", reflect.TypeOf((*MockPacketHandlerManager)(nil).AddWithConnID), destConnID, newConnID, h)
 	return &MockPacketHandlerManagerAddWithConnIDCall{Call: call}
 }
 
diff --git a/mock_packet_handler_test.go b/mock_packet_handler_test.go
index 46c99f8c..f9bcbd12 100644
--- a/mock_packet_handler_test.go
+++ b/mock_packet_handler_test.go
@@ -20,6 +20,7 @@ import (
 type MockPacketHandler struct {
 	ctrl     *gomock.Controller
 	recorder *MockPacketHandlerMockRecorder
+	isgomock struct{}
 }
 
 // MockPacketHandlerMockRecorder is the mock recorder for MockPacketHandler.
diff --git a/mock_packetconn_test.go b/mock_packetconn_test.go
index 45d36cba..59617cdd 100644
--- a/mock_packetconn_test.go
+++ b/mock_packetconn_test.go
@@ -21,6 +21,7 @@ import (
 type MockPacketConn struct {
 	ctrl     *gomock.Controller
 	recorder *MockPacketConnMockRecorder
+	isgomock struct{}
 }
 
 // MockPacketConnMockRecorder is the mock recorder for MockPacketConn.
@@ -117,9 +118,9 @@ func (c *MockPacketConnLocalAddrCall) DoAndReturn(f func() net.Addr) *MockPacket
 }
 
 // ReadFrom mocks base method.
-func (m *MockPacketConn) ReadFrom(arg0 []byte) (int, net.Addr, error) {
+func (m *MockPacketConn) ReadFrom(p []byte) (int, net.Addr, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ReadFrom", arg0)
+	ret := m.ctrl.Call(m, "ReadFrom", p)
 	ret0, _ := ret[0].(int)
 	ret1, _ := ret[1].(net.Addr)
 	ret2, _ := ret[2].(error)
@@ -127,9 +128,9 @@ func (m *MockPacketConn) ReadFrom(arg0 []byte) (int, net.Addr, error) {
 }
 
 // ReadFrom indicates an expected call of ReadFrom.
-func (mr *MockPacketConnMockRecorder) ReadFrom(arg0 any) *MockPacketConnReadFromCall {
+func (mr *MockPacketConnMockRecorder) ReadFrom(p any) *MockPacketConnReadFromCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadFrom", reflect.TypeOf((*MockPacketConn)(nil).ReadFrom), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadFrom", reflect.TypeOf((*MockPacketConn)(nil).ReadFrom), p)
 	return &MockPacketConnReadFromCall{Call: call}
 }
 
@@ -139,8 +140,8 @@ type MockPacketConnReadFromCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockPacketConnReadFromCall) Return(arg0 int, arg1 net.Addr, arg2 error) *MockPacketConnReadFromCall {
-	c.Call = c.Call.Return(arg0, arg1, arg2)
+func (c *MockPacketConnReadFromCall) Return(n int, addr net.Addr, err error) *MockPacketConnReadFromCall {
+	c.Call = c.Call.Return(n, addr, err)
 	return c
 }
 
@@ -157,17 +158,17 @@ func (c *MockPacketConnReadFromCall) DoAndReturn(f func([]byte) (int, net.Addr,
 }
 
 // SetDeadline mocks base method.
-func (m *MockPacketConn) SetDeadline(arg0 time.Time) error {
+func (m *MockPacketConn) SetDeadline(t time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetDeadline", arg0)
+	ret := m.ctrl.Call(m, "SetDeadline", t)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SetDeadline indicates an expected call of SetDeadline.
-func (mr *MockPacketConnMockRecorder) SetDeadline(arg0 any) *MockPacketConnSetDeadlineCall {
+func (mr *MockPacketConnMockRecorder) SetDeadline(t any) *MockPacketConnSetDeadlineCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetDeadline), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetDeadline), t)
 	return &MockPacketConnSetDeadlineCall{Call: call}
 }
 
@@ -195,17 +196,17 @@ func (c *MockPacketConnSetDeadlineCall) DoAndReturn(f func(time.Time) error) *Mo
 }
 
 // SetReadDeadline mocks base method.
-func (m *MockPacketConn) SetReadDeadline(arg0 time.Time) error {
+func (m *MockPacketConn) SetReadDeadline(t time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetReadDeadline", arg0)
+	ret := m.ctrl.Call(m, "SetReadDeadline", t)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SetReadDeadline indicates an expected call of SetReadDeadline.
-func (mr *MockPacketConnMockRecorder) SetReadDeadline(arg0 any) *MockPacketConnSetReadDeadlineCall {
+func (mr *MockPacketConnMockRecorder) SetReadDeadline(t any) *MockPacketConnSetReadDeadlineCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetReadDeadline), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetReadDeadline), t)
 	return &MockPacketConnSetReadDeadlineCall{Call: call}
 }
 
@@ -233,17 +234,17 @@ func (c *MockPacketConnSetReadDeadlineCall) DoAndReturn(f func(time.Time) error)
 }
 
 // SetWriteDeadline mocks base method.
-func (m *MockPacketConn) SetWriteDeadline(arg0 time.Time) error {
+func (m *MockPacketConn) SetWriteDeadline(t time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetWriteDeadline", arg0)
+	ret := m.ctrl.Call(m, "SetWriteDeadline", t)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SetWriteDeadline indicates an expected call of SetWriteDeadline.
-func (mr *MockPacketConnMockRecorder) SetWriteDeadline(arg0 any) *MockPacketConnSetWriteDeadlineCall {
+func (mr *MockPacketConnMockRecorder) SetWriteDeadline(t any) *MockPacketConnSetWriteDeadlineCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetWriteDeadline), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockPacketConn)(nil).SetWriteDeadline), t)
 	return &MockPacketConnSetWriteDeadlineCall{Call: call}
 }
 
@@ -271,18 +272,18 @@ func (c *MockPacketConnSetWriteDeadlineCall) DoAndReturn(f func(time.Time) error
 }
 
 // WriteTo mocks base method.
-func (m *MockPacketConn) WriteTo(arg0 []byte, arg1 net.Addr) (int, error) {
+func (m *MockPacketConn) WriteTo(p []byte, addr net.Addr) (int, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "WriteTo", arg0, arg1)
+	ret := m.ctrl.Call(m, "WriteTo", p, addr)
 	ret0, _ := ret[0].(int)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // WriteTo indicates an expected call of WriteTo.
-func (mr *MockPacketConnMockRecorder) WriteTo(arg0, arg1 any) *MockPacketConnWriteToCall {
+func (mr *MockPacketConnMockRecorder) WriteTo(p, addr any) *MockPacketConnWriteToCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteTo", reflect.TypeOf((*MockPacketConn)(nil).WriteTo), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteTo", reflect.TypeOf((*MockPacketConn)(nil).WriteTo), p, addr)
 	return &MockPacketConnWriteToCall{Call: call}
 }
 
@@ -292,8 +293,8 @@ type MockPacketConnWriteToCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockPacketConnWriteToCall) Return(arg0 int, arg1 error) *MockPacketConnWriteToCall {
-	c.Call = c.Call.Return(arg0, arg1)
+func (c *MockPacketConnWriteToCall) Return(n int, err error) *MockPacketConnWriteToCall {
+	c.Call = c.Call.Return(n, err)
 	return c
 }
 
diff --git a/mock_quic_conn_test.go b/mock_quic_conn_test.go
index 785ef5d3..2f7d296f 100644
--- a/mock_quic_conn_test.go
+++ b/mock_quic_conn_test.go
@@ -22,6 +22,7 @@ import (
 type MockQUICConn struct {
 	ctrl     *gomock.Controller
 	recorder *MockQUICConnMockRecorder
+	isgomock struct{}
 }
 
 // MockQUICConnMockRecorder is the mock recorder for MockQUICConn.
@@ -582,17 +583,17 @@ func (c *MockQUICConnRemoteAddrCall) DoAndReturn(f func() net.Addr) *MockQUICCon
 }
 
 // SendDatagram mocks base method.
-func (m *MockQUICConn) SendDatagram(arg0 []byte) error {
+func (m *MockQUICConn) SendDatagram(payload []byte) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SendDatagram", arg0)
+	ret := m.ctrl.Call(m, "SendDatagram", payload)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SendDatagram indicates an expected call of SendDatagram.
-func (mr *MockQUICConnMockRecorder) SendDatagram(arg0 any) *MockQUICConnSendDatagramCall {
+func (mr *MockQUICConnMockRecorder) SendDatagram(payload any) *MockQUICConnSendDatagramCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendDatagram", reflect.TypeOf((*MockQUICConn)(nil).SendDatagram), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendDatagram", reflect.TypeOf((*MockQUICConn)(nil).SendDatagram), payload)
 	return &MockQUICConnSendDatagramCall{Call: call}
 }
 
diff --git a/mock_raw_conn_test.go b/mock_raw_conn_test.go
index 68f76ec2..ecffca1b 100644
--- a/mock_raw_conn_test.go
+++ b/mock_raw_conn_test.go
@@ -22,6 +22,7 @@ import (
 type MockRawConn struct {
 	ctrl     *gomock.Controller
 	recorder *MockRawConnMockRecorder
+	isgomock struct{}
 }
 
 // MockRawConnMockRecorder is the mock recorder for MockRawConn.
@@ -195,18 +196,18 @@ func (c *MockRawConnSetReadDeadlineCall) DoAndReturn(f func(time.Time) error) *M
 }
 
 // WritePacket mocks base method.
-func (m *MockRawConn) WritePacket(arg0 []byte, arg1 net.Addr, arg2 []byte, arg3 uint16, arg4 protocol.ECN) (int, error) {
+func (m *MockRawConn) WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gsoSize uint16, ecn protocol.ECN) (int, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "WritePacket", arg0, arg1, arg2, arg3, arg4)
+	ret := m.ctrl.Call(m, "WritePacket", b, addr, packetInfoOOB, gsoSize, ecn)
 	ret0, _ := ret[0].(int)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // WritePacket indicates an expected call of WritePacket.
-func (mr *MockRawConnMockRecorder) WritePacket(arg0, arg1, arg2, arg3, arg4 any) *MockRawConnWritePacketCall {
+func (mr *MockRawConnMockRecorder) WritePacket(b, addr, packetInfoOOB, gsoSize, ecn any) *MockRawConnWritePacketCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePacket", reflect.TypeOf((*MockRawConn)(nil).WritePacket), arg0, arg1, arg2, arg3, arg4)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePacket", reflect.TypeOf((*MockRawConn)(nil).WritePacket), b, addr, packetInfoOOB, gsoSize, ecn)
 	return &MockRawConnWritePacketCall{Call: call}
 }
 
diff --git a/mock_receive_stream_internal_test.go b/mock_receive_stream_internal_test.go
index 5204b511..1b59ecda 100644
--- a/mock_receive_stream_internal_test.go
+++ b/mock_receive_stream_internal_test.go
@@ -23,6 +23,7 @@ import (
 type MockReceiveStreamI struct {
 	ctrl     *gomock.Controller
 	recorder *MockReceiveStreamIMockRecorder
+	isgomock struct{}
 }
 
 // MockReceiveStreamIMockRecorder is the mock recorder for MockReceiveStreamI.
@@ -79,18 +80,18 @@ func (c *MockReceiveStreamICancelReadCall) DoAndReturn(f func(qerr.StreamErrorCo
 }
 
 // Read mocks base method.
-func (m *MockReceiveStreamI) Read(arg0 []byte) (int, error) {
+func (m *MockReceiveStreamI) Read(p []byte) (int, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "Read", arg0)
+	ret := m.ctrl.Call(m, "Read", p)
 	ret0, _ := ret[0].(int)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // Read indicates an expected call of Read.
-func (mr *MockReceiveStreamIMockRecorder) Read(arg0 any) *MockReceiveStreamIReadCall {
+func (mr *MockReceiveStreamIMockRecorder) Read(p any) *MockReceiveStreamIReadCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockReceiveStreamI)(nil).Read), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockReceiveStreamI)(nil).Read), p)
 	return &MockReceiveStreamIReadCall{Call: call}
 }
 
@@ -100,8 +101,8 @@ type MockReceiveStreamIReadCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockReceiveStreamIReadCall) Return(arg0 int, arg1 error) *MockReceiveStreamIReadCall {
-	c.Call = c.Call.Return(arg0, arg1)
+func (c *MockReceiveStreamIReadCall) Return(n int, err error) *MockReceiveStreamIReadCall {
+	c.Call = c.Call.Return(n, err)
 	return c
 }
 
@@ -118,17 +119,17 @@ func (c *MockReceiveStreamIReadCall) DoAndReturn(f func([]byte) (int, error)) *M
 }
 
 // SetReadDeadline mocks base method.
-func (m *MockReceiveStreamI) SetReadDeadline(arg0 time.Time) error {
+func (m *MockReceiveStreamI) SetReadDeadline(t time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetReadDeadline", arg0)
+	ret := m.ctrl.Call(m, "SetReadDeadline", t)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SetReadDeadline indicates an expected call of SetReadDeadline.
-func (mr *MockReceiveStreamIMockRecorder) SetReadDeadline(arg0 any) *MockReceiveStreamISetReadDeadlineCall {
+func (mr *MockReceiveStreamIMockRecorder) SetReadDeadline(t any) *MockReceiveStreamISetReadDeadlineCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockReceiveStreamI)(nil).SetReadDeadline), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockReceiveStreamI)(nil).SetReadDeadline), t)
 	return &MockReceiveStreamISetReadDeadlineCall{Call: call}
 }
 
diff --git a/mock_sealing_manager_test.go b/mock_sealing_manager_test.go
index 0c209ea5..23f91a65 100644
--- a/mock_sealing_manager_test.go
+++ b/mock_sealing_manager_test.go
@@ -20,6 +20,7 @@ import (
 type MockSealingManager struct {
 	ctrl     *gomock.Controller
 	recorder *MockSealingManagerMockRecorder
+	isgomock struct{}
 }
 
 // MockSealingManagerMockRecorder is the mock recorder for MockSealingManager.
diff --git a/mock_send_conn_test.go b/mock_send_conn_test.go
index 302bafa2..bfbaee73 100644
--- a/mock_send_conn_test.go
+++ b/mock_send_conn_test.go
@@ -21,6 +21,7 @@ import (
 type MockSendConn struct {
 	ctrl     *gomock.Controller
 	recorder *MockSendConnMockRecorder
+	isgomock struct{}
 }
 
 // MockSendConnMockRecorder is the mock recorder for MockSendConn.
@@ -155,17 +156,17 @@ func (c *MockSendConnRemoteAddrCall) DoAndReturn(f func() net.Addr) *MockSendCon
 }
 
 // Write mocks base method.
-func (m *MockSendConn) Write(arg0 []byte, arg1 uint16, arg2 protocol.ECN) error {
+func (m *MockSendConn) Write(b []byte, gsoSize uint16, ecn protocol.ECN) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "Write", arg0, arg1, arg2)
+	ret := m.ctrl.Call(m, "Write", b, gsoSize, ecn)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // Write indicates an expected call of Write.
-func (mr *MockSendConnMockRecorder) Write(arg0, arg1, arg2 any) *MockSendConnWriteCall {
+func (mr *MockSendConnMockRecorder) Write(b, gsoSize, ecn any) *MockSendConnWriteCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendConn)(nil).Write), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendConn)(nil).Write), b, gsoSize, ecn)
 	return &MockSendConnWriteCall{Call: call}
 }
 
diff --git a/mock_send_stream_internal_test.go b/mock_send_stream_internal_test.go
index 51a67cc1..1c9afc83 100644
--- a/mock_send_stream_internal_test.go
+++ b/mock_send_stream_internal_test.go
@@ -25,6 +25,7 @@ import (
 type MockSendStreamI struct {
 	ctrl     *gomock.Controller
 	recorder *MockSendStreamIMockRecorder
+	isgomock struct{}
 }
 
 // MockSendStreamIMockRecorder is the mock recorder for MockSendStreamI.
@@ -157,17 +158,17 @@ func (c *MockSendStreamIContextCall) DoAndReturn(f func() context.Context) *Mock
 }
 
 // SetWriteDeadline mocks base method.
-func (m *MockSendStreamI) SetWriteDeadline(arg0 time.Time) error {
+func (m *MockSendStreamI) SetWriteDeadline(t time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetWriteDeadline", arg0)
+	ret := m.ctrl.Call(m, "SetWriteDeadline", t)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SetWriteDeadline indicates an expected call of SetWriteDeadline.
-func (mr *MockSendStreamIMockRecorder) SetWriteDeadline(arg0 any) *MockSendStreamISetWriteDeadlineCall {
+func (mr *MockSendStreamIMockRecorder) SetWriteDeadline(t any) *MockSendStreamISetWriteDeadlineCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockSendStreamI)(nil).SetWriteDeadline), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockSendStreamI)(nil).SetWriteDeadline), t)
 	return &MockSendStreamISetWriteDeadlineCall{Call: call}
 }
 
@@ -233,18 +234,18 @@ func (c *MockSendStreamIStreamIDCall) DoAndReturn(f func() protocol.StreamID) *M
 }
 
 // Write mocks base method.
-func (m *MockSendStreamI) Write(arg0 []byte) (int, error) {
+func (m *MockSendStreamI) Write(p []byte) (int, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "Write", arg0)
+	ret := m.ctrl.Call(m, "Write", p)
 	ret0, _ := ret[0].(int)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // Write indicates an expected call of Write.
-func (mr *MockSendStreamIMockRecorder) Write(arg0 any) *MockSendStreamIWriteCall {
+func (mr *MockSendStreamIMockRecorder) Write(p any) *MockSendStreamIWriteCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendStreamI)(nil).Write), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockSendStreamI)(nil).Write), p)
 	return &MockSendStreamIWriteCall{Call: call}
 }
 
@@ -254,8 +255,8 @@ type MockSendStreamIWriteCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockSendStreamIWriteCall) Return(arg0 int, arg1 error) *MockSendStreamIWriteCall {
-	c.Call = c.Call.Return(arg0, arg1)
+func (c *MockSendStreamIWriteCall) Return(n int, err error) *MockSendStreamIWriteCall {
+	c.Call = c.Call.Return(n, err)
 	return c
 }
 
@@ -382,9 +383,9 @@ func (c *MockSendStreamIhasDataCall) DoAndReturn(f func() bool) *MockSendStreamI
 }
 
 // popStreamFrame mocks base method.
-func (m *MockSendStreamI) popStreamFrame(arg0 protocol.ByteCount, arg1 protocol.Version) (ackhandler.StreamFrame, bool, bool) {
+func (m *MockSendStreamI) popStreamFrame(maxBytes protocol.ByteCount, v protocol.Version) (ackhandler.StreamFrame, bool, bool) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "popStreamFrame", arg0, arg1)
+	ret := m.ctrl.Call(m, "popStreamFrame", maxBytes, v)
 	ret0, _ := ret[0].(ackhandler.StreamFrame)
 	ret1, _ := ret[1].(bool)
 	ret2, _ := ret[2].(bool)
@@ -392,9 +393,9 @@ func (m *MockSendStreamI) popStreamFrame(arg0 protocol.ByteCount, arg1 protocol.
 }
 
 // popStreamFrame indicates an expected call of popStreamFrame.
-func (mr *MockSendStreamIMockRecorder) popStreamFrame(arg0, arg1 any) *MockSendStreamIpopStreamFrameCall {
+func (mr *MockSendStreamIMockRecorder) popStreamFrame(maxBytes, v any) *MockSendStreamIpopStreamFrameCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "popStreamFrame", reflect.TypeOf((*MockSendStreamI)(nil).popStreamFrame), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "popStreamFrame", reflect.TypeOf((*MockSendStreamI)(nil).popStreamFrame), maxBytes, v)
 	return &MockSendStreamIpopStreamFrameCall{Call: call}
 }
 
@@ -404,8 +405,8 @@ type MockSendStreamIpopStreamFrameCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockSendStreamIpopStreamFrameCall) Return(arg0 ackhandler.StreamFrame, arg1, arg2 bool) *MockSendStreamIpopStreamFrameCall {
-	c.Call = c.Call.Return(arg0, arg1, arg2)
+func (c *MockSendStreamIpopStreamFrameCall) Return(frame ackhandler.StreamFrame, ok, hasMore bool) *MockSendStreamIpopStreamFrameCall {
+	c.Call = c.Call.Return(frame, ok, hasMore)
 	return c
 }
 
diff --git a/mock_sender_test.go b/mock_sender_test.go
index 02cce86e..ee38ab6c 100644
--- a/mock_sender_test.go
+++ b/mock_sender_test.go
@@ -20,6 +20,7 @@ import (
 type MockSender struct {
 	ctrl     *gomock.Controller
 	recorder *MockSenderMockRecorder
+	isgomock struct{}
 }
 
 // MockSenderMockRecorder is the mock recorder for MockSender.
@@ -152,15 +153,15 @@ func (c *MockSenderRunCall) DoAndReturn(f func() error) *MockSenderRunCall {
 }
 
 // Send mocks base method.
-func (m *MockSender) Send(arg0 *packetBuffer, arg1 uint16, arg2 protocol.ECN) {
+func (m *MockSender) Send(p *packetBuffer, gsoSize uint16, ecn protocol.ECN) {
 	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "Send", arg0, arg1, arg2)
+	m.ctrl.Call(m, "Send", p, gsoSize, ecn)
 }
 
 // Send indicates an expected call of Send.
-func (mr *MockSenderMockRecorder) Send(arg0, arg1, arg2 any) *MockSenderSendCall {
+func (mr *MockSenderMockRecorder) Send(p, gsoSize, ecn any) *MockSenderSendCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockSender)(nil).Send), arg0, arg1, arg2)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockSender)(nil).Send), p, gsoSize, ecn)
 	return &MockSenderSendCall{Call: call}
 }
 
diff --git a/mock_stream_control_frame_getter_test.go b/mock_stream_control_frame_getter_test.go
index 90e85d73..6882ab55 100644
--- a/mock_stream_control_frame_getter_test.go
+++ b/mock_stream_control_frame_getter_test.go
@@ -21,6 +21,7 @@ import (
 type MockStreamControlFrameGetter struct {
 	ctrl     *gomock.Controller
 	recorder *MockStreamControlFrameGetterMockRecorder
+	isgomock struct{}
 }
 
 // MockStreamControlFrameGetterMockRecorder is the mock recorder for MockStreamControlFrameGetter.
@@ -63,8 +64,8 @@ type MockStreamControlFrameGettergetControlFrameCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockStreamControlFrameGettergetControlFrameCall) Return(arg0 ackhandler.Frame, arg1, arg2 bool) *MockStreamControlFrameGettergetControlFrameCall {
-	c.Call = c.Call.Return(arg0, arg1, arg2)
+func (c *MockStreamControlFrameGettergetControlFrameCall) Return(arg0 ackhandler.Frame, ok, hasMore bool) *MockStreamControlFrameGettergetControlFrameCall {
+	c.Call = c.Call.Return(arg0, ok, hasMore)
 	return c
 }
 
diff --git a/mock_stream_internal_test.go b/mock_stream_internal_test.go
index 757f4ec8..dea9d2e0 100644
--- a/mock_stream_internal_test.go
+++ b/mock_stream_internal_test.go
@@ -25,6 +25,7 @@ import (
 type MockStreamI struct {
 	ctrl     *gomock.Controller
 	recorder *MockStreamIMockRecorder
+	isgomock struct{}
 }
 
 // MockStreamIMockRecorder is the mock recorder for MockStreamI.
@@ -193,18 +194,18 @@ func (c *MockStreamIContextCall) DoAndReturn(f func() context.Context) *MockStre
 }
 
 // Read mocks base method.
-func (m *MockStreamI) Read(arg0 []byte) (int, error) {
+func (m *MockStreamI) Read(p []byte) (int, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "Read", arg0)
+	ret := m.ctrl.Call(m, "Read", p)
 	ret0, _ := ret[0].(int)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // Read indicates an expected call of Read.
-func (mr *MockStreamIMockRecorder) Read(arg0 any) *MockStreamIReadCall {
+func (mr *MockStreamIMockRecorder) Read(p any) *MockStreamIReadCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStreamI)(nil).Read), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStreamI)(nil).Read), p)
 	return &MockStreamIReadCall{Call: call}
 }
 
@@ -214,8 +215,8 @@ type MockStreamIReadCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockStreamIReadCall) Return(arg0 int, arg1 error) *MockStreamIReadCall {
-	c.Call = c.Call.Return(arg0, arg1)
+func (c *MockStreamIReadCall) Return(n int, err error) *MockStreamIReadCall {
+	c.Call = c.Call.Return(n, err)
 	return c
 }
 
@@ -232,17 +233,17 @@ func (c *MockStreamIReadCall) DoAndReturn(f func([]byte) (int, error)) *MockStre
 }
 
 // SetDeadline mocks base method.
-func (m *MockStreamI) SetDeadline(arg0 time.Time) error {
+func (m *MockStreamI) SetDeadline(t time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetDeadline", arg0)
+	ret := m.ctrl.Call(m, "SetDeadline", t)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SetDeadline indicates an expected call of SetDeadline.
-func (mr *MockStreamIMockRecorder) SetDeadline(arg0 any) *MockStreamISetDeadlineCall {
+func (mr *MockStreamIMockRecorder) SetDeadline(t any) *MockStreamISetDeadlineCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStreamI)(nil).SetDeadline), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStreamI)(nil).SetDeadline), t)
 	return &MockStreamISetDeadlineCall{Call: call}
 }
 
@@ -270,17 +271,17 @@ func (c *MockStreamISetDeadlineCall) DoAndReturn(f func(time.Time) error) *MockS
 }
 
 // SetReadDeadline mocks base method.
-func (m *MockStreamI) SetReadDeadline(arg0 time.Time) error {
+func (m *MockStreamI) SetReadDeadline(t time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetReadDeadline", arg0)
+	ret := m.ctrl.Call(m, "SetReadDeadline", t)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SetReadDeadline indicates an expected call of SetReadDeadline.
-func (mr *MockStreamIMockRecorder) SetReadDeadline(arg0 any) *MockStreamISetReadDeadlineCall {
+func (mr *MockStreamIMockRecorder) SetReadDeadline(t any) *MockStreamISetReadDeadlineCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStreamI)(nil).SetReadDeadline), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStreamI)(nil).SetReadDeadline), t)
 	return &MockStreamISetReadDeadlineCall{Call: call}
 }
 
@@ -308,17 +309,17 @@ func (c *MockStreamISetReadDeadlineCall) DoAndReturn(f func(time.Time) error) *M
 }
 
 // SetWriteDeadline mocks base method.
-func (m *MockStreamI) SetWriteDeadline(arg0 time.Time) error {
+func (m *MockStreamI) SetWriteDeadline(t time.Time) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetWriteDeadline", arg0)
+	ret := m.ctrl.Call(m, "SetWriteDeadline", t)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // SetWriteDeadline indicates an expected call of SetWriteDeadline.
-func (mr *MockStreamIMockRecorder) SetWriteDeadline(arg0 any) *MockStreamISetWriteDeadlineCall {
+func (mr *MockStreamIMockRecorder) SetWriteDeadline(t any) *MockStreamISetWriteDeadlineCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStreamI)(nil).SetWriteDeadline), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStreamI)(nil).SetWriteDeadline), t)
 	return &MockStreamISetWriteDeadlineCall{Call: call}
 }
 
@@ -384,18 +385,18 @@ func (c *MockStreamIStreamIDCall) DoAndReturn(f func() protocol.StreamID) *MockS
 }
 
 // Write mocks base method.
-func (m *MockStreamI) Write(arg0 []byte) (int, error) {
+func (m *MockStreamI) Write(p []byte) (int, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "Write", arg0)
+	ret := m.ctrl.Call(m, "Write", p)
 	ret0, _ := ret[0].(int)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // Write indicates an expected call of Write.
-func (mr *MockStreamIMockRecorder) Write(arg0 any) *MockStreamIWriteCall {
+func (mr *MockStreamIMockRecorder) Write(p any) *MockStreamIWriteCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStreamI)(nil).Write), arg0)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStreamI)(nil).Write), p)
 	return &MockStreamIWriteCall{Call: call}
 }
 
@@ -405,8 +406,8 @@ type MockStreamIWriteCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockStreamIWriteCall) Return(arg0 int, arg1 error) *MockStreamIWriteCall {
-	c.Call = c.Call.Return(arg0, arg1)
+func (c *MockStreamIWriteCall) Return(n int, err error) *MockStreamIWriteCall {
+	c.Call = c.Call.Return(n, err)
 	return c
 }
 
@@ -609,9 +610,9 @@ func (c *MockStreamIhasDataCall) DoAndReturn(f func() bool) *MockStreamIhasDataC
 }
 
 // popStreamFrame mocks base method.
-func (m *MockStreamI) popStreamFrame(arg0 protocol.ByteCount, arg1 protocol.Version) (ackhandler.StreamFrame, bool, bool) {
+func (m *MockStreamI) popStreamFrame(maxBytes protocol.ByteCount, v protocol.Version) (ackhandler.StreamFrame, bool, bool) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "popStreamFrame", arg0, arg1)
+	ret := m.ctrl.Call(m, "popStreamFrame", maxBytes, v)
 	ret0, _ := ret[0].(ackhandler.StreamFrame)
 	ret1, _ := ret[1].(bool)
 	ret2, _ := ret[2].(bool)
@@ -619,9 +620,9 @@ func (m *MockStreamI) popStreamFrame(arg0 protocol.ByteCount, arg1 protocol.Vers
 }
 
 // popStreamFrame indicates an expected call of popStreamFrame.
-func (mr *MockStreamIMockRecorder) popStreamFrame(arg0, arg1 any) *MockStreamIpopStreamFrameCall {
+func (mr *MockStreamIMockRecorder) popStreamFrame(maxBytes, v any) *MockStreamIpopStreamFrameCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "popStreamFrame", reflect.TypeOf((*MockStreamI)(nil).popStreamFrame), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "popStreamFrame", reflect.TypeOf((*MockStreamI)(nil).popStreamFrame), maxBytes, v)
 	return &MockStreamIpopStreamFrameCall{Call: call}
 }
 
diff --git a/mock_stream_manager_test.go b/mock_stream_manager_test.go
index 6bafb60d..866e0e93 100644
--- a/mock_stream_manager_test.go
+++ b/mock_stream_manager_test.go
@@ -22,6 +22,7 @@ import (
 type MockStreamManager struct {
 	ctrl     *gomock.Controller
 	recorder *MockStreamManagerMockRecorder
+	isgomock struct{}
 }
 
 // MockStreamManagerMockRecorder is the mock recorder for MockStreamManager.
diff --git a/mock_stream_sender_test.go b/mock_stream_sender_test.go
index 08906151..d3418ee8 100644
--- a/mock_stream_sender_test.go
+++ b/mock_stream_sender_test.go
@@ -20,6 +20,7 @@ import (
 type MockStreamSender struct {
 	ctrl     *gomock.Controller
 	recorder *MockStreamSenderMockRecorder
+	isgomock struct{}
 }
 
 // MockStreamSenderMockRecorder is the mock recorder for MockStreamSender.
diff --git a/mock_unpacker_test.go b/mock_unpacker_test.go
index f644e825..b2f64dbb 100644
--- a/mock_unpacker_test.go
+++ b/mock_unpacker_test.go
@@ -22,6 +22,7 @@ import (
 type MockUnpacker struct {
 	ctrl     *gomock.Controller
 	recorder *MockUnpackerMockRecorder
+	isgomock struct{}
 }
 
 // MockUnpackerMockRecorder is the mock recorder for MockUnpacker.
@@ -42,18 +43,18 @@ func (m *MockUnpacker) EXPECT() *MockUnpackerMockRecorder {
 }
 
 // UnpackLongHeader mocks base method.
-func (m *MockUnpacker) UnpackLongHeader(arg0 *wire.Header, arg1 []byte) (*unpackedPacket, error) {
+func (m *MockUnpacker) UnpackLongHeader(hdr *wire.Header, data []byte) (*unpackedPacket, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "UnpackLongHeader", arg0, arg1)
+	ret := m.ctrl.Call(m, "UnpackLongHeader", hdr, data)
 	ret0, _ := ret[0].(*unpackedPacket)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
 // UnpackLongHeader indicates an expected call of UnpackLongHeader.
-func (mr *MockUnpackerMockRecorder) UnpackLongHeader(arg0, arg1 any) *MockUnpackerUnpackLongHeaderCall {
+func (mr *MockUnpackerMockRecorder) UnpackLongHeader(hdr, data any) *MockUnpackerUnpackLongHeaderCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnpackLongHeader", reflect.TypeOf((*MockUnpacker)(nil).UnpackLongHeader), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnpackLongHeader", reflect.TypeOf((*MockUnpacker)(nil).UnpackLongHeader), hdr, data)
 	return &MockUnpackerUnpackLongHeaderCall{Call: call}
 }
 
@@ -81,9 +82,9 @@ func (c *MockUnpackerUnpackLongHeaderCall) DoAndReturn(f func(*wire.Header, []by
 }
 
 // UnpackShortHeader mocks base method.
-func (m *MockUnpacker) UnpackShortHeader(arg0 time.Time, arg1 []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
+func (m *MockUnpacker) UnpackShortHeader(rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "UnpackShortHeader", arg0, arg1)
+	ret := m.ctrl.Call(m, "UnpackShortHeader", rcvTime, data)
 	ret0, _ := ret[0].(protocol.PacketNumber)
 	ret1, _ := ret[1].(protocol.PacketNumberLen)
 	ret2, _ := ret[2].(protocol.KeyPhaseBit)
@@ -93,9 +94,9 @@ func (m *MockUnpacker) UnpackShortHeader(arg0 time.Time, arg1 []byte) (protocol.
 }
 
 // UnpackShortHeader indicates an expected call of UnpackShortHeader.
-func (mr *MockUnpackerMockRecorder) UnpackShortHeader(arg0, arg1 any) *MockUnpackerUnpackShortHeaderCall {
+func (mr *MockUnpackerMockRecorder) UnpackShortHeader(rcvTime, data any) *MockUnpackerUnpackShortHeaderCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnpackShortHeader", reflect.TypeOf((*MockUnpacker)(nil).UnpackShortHeader), arg0, arg1)
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnpackShortHeader", reflect.TypeOf((*MockUnpacker)(nil).UnpackShortHeader), rcvTime, data)
 	return &MockUnpackerUnpackShortHeaderCall{Call: call}
 }