From 49b46b85dc301bfe1f311fcbde4563baa03416b7 Mon Sep 17 00:00:00 2001 From: Fletcher Dunn Date: Wed, 13 Feb 2019 10:16:14 -0800 Subject: [PATCH] Fix bug not initializing data structures early enough. We were initialzing some sentinels and iterators when a connection was established. But these variables are accessed when you just query the state of the connection, which might happen before then. --- .../clientlib/steamnetworkingsockets_snp.cpp | 50 ++++++++++--------- .../clientlib/steamnetworkingsockets_snp.h | 3 ++ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_snp.cpp b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_snp.cpp index 1b47f91..e8981dd 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_snp.cpp +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_snp.cpp @@ -198,34 +198,38 @@ void SSNPSenderState::RemoveAckedReliableMessageFromUnackedList() } } +//----------------------------------------------------------------------------- +SSNPSenderState::SSNPSenderState() +{ + // Setup the table of inflight packets with a sentinel. + m_mapInFlightPacketsByPktNum.clear(); + SNPInFlightPacket_t &sentinel = m_mapInFlightPacketsByPktNum[INT64_MIN]; + sentinel.m_bNack = false; + sentinel.m_usecWhenSent = 0; + m_itNextInFlightPacketToTimeout = m_mapInFlightPacketsByPktNum.end(); +} + +//----------------------------------------------------------------------------- +SSNPReceiverState::SSNPReceiverState() +{ + // Init packet gaps with a sentinel + m_mapPacketGaps.clear(); + SSNPPacketGap &sentinel = m_mapPacketGaps[INT64_MAX]; + sentinel.m_nEnd = INT64_MAX; // Fixed value + sentinel.m_usecWhenOKToNack = INT64_MAX; // Fixed value, for when there is nothing left to nack + sentinel.m_usecWhenAckPrior = INT64_MAX; // Time when we need to flush a report on all lower-numbered packets + + // Point at the sentinel + m_itPendingAck = m_mapPacketGaps.end(); + --m_itPendingAck; + m_itPendingNack = m_itPendingAck; +} + //----------------------------------------------------------------------------- void CSteamNetworkConnectionBase::SNP_InitializeConnection( SteamNetworkingMicroseconds usecNow ) { m_senderState.TokenBucket_Init( usecNow ); - // Setup the table of inflight packets with a sentinel. - { - m_senderState.m_mapInFlightPacketsByPktNum.clear(); - SNPInFlightPacket_t &sentinel = m_senderState.m_mapInFlightPacketsByPktNum[INT64_MIN]; - sentinel.m_bNack = false; - sentinel.m_usecWhenSent = 0; - m_senderState.m_itNextInFlightPacketToTimeout = m_senderState.m_mapInFlightPacketsByPktNum.end(); - } - - // Init packet gaps with a sentinel - { - m_receiverState.m_mapPacketGaps.clear(); - SSNPPacketGap &sentinel = m_receiverState.m_mapPacketGaps[INT64_MAX]; - sentinel.m_nEnd = INT64_MAX; // Fixed value - sentinel.m_usecWhenOKToNack = INT64_MAX; // Fixed value, for when there is nothing left to nack - sentinel.m_usecWhenAckPrior = INT64_MAX; // Time when we need to flush a report on all lower-numbered packets - - // Point at the sentinel - m_receiverState.m_itPendingAck = m_receiverState.m_mapPacketGaps.end(); - --m_receiverState.m_itPendingAck; - m_receiverState.m_itPendingNack = m_receiverState.m_itPendingAck; - } - SteamNetworkingMicroseconds usecPing = GetUsecPingWithFallback( this ); /* diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_snp.h b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_snp.h index 008d29a..e50801d 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_snp.h +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_snp.h @@ -170,6 +170,7 @@ struct SSNPSendMessageList struct SSNPSenderState { + SSNPSenderState(); ~SSNPSenderState() { Reset(); } @@ -350,6 +351,8 @@ struct SSNPPacketGap struct SSNPReceiverState { + SSNPReceiverState(); + /// Unreliable message segments that we have received. When an unreliable message /// needs to be fragmented, we store the pieces here. NOTE: it might be more efficient /// to use a simpler container, with worse O(), since this should ordinarily be