From 7e999542a9dad68617b90e22343923bdda3a6f80 Mon Sep 17 00:00:00 2001 From: Maria Sharabayko Date: Thu, 25 Mar 2021 16:32:59 +0100 Subject: [PATCH] Final changes after review --- srtcore/core.cpp | 20 ++++-- srtcore/core.h | 170 +++++++++++++++++++++++------------------------ srtcore/window.h | 10 +-- 3 files changed, 103 insertions(+), 97 deletions(-) diff --git a/srtcore/core.cpp b/srtcore/core.cpp index ffa1869b6..3ce3be4f0 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -8204,21 +8204,27 @@ void CUDT::processCtrl(const CPacket &ctrlpkt) if (rtt == -1) { + if (ctrlpkt.getAckSeqNo() > (m_iAckSeqNo - static_cast(ACK_WND_SIZE)) && ctrlpkt.getAckSeqNo() <= m_iAckSeqNo) + { + LOGC(inlog.Warn, + log << CONID() << "ACKACK out of order, skipping RTT calculation " + << "(ACK number: " << ctrlpkt.getAckSeqNo() << ", last ACK sent: " << m_iAckSeqNo + << ", RTT (EWMA): " << m_iRTT << ")"); + break; + } + LOGC(inlog.Error, - log << CONID() << "IPE: The record about ACK is not found, " - << "RTT estimate at the receiver side can not be calculated " + log << CONID() << "IPE: ACK record not found, RTT estimate impossible " << "(ACK number: " << ctrlpkt.getAckSeqNo() << ", last ACK sent: " << m_iAckSeqNo - << ", oldest ACK record: " << "not yet available" << ", RTT (EWMA): " << m_iRTT << ")"); + << ", RTT (EWMA): " << m_iRTT << ")"); break; } if (rtt <= 0) { LOGC(inlog.Error, - log << CONID() << "IPE: RTT estimate obtained by the receiver is negative or zero, " - << "there may have been a time shift " - << "(current time: " << FormatTime(currtime) << ", the time of sending ACK: " << "not yet available" - << ", RTT estimate: " << rtt << "). The usage of monotonic clocks is recommended. "); + log << CONID() << "IPE: invalid RTT estimate " << rtt + << ", possible time shift. Clock: " << SRT_SYNC_CLOCK_STR); break; } diff --git a/srtcore/core.h b/srtcore/core.h index 0a4c2d86d..9ee3df6d7 100644 --- a/srtcore/core.h +++ b/srtcore/core.h @@ -259,23 +259,22 @@ class CUDT } }; - static const SRTSOCKET INVALID_SOCK = -1; // invalid socket descriptor - static const int ERROR = -1; // socket api error returned value + static const SRTSOCKET INVALID_SOCK = -1; // Invalid socket descriptor + static const int ERROR = -1; // Socket api error returned value static const int HS_VERSION_UDT4 = 4; static const int HS_VERSION_SRT1 = 5; // Parameters // - // Note: use notation with X*1000*1000* ... instead of million zeros in a row. - // In C++17 there is a possible notation of 5'000'000 for convenience, but that's - // something only for a far future. - static const int COMM_RESPONSE_MAX_EXP = 16; - static const int SRT_TLPKTDROP_MINTHRESHOLD_MS = 1000; - static const uint64_t COMM_KEEPALIVE_PERIOD_US = 1*1000*1000; - static const int32_t COMM_SYN_INTERVAL_US = 10*1000; - static const int COMM_CLOSE_BROKEN_LISTENER_TIMEOUT_MS = 3000; - static const uint16_t MAX_WEIGHT = 32767; + // Note: use notation with X*1000*1000*... instead of million zeros in a row + static const int COMM_RESPONSE_MAX_EXP = 16; + static const int SRT_TLPKTDROP_MINTHRESHOLD_MS = 1000; + static const uint64_t COMM_KEEPALIVE_PERIOD_US = 1*1000*1000; + static const int32_t COMM_SYN_INTERVAL_US = 10*1000; + static const int COMM_CLOSE_BROKEN_LISTENER_TIMEOUT_MS = 3000; + static const uint16_t MAX_WEIGHT = 32767; + static const size_t ACK_WND_SIZE = 1024; int handshakeVersion() { @@ -295,37 +294,38 @@ class CUDT SRTSOCKET socketID() const { return m_SocketID; } - static CUDT* getUDTHandle(SRTSOCKET u); - static std::vector existingSockets(); + static CUDT* getUDTHandle(SRTSOCKET u); + static std::vector existingSockets(); void addressAndSend(CPacket& pkt); void sendSrtMsg(int cmd, uint32_t *srtdata_in = NULL, size_t srtlen_in = 0); - bool isOPT_TsbPd() const { return m_config.bTSBPD; } - int RTT() const { return m_iRTT; } - int RTTVar() const { return m_iRTTVar; } - int32_t sndSeqNo() const { return m_iSndCurrSeqNo; } - int32_t schedSeqNo() const { return m_iSndNextSeqNo; } - bool overrideSndSeqNo(int32_t seq); - srt::sync::steady_clock::time_point lastRspTime() const { return m_tsLastRspTime; } - srt::sync::steady_clock::time_point freshActivationStart() const { return m_tsFreshActivation; } - - int32_t rcvSeqNo() const { return m_iRcvCurrSeqNo; } - int flowWindowSize() const { return m_iFlowWindowSize; } - int32_t deliveryRate() const { return m_iDeliveryRate; } - int bandwidth() const { return m_iBandwidth; } - int64_t maxBandwidth() const { return m_config.llMaxBW; } - int MSS() const { return m_config.iMSS; } - - uint32_t peerLatency_us() const {return m_iPeerTsbPdDelay_ms * 1000; } - int peerIdleTimeout_ms() const { return m_config.iPeerIdleTimeout; } - size_t maxPayloadSize() const { return m_iMaxSRTPayloadSize; } - size_t OPT_PayloadSize() const { return m_config.zExpPayloadSize; } - int sndLossLength() { return m_pSndLossList->getLossLength(); } - int32_t ISN() const { return m_iISN; } - int32_t peerISN() const { return m_iPeerISN; } - duration minNAKInterval() const { return m_tdMinNakInterval; } - sockaddr_any peerAddr() const { return m_PeerAddr; } + bool isOPT_TsbPd() const { return m_config.bTSBPD; } + int RTT() const { return m_iRTT; } + int RTTVar() const { return m_iRTTVar; } + int32_t sndSeqNo() const { return m_iSndCurrSeqNo; } + int32_t schedSeqNo() const { return m_iSndNextSeqNo; } + bool overrideSndSeqNo(int32_t seq); + + srt::sync::steady_clock::time_point lastRspTime() const { return m_tsLastRspTime; } + srt::sync::steady_clock::time_point freshActivationStart() const { return m_tsFreshActivation; } + + int32_t rcvSeqNo() const { return m_iRcvCurrSeqNo; } + int flowWindowSize() const { return m_iFlowWindowSize; } + int32_t deliveryRate() const { return m_iDeliveryRate; } + int bandwidth() const { return m_iBandwidth; } + int64_t maxBandwidth() const { return m_config.llMaxBW; } + int MSS() const { return m_config.iMSS; } + + uint32_t peerLatency_us() const { return m_iPeerTsbPdDelay_ms * 1000; } + int peerIdleTimeout_ms() const { return m_config.iPeerIdleTimeout; } + size_t maxPayloadSize() const { return m_iMaxSRTPayloadSize; } + size_t OPT_PayloadSize() const { return m_config.zExpPayloadSize; } + int sndLossLength() { return m_pSndLossList->getLossLength(); } + int32_t ISN() const { return m_iISN; } + int32_t peerISN() const { return m_iPeerISN; } + duration minNAKInterval() const { return m_tdMinNakInterval; } + sockaddr_any peerAddr() const { return m_PeerAddr; } /// Returns the number of packets in flight (sent, but not yet acknowledged). /// @param lastack is the sequence number of the first unacknowledged packet. @@ -691,28 +691,28 @@ class CUDT static loss_seqs_t defaultPacketArrival(void* vself, CPacket& pkt); static loss_seqs_t groupPacketArrival(void* vself, CPacket& pkt); - static CUDTUnited s_UDTUnited; // UDT global management base + static CUDTUnited s_UDTUnited; // UDT global management base private: // Identification - CUDTSocket* const m_parent; // temporary, until the CUDTSocket class is merged with CUDT - SRTSOCKET m_SocketID; // UDT socket number - SRTSOCKET m_PeerID; // peer id, for multiplexer + CUDTSocket* const m_parent; // Temporary, until the CUDTSocket class is merged with CUDT + SRTSOCKET m_SocketID; // UDT socket number + SRTSOCKET m_PeerID; // Peer ID, for multiplexer // HSv4 (legacy handshake) support) - time_point m_tsSndHsLastTime; //Last SRT handshake request time - int m_iSndHsRetryCnt; //SRT handshake retries left + time_point m_tsSndHsLastTime; // Last SRT handshake request time + int m_iSndHsRetryCnt; // SRT handshake retries left #if ENABLE_EXPERIMENTAL_BONDING - SRT_GROUP_TYPE m_HSGroupType; // group type about-to-be-set in the handshake + SRT_GROUP_TYPE m_HSGroupType; // Group type about-to-be-set in the handshake #endif private: - int m_iMaxSRTPayloadSize; // Maximum/regular payload size, in bytes - int m_iTsbPdDelay_ms; // Rx delay to absorb burst in milliseconds - int m_iPeerTsbPdDelay_ms; // Tx delay that the peer uses to absorb burst in milliseconds - bool m_bTLPktDrop; // Enable Too-late Packet Drop - UniquePtr m_pCryptoControl; // congestion control SRT class (small data extension) - CCache* m_pCache; // network information cache + int m_iMaxSRTPayloadSize; // Maximum/regular payload size, in bytes + int m_iTsbPdDelay_ms; // Rx delay to absorb burst, in milliseconds + int m_iPeerTsbPdDelay_ms; // Tx delay that the peer uses to absorb burst, in milliseconds + bool m_bTLPktDrop; // Enable Too-late Packet Drop + UniquePtr m_pCryptoControl; // Congestion control SRT class (small data extension) + CCache* m_pCache; // Network information cache // Congestion control std::vector m_Slots[TEV_E_SIZE]; @@ -727,7 +727,7 @@ class CUDT void EmitSignal(ETransmissionEvent tev, EventVariant var); // Internal state - volatile bool m_bListening; // If the UDT entit is listening to connection + volatile bool m_bListening; // If the UDT entity is listening to connection volatile bool m_bConnecting; // The short phase when connect() is called but not yet completed volatile bool m_bConnected; // Whether the connection is on or off volatile bool m_bClosing; // If the UDT entity is closing @@ -736,7 +736,7 @@ class CUDT volatile bool m_bPeerHealth; // If the peer status is normal volatile int m_RejectReason; bool m_bOpened; // If the UDT entity has been opened - int m_iBrokenCounter; // a counter (number of GC checks) to let the GC tag this socket as disconnected + int m_iBrokenCounter; // A counter (number of GC checks) to let the GC tag this socket as disconnected int m_iEXPCount; // Expiration counter int m_iBandwidth; // Estimated bandwidth, number of packets per second @@ -746,8 +746,8 @@ class CUDT int m_iByteDeliveryRate; // Byte arrival rate at the receiver side - CHandShake m_ConnReq; // connection request - CHandShake m_ConnRes; // connection response + CHandShake m_ConnReq; // Connection request + CHandShake m_ConnRes; // Connection response CHandShake::RendezvousState m_RdvState; // HSv5 rendezvous state HandshakeSide m_SrtHsSide; // HSv5 rendezvous handshake side resolved from cookie contest (DRAW if not yet resolved) @@ -758,32 +758,32 @@ class CUDT /*volatile*/ duration m_tdSendInterval; // Inter-packet time, in CPU clock cycles - /*volatile*/ duration m_tdSendTimeDiff; // aggregate difference in inter-packet sending time + /*volatile*/ duration m_tdSendTimeDiff; // Aggregate difference in inter-packet sending time volatile int m_iFlowWindowSize; // Flow control window size - volatile double m_dCongestionWindow; // congestion window size + volatile double m_dCongestionWindow; // Congestion window size private: // Timers - /*volatile*/ time_point m_tsNextACKTime; // Next ACK time, in CPU clock cycles, same below - /*volatile*/ time_point m_tsNextNAKTime; // Next NAK time - - /*volatile*/ duration m_tdACKInterval; // ACK interval - /*volatile*/ duration m_tdNAKInterval; // NAK interval - /*volatile*/ time_point m_tsLastRspTime; // time stamp of last response from the peer - /*volatile*/ time_point m_tsLastRspAckTime; // time stamp of last ACK from the peer - /*volatile*/ time_point m_tsLastSndTime; // time stamp of last data/ctrl sent (in system ticks) - time_point m_tsLastWarningTime; // Last time that a warning message is sent - time_point m_tsLastReqTime; // last time when a connection request is sent + /*volatile*/ time_point m_tsNextACKTime; // Next ACK time, in CPU clock cycles, same below + /*volatile*/ time_point m_tsNextNAKTime; // Next NAK time + + /*volatile*/ duration m_tdACKInterval; // ACK interval + /*volatile*/ duration m_tdNAKInterval; // NAK interval + /*volatile*/ time_point m_tsLastRspTime; // Timestamp of last response from the peer + /*volatile*/ time_point m_tsLastRspAckTime; // Timestamp of last ACK from the peer + /*volatile*/ time_point m_tsLastSndTime; // Timestamp of last data/ctrl sent (in system ticks) + time_point m_tsLastWarningTime; // Last time that a warning message is sent + time_point m_tsLastReqTime; // last time when a connection request is sent time_point m_tsRcvPeerStartTime; - time_point m_tsLingerExpiration; // Linger expiration time (for GC to close a socket with data in sending buffer) - time_point m_tsLastAckTime; // Timestamp of last ACK - duration m_tdMinNakInterval; // NAK timeout lower bound; too small value can cause unnecessary retransmission - duration m_tdMinExpInterval; // timeout lower bound threshold: too small timeout can cause problem + time_point m_tsLingerExpiration; // Linger expiration time (for GC to close a socket with data in sending buffer) + time_point m_tsLastAckTime; // Timestamp of last ACK + duration m_tdMinNakInterval; // NAK timeout lower bound; too small value can cause unnecessary retransmission + duration m_tdMinExpInterval; // Timeout lower bound threshold: too small timeout can cause problem - int m_iPktCount; // packet counter for ACK - int m_iLightACKCount; // light ACK counter + int m_iPktCount; // Packet counter for ACK + int m_iLightACKCount; // Light ACK counter - time_point m_tsNextSendTime; // scheduled time of next packet sending + time_point m_tsNextSendTime; // Scheduled time of next packet sending volatile int32_t m_iSndLastFullAck; // Last full ACK received volatile int32_t m_iSndLastAck; // Last ACK received @@ -843,17 +843,17 @@ class CUDT int32_t m_iReXmitCount; // Re-Transmit Count since last ACK private: // Receiving related data - CRcvBuffer* m_pRcvBuffer; //< Receiver buffer - CRcvLossList* m_pRcvLossList; //< Receiver loss list - std::deque m_FreshLoss; //< Lost sequence already added to m_pRcvLossList, but not yet sent UMSG_LOSSREPORT for. - int m_iReorderTolerance; //< Current value of dynamic reorder tolerance - int m_iConsecEarlyDelivery; //< Increases with every OOO packet that came m_FreshLoss; // Lost sequence already added to m_pRcvLossList, but not yet sent UMSG_LOSSREPORT for. + int m_iReorderTolerance; // Current value of dynamic reorder tolerance + int m_iConsecEarlyDelivery; // Increases with every OOO packet that came m_ACKWindow; //< ACK history window - CPktTimeWindow<16, 64> m_RcvTimeWindow; //< Packet arrival time window + CACKWindow m_ACKWindow; // ACK history window + CPktTimeWindow<16, 64> m_RcvTimeWindow; // Packet arrival time window - int32_t m_iRcvLastAck; //< Last sent ACK + int32_t m_iRcvLastAck; // Last sent ACK #ifdef ENABLE_LOGGING int32_t m_iDebugPrevLastAck; #endif @@ -869,10 +869,10 @@ class CUDT uint32_t m_uPeerSrtFlags; bool m_bTsbPd; // Peer sends TimeStamp-Based Packet Delivery Packets - bool m_bGroupTsbPd; // TSBPD should be used for GROUP RECEIVER instead. + bool m_bGroupTsbPd; // TSBPD should be used for GROUP RECEIVER instead srt::sync::CThread m_RcvTsbPdThread; // Rcv TsbPD Thread handle - srt::sync::Condition m_RcvTsbPdCond; // TSBPD signals if reading is ready. Use together with m_RecvLock. + srt::sync::Condition m_RcvTsbPdCond; // TSBPD signals if reading is ready. Use together with m_RecvLock bool m_bTsbPdAckWakeup; // Signal TsbPd thread on Ack sent srt::sync::Mutex m_RcvTsbPdStartupLock; // Protects TSBPD thread creating and joining diff --git a/srtcore/window.h b/srtcore/window.h index 614862760..b7f510163 100644 --- a/srtcore/window.h +++ b/srtcore/window.h @@ -326,7 +326,7 @@ class CPktTimeWindow: CPktTimeWindowTools private: int m_aPktWindow[ASIZE]; // Packet information window (inter-packet time) - int m_aBytesWindow[ASIZE]; // + int m_aBytesWindow[ASIZE]; int m_iPktWindowPtr; // Position pointer of the packet info. window mutable srt::sync::Mutex m_lockPktWindow; // Used to synchronize access to the packet window @@ -337,10 +337,10 @@ class CPktTimeWindow: CPktTimeWindowTools int m_iLastSentTime; // Last packet sending time int m_iMinPktSndInt; // Minimum packet sending interval - srt::sync::steady_clock::time_point m_tsLastArrTime; // last packet arrival time - srt::sync::steady_clock::time_point m_tsCurrArrTime; // Current packet arrival time - srt::sync::steady_clock::time_point m_tsProbeTime; // Arrival time of the first probing packet - int32_t m_Probe1Sequence; // Sequence number for which the arrival time was notified + srt::sync::steady_clock::time_point m_tsLastArrTime; // Last packet arrival time + srt::sync::steady_clock::time_point m_tsCurrArrTime; // Current packet arrival time + srt::sync::steady_clock::time_point m_tsProbeTime; // Arrival time of the first probing packet + int32_t m_Probe1Sequence; // Sequence number for which the arrival time was notified private: CPktTimeWindow(const CPktTimeWindow&);