Repository: quic-go/quic-go
Pull request #5160 (2025-05-28 04:30:41)

qlog: add support for reset_stream_at frame and transport parameter
For #4139.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/quic-go/quic-go/pull/5160?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=quic-go) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 83.69%. Comparing base [(`5d7ee61`)](https://app.codecov.io/gh/quic-go/quic-go/commit/5d7ee61f5fd18b925a96cdf90888dfc9d4689e4a?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=quic-go) to head [(`ddbdb04`)](https://app.codecov.io/gh/quic-go/quic-go/commit/ddbdb04208b2c5795f860f30473df37ded064843?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=quic-go).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #5160      +/-   ##
==========================================
+ Coverage   83.65%   83.69%   +0.04%     
==========================================
  Files         150      150              
  Lines       17006    17017      +11     
==========================================
+ Hits        14226    14242      +16     
+ Misses       2228     2223       -5     
  Partials      552      552              
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/quic-go/quic-go/pull/5160?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=quic-go).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=quic-go).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>

Patch:
diff --git a/qlog/connection_tracer.go b/qlog/connection_tracer.go
index b696c2c7..f8873bc5 100644
--- a/qlog/connection_tracer.go
+++ b/qlog/connection_tracer.go
@@ -227,6 +227,7 @@ func (t *connectionTracer) toTransportParameters(tp *wire.TransportParameters) *
 		InitialMaxStreamsUni:            int64(tp.MaxUniStreamNum),
 		PreferredAddress:                pa,
 		MaxDatagramFrameSize:            tp.MaxDatagramFrameSize,
+		EnableResetStreamAt:             tp.EnableResetStreamAt,
 	}
 }
 
diff --git a/qlog/event.go b/qlog/event.go
index 9d20e215..b6e6b3e8 100644
--- a/qlog/event.go
+++ b/qlog/event.go
@@ -435,6 +435,7 @@ type eventTransportParameters struct {
 	PreferredAddress *preferredAddress
 
 	MaxDatagramFrameSize protocol.ByteCount
+	EnableResetStreamAt  bool
 }
 
 func (e eventTransportParameters) Category() category { return categoryTransport }
@@ -480,6 +481,9 @@ func (e eventTransportParameters) MarshalJSONObject(enc *gojay.Encoder) {
 	if e.MaxDatagramFrameSize != protocol.InvalidByteCount {
 		enc.Int64Key("max_datagram_frame_size", int64(e.MaxDatagramFrameSize))
 	}
+	if e.EnableResetStreamAt {
+		enc.BoolKey("reset_stream_at", true)
+	}
 }
 
 type preferredAddress struct {
diff --git a/qlog/frame.go b/qlog/frame.go
index 0d44f073..6f04deb3 100644
--- a/qlog/frame.go
+++ b/qlog/frame.go
@@ -112,10 +112,17 @@ func marshalAckFrame(enc *gojay.Encoder, f *logging.AckFrame) {
 }
 
 func marshalResetStreamFrame(enc *gojay.Encoder, f *logging.ResetStreamFrame) {
-	enc.StringKey("frame_type", "reset_stream")
+	if f.ReliableSize > 0 {
+		enc.StringKey("frame_type", "reset_stream_at")
+	} else {
+		enc.StringKey("frame_type", "reset_stream")
+	}
 	enc.Int64Key("stream_id", int64(f.StreamID))
 	enc.Int64Key("error_code", int64(f.ErrorCode))
 	enc.Int64Key("final_size", int64(f.FinalSize))
+	if f.ReliableSize > 0 {
+		enc.Int64Key("reliable_size", int64(f.ReliableSize))
+	}
 }
 
 func marshalStopSendingFrame(enc *gojay.Encoder, f *logging.StopSendingFrame) {


Test patch:
diff --git a/qlog/connection_tracer_test.go b/qlog/connection_tracer_test.go
index 1705da9b..d0ff6d63 100644
--- a/qlog/connection_tracer_test.go
+++ b/qlog/connection_tracer_test.go
@@ -213,6 +213,7 @@ func TestSentTransportParameters(t *testing.T) {
 		RetrySourceConnectionID:         &rcid,
 		ActiveConnectionIDLimit:         7,
 		MaxDatagramFrameSize:            protocol.InvalidByteCount,
+		EnableResetStreamAt:             true,
 	})
 	tracer.Close()
 	entry := exportAndParseSingle(t, buf)
@@ -234,6 +235,7 @@ func TestSentTransportParameters(t *testing.T) {
 	require.Equal(t, float64(3000), ev["initial_max_stream_data_uni"])
 	require.Equal(t, float64(10), ev["initial_max_streams_bidi"])
 	require.Equal(t, float64(20), ev["initial_max_streams_uni"])
+	require.True(t, ev["reset_stream_at"].(bool))
 	require.NotContains(t, ev, "preferred_address")
 	require.NotContains(t, ev, "max_datagram_frame_size")
 }
diff --git a/qlog/frame_test.go b/qlog/frame_test.go
index dc7e55f3..5b5e3c3c 100644
--- a/qlog/frame_test.go
+++ b/qlog/frame_test.go
@@ -119,6 +119,24 @@ func TestResetStreamFrame(t *testing.T) {
 	)
 }
 
+func TestResetStreamAtFrame(t *testing.T) {
+	check(t,
+		&logging.ResetStreamFrame{
+			StreamID:     987,
+			FinalSize:    1234,
+			ErrorCode:    42,
+			ReliableSize: 999,
+		},
+		map[string]interface{}{
+			"frame_type":    "reset_stream_at",
+			"stream_id":     987,
+			"error_code":    42,
+			"final_size":    1234,
+			"reliable_size": 999,
+		},
+	)
+}
+
 func TestStopSendingFrame(t *testing.T) {
 	check(t,
 		&logging.StopSendingFrame{