diff options
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h | 2 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/RtpSession.cpp | 35 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/RtpSession.h | 19 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/VoIp.cpp | 153 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp | 2 | ||||
-rw-r--r-- | orkaudio/audiocaptureplugins/voip/VoIpConfig.h | 1 |
6 files changed, 211 insertions, 1 deletions
diff --git a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h index ce33534..cc1ed0a 100644 --- a/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h +++ b/orkaudio/audiocaptureplugins/voip/PacketHeaderDefs.h @@ -347,9 +347,11 @@ struct Iax2MetaTrunkEntryTs { #define SIP_METHOD_INVITE_SIZE 6 #define SIP_METHOD_BYE_SIZE 3 #define SIP_RESPONSE_200_OK_SIZE 11 +#define SIP_RESPONSE_SESSION_PROGRESS_SIZE 28 #define SIP_METHOD_INVITE "INVITE" #define SIP_METHOD_BYE "BYE" #define SIP_RESPONSE_200_OK "SIP/2.0 200" +#define SIP_RESPONSE_SESSION_PROGRESS "SIP/2.0 183 Session Progress" #endif diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp index d6f147f..0a0bc91 100644 --- a/orkaudio/audiocaptureplugins/voip/RtpSession.cpp +++ b/orkaudio/audiocaptureplugins/voip/RtpSession.cpp @@ -1173,6 +1173,20 @@ void RtpSessions::ReportSipErrorPacket(SipFailureMessageInfoRef& info) return; } +void RtpSessions::ReportSipSessionProgress(SipSessionProgressInfoRef& info) +{ + std::map<CStdString, RtpSessionRef>::iterator pair; + + pair = m_byCallId.find(info->m_callId); + if (pair != m_byCallId.end()) + { + RtpSessionRef session = pair->second; + unsigned short mediaPort = ACE_OS::atoi(info->m_mediaPort); + + SetMediaAddress(session, info->m_mediaIp, mediaPort); + } +} + void RtpSessions::ReportSip200Ok(Sip200OkInfoRef info) { std::map<CStdString, RtpSessionRef>::iterator pair; @@ -2328,3 +2342,24 @@ void Sip200OkInfo::ToString(CStdString& string) string.Format("sender:%s from:%s to:%s rcvr:%s callid:%s", senderIp, m_from, m_to, receiverIp, m_callId); } } + +SipSessionProgressInfo::SipSessionProgressInfo() +{ + m_mediaIp.s_addr = 0; + m_senderIp.s_addr = 0; + m_receiverIp.s_addr = 0; +} + +void SipSessionProgressInfo::ToString(CStdString& string) +{ + char mediaIp[16]; + ACE_OS::inet_ntop(AF_INET, (void*)&m_mediaIp, mediaIp, sizeof(mediaIp)); + + char senderIp[16]; + ACE_OS::inet_ntop(AF_INET, (void*)&m_senderIp, senderIp, sizeof(senderIp)); + + char receiverIp[16]; + ACE_OS::inet_ntop(AF_INET, (void*)&m_receiverIp, receiverIp, sizeof(receiverIp)); + + string.Format("sender:%s from:%s RTP:%s,%s to:%s rcvr:%s callid:%s", senderIp, m_from, mediaIp, m_mediaPort, m_to, receiverIp, m_callId); +} diff --git a/orkaudio/audiocaptureplugins/voip/RtpSession.h b/orkaudio/audiocaptureplugins/voip/RtpSession.h index abf7787..089086f 100644 --- a/orkaudio/audiocaptureplugins/voip/RtpSession.h +++ b/orkaudio/audiocaptureplugins/voip/RtpSession.h @@ -92,10 +92,26 @@ public: CStdString m_from; CStdString m_to; }; - typedef boost::shared_ptr<Sip200OkInfo> Sip200OkInfoRef; +class SipSessionProgressInfo +{ +public: + SipSessionProgressInfo(); + void ToString(CStdString& string); + + CStdString m_callId; + struct in_addr m_mediaIp; + CStdString m_mediaPort; + + struct in_addr m_senderIp; + struct in_addr m_receiverIp; + CStdString m_from; + CStdString m_to; +}; +typedef boost::shared_ptr<SipSessionProgressInfo> SipSessionProgressInfoRef; + //============================================================= class EndpointInfo @@ -226,6 +242,7 @@ public: void ReportRtpPacket(RtpPacketInfoRef& rtpPacket); void ReportSipErrorPacket(SipFailureMessageInfoRef& sipError); void ReportSip200Ok(Sip200OkInfoRef info); + void ReportSipSessionProgress(SipSessionProgressInfoRef& info); void Hoover(time_t now); EndpointInfoRef GetEndpointInfo(struct in_addr endpointIp); void StartCapture(CStdString& party); diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp index 1f8620b..948d364 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp @@ -1454,6 +1454,152 @@ bool TrySipTcp(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, T return result; } +bool TrySipSessionProgress(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, UdpHeaderStruct* udpHeader, u_char* udpPayload, u_char* packetEnd) +{ + bool result = false; + + int sipLength = ntohs(udpHeader->len) - sizeof(UdpHeaderStruct); + char* sipEnd = (char*)udpPayload + sipLength; + + if(sipLength < SIP_RESPONSE_SESSION_PROGRESS_SIZE || sipEnd > (char*)packetEnd) + { + ; // packet too short + } + else if(memcmp(SIP_RESPONSE_SESSION_PROGRESS, (void*)udpPayload, SIP_RESPONSE_SESSION_PROGRESS_SIZE) == 0) + { + bool hasSdp = false; + SipSessionProgressInfoRef info(new SipSessionProgressInfo()); + + result = true; + + char* fromField = memFindAfter("From:", (char*)udpPayload, sipEnd); + if(!fromField) + { + fromField = memFindAfter("\nf:", (char*)udpPayload, sipEnd); + } + char* toField = memFindAfter("To:", (char*)udpPayload, sipEnd); + if(!toField) + { + toField = memFindAfter("\nt:", (char*)udpPayload, sipEnd); + } + + char* callIdField = memFindAfter("Call-ID:", (char*)udpPayload, sipEnd); + if(!callIdField) + { + callIdField = memFindAfter("\ni:", (char*)udpPayload, sipEnd); + } + + char* audioField = NULL; + char* connectionAddressField = NULL; + + if(callIdField) + { + GrabTokenSkipLeadingWhitespaces(callIdField, sipEnd, info->m_callId); + audioField = memFindAfter("m=audio ", callIdField, sipEnd); + connectionAddressField = memFindAfter("c=IN IP4 ", callIdField, sipEnd); + } + if(audioField && connectionAddressField) + { + hasSdp = true; + + GrabToken(audioField, sipEnd, info->m_mediaPort); + + CStdString connectionAddress; + GrabToken(connectionAddressField, sipEnd, connectionAddress); + struct in_addr mediaIp; + if(connectionAddress.size()) + { + if(ACE_OS::inet_aton((PCSTR)connectionAddress, &mediaIp)) + { + info->m_mediaIp = mediaIp; + } + } + } + + if(fromField) + { + if(s_sipExtractionLog->isDebugEnabled()) + { + CStdString from; + GrabLine(fromField, sipEnd, from); + LOG4CXX_DEBUG(s_sipExtractionLog, "from: " + from); + } + + char* fromFieldEnd = memFindEOL(fromField, sipEnd); + + char* sipUser = memFindAfter("sip:", fromField, fromFieldEnd); + if(sipUser) + { + if(DLLCONFIG.m_sipReportFullAddress) + { + GrabSipUserAddress(sipUser, fromFieldEnd, info->m_from); + } + else + { + GrabSipUriUser(sipUser, fromFieldEnd, info->m_from); + } + } + else + { + if(DLLCONFIG.m_sipReportFullAddress) + { + GrabSipUserAddress(fromField, fromFieldEnd, info->m_from); + } + else + { + GrabSipUriUser(fromField, fromFieldEnd, info->m_from); + } + } + } + if(toField) + { + CStdString to; + char* toFieldEnd = GrabLine(toField, sipEnd, to); + LOG4CXX_DEBUG(s_sipExtractionLog, "to: " + to); + + char* sipUser = memFindAfter("sip:", toField, toFieldEnd); + if(sipUser) + { + if(DLLCONFIG.m_sipReportFullAddress) + { + GrabSipUserAddress(sipUser, toFieldEnd, info->m_to); + } + else + { + GrabSipUriUser(sipUser, toFieldEnd, info->m_to); + } + } + else + { + if(DLLCONFIG.m_sipReportFullAddress) + { + GrabSipUserAddress(toField, toFieldEnd, info->m_to); + } + else + { + GrabSipUriUser(toField, toFieldEnd, info->m_to); + } + } + } + info->m_senderIp = ipHeader->ip_src; + info->m_receiverIp = ipHeader->ip_dest; + + CStdString logMsg; + + info->ToString(logMsg); + logMsg = "183 Session Progress: " + logMsg; + if(!hasSdp) + { + logMsg = logMsg + " dropped because it lacks the SDP"; + } + else + { + RtpSessionsSingleton::instance()->ReportSipSessionProgress(info); + } + LOG4CXX_INFO(s_sipPacketLog, logMsg); + } +} + bool TrySip200Ok(EthernetHeaderStruct* ethernetHeader, IpHeaderStruct* ipHeader, UdpHeaderStruct* udpHeader, u_char* udpPayload, u_char* packetEnd) { bool result = false; @@ -2209,6 +2355,13 @@ void HandlePacket(u_char *param, const struct pcap_pkthdr *header, const u_char } if(!detectedUsefulPacket) { + if(DLLCONFIG.m_sipDetectSessionProgress == true) + { + TrySipSessionProgress(ethernetHeader, ipHeader, udpHeader, udpPayload, ipPacketEnd); + } + } + + if(!detectedUsefulPacket) { detectedUsefulPacket = TrySipBye(ethernetHeader, ipHeader, udpHeader, udpPayload, ipPacketEnd); } diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp index f0701df..7100fb3 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp +++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp @@ -43,6 +43,7 @@ VoIpConfig::VoIpConfig() m_sipOverTcpSupport = false; // Disabled by default m_sipLogFailedCalls = false; m_sipUse200OkMediaAddress = false; + m_sipDetectSessionProgress = true; // Enabled by default m_sipReportFullAddress = false; m_sipDynamicMediaAddress = false; @@ -104,6 +105,7 @@ void VoIpConfig::Define(Serializer* s) s->BoolValue("SipOverTcpSupport", m_sipOverTcpSupport); s->BoolValue("SipLogFailedCalls", m_sipLogFailedCalls); s->BoolValue("SipUse200OkMediaAddress", m_sipUse200OkMediaAddress); + s->BoolValue("SipDetectSessionProgress", m_sipDetectSessionProgress); s->BoolValue("SipReportFullAddress", m_sipReportFullAddress); s->BoolValue("SipDynamicMediaAddress", m_sipDynamicMediaAddress); s->IpRangesValue("SipIgnoredMediaAddresses", m_sipIgnoredMediaAddresses); diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h index d8a4a6d..de13605 100644 --- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h +++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h @@ -77,6 +77,7 @@ public: bool m_sipOverTcpSupport; bool m_sipLogFailedCalls; bool m_sipUse200OkMediaAddress; + bool m_sipDetectSessionProgress; bool m_sipReportFullAddress; bool m_sipDynamicMediaAddress; IpRanges m_sipIgnoredMediaAddresses; |