From 0a7608faba11e784f69f0539446e58b9f2a32f53 Mon Sep 17 00:00:00 2001 From: schmirl Date: Mon, 23 Apr 2007 12:00:27 +0000 Subject: [PATCH] client_invalid-section-data_and_pipe-overflow.patch by Petri Hintukainen - Reset section data unpacker only after first non-full TS packet (last TS packet of section is typically not full - Do not close filter if socket buffer is full (EAGAIN, EWOULDBLOCK) (closing results in 100% CPU usage in VDR section handler) --- client/filter.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/client/filter.c b/client/filter.c index 8cdd0ea..5f03af6 100644 --- a/client/filter.c +++ b/client/filter.c @@ -1,5 +1,5 @@ /* - * $Id: filter.c,v 1.7 2007/04/23 11:33:26 schmirl Exp $ + * $Id: filter.c,v 1.8 2007/04/23 12:00:27 schmirl Exp $ */ #include "client/filter.h" @@ -79,19 +79,35 @@ bool cStreamdevFilter::PutSection(const uchar *Data, int Length) { if (m_Used + Length >= (int)sizeof(m_Buffer)) { esyslog("ERROR: Streamdev: Section handler buffer overflow (%d bytes lost)", Length); - m_Used = 0; + Reset(); return true; } + memcpy(m_Buffer + m_Used, Data, Length); m_Used += Length; - if (m_Used > 3) { int length = (((m_Buffer[1] & 0x0F) << 8) | m_Buffer[2]) + 3; if (m_Used == length) { - if (write(m_Pipe[1], m_Buffer, length) < 0) - return false; m_Used = 0; + if (write(m_Pipe[1], m_Buffer, length) < 0) { + if(errno == EAGAIN || errno == EWOULDBLOCK) + dsyslog("cStreamdevFilter::PutSection socket overflow, " + "Pid %4d Tid %3d", m_Pid, m_Tid); + + else + return false; + } } + + if (m_Used > length) { + dsyslog("cStreamdevFilter::PutSection: m_Used > length ! Pid %2d, Tid%2d " + "(len %3d, got %d/%d)", m_Pid, m_Tid, Length, m_Used, length); + if(Length < TS_SIZE-5) { + // TS packet not full -> this must be last TS packet of section data -> safe to reset now + Reset(); + } + } + } return true; }