Fix SIP packet capturing for TCP.

Wait for whole SIP packet to be received/sent before sending it to the capture.
Capturing at socket level would send HEP packets containing SIP fragments.
This commit is contained in:
Ioana Stanciu 2023-06-23 17:57:00 +03:00
parent 2d156f31ec
commit ef0d8d4c6a
1 changed files with 39 additions and 12 deletions

View File

@ -219,7 +219,7 @@ protected:
int m_methods[MethodCount];
};
class CaptureFilter : virtual public SocketFilter
class CaptureFilter : virtual public SocketFilter, public RefObject
{
public:
CaptureFilter(const char* name = 0)
@ -246,6 +246,9 @@ public:
m_remote = rAddr;
}
virtual void destruct()
{ RefObject::destruct(); }
bool init(YateSIPTransport* transp, const NamedList& params, const SocketAddr& lAddr, const SocketAddr& rAddr);
virtual void* getObject(const String& name) const;
virtual bool received(const void* buffer, int length, int flags, const struct sockaddr* addr, socklen_t adrlen);
@ -597,6 +600,8 @@ protected:
void setIdleTimeout(u_int64_t time = Time::now());
// Send keep alive (or response to keep alive)
bool sendKeepAlive(bool request);
// Capture SIP TCP messages
void capture(const void* data, unsigned int len, bool rx);
inline bool sendPendingKeepAlive() {
if (!m_keepAlivePending)
return true;
@ -3200,7 +3205,7 @@ void* CaptureFilter::getObject(const String& name) const
{
if (name == "CaptureFilter")
return (void*) this;
return GenObject::getObject(name);
return RefObject::getObject(name);
}
bool CaptureFilter::init(YateSIPTransport* transp, const NamedList& params,
@ -3239,9 +3244,14 @@ bool CaptureFilter::received(const void* buffer, int length, int flags,
DDebug(&plugin,DebugAll,"CaptureFilter::received(%p,%d,%x,%p,%u) [%p]",
buffer,length,flags,addr,adrlen,this);
SocketAddr a(addr,adrlen);
RLock l(m_lock);
CaptureInfo info(Time::now(),addr && adrlen ? &a : &m_remote,&m_local);
if (!m_captureAgent->write((const uint8_t*)buffer,length,info)) {
if (!m_captureAgent->valid() && !m_warned) {
RefPointer<Capture> capt = m_captureAgent;
l.drop();
if (!capt)
return false;
if (!capt->write((const uint8_t*)buffer,length,info)) {
if (!capt->valid() && !m_warned) {
Debug(&plugin,DebugWarn,"Capture filter '%s' has become invalid [%p]",m_captureAgent->toString().c_str(),this);
m_warned = true;
}
@ -3257,9 +3267,14 @@ bool CaptureFilter::sent(const void* buffer, int length, int flags,
DDebug(&plugin,DebugAll,"CaptureFilter::sent(%p,%d,%x,%p,%u) [%p]",
buffer,length,flags,addr,adrlen,this);
SocketAddr a(addr,adrlen);
RLock l(m_lock);
CaptureInfo info(Time::now(),&m_local,addr && adrlen ? &a : &m_remote);
if (!m_captureAgent->write((const uint8_t*)buffer,length,info)) {
if (!m_captureAgent->valid() && !m_warned) {
RefPointer<Capture> capt = m_captureAgent;
l.drop();
if (!capt)
return false;
if (!capt->write((const uint8_t*)buffer,length,info)) {
if (!capt->valid() && !m_warned) {
Debug(&plugin,DebugWarn,"Capture filter '%s' has become invalid [%p]",m_captureAgent->toString().c_str(),this);
m_warned = true;
}
@ -3314,7 +3329,7 @@ bool YateSIPTransport::init(const NamedList& params, const NamedList& defs,
bool install = false;
if (!m_capture) {
m_capture = new CaptureFilter(captParams.getValue("agent"));
install = true;
install = protocol() == Udp;
}
if (!m_capture->init(this,captParams,m_local,m_remote)) {
if (m_sock)
@ -3921,8 +3936,10 @@ int YateSIPTCPTransport::process()
if (s_printMsg && (o != first || m_sent < 0))
printSendMsg(msg);
if (!msg->dontSend()) {
if (o != first || m_sent <= 0)
if (o != first || m_sent <= 0) {
capture(msg->getBuffer().data(),msg->getBuffer().length(),false);
buf += msg->getBuffer();
}
else {
int remaining = msg->getBuffer().length() - m_sent;
if (remaining > 0)
@ -4237,6 +4254,7 @@ bool YateSIPTCPTransport::sendPending(const Time& time, bool& sent)
Debug(&plugin,DebugAll,"Transport(%s) sent (%p,%s) [%p]",
m_id.c_str(),msg,tmp.c_str(),this);
#endif
capture(buf.data(),buf.length(),false);
o->remove();
m_sent = -1;
continue;
@ -4352,6 +4370,7 @@ bool YateSIPTCPTransport::readData(const Time& time, bool& read)
print = false;
printRecvMsg(data,m_sipBufOffs);
}
capture(data,m_sipBufOffs,true);
SIPMessage* msg = m_msg;
msg->msgPrint = print;
m_msg = 0;
@ -4414,10 +4433,6 @@ void YateSIPTCPTransport::resetConnection(Socket* sock)
if (m_capture) {
m_capture->setLocalAddr(m_local);
m_capture->setRemoteAddr(m_remote);
// doesn't matter if we installed if before, install filter checks
if (!m_sock->installFilter(m_capture))
Debug(&plugin,DebugNote,"Transport(%s)) failed to install capture filter [%p]",
m_id.c_str(),this);
}
}
// Update party local/remote ip/port
@ -4450,6 +4465,18 @@ bool YateSIPTCPTransport::sendKeepAlive(bool request)
return wr >= 0 || m_sock->canRetry();
}
void YateSIPTCPTransport::capture(const void* data, unsigned int len, bool rx)
{
Lock l(this);
RefPointer<CaptureFilter> capt = m_capture;
l.drop();
if (!capt)
return;
if (rx)
capt->received(data,len,0,0,0);
else
capt->sent(data,len,0,0,0);
}
YateSIPTransportWorker::YateSIPTransportWorker(YateSIPTransport* trans,
Thread::Priority prio)