-
Notifications
You must be signed in to change notification settings - Fork 840
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 memory leak #2757
Fix memory leak #2757
Conversation
2ddf398
to
001eae7
Compare
The fix is correct. A couple of suggestions to improve the code. TODO
|
Just a side note, should that help understand this code. This storage is used for the initial period, when the case of "confused connection state" happens. This situation happens in case when you have a caller-listener arrangement, the LISTENER side is about to send data, and the flow is:
In this case Caller will repeat sending the conclusion handshake request and wait for the listener's response, but in the meantime it must do something about these data packets. Therefore these packets are stored in a special spare storage, from which they will be delivered directly to the receiver buffer once the caller received finally the handshake conclusion response packet. I don't know what the state of this feature really is (if anyone fixed it, then I missed it), but it exists since UDT codebase and it didn't work there. That is, the storage was being filled with incoming packets, but I didn't see any code that re-delivers these packets. Instead, all packets between ISN and the last received one before reception of the final handshake packet are simply considered lost and get retransmitted. EDIT: I took a look at the code and the only place where the Ah, and as per possible refactoring there: note that this feature is older than |
More fixes after my changes are required. diff --git a/srtcore/packet.cpp b/srtcore/packet.cpp
index 33555e7b..3a17c44b 100644
--- a/srtcore/packet.cpp
+++ b/srtcore/packet.cpp
@@ -221,6 +221,7 @@ void CPacket::deallocate()
if (m_data_owned)
delete[](char*) m_PacketVector[PV_DATA].data();
m_PacketVector[PV_DATA].set(NULL, 0);
+ m_data_owned = false;
}
char* CPacket::release()
@@ -241,8 +242,7 @@ CPacket::~CPacket()
{
// PV_HEADER is always owned, PV_DATA may use a "borrowed" buffer.
// Delete the internal buffer only if it was declared as owned.
- if (m_data_owned)
- delete[](char*) m_PacketVector[PV_DATA].data();
+ deallocate();
}
size_t CPacket::getLength() const
@@ -561,10 +561,8 @@ CPacket* CPacket::clone() const
{
CPacket* pkt = new CPacket;
memcpy((pkt->m_nHeader), m_nHeader, HDR_SIZE);
- pkt->m_pcData = new char[m_PacketVector[PV_DATA].size()];
+ pkt->allocate(m_PacketVector[PV_DATA].size());
memcpy((pkt->m_pcData), m_pcData, m_PacketVector[PV_DATA].size());
- pkt->m_PacketVector[PV_DATA].setLength(m_PacketVector[PV_DATA].size());
-
pkt->m_DestAddr = m_DestAddr;
return pkt;
diff --git a/srtcore/queue.cpp b/srtcore/queue.cpp
index 4282965b..8db669f7 100644
--- a/srtcore/queue.cpp
+++ b/srtcore/queue.cpp
@@ -1162,7 +1162,6 @@ srt::CRcvQueue::~CRcvQueue()
while (!i->second.empty())
{
CPacket* pkt = i->second.front();
- delete[] pkt->m_pcData;
delete pkt;
i->second.pop();
}
@@ -1365,14 +1364,12 @@ srt::EReadStatus srt::CRcvQueue::worker_RetrieveUnit(int32_t& w_id, CUnit*& w_un
{
// no space, skip this packet
CPacket temp;
- temp.m_pcData = new char[m_szPayloadSize];
- temp.setLength(m_szPayloadSize);
+ temp.allocate(m_szPayloadSize);
THREAD_PAUSED();
EReadStatus rst = m_pChannel->recvfrom((w_addr), (temp));
THREAD_RESUMED();
// Note: this will print nothing about the packet details unless heavy logging is on.
LOGC(qrlog.Error, log << CONID() << "LOCAL STORAGE DEPLETED. Dropping 1 packet: " << temp.Info());
- delete[] temp.m_pcData;
// Be transparent for RST_ERROR, but ignore the correct
// data read and fake that the packet was dropped.
@@ -1680,7 +1677,6 @@ int srt::CRcvQueue::recvfrom(int32_t id, CPacket& w_packet)
w_packet.setLength(newpkt->getLength());
w_packet.m_DestAddr = newpkt->m_DestAddr;
- delete[] newpkt->m_pcData;
delete newpkt;
// remove this message from queue,
@@ -1735,7 +1731,6 @@ void srt::CRcvQueue::removeConnector(const SRTSOCKET& id)
log << "removeConnector: ... and its packet queue with " << i->second.size() << " packets collected");
while (!i->second.empty())
{
- delete[] i->second.front()->m_pcData;
delete i->second.front();
i->second.pop();
}
@@ -1783,7 +1778,10 @@ void srt::CRcvQueue::storePkt(int32_t id, CPacket* pkt)
{
// avoid storing too many packets, in case of malfunction or attack
if (i->second.size() > 16)
+ {
+ delete pkt;
return;
+ }
i->second.push(pkt);
} |
fc5f906
to
001eae7
Compare
Reverted my changes. Too much refactoring hides the bugfix itself. The refactoring is to be moved to a separate PR. diff --git a/srtcore/packet.cpp b/srtcore/packet.cpp
index 33555e7..3a17c44 100644
--- a/srtcore/packet.cpp
+++ b/srtcore/packet.cpp
@@ -221,6 +221,7 @@ void CPacket::deallocate()
if (m_data_owned)
delete[](char*) m_PacketVector[PV_DATA].data();
m_PacketVector[PV_DATA].set(NULL, 0);
+ m_data_owned = false;
}
char* CPacket::release()
@@ -241,8 +242,7 @@ CPacket::~CPacket()
{
// PV_HEADER is always owned, PV_DATA may use a "borrowed" buffer.
// Delete the internal buffer only if it was declared as owned.
- if (m_data_owned)
- delete[](char*) m_PacketVector[PV_DATA].data();
+ deallocate();
}
size_t CPacket::getLength() const
@@ -561,10 +561,8 @@ CPacket* CPacket::clone() const
{
CPacket* pkt = new CPacket;
memcpy((pkt->m_nHeader), m_nHeader, HDR_SIZE);
- pkt->m_pcData = new char[m_PacketVector[PV_DATA].size()];
+ pkt->allocate(m_PacketVector[PV_DATA].size());
memcpy((pkt->m_pcData), m_pcData, m_PacketVector[PV_DATA].size());
- pkt->m_PacketVector[PV_DATA].setLength(m_PacketVector[PV_DATA].size());
-
pkt->m_DestAddr = m_DestAddr;
return pkt;
diff --git a/srtcore/queue.cpp b/srtcore/queue.cpp
index 9b13a62..b8e3f07 100644
--- a/srtcore/queue.cpp
+++ b/srtcore/queue.cpp
@@ -1162,7 +1162,6 @@ srt::CRcvQueue::~CRcvQueue()
while (!i->second.empty())
{
CPacket* pkt = i->second.front();
- delete[] pkt->m_pcData;
delete pkt;
i->second.pop();
}
@@ -1365,14 +1364,12 @@ srt::EReadStatus srt::CRcvQueue::worker_RetrieveUnit(int32_t& w_id, CUnit*& w_un
{
// no space, skip this packet
CPacket temp;
- temp.m_pcData = new char[m_szPayloadSize];
- temp.setLength(m_szPayloadSize);
+ temp.allocate(m_szPayloadSize);
THREAD_PAUSED();
EReadStatus rst = m_pChannel->recvfrom((w_addr), (temp));
THREAD_RESUMED();
// Note: this will print nothing about the packet details unless heavy logging is on.
LOGC(qrlog.Error, log << CONID() << "LOCAL STORAGE DEPLETED. Dropping 1 packet: " << temp.Info());
- delete[] temp.m_pcData;
// Be transparent for RST_ERROR, but ignore the correct
// data read and fake that the packet was dropped.
@@ -1680,7 +1677,6 @@ int srt::CRcvQueue::recvfrom(int32_t id, CPacket& w_packet)
w_packet.setLength(newpkt->getLength());
w_packet.m_DestAddr = newpkt->m_DestAddr;
- delete[] newpkt->m_pcData;
delete newpkt;
// remove this message from queue,
@@ -1735,7 +1731,6 @@ void srt::CRcvQueue::removeConnector(const SRTSOCKET& id)
log << "removeConnector: ... and its packet queue with " << i->second.size() << " packets collected");
while (!i->second.empty())
{
- delete[] i->second.front()->m_pcData;
delete i->second.front();
i->second.pop();
}
@@ -1781,10 +1776,9 @@ void srt::CRcvQueue::storePkt(int32_t id, CPacket* pkt)
}
else
{
- // avoid storing too many packets, in case of malfunction or attack
+ // Avoid storing too many packets, in case of malfunction or attack.
if (i->second.size() > 16)
{
- delete[] pkt->m_pcData;
delete pkt;
return;
}
@@ -1795,7 +1789,7 @@ void srt::CRcvQueue::storePkt(int32_t id, CPacket* pkt)
void srt::CMultiplexer::destroy()
{
- // Reverse order of the assigned
+ // Reverse order of the assigned.
delete m_pRcvQueue;
delete m_pSndQueue;
delete m_pTimer;
|
* [core] Fix crypto mode auto for listener sender (Haivision#2711). Co-authored-by: oviano <ovcollyer@mac.com> * [build] Upgraded CI: ubuntu to version 20.04 (Haivision#2682). * [docs] Added the link for registration in slack to the getting started table (Haivision#2721). * [core] Fixed FEC Emergency resize crash (Haivision#2717). Fixed minimum history condition. * [core] Fixed various compiler warnings on various platforms (Haivision#2679). * [core] Minor fix of variable shadowing. * [tests] Minor fix of variable shadowing. * [build] Add -Wshadow=local to CMake build flags. Supported since GCC 7.0. * [core] Correct remaining endianness issues Fixes the last two remaining test failures on big-endian. These operations were all already no-ops on little-endian, and unnecessarily byteswapped the IP addresses on big-endian. Closes: Haivision#2697 * [docs] Minor updates to AEAD docs plus changed v1.6.0 to 1.5.2 in some files * [build] Fix downversioning of _WIN32_WINNT (Haivision#2754). * [core] Fixed unhandled error in haicrypt (Haivision#2685). * [core] Use overlapped WSASendTo to avoid loss in UDP sending (Haivision#2632). * [core] Add volatile keyword to asm block in rdtsc (Haivision#2759). * [core] Fixed srctime from closing socket was mistakenly cleared * [core] Fixed group read-ready epoll events. * [core] Removed unused CUDTGroup::m_Positions. * [core] Perf improvement of group reading. * [core] Fixed RCV buffer initialization in Rendezvous. * [docs] Updating the explicit information for binding to IPv6 wildcard (Haivision#2765). * [tests] Added custom main with transparent parameters for tests (Haivision#2681). * [core] Fix memory leak when can't buffer a HS packet (Haivision#2757). * [core] Refactor CRcvQueue::storePkt(..) for better resource management (Haivision#2775). * [core] Fix hang up on not enough space in the RCV buffer (Haivision#2745). When there is space available in the receiving buffer after it is full, send an ack to allow the sender to resume transmission. Reschedule sending if ACK decreases the flight span after sending is congested. Co-authored-by: Maxim Sharabayko <maxlovic@gmail.com> * [core] fix tsbpd() may deadlock with processCtrlShutdown() * [core] Slightly optimize the RCV drop by message number (Haivision#2686). Some minor improvements of logs and comments. * [core] Rejection not undertaken in rendezvous after KMX failure (Haivision#2692). * [core] Fix: In rendezvous when processing resulted in ACCEPT it was still sending rejection * [core] Minor code clean up in CRateEstimator. * [core] Initialize ISN and PeerISN in CUDT. * [core] Drop unencrypted packets in GCM mode. * [apps] Fix the build for target without IP_ADD_SOURCE_MEMBERSHIP (Haivision#2779). * [core] Added maximum BW limit for retransmissions (Haivision#2714). * [API] SRT version raised to 1.5.3. * [apps] Fixed conditional IP_ADD_SOURCE_MEMBERSHIP in testmedia (Haivision#2780). * [core] Fixed SRT_ATTR_REQUIRES use. * [build] Added missing public header files in Windows binary installer (Haivision#2784). The header file access_control.h was added to the source tree at some point but was not added to the Windows installer. --------- Co-authored-by: Maxim Sharabayko <maxlovic@gmail.com> Co-authored-by: oviano <ovcollyer@mac.com> Co-authored-by: Sektor van Skijlen <ethouris@gmail.com> Co-authored-by: Maria Sharabayko <41019697+mbakholdina@users.noreply.github.com> Co-authored-by: Maxim Sharabayko <maxsharabayko@haivision.com> Co-authored-by: matoro <matoro@users.noreply.github.com> Co-authored-by: Maria Sharabayko <msharabayko@haivision.com> Co-authored-by: Steve Lhomme <robux4@ycbcr.xyz> Co-authored-by: Aaron Jencks <32805004+aaron-jencks@users.noreply.github.com> Co-authored-by: Guangqing Chen <hi@goushi.me> Co-authored-by: john <hondaxiao@tencent.com> Co-authored-by: yomnes0 <127947185+yomnes0@users.noreply.github.com> Co-authored-by: Mikołaj Małecki <mmalecki@haivision.com> Co-authored-by: Jose Santiago <jsantiago@haivision.com> Co-authored-by: Thierry Lelegard <lelegard@users.noreply.github.com>
No description provided.