Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core] CSndLossList limits the maximum offset #1733

Merged
merged 4 commits into from Jan 14, 2021

Conversation

maxsharabayko
Copy link
Collaborator

Introduction

In runtime, the maximum number of sequence numbers that may be considered lost is limited by the flight span (limited by flow window).

The actual number of items in the sender's loss list may probably be a bit more in the case when sending moved forward, but not all sequences previously reported as lost were retransmitted. Still, most of the operations ensure the loss list is properly updated. For example, CUDT::checkNeedDrop also removes dropped sequence numbers, and m_iSndLastAck ensures old numbers are not added to the list when processing a NAK report.

Anyway, the size of the loss list is set to twice the size of the flow window just in case there would be more elements to store.
m_pSndLossList = new CSndLossList(m_iFlowWindowSize * 2); - link.

What is Fixed

When a new entry is added, it is checked if the offset from the head entry fits the size of the list, which should be more than enough (m_iFlowWindowSize * 2).
Even if there is enough room to add this new entry (e.g. elements coalesced), it must not be allowed to add an entry outside of the valid sequence span.

The corresponding unit test was updated.

Notes

Addresses #1000, #1604.
@alexpokotilo Feel free to join the review.

@maxsharabayko maxsharabayko added Type: Bug Indicates an unexpected problem or unintended behavior [core] Area: Changes in SRT library core labels Jan 11, 2021
@maxsharabayko maxsharabayko added this to the v1.4.3 milestone Jan 11, 2021
@maxsharabayko maxsharabayko marked this pull request as draft January 11, 2021 16:35
@maxsharabayko maxsharabayko marked this pull request as ready for review January 11, 2021 17:22
@@ -123,7 +123,16 @@ int CSndLossList::insert(int32_t seqno1, int32_t seqno2)
// Find the insert position in the non-empty list
const int origlen = m_iLength;
const int offset = CSeqNo::seqoff(m_caSeq[m_iHead].seqstart, seqno1);
int loc = (m_iHead + offset + m_iSize) % m_iSize;

if (offset >= m_iSize)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this check doesn't cover case with seqno2!= seqno1.
E.g is offset < m_iSize but (offset + CSeqNo::seqlen(seqno1, seqno2)) >= m_iSize we should probably
fix seqno2 or fail CSndLossList::insert

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! Inserting a longer range should not produce any issue, but logically should be limited.
At the same time, additional validation of seqno2 might slightly impact the performance of this insert call. 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore this finding then. As I understand we need this quick fix for 1.4.*, but later we will have #1012 finally integrated so we don't have to worry too much about such minor issues.
Please reply my comment below about m_iFlowWindowSize. I think it is more important.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1012 has to be reworked a bit. All entries must be stored in order in the sender loss list. In that PR the insert function tries to loop over the container and find an empty place to store a new entry.

@alexpokotilo
Copy link
Contributor

@maxsharabayko, great fix and I've reviewed and commented it. One question not related to CSendLostList itself: as list is initizlized with m_iFlowWindowSize, is there any check during a handshake preventing us setting m_iFlowWindowSize, to 0, negative or invalid value? I was not able to find such check but probably I'm missing something.

Copy link
Contributor

@alexpokotilo alexpokotilo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maxsharabayko
we need to add following code at the beginning of CSndLossList::insert instead of
SRT_ASSERT(CSeqNo::seqlen(seqno1, seqno2) > 0);

    const int inserted_range = CSeqNo::seqlen(seqno1, seqno2);

    if (seqno1 < 0 || seqno2 < 0 || inserted_range <= 0 || inserted_range >= m_iSize) {
        LOGC(qslog.Error, log << "IPE: Try to insert huge range. " << inserted_range <<  " Ignoring. "
                << "seqno " << seqno1 << ":" << seqno2);
        return 0;
    }

assert is good for debugging but in runtime we need to check these values to prevent issues like
#1604 (comment)

@alexpokotilo
Copy link
Contributor

@maxsharabayko
please also add following test into test_list.cpp

TEST_F(CSndLossListTest, InsertSRT_SEQNO_NONE)
{
    cerr << "Expecting IPE message:" << endl;
    EXPECT_EQ(m_lossList->insert(1, SRT_SEQNO_NONE), 0);
    while(m_lossList->popLostSeq() != -1) {}
}

this test will panic without this fix #1733 (review)

Co-authored-by: Alex Pokotilo <support@wmspanel.com>
@maxsharabayko maxsharabayko merged commit 648e8b5 into Haivision:master Jan 14, 2021
@maxsharabayko maxsharabayko deleted the develop/sndloss-1604 branch January 14, 2021 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[core] Area: Changes in SRT library core Type: Bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants