Skip to content

Commit b7b2d5e

Browse files
authored
Support Delaying Stream ID FC Updates to StreamClose (#3665) (#3684)
1 parent c0281d1 commit b7b2d5e

File tree

15 files changed

+143
-23
lines changed

15 files changed

+143
-23
lines changed

docs/api/QUIC_CONNECTION_EVENT.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ Value | Meaning
176176
**QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL**<br>1 | A unidirectional stream.
177177
**QUIC_STREAM_OPEN_FLAG_0_RTT**<br>2 | The stream was received in 0-RTT.
178178

179+
If a server wishes to use `QUIC_STREAM_OPEN_FLAG_DELAY_ID_FC_UPDATES` for the newly started stream, it may append this flag to `Flags` before it returns from the callback.
180+
179181
## QUIC_CONNECTION_EVENT_STREAMS_AVAILABLE
180182

181183
This event indicates the number of streams the peer is willing to accept has changed.

docs/api/StreamOpen.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Value | Meaning
3434
**QUIC_STREAM_OPEN_FLAG_NONE**<br>0 | No special behavior. Defaults to bidirectional stream.
3535
**QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL**<br>1 | Opens a unidirectional stream.
3636
**QUIC_STREAM_OPEN_FLAG_0_RTT**<br>2 | Indicates that the stream may be sent in 0-RTT.
37+
**QUIC_STREAM_OPEN_FLAG_DELAY_ID_FC_UPDATES**<br>4 | Indicates stream ID flow control limit updates for the connection should be delayed to StreamClose.
3738
3839
`Handler`
3940

src/core/api.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -658,13 +658,7 @@ MsQuicStreamOpen(
658658
goto Error;
659659
}
660660

661-
Status =
662-
QuicStreamInitialize(
663-
Connection,
664-
FALSE,
665-
!!(Flags & QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL),
666-
!!(Flags & QUIC_STREAM_OPEN_FLAG_0_RTT),
667-
(QUIC_STREAM**)NewStream);
661+
Status = QuicStreamInitialize(Connection, FALSE, Flags, (QUIC_STREAM**)NewStream);
668662
if (QUIC_FAILED(Status)) {
669663
goto Error;
670664
}

src/core/stream.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ QUIC_STATUS
2020
QuicStreamInitialize(
2121
_In_ QUIC_CONNECTION* Connection,
2222
_In_ BOOLEAN OpenedRemotely,
23-
_In_ BOOLEAN Unidirectional,
24-
_In_ BOOLEAN Opened0Rtt,
23+
_In_ QUIC_STREAM_OPEN_FLAGS Flags,
2524
_Outptr_ _At_(*NewStream, __drv_allocatesMem(Mem))
2625
QUIC_STREAM** NewStream
2726
)
@@ -55,8 +54,15 @@ QuicStreamInitialize(
5554
Stream->Type = QUIC_HANDLE_TYPE_STREAM;
5655
Stream->Connection = Connection;
5756
Stream->ID = UINT64_MAX;
58-
Stream->Flags.Unidirectional = Unidirectional;
59-
Stream->Flags.Opened0Rtt = Opened0Rtt;
57+
Stream->Flags.Unidirectional = !!(Flags & QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL);
58+
Stream->Flags.Opened0Rtt = !!(Flags & QUIC_STREAM_OPEN_FLAG_0_RTT);
59+
Stream->Flags.DelayIdFcUpdate = !!(Flags & QUIC_STREAM_OPEN_FLAG_DELAY_ID_FC_UPDATES);
60+
if (Stream->Flags.DelayIdFcUpdate) {
61+
QuicTraceLogStreamVerbose(
62+
ConfiguredForDelayedIDFC,
63+
Stream,
64+
"Configured for delayed ID FC updates");
65+
}
6066
Stream->Flags.Allocated = TRUE;
6167
Stream->Flags.SendEnabled = TRUE;
6268
Stream->Flags.ReceiveEnabled = TRUE;
@@ -73,7 +79,7 @@ QuicStreamInitialize(
7379
Stream->RefTypeCount[QUIC_STREAM_REF_APP] = 1;
7480
#endif
7581

76-
if (Unidirectional) {
82+
if (Stream->Flags.Unidirectional) {
7783
if (!OpenedRemotely) {
7884

7985
//
@@ -354,7 +360,7 @@ QuicStreamClose(
354360

355361
if (!Stream->Flags.ShutdownComplete) {
356362

357-
if (Stream->Flags.Started) {
363+
if (Stream->Flags.Started && !Stream->Flags.HandleShutdown) {
358364
//
359365
// TODO - If the stream hasn't been aborted already, then this is a
360366
// fatal error for the connection. The QUIC transport cannot "just
@@ -384,9 +390,17 @@ QuicStreamClose(
384390
// since nothing else can be done with it now.
385391
//
386392
Stream->Flags.ShutdownComplete = TRUE;
393+
CXPLAT_DBG_ASSERT(!Stream->Flags.InStreamTable);
387394
}
388395
}
389396

397+
if (Stream->Flags.DelayIdFcUpdate && Stream->Flags.ShutdownComplete) {
398+
//
399+
// Indicate the stream is completely shut down to the connection.
400+
//
401+
QuicStreamSetReleaseStream(&Stream->Connection->Streams, Stream);
402+
}
403+
390404
Stream->ClientCallbackHandler = NULL;
391405

392406
QuicStreamRelease(Stream, QUIC_STREAM_REF_APP);
@@ -593,7 +607,9 @@ QuicStreamTryCompleteShutdown(
593607
//
594608
// Indicate the stream is completely shut down to the connection.
595609
//
596-
QuicStreamSetReleaseStream(&Stream->Connection->Streams, Stream);
610+
if (!Stream->Flags.DelayIdFcUpdate || Stream->Flags.HandleClosed) {
611+
QuicStreamSetReleaseStream(&Stream->Connection->Streams, Stream);
612+
}
597613
}
598614
}
599615

src/core/stream.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ typedef union QUIC_STREAM_FLAGS {
151151
BOOLEAN Freed : 1; // Freed after last ref count released. Used for Debugging.
152152

153153
BOOLEAN InStreamTable : 1; // The stream is currently in the connection's table.
154+
BOOLEAN DelayIdFcUpdate : 1; // Delay stream ID FC updates to StreamClose.
154155
};
155156
} QUIC_STREAM_FLAGS;
156157

@@ -530,8 +531,7 @@ QUIC_STATUS
530531
QuicStreamInitialize(
531532
_In_ QUIC_CONNECTION* Connection,
532533
_In_ BOOLEAN OpenedRemotely,
533-
_In_ BOOLEAN Unidirectional,
534-
_In_ BOOLEAN Opened0Rtt,
534+
_In_ QUIC_STREAM_OPEN_FLAGS Flags,
535535
_Outptr_ _At_(*Stream, __drv_allocatesMem(Mem))
536536
QUIC_STREAM** Stream
537537
);

src/core/stream_set.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -658,14 +658,16 @@ QuicStreamSetGetStreamForPeer(
658658
// Calculate the next Stream ID.
659659
//
660660
uint64_t NewStreamId = StreamType + (Info->TotalStreamCount << 2);
661+
QUIC_STREAM_OPEN_FLAGS OpenFlags = QUIC_STREAM_OPEN_FLAG_NONE;
662+
if (STREAM_ID_IS_UNI_DIR(StreamId)) {
663+
OpenFlags |= QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL;
664+
}
665+
if (FrameIn0Rtt) {
666+
OpenFlags |= QUIC_STREAM_OPEN_FLAG_0_RTT;
667+
}
661668

662669
QUIC_STATUS Status =
663-
QuicStreamInitialize(
664-
Connection,
665-
TRUE,
666-
STREAM_ID_IS_UNI_DIR(StreamId), // Unidirectional
667-
FrameIn0Rtt, // Opened0Rtt
668-
&Stream);
670+
QuicStreamInitialize(Connection, TRUE, OpenFlags, &Stream);
669671
if (QUIC_FAILED(Status)) {
670672
*FatalError = TRUE;
671673
QuicConnTransportError(Connection, QUIC_ERROR_INTERNAL_ERROR);
@@ -721,6 +723,13 @@ QuicStreamSetGetStreamForPeer(
721723
CXPLAT_FRE_ASSERTMSG(
722724
Stream->ClientCallbackHandler != NULL,
723725
"App MUST set callback handler!");
726+
if (Event.PEER_STREAM_STARTED.Flags & QUIC_STREAM_OPEN_FLAG_DELAY_ID_FC_UPDATES) {
727+
Stream->Flags.DelayIdFcUpdate = TRUE;
728+
QuicTraceLogStreamVerbose(
729+
ConfiguredForDelayedIDFC,
730+
Stream,
731+
"Configured for delayed ID FC updates");
732+
}
724733
}
725734

726735
} while (Info->TotalStreamCount != StreamCount);

src/cs/lib/msquic_generated.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ internal enum QUIC_STREAM_OPEN_FLAGS
151151
NONE = 0x0000,
152152
UNIDIRECTIONAL = 0x0001,
153153
ZERO_RTT = 0x0002,
154+
DELAY_ID_FC_UPDATES = 0x0004,
154155
}
155156

156157
[System.Flags]

src/generated/linux/stream.c.clog.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,24 @@ tracepoint(CLOG_STREAM_C, UpdatePriority , arg1, arg3);\
8989

9090

9191

92+
/*----------------------------------------------------------
93+
// Decoder Ring for ConfiguredForDelayedIDFC
94+
// [strm][%p] Configured for delayed ID FC updates
95+
// QuicTraceLogStreamVerbose(
96+
ConfiguredForDelayedIDFC,
97+
Stream,
98+
"Configured for delayed ID FC updates");
99+
// arg1 = arg1 = Stream = arg1
100+
----------------------------------------------------------*/
101+
#ifndef _clog_3_ARGS_TRACE_ConfiguredForDelayedIDFC
102+
#define _clog_3_ARGS_TRACE_ConfiguredForDelayedIDFC(uniqueId, arg1, encoded_arg_string)\
103+
tracepoint(CLOG_STREAM_C, ConfiguredForDelayedIDFC , arg1);\
104+
105+
#endif
106+
107+
108+
109+
92110
/*----------------------------------------------------------
93111
// Decoder Ring for IndicateStartComplete
94112
// [strm][%p] Indicating QUIC_STREAM_EVENT_START_COMPLETE [Status=0x%x ID=%llu Accepted=%hhu]

src/generated/linux/stream.c.clog.h.lttng.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,25 @@ TRACEPOINT_EVENT(CLOG_STREAM_C, UpdatePriority,
6262

6363

6464

65+
/*----------------------------------------------------------
66+
// Decoder Ring for ConfiguredForDelayedIDFC
67+
// [strm][%p] Configured for delayed ID FC updates
68+
// QuicTraceLogStreamVerbose(
69+
ConfiguredForDelayedIDFC,
70+
Stream,
71+
"Configured for delayed ID FC updates");
72+
// arg1 = arg1 = Stream = arg1
73+
----------------------------------------------------------*/
74+
TRACEPOINT_EVENT(CLOG_STREAM_C, ConfiguredForDelayedIDFC,
75+
TP_ARGS(
76+
const void *, arg1),
77+
TP_FIELDS(
78+
ctf_integer_hex(uint64_t, arg1, arg1)
79+
)
80+
)
81+
82+
83+
6584
/*----------------------------------------------------------
6685
// Decoder Ring for IndicateStartComplete
6786
// [strm][%p] Indicating QUIC_STREAM_EVENT_START_COMPLETE [Status=0x%x ID=%llu Accepted=%hhu]

src/generated/linux/stream_set.c.clog.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,24 @@ tracepoint(CLOG_STREAM_SET_C, IndicatePeerAccepted , arg1);\
7575

7676

7777

78+
/*----------------------------------------------------------
79+
// Decoder Ring for ConfiguredForDelayedIDFC
80+
// [strm][%p] Configured for delayed ID FC updates
81+
// QuicTraceLogStreamVerbose(
82+
ConfiguredForDelayedIDFC,
83+
Stream,
84+
"Configured for delayed ID FC updates");
85+
// arg1 = arg1 = Stream = arg1
86+
----------------------------------------------------------*/
87+
#ifndef _clog_3_ARGS_TRACE_ConfiguredForDelayedIDFC
88+
#define _clog_3_ARGS_TRACE_ConfiguredForDelayedIDFC(uniqueId, arg1, encoded_arg_string)\
89+
tracepoint(CLOG_STREAM_SET_C, ConfiguredForDelayedIDFC , arg1);\
90+
91+
#endif
92+
93+
94+
95+
7896
/*----------------------------------------------------------
7997
// Decoder Ring for MaxStreamCountUpdated
8098
// [conn][%p] App configured max stream count of %hu (type=%hhu).

0 commit comments

Comments
 (0)