summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2017-01-13 16:33:33 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2017-01-13 16:33:33 +0100
commit1bbbac7f62d71f0d0c4c71d429aeb2cfdf96e5ac (patch)
treef9234c8e6491151fddccc2c8d1ff0b0600c44c5f
parent7c8ae25ba83fc658dfbe4cd468bb1bdfd3513c74 (diff)
downloaddabmod-1bbbac7f62d71f0d0c4c71d429aeb2cfdf96e5ac.tar.gz
dabmod-1bbbac7f62d71f0d0c4c71d429aeb2cfdf96e5ac.tar.bz2
dabmod-1bbbac7f62d71f0d0c4c71d429aeb2cfdf96e5ac.zip
EDI: add protection against runaway memory usage
-rw-r--r--lib/UdpSocket.cpp7
-rw-r--r--lib/UdpSocket.h3
-rw-r--r--src/EtiReader.cpp9
3 files changed, 15 insertions, 4 deletions
diff --git a/lib/UdpSocket.cpp b/lib/UdpSocket.cpp
index b88c731..570da5f 100644
--- a/lib/UdpSocket.cpp
+++ b/lib/UdpSocket.cpp
@@ -261,8 +261,9 @@ UdpReceiver::~UdpReceiver() {
}
}
-void UdpReceiver::start(int port) {
+void UdpReceiver::start(int port, size_t max_packets_queued) {
m_port = port;
+ m_max_packets_queued = max_packets_queued;
m_thread = std::thread(&UdpReceiver::m_run, this);
}
@@ -299,7 +300,9 @@ void UdpReceiver::m_run()
// TODO replace fprintf
fprintf(stderr, "Warning, possible UDP truncation\n");
}
- m_packets.push(packet);
+
+ // If this blocks, the UDP socket will lose incoming packets
+ m_packets.push_wait_if_full(packet, m_max_packets_queued);
}
else
{
diff --git a/lib/UdpSocket.h b/lib/UdpSocket.h
index 81a7d2b..8c968d2 100644
--- a/lib/UdpSocket.h
+++ b/lib/UdpSocket.h
@@ -184,7 +184,7 @@ class UdpReceiver {
UdpReceiver operator=(const UdpReceiver&) = delete;
// Start the receiver in a separate thread
- void start(int port);
+ void start(int port, size_t max_packets_queued);
// Get the data contained in a UDP packet, blocks if none available
// In case of error, throws a runtime_error
@@ -194,6 +194,7 @@ class UdpReceiver {
void m_run(void);
int m_port;
+ size_t m_max_packets_queued;
std::thread m_thread;
std::atomic<bool> m_stop;
ThreadsafeQueue<UdpPacket> m_packets;
diff --git a/src/EtiReader.cpp b/src/EtiReader.cpp
index f0a1793..de23142 100644
--- a/src/EtiReader.cpp
+++ b/src/EtiReader.cpp
@@ -545,7 +545,14 @@ void EdiUdpInput::Open(const std::string& uri)
m_port = std::stoi(m[1].str());
etiLog.level(info) << "EDI port :" << m_port;
- m_udp_rx.start(m_port);
+
+ // The max_fragments_queued is only a protection against a runaway
+ // memory usage.
+ // Rough calculation:
+ // 300 seconds, 24ms per frame, up to 20 fragments per frame
+ const size_t max_fragments_queued = 20 * 300 * 1000 / 24;
+
+ m_udp_rx.start(m_port, max_fragments_queued);
m_enabled = true;
}
}