[Opalvoip-svn] SF.net SVN: opalvoip:[27050] opal/trunk
Brought to you by:
csoutheren,
rjongbloed
From: <rjo...@us...> - 2012-02-23 02:25:41
|
Revision: 27050 http://opalvoip.svn.sourceforge.net/opalvoip/?rev=27050&view=rev Author: rjongbloed Date: 2012-02-23 02:25:34 +0000 (Thu, 23 Feb 2012) Log Message: ----------- Improved error reporting if SIP handler (e.g. REGISTER) has transport p\dropped by remote. First tries to silently re-establish the connection before reporting error and going into "offline" mode. Modified Paths: -------------- opal/trunk/include/sip/handlers.h opal/trunk/include/sip/sipep.h opal/trunk/include/sip/sippdu.h opal/trunk/src/sip/handlers.cxx opal/trunk/src/sip/sipep.cxx opal/trunk/src/sip/sippdu.cxx Modified: opal/trunk/include/sip/handlers.h =================================================================== --- opal/trunk/include/sip/handlers.h 2012-02-23 01:54:37 UTC (rev 27049) +++ opal/trunk/include/sip/handlers.h 2012-02-23 02:25:34 UTC (rev 27050) @@ -90,8 +90,6 @@ inline SIPHandler::State GetState () { return m_state; } - virtual OpalTransport * GetTransport(); - virtual SIPAuthentication * GetAuthentication() { return authentication; } @@ -140,7 +138,7 @@ const SIPURL & GetRemoteAddress() const { return m_remoteAddress; } const SIPURL & GetProxy() const { return m_proxy; } - SIPMIMEInfo m_mime; + OpalTransport * GetTransport() const { return m_transport; } protected: virtual PBoolean SendRequest(SIPHandler::State state); @@ -163,6 +161,8 @@ const SIPURL m_addressOfRecord; SIPURL m_remoteAddress; const PString m_callID; + SIPMIMEInfo m_mime; + unsigned m_lastCseq; int m_currentExpireTime; int m_originalExpireTime; Modified: opal/trunk/include/sip/sipep.h =================================================================== --- opal/trunk/include/sip/sipep.h 2012-02-23 01:54:37 UTC (rev 27049) +++ opal/trunk/include/sip/sipep.h 2012-02-23 02:25:34 UTC (rev 27050) @@ -271,7 +271,8 @@ */ OpalTransport * CreateTransport( const SIPURL & remoteURL, - const PString & localInterface = PString::Empty() + const PString & localInterface = PString::Empty(), + SIP_PDU::StatusCodes * reason = NULL ); virtual void HandlePDU( Modified: opal/trunk/include/sip/sippdu.h =================================================================== --- opal/trunk/include/sip/sippdu.h 2012-02-23 01:54:37 UTC (rev 27049) +++ opal/trunk/include/sip/sippdu.h 2012-02-23 02:25:34 UTC (rev 27050) @@ -410,7 +410,7 @@ PString GetSIPETag() const; void SetSIPETag(const PString & v); - void GetAlertInfo(PString & info, int & appearance); + void GetAlertInfo(PString & info, int & appearance) const; void SetAlertInfo(const PString & info, int appearance); PString GetCallInfo() const; @@ -520,6 +520,8 @@ Local_TransportError, Local_BadTransportAddress, Local_Timeout, + Local_NoCompatibleListener, + Local_CannotMapScheme, Information_Trying = 100, Information_Ringing = 180, Modified: opal/trunk/src/sip/handlers.cxx =================================================================== --- opal/trunk/src/sip/handlers.cxx 2012-02-23 01:54:37 UTC (rev 27049) +++ opal/trunk/src/sip/handlers.cxx 2012-02-23 02:25:34 UTC (rev 27050) @@ -278,69 +278,65 @@ SetState(newState); - if (GetTransport() == NULL) - OnFailed(SIP_PDU::Local_BadTransportAddress); - else { - m_lastCseq = 0; + SIP_PDU::StatusCodes reason = SIP_PDU::Local_BadTransportAddress; - // Restoring or first time, try every interface - if (newState == Restoring || m_transport->GetInterface().IsEmpty()) { - PWaitAndSignal mutex(m_transport->GetWriteMutex()); - if (m_transport->WriteConnect(WriteSIPHandler, this)) - return true; - } - else { - // We contacted the server on an interface last time, assume it still works! - if (WriteSIPHandler(*m_transport, false)) - return true; - } + for (unsigned retry = 0; retry < 2; ++retry) { + if (m_transport == NULL) { + if (m_proxy.IsEmpty()) { + // Look for a "proxy" parameter to override default proxy + const PStringToString & params = m_remoteAddress.GetParamVars(); + if (params.Contains(OPAL_PROXY_PARAM)) { + m_proxy.Parse(params(OPAL_PROXY_PARAM)); + m_remoteAddress.SetParamVar(OPAL_PROXY_PARAM, PString::Empty()); + } + } - OnFailed(SIP_PDU::Local_TransportError); - } + SIPURL url; + if (!m_proxy.IsEmpty()) + url = m_proxy; + else { + url = m_remoteAddress; + url.AdjustToDNS(); + } - if (newState == Unsubscribing) { - // Transport level error, probably never going to get the unsubscribe through - SetState(Unsubscribed); - return true; - } + // Must specify a network interface or get infinite recursion + m_transport = GetEndPoint().CreateTransport(url, "*", &reason); + if (m_transport == NULL) + break; - RetryLater(m_offlineExpireTime); - return true; -} + PTRACE_CONTEXT_ID_TO(m_transport); + } + if (m_transport->IsOpen()) { + m_lastCseq = 0; -OpalTransport * SIPHandler::GetTransport() -{ - if (m_transport != NULL) { - if (m_transport->IsOpen()) - return m_transport; + // Restoring or first time, try every interface + if (newState == Restoring || m_transport->GetInterface().IsEmpty()) { + PWaitAndSignal mutex(m_transport->GetWriteMutex()); + if (m_transport->WriteConnect(WriteSIPHandler, this)) + return true; + } + else { + // We contacted the server on an interface last time, assume it still works! + if (WriteSIPHandler(*m_transport, false)) + return true; + } - m_transport->CloseWait(); + reason = SIP_PDU::Local_TransportError; + m_transport->CloseWait(); + } + delete m_transport; m_transport = NULL; } - if (m_proxy.IsEmpty()) { - // Look for a "proxy" parameter to override default proxy - const PStringToString & params = m_remoteAddress.GetParamVars(); - if (params.Contains(OPAL_PROXY_PARAM)) { - m_proxy.Parse(params(OPAL_PROXY_PARAM)); - m_remoteAddress.SetParamVar(OPAL_PROXY_PARAM, PString::Empty()); - } - } + OnFailed(reason); - SIPURL url; - if (!m_proxy.IsEmpty()) - url = m_proxy; - else { - url = m_remoteAddress; - url.AdjustToDNS(); - } - - // Must specify a network interface or get infinite recursion - m_transport = GetEndPoint().CreateTransport(url, "*"); - PTRACE_CONTEXT_ID_TO(m_transport); - return m_transport; + if (newState == Unsubscribing) + SetState(Unsubscribed); // Transport level error, probably never going to get the unsubscribe through + else + RetryLater(m_offlineExpireTime); + return true; } Modified: opal/trunk/src/sip/sipep.cxx =================================================================== --- opal/trunk/src/sip/sipep.cxx 2012-02-23 01:54:37 UTC (rev 27049) +++ opal/trunk/src/sip/sipep.cxx 2012-02-23 02:25:34 UTC (rev 27050) @@ -276,11 +276,13 @@ } -OpalTransport * SIPEndPoint::CreateTransport(const SIPURL & remoteURL, const PString & localInterface) +OpalTransport * SIPEndPoint::CreateTransport(const SIPURL & remoteURL, const PString & localInterface, SIP_PDU::StatusCodes * reason) { OpalTransportAddress remoteAddress = remoteURL.GetHostAddress(); if (remoteAddress.IsEmpty()) { if (GetRegistrationsCount() == 0) { + if (reason != NULL) + *reason = SIP_PDU::Local_CannotMapScheme; PTRACE(1, "SIP\tCannot use tel URI with phone-context or existing registration."); return false; } @@ -313,6 +315,8 @@ if (transport == NULL) { // No compatible listeners, can't create a transport to send if we cannot hear the responses! PTRACE(2, "SIP\tNo compatible listener to create transport for " << remoteAddress); + if (reason != NULL) + *reason = SIP_PDU::Local_NoCompatibleListener; return NULL; } @@ -327,6 +331,16 @@ transport->SetBufferSize(m_maxSizeUDP); if (!transport->Connect()) { PTRACE(1, "SIP\tCould not connect to " << remoteAddress << " - " << transport->GetErrorText()); + if (reason != NULL) { + switch (transport->GetErrorCode()) { + case PChannel::Timeout : + *reason = SIP_PDU::Local_Timeout; + break; + default : + *reason = SIP_PDU::Local_BadTransportAddress; + break; + } + } transport->CloseWait(); delete transport; return NULL; @@ -804,7 +818,9 @@ handler.SetSafetyMode(PSafeReadWrite); activeSIPHandlers.Append(handler); - handler->GetTransport()->SetInterface(transport.GetInterface()); + OpalTransport * handlerTransport = handler->GetTransport(); + if (handlerTransport != NULL) + handlerTransport->SetInterface(transport.GetInterface()); mime.SetTo(dialog->GetLocalURI().AsQuotedString()); } @@ -1791,12 +1807,12 @@ OpalTransportAddress addr(myAddress, myPort, transport.GetLocalAddress().GetProtoPrefix()); PString defPartyName(GetDefaultLocalPartyName()); SIPURL rpn; - PINDEX pos; - if ((pos = defPartyName.Find('@')) == P_MAX_INDEX) + PString user, host; + if (!defPartyName.Split('@', user, host)) rpn = SIPURL(defPartyName, addr, myPort); else { - rpn = SIPURL(defPartyName.Left(pos), addr, myPort); // set transport from address - rpn.SetHostName(defPartyName.Mid(pos+1)); + rpn = SIPURL(user, addr, myPort); // set transport from address + rpn.SetHostName(host); } rpn.SetDisplayName(GetDefaultDisplayName()); @@ -1991,12 +2007,13 @@ void SIPEndPoint::InterfaceMonitor::OnRemoveInterface(const PIPSocket::InterfaceEntry & entry) { + OpalTransport * transport = NULL; if (priority == SIPEndPoint::LowPriority) { for (PSafePtr<SIPHandler> handler = m_endpoint.activeSIPHandlers.GetFirstHandler(PSafeReadOnly); handler != NULL; ++handler) { if (handler->GetState() == SIPHandler::Subscribed && - handler->GetTransport() != NULL && - handler->GetTransport()->GetInterface().Find(entry.GetName()) != P_MAX_INDEX) { - handler->GetTransport()->SetInterface(PString::Empty()); + (transport = handler->GetTransport()) != NULL && + transport->GetInterface().Find(entry.GetName()) != P_MAX_INDEX) { + transport->SetInterface(PString::Empty()); handler->ActivateState(SIPHandler::Refreshing); } } Modified: opal/trunk/src/sip/sippdu.cxx =================================================================== --- opal/trunk/src/sip/sippdu.cxx 2012-02-23 01:54:37 UTC (rev 27049) +++ opal/trunk/src/sip/sippdu.cxx 2012-02-23 02:25:34 UTC (rev 27050) @@ -162,6 +162,8 @@ { SIP_PDU::Local_TransportError, "Transport Error" }, { SIP_PDU::Local_BadTransportAddress, "Invalid Address/Hostname" }, { SIP_PDU::Local_Timeout, "Timeout or retries exceeded" }, + { SIP_PDU::Local_NoCompatibleListener, "No compatible listener" }, + { SIP_PDU::Local_CannotMapScheme, "Cannot map URI scheme to registration" }, { 0 } }; @@ -1493,7 +1495,7 @@ } -void SIPMIMEInfo::GetAlertInfo(PString & info, int & appearance) +void SIPMIMEInfo::GetAlertInfo(PString & info, int & appearance) const { info.MakeEmpty(); appearance = -1; @@ -2090,8 +2092,16 @@ *stream >> cmd >> m_mime; if (!stream->good() || cmd.IsEmpty() || m_mime.IsEmpty()) { - PTRACE(1, "SIP\tInvalid datagram from " << transport.GetLastReceivedAddress() - << " - " << pdu.GetSize() << " bytes.\n" << hex << setprecision(2) << pdu << dec); +#if PTRACING + if (stream->good() && cmd.IsEmpty() && m_mime.IsEmpty()) + PTRACE(5, "SIP\tProbable keep-alive from " << transport.GetLastReceivedAddress()); + else if (pdu.IsEmpty()) + PTRACE(1, "SIP\tInvalid message from " << transport.GetLastReceivedAddress() + << ", request \"" << cmd << "\", mime:\n" << m_mime); + else + PTRACE(1, "SIP\tInvalid datagram from " << transport.GetLastReceivedAddress() + << " - " << pdu.GetSize() << " bytes:\n" << hex << setprecision(2) << pdu << dec); +#endif return SIP_PDU::Failure_BadRequest; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |