-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Fix regression (crash) in transport-cc feedback generation #1339
Conversation
- Fixes #1336 ### Details - Regression introduced in PR #1088, which has many issues. - Basically there are cases in which `this->transportCcFeedbackPacket` is reset so it's a complete new packet and hence its `baseSet` is `false`. - However in `TransportCongestionControlServer::FillAndSendTransportCcFeedback()` in which we just call `this->transportCcFeedbackPacket.SetBase()` once at the top, but then we enter a loop in which the packet maybe full so it's sent (or other things) and hence we **reset** the packet while in the loop. And then at the top of the loop `this->transportCcFeedbackPacket.AddPacket()` is called so the assertion fails because its `SetBase()` was not called on that fresh packet. - Also add a missing `break` in a `case` block in that loop. - Also set proper packet count in all cases in which we reset `this->transportCcFeedbackPacket`. ### TODO This is not done yet. The issue is mainly identified but I don't know yet how to properly fix it without doing other wrong things. Basically I'm not sure if the whole logic is ok after PR #1088: - As said before we only set the base of the packet once at the beginning of the loop, and such a `SetBase()` is called with `this->transportCcFeedbackWideSeqNumStart` and a computed `timestamp`. - However, within the loop below, the packet may become full and hence `SendTransportCcFeedback()` is called, which updates `++this->transportCcFeedbackPacketCount` and `this->transportCcFeedbackWideSeqNumStart`, and **also** resets the packet (so missing base again). - So in order to fix the crash, we must call `SetBase()` again, but which which values? Because the values given initially at the top of `TransportCongestionControlServer::FillAndSendTransportCcFeedback()` were the value of `this->transportCcFeedbackWideSeqNumStart` at that time and a timestamp. But that `this->transportCcFeedbackWideSeqNumStart` has now changed, so then what? - Basically every time `this->transportCcFeedbackPacket.reset()` is called (and there are various cases in the whole `TransportCongestionControlServer.cpp` file) **we must** call ``SetBase()` on the fresh packet **with** proper values. And which are those proper values if we are within that loop?
This is a draft PR because I need help. See TODO above. |
I think I know how to solve it properly. Just a question: Does somebody remember what is And why are we setting it when initiating transport server control? /* Instance methods. */
TransportCongestionControlServer::TransportCongestionControlServer(
RTC::TransportCongestionControlServer::Listener* listener,
RTC::BweType bweType,
size_t maxRtcpPacketLen)
: listener(listener), bweType(bweType), maxRtcpPacketLen(maxRtcpPacketLen)
{
MS_TRACE();
switch (this->bweType)
{
case RTC::BweType::TRANSPORT_CC:
{
// Create a feedback packet.
this->transportCcFeedbackPacket.reset(new RTC::RTCP::FeedbackRtpTransportPacket(0u, 0u));
// Set initial packet count.
this->transportCcFeedbackPacket->SetFeedbackPacketCount(this->transportCcFeedbackPacketCount); |
Ah, is the number of CC feedback packet sent, right? so it's just a counter that must be incremented every time a feedback packet is sent. Right? |
Concerns resolved in theory. PR ready for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Just a couple cosmetic suggestions
I've done this change to test: uint16_t FeedbackRtpTransportPacket::maxMissingPackets{ (1 << 13) - 1 };
// uint16_t FeedbackRtpTransportPacket::maxPacketStatusCount{ (1 << 16) - 1 }; and it crashes:
Why? Because when if (!this->transportCcFeedbackPacket->IsSerializable())
{
return;
} So here another regression in that PR or perhaps |
Details
this->transportCcFeedbackPacket
is reset so it's a complete new packet and hence itsbaseSet
isfalse
.TransportCongestionControlServer::FillAndSendTransportCcFeedback()
in which we just callthis->transportCcFeedbackPacket.SetBase()
once at the top, but then we enter a loop in which the packet maybe full so it's sent (or other things) and hence we reset the packet while in the loop. And then at the top of the loopthis->transportCcFeedbackPacket.AddPacket()
is called so the assertion fails because itsSetBase()
was not called on that fresh packet.SetBase()
conditionally in every iteration of the loop by checking if current feedback has the base set or not.break
in acase
block in that loop.this->transportCcFeedbackPacket
.