diff --git a/src/core/connection.c b/src/core/connection.c index 85909bf3f3..70fe9425ae 100644 --- a/src/core/connection.c +++ b/src/core/connection.c @@ -990,6 +990,16 @@ QuicConnRetireCid( DestCid->CID.Retired = TRUE; DestCid->CID.NeedsToSend = TRUE; QuicSendSetSendFlag(&Connection->Send, QUIC_CONN_SEND_FLAG_RETIRE_CONNECTION_ID); + + Connection->RetiredDestCidCount++; + if (Connection->RetiredDestCidCount > 8 * QUIC_ACTIVE_CONNECTION_ID_LIMIT) { + QuicTraceEvent( + ConnError, + "[conn][%p] ERROR, %s.", + Connection, + "Peer exceeded retire CID limit"); + QuicConnSilentlyAbort(Connection); + } } _IRQL_requires_max_(PASSIVE_LEVEL) diff --git a/src/core/connection.h b/src/core/connection.h index e149d81d0c..7a327f497e 100644 --- a/src/core/connection.h +++ b/src/core/connection.h @@ -392,6 +392,11 @@ typedef struct QUIC_CONNECTION { // uint8_t DestCidCount; + // + // Number of retired desintation CIDs we currently have cached. + // + uint8_t RetiredDestCidCount; + // // The maximum number of source CIDs to give the peer. This is a minimum of // what we're willing to support and what the peer is willing to accept. diff --git a/src/core/loss_detection.c b/src/core/loss_detection.c index e4356c202a..d8bce352ce 100644 --- a/src/core/loss_detection.c +++ b/src/core/loss_detection.c @@ -608,6 +608,8 @@ QuicLossDetectionOnPacketAcknowledged( CXPLAT_DBG_ASSERT(DestCid->CID.Retired); CXPLAT_DBG_ASSERT(Path == NULL || Path->DestCid != DestCid); QUIC_CID_VALIDATE_NULL(Connection, DestCid); + CXPLAT_DBG_ASSERT(Connection->RetiredDestCidCount > 0); + Connection->RetiredDestCidCount--; CXPLAT_FREE(DestCid, QUIC_POOL_CIDLIST); } break;