Skip to content
Snippets Groups Projects
Commit 6f4d775d authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Fix packet buffer overflow

parent 9ac0cd04
Branches
Tags
No related merge requests found
......@@ -262,6 +262,7 @@ void Net::_processPacket(ftl::net::Peer *p, int16_t ttimeoff, const StreamPacket
_processRequest(p, &spkt, pkt);
}
if (!host_) {
pair.second = std::move(pkt);
mgr_.submit(pair, [this, now, ttimeoff, p](const ftl::protocol::PacketPair &pair) {
const StreamPacket &spkt = pair.first;
......@@ -270,6 +271,10 @@ void Net::_processPacket(ftl::net::Peer *p, int16_t ttimeoff, const StreamPacket
trigger(spkt, pkt);
if (pkt.data.size() > 0) _checkRXRate(pkt.data.size(), now-(spkt.timestamp+ttimeoff), spkt.timestamp);
});
} else {
trigger(spkt, pkt);
if (pkt.data.size() > 0) _checkRXRate(pkt.data.size(), now-(spkt.timestamp+ttimeoff), spkt.timestamp);
}
}
void Net::inject(const ftl::protocol::StreamPacket &spkt, const ftl::protocol::DataPacket &pkt) {
......
......@@ -61,10 +61,10 @@ void PacketManager::submit(PacketPair &packets, const std::function<void(const P
lk.unlock();
// Loop over the buffer, checking for anything that can be processed
for (size_t i = start; i < stop; ++i) {
if (state.buffer[i].first.channel == Channel::kEndFrame) {
if (state.buffer[i % StreamState::kMaxBuffer].first.channel == Channel::kEndFrame) {
--state.bufferedEndFrames;
}
submit(state.buffer[i], cb, true);
submit(state.buffer[i % StreamState::kMaxBuffer], cb, true);
}
} else {
state.timestamp = -1;
......@@ -74,6 +74,9 @@ void PacketManager::submit(PacketPair &packets, const std::function<void(const P
}
} else if (state.timestamp > packets.first.timestamp) {
LOG(WARNING) << "Old packet received";
// Note: not ideal but still better than discarding
cb(packets);
return;
} else {
DLOG(WARNING) << "Buffer packets: " << packets.first.timestamp;
// Change the current frame
......@@ -123,12 +126,12 @@ void PacketManager::submit(PacketPair &packets, const std::function<void(const P
lk.unlock();
// Loop over the buffer, checking for anything that can be processed
for (size_t i = start; i < stop; ++i) {
if (state.buffer[i].first.channel == Channel::kEndFrame) {
if (state.buffer[i % StreamState::kMaxBuffer].first.channel == Channel::kEndFrame) {
--state.bufferedEndFrames;
}
submit(state.buffer[i], cb, true);
submit(state.buffer[i % StreamState::kMaxBuffer], cb, true);
std::vector<uint8_t> temp;
state.buffer[i].second.data.swap(temp);
state.buffer[i % StreamState::kMaxBuffer].second.data.swap(temp);
}
}
}
......
......@@ -26,7 +26,6 @@ struct StreamState {
std::array<ftl::protocol::PacketPair, kMaxBuffer> buffer;
int64_t timestamp = -1;
int64_t minTimestamp = -1;
int expected = -1;
std::atomic_int processed = 0;
size_t readPos = 0;
......
......@@ -180,3 +180,44 @@ TEST_CASE( "Incomplete frames" ) {
REQUIRE(count == 7);
}
TEST_CASE( "Overflow the buffer" ) {
PacketManager mgr;
int count = 0;
PacketPair p;
p = makePair(400, Channel::kEndFrame);
p.second.packet_count = 2;
mgr.submit(p, [&count](const PacketPair &pp) {
++count;
});
p = makePair(401, Channel::kColour);
for (int i = 0; i<95; ++i) {
mgr.submit(p, [&count](const PacketPair &pp) {
++count;
});
}
p = makePair(400, Channel::kColour);
mgr.submit(p, [&count](const PacketPair &pp) {
++count;
});
p = makePair(402, Channel::kColour);
for (int i = 0; i<95; ++i) {
mgr.submit(p, [&count](const PacketPair &pp) {
++count;
});
}
p = makePair(401, Channel::kEndFrame);
p.second.packet_count = 96;
mgr.submit(p, [&count](const PacketPair &pp) {
++count;
});
REQUIRE(count == 96 + 95 + 2);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment