]> git.feebdaed.xyz Git - 0xmirror/msquic.git/commitdiff
Add detailed Configuration reference tracking (#5574)
authorAnthony Rossi <41394064+anrossi@users.noreply.github.com>
Thu, 13 Nov 2025 13:06:39 +0000 (05:06 -0800)
committerGitHub <noreply@github.com>
Thu, 13 Nov 2025 13:06:39 +0000 (13:06 +0000)
## Description

Add detailed reference tracking to the Configuration object.

## Testing

CI

## Documentation

N/A

src/core/api.c
src/core/configuration.c
src/core/configuration.h
src/core/connection.c
src/core/operation.c

index ce9f2ab5fa758e71f4b734f0d8aa2431da3993fc..8bf71553b08a6298fc3ffd69e33c1fcc9942e4fc 100644 (file)
@@ -444,7 +444,7 @@ MsQuicConnectionStart(
         goto Error;
     }
 
-    QuicConfigurationAddRef(Configuration);
+    QuicConfigurationAddRef(Configuration, QUIC_CONF_REF_CONN_START_OP);
     Oper->API_CALL.Context->Type = QUIC_API_TYPE_CONN_START;
     Oper->API_CALL.Context->CONN_START.Configuration = Configuration;
     Oper->API_CALL.Context->CONN_START.ServerName = ServerNameCopy;
@@ -543,7 +543,7 @@ MsQuicConnectionSetConfiguration(
         goto Error;
     }
 
-    QuicConfigurationAddRef(Configuration);
+    QuicConfigurationAddRef(Configuration, QUIC_CONF_REF_CONN_SET_OP);
     Oper->API_CALL.Context->Type = QUIC_API_TYPE_CONN_SET_CONFIGURATION;
     Oper->API_CALL.Context->CONN_SET_CONFIGURATION.Configuration = Configuration;
 
index 96653ecf104235ed98c194f28e198d9fef29b73a..0033f0ff6051ed8044931eeb1a86d0d81407fb65 100644 (file)
@@ -84,6 +84,10 @@ MsQuicConfigurationOpen(
     Configuration->ClientContext = Context;
     Configuration->Registration = Registration;
     CxPlatRefInitialize(&Configuration->RefCount);
+#if DEBUG
+    CxPlatRefInitializeMultiple(Configuration->RefTypeBiasedCount, QUIC_CONF_REF_COUNT);
+    CxPlatRefIncrement(&Configuration->RefTypeBiasedCount[QUIC_CONF_REF_HANDLE]);
+#endif
 
     Configuration->AlpnListLength = (uint16_t)AlpnListLength;
     AlpnList = Configuration->AlpnList;
@@ -208,6 +212,9 @@ MsQuicConfigurationOpen(
 Error:
 
     if (QUIC_FAILED(Status) && Configuration != NULL) {
+#if DEBUG
+        CXPLAT_DBG_ASSERT(!CxPlatRefDecrement(&Configuration->RefTypeBiasedCount[QUIC_CONF_REF_HANDLE]));
+#endif
         CxPlatStorageClose(Configuration->AppSpecificStorage);
 #ifdef QUIC_SILO
         CxPlatStorageClose(Configuration->Storage);
@@ -259,6 +266,12 @@ QuicConfigurationUninitialize(
 
     QuicRegistrationRundownRelease(Configuration->Registration, QUIC_REG_REF_CONFIGURATION);
 
+#if DEBUG
+    for (uint32_t i = 0; i < QUIC_CONF_REF_COUNT; i++) {
+        CXPLAT_DBG_ASSERT(QuicReadLongPtrNoFence(&Configuration->RefTypeBiasedCount[i]) == 1);
+    }
+#endif
+
     QuicTraceEvent(
         ConfigurationDestroyed,
         "[cnfg][%p] Destroyed",
@@ -282,7 +295,7 @@ MsQuicConfigurationClose(
 
     if (Handle != NULL && Handle->Type == QUIC_HANDLE_TYPE_CONFIGURATION) {
 #pragma prefast(suppress: __WARNING_25024, "Pointer cast already validated.")
-        QuicConfigurationRelease((QUIC_CONFIGURATION*)Handle);
+        QuicConfigurationRelease((QUIC_CONFIGURATION*)Handle, QUIC_CONF_REF_HANDLE);
     }
 
     QuicTraceEvent(
@@ -319,7 +332,7 @@ MsQuicConfigurationLoadCredentialComplete(
             (HQUIC)Configuration,
             Configuration->ClientContext,
             Status);
-        QuicConfigurationRelease(Configuration);
+        QuicConfigurationRelease(Configuration, QUIC_CONF_REF_LOAD_CRED);
     }
 }
 
@@ -351,7 +364,7 @@ MsQuicConfigurationLoadCredential(
             TlsCredFlags |= CXPLAT_TLS_CREDENTIAL_FLAG_DISABLE_RESUMPTION;
         }
 
-        QuicConfigurationAddRef(Configuration);
+        QuicConfigurationAddRef(Configuration, QUIC_CONF_REF_LOAD_CRED);
 
         Status =
             CxPlatTlsSecConfigCreate(
@@ -365,7 +378,7 @@ MsQuicConfigurationLoadCredential(
             //
             // Release ref for synchronous calls or asynchronous failures.
             //
-            QuicConfigurationRelease(Configuration);
+            QuicConfigurationRelease(Configuration, QUIC_CONF_REF_LOAD_CRED);
         }
     }
 
index c8fec06e39aca952633ceeae0198cb79294060ba..dd1a2bc31c345d6ef73c7f88313c4db2f483786b 100644 (file)
@@ -5,6 +5,20 @@
 
 --*/
 
+//
+// The different kinds of references on a Configuration.
+//
+typedef enum QUIC_CONFIGURATION_REF {
+
+    QUIC_CONF_REF_HANDLE,
+    QUIC_CONF_REF_CONNECTION,
+    QUIC_CONF_REF_LOAD_CRED,
+    QUIC_CONF_REF_CONN_START_OP,
+    QUIC_CONF_REF_CONN_SET_OP,
+
+    QUIC_CONF_REF_COUNT
+} QUIC_CONFIGURATION_REF;
+
 //
 // Represents a set of TLS and QUIC configurations and settings.
 //
@@ -31,6 +45,15 @@ typedef struct QUIC_CONFIGURATION {
     //
     CXPLAT_REF_COUNT RefCount;
 
+#if DEBUG
+    //
+    // Detailed ref counts.
+    // Note: These ref counts are biased by 1, so lowest they go is 1. It is an
+    // error for them to ever be zero.
+    //
+    CXPLAT_REF_COUNT RefTypeBiasedCount[QUIC_CONF_REF_COUNT];
+#endif
+
     //
     // The TLS security configurations.
     //
@@ -106,10 +129,16 @@ QuicConfigurationUninitialize(
 QUIC_INLINE
 void
 QuicConfigurationAddRef(
-    _In_ QUIC_CONFIGURATION* Configuration
+    _In_ QUIC_CONFIGURATION* Configuration,
+    _In_ QUIC_CONFIGURATION_REF Ref
     )
 {
     CxPlatRefIncrement(&Configuration->RefCount);
+#if DEBUG
+    CxPlatRefIncrement(&Configuration->RefTypeBiasedCount[Ref]);
+#else
+    UNREFERENCED_PARAMETER(Ref);
+#endif
 }
 
 //
@@ -118,9 +147,15 @@ QuicConfigurationAddRef(
 QUIC_INLINE
 void
 QuicConfigurationRelease(
-    _In_ QUIC_CONFIGURATION* Configuration
+    _In_ QUIC_CONFIGURATION* Configuration,
+    _In_ QUIC_CONFIGURATION_REF Ref
     )
 {
+#if DEBUG
+    CXPLAT_DBG_ASSERT(!CxPlatRefDecrement(&Configuration->RefTypeBiasedCount[Ref]));
+#else
+    UNREFERENCED_PARAMETER(Ref);
+#endif
     if (CxPlatRefDecrement(&Configuration->RefCount)) {
         QuicConfigurationUninitialize(Configuration);
     }
index 1bae7707242deaf61e1527e1b0bf4daeb5a872c0..41b01449ab1f821e9a42a51cfe7722898f1e3889 100644 (file)
@@ -383,7 +383,7 @@ QuicConnFree(
         Silo = Connection->Configuration->Silo;
         QuicSiloAddRef(Silo);
 #endif
-        QuicConfigurationRelease(Connection->Configuration);
+        QuicConfigurationRelease(Connection->Configuration, QUIC_CONF_REF_CONNECTION);
         Connection->Configuration = NULL;
     }
     if (Connection->RemoteServerName != NULL) {
@@ -2480,7 +2480,7 @@ QuicConnSetConfiguration(
         "Configuration set, %p",
         Configuration);
 
-    QuicConfigurationAddRef(Configuration);
+    QuicConfigurationAddRef(Configuration, QUIC_CONF_REF_CONNECTION);
     QuicConfigurationAttachSilo(Configuration);
     Connection->Configuration = Configuration;
 
index 0270f9ea71fb9dd1cf3fe57d0b7f584e773d8654..c0541a0d36991650883db2bc4e776460835e54c9 100644 (file)
@@ -95,12 +95,12 @@ QuicOperationFree(
     if (Oper->Type == QUIC_OPER_TYPE_API_CALL) {
         QUIC_API_CONTEXT* ApiCtx = Oper->API_CALL.Context;
         if (ApiCtx->Type == QUIC_API_TYPE_CONN_START) {
-            QuicConfigurationRelease(ApiCtx->CONN_START.Configuration);
+            QuicConfigurationRelease(ApiCtx->CONN_START.Configuration, QUIC_CONF_REF_CONN_START_OP);
             if (ApiCtx->CONN_START.ServerName != NULL) {
                 CXPLAT_FREE(ApiCtx->CONN_START.ServerName, QUIC_POOL_SERVERNAME);
             }
         } else if (ApiCtx->Type == QUIC_API_TYPE_CONN_SET_CONFIGURATION) {
-            QuicConfigurationRelease(ApiCtx->CONN_SET_CONFIGURATION.Configuration);
+            QuicConfigurationRelease(ApiCtx->CONN_SET_CONFIGURATION.Configuration, QUIC_CONF_REF_CONN_SET_OP);
         } else if (ApiCtx->Type == QUIC_API_TYPE_CONN_SEND_RESUMPTION_TICKET) {
             if (ApiCtx->CONN_SEND_RESUMPTION_TICKET.ResumptionAppData != NULL) {
                 CXPLAT_DBG_ASSERT(ApiCtx->CONN_SEND_RESUMPTION_TICKET.AppDataLength != 0);