public void FullTraceSIPSwitchUnitTest() { Console.WriteLine("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); SIPMonitorFilter filter = new SIPMonitorFilter("event full and regex :test@"); Console.WriteLine(filter.GetFilterDescription()); Assert.IsTrue(filter != null, "The filter was not correctly instantiated."); //Assert.AreEqual(filter.Username, "test", "The filter username was not correctly set."); Assert.AreEqual(filter.EventFilterDescr, "full", "The filter event full was not correctly set."); Assert.AreEqual(filter.RegexFilter, ":test@", "The regex was not correctly set."); string inviteRequest = "INVITE sip:213.200.94.181 SIP/2.0" + m_CRLF + "Via: SIP/2.0/UDP 192.168.1.32:10254;branch=z9hG4bK-d87543-eb7c9f44883c5955-1--d87543-;rport;received=89.100.104.191" + m_CRLF + "To: aaronxten <sip:[email protected]>" + m_CRLF + "From: test <sip:[email protected]>;tag=774d2561" + m_CRLF + "Call-ID: MTBhNGZjZmQ2OTc3MWU5MTZjNWUxMDYxOTk1MjdmYzk." + m_CRLF + "CSeq: 2 REGISTER" + m_CRLF + "Contact: <sip:[email protected]:10254;rinstance=6d2bbd8014ca7a76>;expires=0" + m_CRLF + "Max-Forwards: 69" + m_CRLF + "User-Agent: X-Lite release 1006e stamp 34025" + m_CRLF + "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO" + m_CRLF + m_CRLF; SIPMonitorEvent monitorEvent = new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.FullSIPTrace, inviteRequest, null); bool showEventResult = filter.ShowSIPMonitorEvent(monitorEvent); Assert.IsTrue(showEventResult, "The filter should have shown this event."); }
private void LogMonitorEvent(SIPMonitorEvent monitorEvent) { if (monitorEvent is SIPMonitorConsoleEvent) { SIPMonitorConsoleEvent consoleEvent = monitorEvent as SIPMonitorConsoleEvent; if (consoleEvent.EventType != SIPMonitorEventTypesEnum.FullSIPTrace && consoleEvent.EventType != SIPMonitorEventTypesEnum.SIPTransaction) { logger.Debug(monitorEvent.Message); } } }
public static SIPMonitorConsoleEvent ParseClientControlEventCSV(string eventCSV) { try { SIPMonitorConsoleEvent monitorEvent = new SIPMonitorConsoleEvent(); if (eventCSV.IndexOf(END_MESSAGE_DELIMITER) != -1) { eventCSV.Remove(eventCSV.Length - 2, 2); } string[] eventFields = eventCSV.Split(new char[] { '|' }); monitorEvent.SessionID = eventFields[1]; monitorEvent.MonitorServerID = eventFields[2]; monitorEvent.ServerType = SIPMonitorServerTypes.GetProxyServerType(eventFields[3]); monitorEvent.EventType = SIPMonitorEventTypes.GetProxyEventType(eventFields[4]); monitorEvent.Created = DateTimeOffset.ParseExact(eventFields[5], SERIALISATION_DATETIME_FORMAT, CultureInfo.InvariantCulture); string serverEndPointStr = eventFields[6]; if (serverEndPointStr != null && serverEndPointStr.Trim().Length > 0) { monitorEvent.ServerEndPoint = SIPEndPoint.ParseSIPEndPoint(serverEndPointStr); } string remoteEndPointStr = eventFields[7]; if (remoteEndPointStr != null && remoteEndPointStr.Trim().Length > 0) { monitorEvent.RemoteEndPoint = SIPEndPoint.ParseSIPEndPoint(remoteEndPointStr); } string dstEndPointStr = eventFields[8]; if (dstEndPointStr != null && dstEndPointStr.Trim().Length > 0) { monitorEvent.DestinationEndPoint = SIPEndPoint.ParseSIPEndPoint(dstEndPointStr); } monitorEvent.Username = eventFields[9]; Int32.TryParse(eventFields[10], out monitorEvent.ProcessID); monitorEvent.Message = eventFields[11].Trim('#'); return(monitorEvent); } catch (Exception excp) { Logger.Logger.Error("Exception SIPMonitorConsoleEvent ParseEventCSV. ->" + excp.Message); return(null); } }
public void BlockIPAddressUnitTest() { Console.WriteLine("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); SIPMonitorFilter filter = new SIPMonitorFilter("ipaddress 127.0.0.1 and event full"); Console.WriteLine(filter.GetFilterDescription()); Assert.IsTrue(filter != null, "The filter was not correctly instantiated."); Assert.AreEqual(filter.IPAddress, "127.0.0.1", "The filter ip address was not correctly set."); SIPMonitorEvent monitorEvent = new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.FullSIPTrace, "blah blah", String.Empty, SIPEndPoint.ParseSIPEndPoint("127.0.0.2"), null); bool showEventResult = filter.ShowSIPMonitorEvent(monitorEvent); Assert.IsFalse(showEventResult, "The filter should not have shown this event."); }
public static SIPMonitorEvent ParseEventCSV(string eventCSV) { if (eventCSV == null || eventCSV.Trim().Length == 0) { return(null); } else if (eventCSV.Trim().StartsWith(SIPMonitorConsoleEvent.SERIALISATION_PREFIX)) { return(SIPMonitorConsoleEvent.ParseClientControlEventCSV(eventCSV)); } else if (eventCSV.Trim().StartsWith(SIPMonitorMachineEvent.SERIALISATION_PREFIX)) { return(SIPMonitorMachineEvent.ParseMachineEventCSV(eventCSV)); } else { logger.LogWarning("The monitor event prefix of " + eventCSV.Trim().Substring(0, 1) + " was not recognised. " + eventCSV); return(null); } }
private void SendMonitorEvent(SIPMonitorEventTypesEnum eventType, string message, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, SIPEndPoint dstEndPoint) { SIPMonitorEvent proxyEvent = new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.SIPProxy, eventType, message, localEndPoint, remoteEndPoint, dstEndPoint); SendMonitorEvent(proxyEvent); }
/// <summary> /// From RFC3261: Stateless Proxy Response Processing: /// /// When a response arrives at a stateless proxy, the proxy MUST inspect the sent-by value in the first /// (topmost) Via header field value. If that address matches the proxy, (it equals a value this proxy has /// inserted into previous requests) the proxy MUST remove that header field value from the response and /// forward the result to the location indicated in the next Via header field value. The proxy MUST NOT add /// to, modify, or remove the message body. Unless specified otherwise, the proxy MUST NOT remove /// any other header field values. If the address does not match the proxy, the message MUST be silently discarded. /// </summary> private void GotResponse(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse) { try { // Used in the proxy monitor messages only, plays no part in response processing. string fromUser = (sipResponse.Header.From != null) ? sipResponse.Header.From.FromURI.User : null; string toUser = (sipResponse.Header.To != null) ? sipResponse.Header.To.ToURI.User : null; string summaryStr = "resp " + sipResponse.Header.CSeqMethod + " from=" + fromUser + ", to=" + toUser + ", " + remoteEndPoint.ToString(); SIPViaHeader topVia = sipResponse.Header.Vias.PopTopViaHeader(); SIPEndPoint outSocket = localSIPEndPoint; // If the second Via header on the response was also set by this proxy it means the request was originally received and forwarded // on different sockets. To get the response to travel the same path in reverse it must be forwarded from the proxy socket indicated // by the second top Via. if (sipResponse.Header.Vias.Length > 1) { SIPViaHeader nextTopVia = sipResponse.Header.Vias.TopViaHeader; SIPEndPoint nextTopViaSIPEndPoint = SIPEndPoint.ParseSIPEndPoint(nextTopVia.Transport + ":" + nextTopVia.ReceivedFromAddress); //if (!(PublicIPAddress != null && nextTopVia.ReceivedFromIPAddress != null && nextTopVia.ReceivedFromIPAddress != PublicIPAddress.ToString()) // && // (m_sipTransport.IsLocalSIPEndPoint(nextTopViaSIPEndPoint) || (PublicIPAddress != null && nextTopVia.ReceivedFromIPAddress == PublicIPAddress.ToString()))) if(m_sipTransport.IsLocalSIPEndPoint(nextTopViaSIPEndPoint)) { sipResponse.Header.Vias.PopTopViaHeader(); outSocket = nextTopViaSIPEndPoint; } } bool isFromAppServer = (m_sipCallDispatcherFile != null) ? m_sipCallDispatcherFile.IsAppServerEndPoint(remoteEndPoint) : false; lock (this) { m_compiledScript.DefaultScope.RemoveVariable("sys"); m_compiledScript.DefaultScope.RemoveVariable("isreq"); m_compiledScript.DefaultScope.RemoveVariable("localEndPoint"); m_compiledScript.DefaultScope.RemoveVariable("outSocket"); m_compiledScript.DefaultScope.RemoveVariable("resp"); m_compiledScript.DefaultScope.RemoveVariable("remoteEndPoint"); m_compiledScript.DefaultScope.RemoveVariable("summary"); m_compiledScript.DefaultScope.RemoveVariable("sipMethod"); m_compiledScript.DefaultScope.RemoveVariable("topVia"); m_compiledScript.DefaultScope.RemoveVariable("IsFromAppServer"); m_compiledScript.DefaultScope.SetVariable("sys", m_proxyScriptFacade); m_compiledScript.DefaultScope.SetVariable("isreq", false); m_compiledScript.DefaultScope.SetVariable("localEndPoint", localSIPEndPoint); m_compiledScript.DefaultScope.SetVariable("outSocket", outSocket); m_compiledScript.DefaultScope.SetVariable("resp", sipResponse); m_compiledScript.DefaultScope.SetVariable("remoteEndPoint", remoteEndPoint); m_compiledScript.DefaultScope.SetVariable("summary", summaryStr); m_compiledScript.DefaultScope.SetVariable("sipMethod", sipResponse.Header.CSeqMethod.ToString()); m_compiledScript.DefaultScope.SetVariable("topVia", topVia); m_compiledScript.DefaultScope.SetVariable("IsFromAppServer", isFromAppServer); m_compiledScript.Execute(); } //if (responseStopwatch.ElapsedMilliseconds > 20) //{ // logger.Debug("GotResponse processing time=" + responseStopwatch.ElapsedMilliseconds + "ms, script time=" + scriptStopwatch.ElapsedMilliseconds + "ms."); //} } catch (Exception excp) { string respExcpError = "Exception SIPProxyCore GotResponse. " + excp.Message; logger.Error(respExcpError + "\n" + sipResponse.ToString()); SIPMonitorEvent respExcpEvent = new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.SIPProxy, SIPMonitorEventTypesEnum.Error, respExcpError, localSIPEndPoint, remoteEndPoint, null); SendMonitorEvent(respExcpEvent); throw excp; } }
/// <summary> /// From RFC3261: Stateless Proxy Request Processing: /// /// For each target, the proxy forwards the request following these /// 1. Make a copy of the received request /// 2. Update the Request-URI /// 3. Update the Max-Forwards header field /// 4. Optionally add a Record-route header field value /// 5. Optionally add additional header fields /// 6. Postprocess routing information /// 7. Determine the next-hop address, port, and transport /// 8. Add a Via header field value /// 9. Add a Content-Length header field if necessary /// 10. Forward the new request /// /// See sections 12.2.1.1 and 16.12.1.2 in the SIP RFC for the best explanation on the way the Route header works. /// </summary> /// <param name="sipRequest"></param> /// <param name="inEndPoint">End point the request was received on.</param> /// <param name="sipChannel"></param> private void GotRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { // Calculate the proxy branch parameter for this request. The branch parameter has to be calculated so that INVITE's and CANCEL's generate the same branchid. //string toTag = (sipRequest.Header.To != null) ? sipRequest.Header.To.ToTag : null; //string fromTag = (sipRequest.Header.From != null) ? sipRequest.Header.From.FromTag : null; string route = (sipRequest.Header.Routes != null) ? sipRequest.Header.Routes.ToString() : null; //string authHeader = (sipRequest.Header.AuthenticationHeader != null) ? sipRequest.Header.AuthenticationHeader.ToString() : null; string proxyBranch = CallProperties.CreateBranchId(SIPConstants.SIP_BRANCH_MAGICCOOKIE, null, null, sipRequest.Header.CallId, sipRequest.URI.ToString(), null, sipRequest.Header.CSeq, route, null, null); // Check whether the branch parameter already exists in the Via list. One instance of an already added Via header will be allowed to support a single spiral. int loopedViaCount = 0; foreach (SIPViaHeader viaHeader in sipRequest.Header.Vias.Via) { //if (viaHeader.Branch == proxyBranch) SIPEndPoint sentFromEndPoint = SIPEndPoint.TryParse(viaHeader.Transport + ":" + viaHeader.ContactAddress); if (sentFromEndPoint != null && m_sipTransport.IsLocalSIPEndPoint(sentFromEndPoint)) { loopedViaCount++; } if (loopedViaCount >= 2) { SendMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.SIPProxy, SIPMonitorEventTypesEnum.Warn, "Loop detected on request from " + remoteEndPoint + " to " + sipRequest.URI.ToString() + ".", null)); m_sipTransport.SendResponse(SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.LoopDetected, null)); return; } } // Used in the proxy monitor messages only, plays no part in request routing. string fromUser = (sipRequest.Header.From != null) ? sipRequest.Header.From.FromURI.User : null; string toUser = (sipRequest.Header.To != null) ? sipRequest.Header.To.ToURI.User : null; string summaryStr = "req " + sipRequest.Method + " from=" + fromUser + ", to=" + toUser + ", " + remoteEndPoint.ToString(); bool isFromAppServer = (m_sipCallDispatcherFile != null) ? m_sipCallDispatcherFile.IsAppServerEndPoint(remoteEndPoint) : false; lock (this) { m_compiledScript.DefaultScope.RemoveVariable("sys"); m_compiledScript.DefaultScope.RemoveVariable("localEndPoint"); m_compiledScript.DefaultScope.RemoveVariable("isreq"); m_compiledScript.DefaultScope.RemoveVariable("req"); m_compiledScript.DefaultScope.RemoveVariable("remoteEndPoint"); m_compiledScript.DefaultScope.RemoveVariable("summary"); m_compiledScript.DefaultScope.RemoveVariable("proxyBranch"); m_compiledScript.DefaultScope.RemoveVariable("sipMethod"); m_compiledScript.DefaultScope.RemoveVariable("publicip"); m_compiledScript.DefaultScope.RemoveVariable("IsFromAppServer"); m_compiledScript.DefaultScope.SetVariable("sys", m_proxyScriptFacade); m_compiledScript.DefaultScope.SetVariable("localEndPoint", localSIPEndPoint); m_compiledScript.DefaultScope.SetVariable("isreq", true); m_compiledScript.DefaultScope.SetVariable("req", sipRequest); m_compiledScript.DefaultScope.SetVariable("remoteEndPoint", remoteEndPoint); m_compiledScript.DefaultScope.SetVariable("summary", summaryStr); m_compiledScript.DefaultScope.SetVariable("proxyBranch", proxyBranch); m_compiledScript.DefaultScope.SetVariable("sipMethod", sipRequest.Method.ToString()); m_compiledScript.DefaultScope.SetVariable("publicip", PublicIPAddress); m_compiledScript.DefaultScope.SetVariable("IsFromAppServer", isFromAppServer); m_compiledScript.Execute(); } //if (requestStopwatch.ElapsedMilliseconds > 20) //{ // logger.Debug("GotRequest processing time=" + requestStopwatch.ElapsedMilliseconds + "ms, script time=" + scriptStopwatch.ElapsedMilliseconds + "ms."); //} } catch (SIPValidationException) { throw; } catch (Exception excp) { string remoteEndPointStr = (remoteEndPoint != null) ? remoteEndPoint.ToString() : null; string reqExcpError = "Exception SIPProxyCore GotRequest (from " + remoteEndPointStr + "). " + excp.Message; logger.Error(reqExcpError); SIPMonitorEvent reqExcpEvent = new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.SIPProxy, SIPMonitorEventTypesEnum.Error, reqExcpError, localSIPEndPoint, remoteEndPoint, null); SendMonitorEvent(reqExcpEvent); throw excp; } }
public void GotRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { // Used in the proxy monitor messages only, plays no part in request routing. string fromUser = (sipRequest.Header.From != null) ? sipRequest.Header.From.FromURI.User : null; string fromURIStr = (sipRequest.Header.From != null) ? sipRequest.Header.From.FromURI.ToString() : "null"; //string toUser = (sipRequest.Header.To != null) ? sipRequest.Header.To.ToURI.User : null; //string summaryStr = "req " + sipRequest.Method + " from=" + fromUser + ", to=" + toUser + ", " + remoteEndPoint.ToString(); //logger.Debug("AppServerCore GotRequest " + sipRequest.Method + " from " + remoteEndPoint.ToString() + " callid=" + sipRequest.Header.CallId + "."); SIPDialogue dialogue = null; // Check dialogue requests for an existing dialogue. if ((sipRequest.Method == SIPMethodsEnum.BYE || sipRequest.Method == SIPMethodsEnum.INFO || sipRequest.Method == SIPMethodsEnum.INVITE || sipRequest.Method == SIPMethodsEnum.MESSAGE || sipRequest.Method == SIPMethodsEnum.NOTIFY || sipRequest.Method == SIPMethodsEnum.OPTIONS || sipRequest.Method == SIPMethodsEnum.REFER) && sipRequest.Header.From != null && sipRequest.Header.From.FromTag != null && sipRequest.Header.To != null && sipRequest.Header.To.ToTag != null) { dialogue = m_sipDialogueManager.GetDialogue(sipRequest); } if (dialogue != null && sipRequest.Method != SIPMethodsEnum.ACK) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Matching dialogue found for " + sipRequest.Method + " to " + sipRequest.URI.ToString() + " from " + remoteEndPoint + ".", dialogue.Owner)); if (sipRequest.Method != SIPMethodsEnum.REFER) { m_sipDialogueManager.ProcessInDialogueRequest(localSIPEndPoint, remoteEndPoint, sipRequest, dialogue); } else { m_sipDialogueManager.ProcessInDialogueReferRequest(localSIPEndPoint, remoteEndPoint, sipRequest, dialogue, m_callManager.BlindTransfer); } } else if (sipRequest.Method == SIPMethodsEnum.CANCEL) { #region CANCEL request handling. UASInviteTransaction inviteTransaction = (UASInviteTransaction)m_sipTransport.GetTransaction(SIPTransaction.GetRequestTransactionId(sipRequest.Header.Vias.TopViaHeader.Branch, SIPMethodsEnum.INVITE)); if (inviteTransaction != null) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Cancelling call for " + sipRequest.URI.ToString() + ".", fromUser)); SIPCancelTransaction cancelTransaction = m_sipTransport.CreateCancelTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, inviteTransaction); cancelTransaction.GotRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "No matching transaction was found for CANCEL to " + sipRequest.URI.ToString() + ".", fromUser)); SIPResponse noCallLegResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); m_sipTransport.SendResponse(noCallLegResponse); } #endregion } else if (sipRequest.Method == SIPMethodsEnum.BYE) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "No dialogue matched for BYE to " + sipRequest.URI.ToString() + ".", fromUser)); SIPResponse noCallLegResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); m_sipTransport.SendResponse(noCallLegResponse); } else if (sipRequest.Method == SIPMethodsEnum.REFER) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "No dialogue matched for REFER to " + sipRequest.URI.ToString() + ".", fromUser)); SIPResponse noCallLegResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); m_sipTransport.SendResponse(noCallLegResponse); } else if (sipRequest.Method == SIPMethodsEnum.ACK) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "No transaction matched for ACK for " + sipRequest.URI.ToString() + ".", fromUser)); } else if (sipRequest.Method == SIPMethodsEnum.INVITE) { #region INVITE request processing. FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "AppServerCore INVITE received, uri=" + sipRequest.URI.ToString() + ", cseq=" + sipRequest.Header.CSeq + ".", null)); if (sipRequest.URI.User == m_dispatcherUsername) { // Incoming call from monitoring process checking the application server is still running. UASInviteTransaction uasTransaction = m_sipTransport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, m_outboundProxy); uasTransaction.CDR = null; SIPServerUserAgent incomingCall = new SIPServerUserAgent(m_sipTransport, m_outboundProxy, sipRequest.URI.User, sipRequest.URI.Host, SIPCallDirection.In, null, null, null, uasTransaction); incomingCall.NoCDR(); uasTransaction.NewCallReceived += (local, remote, transaction, request) => { m_callManager.QueueNewCall(incomingCall); }; uasTransaction.GotRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else if (GetCanonicalDomain_External(sipRequest.Header.From.FromUserField.URI.Host, false) != null) { // Call identified as outgoing call for application server serviced domain. string fromDomain = GetCanonicalDomain_External(sipRequest.Header.From.FromUserField.URI.Host, false); UASInviteTransaction uasTransaction = m_sipTransport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, m_outboundProxy); SIPServerUserAgent outgoingCall = new SIPServerUserAgent(m_sipTransport, m_outboundProxy, fromUser, fromDomain, SIPCallDirection.Out, GetSIPAccount_External, SIPRequestAuthenticator.AuthenticateSIPRequest, FireProxyLogEvent, uasTransaction); uasTransaction.NewCallReceived += (local, remote, transaction, request) => { m_callManager.QueueNewCall(outgoingCall); }; uasTransaction.GotRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else if (GetCanonicalDomain_External(sipRequest.URI.Host, true) != null) { // Call identified as incoming call for application server serviced domain. if (sipRequest.URI.User.IsNullOrBlank()) { // Cannot process incoming call if no user is specified. FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "INVITE received with an empty URI user " + sipRequest.URI.ToString() + ", returning address incomplete.", null)); UASInviteTransaction uasTransaction = m_sipTransport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, m_outboundProxy); SIPResponse addressIncompleteResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.AddressIncomplete, "No user specified"); uasTransaction.SendFinalResponse(addressIncompleteResponse); } else { // Send the incoming call to the call manager for processing. string uriUser = sipRequest.URI.User; string uriDomain = GetCanonicalDomain_External(sipRequest.URI.Host, true); UASInviteTransaction uasTransaction = m_sipTransport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, m_outboundProxy); SIPServerUserAgent incomingCall = new SIPServerUserAgent(m_sipTransport, m_outboundProxy, uriUser, uriDomain, SIPCallDirection.In, GetSIPAccount_External, null, FireProxyLogEvent, uasTransaction); uasTransaction.NewCallReceived += (local, remote, transaction, request) => { m_callManager.QueueNewCall(incomingCall); }; uasTransaction.GotRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } } else { // Return not found for non-serviced domain. FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Domain not serviced " + sipRequest.URI.ToString() + ", returning not found.", null)); UASInviteTransaction uasTransaction = m_sipTransport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, m_outboundProxy); SIPResponse notServicedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Domain not serviced"); uasTransaction.SendFinalResponse(notServicedResponse); } #endregion } else if (sipRequest.Method == SIPMethodsEnum.MESSAGE) { #region Processing non-INVITE requests that are accepted by the dialplan processing engine. if (GetCanonicalDomain_External(sipRequest.Header.From.FromUserField.URI.Host, false) != null) { // Call identified as outgoing request for application server serviced domain. string fromDomain = GetCanonicalDomain_External(sipRequest.Header.From.FromUserField.URI.Host, false); SIPNonInviteTransaction nonInviteTransaction = m_sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, m_outboundProxy); SIPNonInviteServerUserAgent outgoingRequest = new SIPNonInviteServerUserAgent(m_sipTransport, m_outboundProxy, fromUser, fromDomain, SIPCallDirection.Out, GetSIPAccount_External, SIPRequestAuthenticator.AuthenticateSIPRequest, FireProxyLogEvent, nonInviteTransaction); nonInviteTransaction.NonInviteRequestReceived += (local, remote, transaction, request) => { m_callManager.QueueNewCall(outgoingRequest); }; nonInviteTransaction.GotRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else if (GetCanonicalDomain_External(sipRequest.URI.Host, true) != null) { // Call identified as incoming call for application server serviced domain. if (sipRequest.URI.User.IsNullOrBlank()) { // Cannot process incoming call if no user is specified. FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, sipRequest.Method + " request received with an empty URI user " + sipRequest.URI.ToString() + ", returning address incomplete.", null)); SIPResponse addressIncompleteResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.AddressIncomplete, "No user specified"); m_sipTransport.SendResponse(addressIncompleteResponse); } else { // Send the incoming call to the call manager for processing. string uriUser = sipRequest.URI.User; string uriDomain = GetCanonicalDomain_External(sipRequest.URI.Host, true); SIPNonInviteTransaction nonInviteTransaction = m_sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, m_outboundProxy); SIPNonInviteServerUserAgent incomingRequest = new SIPNonInviteServerUserAgent(m_sipTransport, m_outboundProxy, uriUser, uriDomain, SIPCallDirection.In, GetSIPAccount_External, null, FireProxyLogEvent, nonInviteTransaction); nonInviteTransaction.NonInviteRequestReceived += (local, remote, transaction, request) => { m_callManager.QueueNewCall(incomingRequest); }; nonInviteTransaction.GotRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } } else { // Return not found for non-serviced domain. FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Domain not serviced " + sipRequest.URI.ToString() + ", returning not found.", null)); SIPResponse notServicedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Domain not serviced"); m_sipTransport.SendResponse(notServicedResponse); } #endregion } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.UnrecognisedMessage, "MethodNotAllowed response for " + sipRequest.Method + " from " + fromUser + " socket " + remoteEndPoint.ToString() + ".", null)); SIPResponse notAllowedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); m_sipTransport.SendResponse(notAllowedResponse); } } catch (Exception excp) { string reqExcpError = "Exception SIPAppServerCore GotRequest (" + remoteEndPoint + "). " + excp.Message; logger.Error(reqExcpError); SIPMonitorEvent reqExcpEvent = new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.Error, reqExcpError, sipRequest, null, localSIPEndPoint, remoteEndPoint, SIPCallDirection.In); FireProxyLogEvent(reqExcpEvent); throw excp; } }
public static SIPMonitorConsoleEvent ParseClientControlEventCSV(string eventCSV) { try { SIPMonitorConsoleEvent monitorEvent = new SIPMonitorConsoleEvent(); if (eventCSV.IndexOf(END_MESSAGE_DELIMITER) != -1) { eventCSV.Remove(eventCSV.Length - 2, 2); } string[] eventFields = eventCSV.Split(new char[] { '|' }); monitorEvent.SessionID = eventFields[1]; monitorEvent.MonitorServerID = eventFields[2]; monitorEvent.ServerType = SIPMonitorServerTypes.GetProxyServerType(eventFields[3]); monitorEvent.EventType = SIPMonitorEventTypes.GetProxyEventType(eventFields[4]); monitorEvent.Created = DateTimeOffset.ParseExact(eventFields[5], SERIALISATION_DATETIME_FORMAT, CultureInfo.InvariantCulture); string serverEndPointStr = eventFields[6]; if (serverEndPointStr != null && serverEndPointStr.Trim().Length > 0) { monitorEvent.ServerEndPoint = SIPEndPoint.ParseSIPEndPoint(serverEndPointStr); } string remoteEndPointStr = eventFields[7]; if (remoteEndPointStr != null && remoteEndPointStr.Trim().Length > 0) { monitorEvent.RemoteEndPoint = SIPEndPoint.ParseSIPEndPoint(remoteEndPointStr); } string dstEndPointStr = eventFields[8]; if (dstEndPointStr != null && dstEndPointStr.Trim().Length > 0) { monitorEvent.DestinationEndPoint = SIPEndPoint.ParseSIPEndPoint(dstEndPointStr); } monitorEvent.Username = eventFields[9]; Int32.TryParse(eventFields[10], out monitorEvent.ProcessID); monitorEvent.Message = eventFields[11].Trim('#'); return monitorEvent; } catch (Exception excp) { logger.Error("Exception SIPMonitorConsoleEvent ParseEventCSV. " + excp.Message); return null; } }
/// <summary> /// Rules for displaying events. /// 1. The event type is checked to see if it matches. If no event type has been specified than all events EXCEPT FullSIPTrace are /// matched, /// 2. If the event type is FullSIPTrace then the messages can be filtered on the request type. If the request type is not set all /// SIP trace messages are matched otherwise only those pertaining to the request type specified, /// 3. The server type is checked, if it's not set all events are matched, /// 4. If the event has matched up until this point a decision is now made as to whether to display or reject it: /// a. If the IPAddress filter is set is checked, if it matches the event is displayed otherwise it's rejected, /// b. If the username AND server IP AND request type AND regex filters all match the vent is displayed otherwise rejected. /// </summary> /// <param name="proxyEvent"></param> /// <returns></returns> public bool ShowSIPMonitorEvent(SIPMonitorEvent proxyEvent) { if (proxyEvent is SIPMonitorMachineEvent) { #region Machine event filtering. if (BaseType == MACHINE_BASE_TYPE) { if (EventFilterDescr == WILDCARD) { return(ShowUsername(proxyEvent.Username)); } else { SIPMonitorMachineEvent machineEvent = proxyEvent as SIPMonitorMachineEvent; if ((machineEvent.MachineEventType == SIPMonitorMachineEventTypesEnum.SIPDialogueCreated || machineEvent.MachineEventType == SIPMonitorMachineEventTypesEnum.SIPDialogueRemoved || machineEvent.MachineEventType == SIPMonitorMachineEventTypesEnum.SIPDialogueUpdated || machineEvent.MachineEventType == SIPMonitorMachineEventTypesEnum.SIPDialogueTransfer) && SIPEventDialogURI != null) { if (SIPEventDialogURI.User == WILDCARD) { return(ShowUsername(proxyEvent.Username) && ShowMachineEvent(machineEvent.MachineEventType)); } else { return(proxyEvent.Username == Username && machineEvent.ResourceURI != null && machineEvent.ResourceURI.User == SIPEventDialogURI.User && machineEvent.ResourceURI.Host == SIPEventDialogURI.Host); } } else if ((machineEvent.MachineEventType == SIPMonitorMachineEventTypesEnum.SIPRegistrarBindingRemoval || machineEvent.MachineEventType == SIPMonitorMachineEventTypesEnum.SIPRegistrarBindingUpdate) && SIPEventPresenceURI != null) { if (SIPEventPresenceURI.User == WILDCARD) { return(ShowUsername(proxyEvent.Username)); } else { return(proxyEvent.Username == Username && machineEvent.ResourceURI != null && machineEvent.ResourceURI.User == SIPEventPresenceURI.User && machineEvent.ResourceURI.Host == SIPEventPresenceURI.Host); } } else if (SIPEventDialogURI == null && SIPEventPresenceURI == null) { return(ShowUsername(proxyEvent.Username)); } else { return(false); } } } else { return(false); } #endregion } else if (BaseType == MACHINE_BASE_TYPE && !(proxyEvent is SIPMonitorMachineEvent)) { return(false); } else { SIPMonitorConsoleEvent consoleEvent = proxyEvent as SIPMonitorConsoleEvent; string serverAddress = (consoleEvent.ServerEndPoint != null) ? consoleEvent.ServerEndPoint.Address.ToString() : null; string remoteIPAddress = (consoleEvent.RemoteEndPoint != null) ? consoleEvent.RemoteEndPoint.Address.ToString() : null; string dstIPAddress = (consoleEvent.DestinationEndPoint != null) ? consoleEvent.DestinationEndPoint.Address.ToString() : null; if (SIPRequestFilter != WILDCARD && consoleEvent.Message != null && consoleEvent.EventType == SIPMonitorEventTypesEnum.FullSIPTrace) { if (ShowEvent(consoleEvent.EventType, consoleEvent.ServerEndPoint) && ShowServer(consoleEvent.ServerType)) { if (SIPRequestFilter == SIPREQUEST_INVITE_VALUE) { // Do a regex to pick out ACKs, BYEs, CANCELs, INVITEs and REFERs. if (Regex.Match(consoleEvent.Message, "(ACK|BYE|CANCEL|INVITE|REFER) +?sips?:", RegexOptions.IgnoreCase).Success || Regex.Match(consoleEvent.Message, @"CSeq: \d+ (ACK|BYE|CANCEL|INVITE|REFER)(\r|\n)", RegexOptions.IgnoreCase).Success) { return(ShowRegex(consoleEvent.Message) && (ShowIPAddress(remoteIPAddress) || ShowIPAddress(dstIPAddress))); } } else if (SIPRequestFilter == SIPREQUEST_REGISTER_VALUE) { // Do a regex to pick out REGISTERs. if (Regex.Match(consoleEvent.Message, "REGISTER +?sips?:", RegexOptions.IgnoreCase).Success || Regex.Match(consoleEvent.Message, @"CSeq: \d+ REGISTER(\r|\n)", RegexOptions.IgnoreCase).Success) { return(ShowRegex(consoleEvent.Message) && (ShowIPAddress(remoteIPAddress) || ShowIPAddress(dstIPAddress))); } } else if (SIPRequestFilter == SIPREQUEST_NOTIFY_VALUE) { // Do a regex to pick out NOTIFYs and SUBSCRIBEs. if (Regex.Match(consoleEvent.Message, "(NOTIFY|SUBSCRIBE) +?sips?:", RegexOptions.IgnoreCase).Success || Regex.Match(consoleEvent.Message, @"CSeq: \d+ (NOTIFY|SUBSCRIBE)(\r|\n)", RegexOptions.IgnoreCase).Success) { return(ShowRegex(consoleEvent.Message) && (ShowIPAddress(remoteIPAddress) || ShowIPAddress(dstIPAddress))); } } return(false); } } if (ShowEvent(consoleEvent.EventType, consoleEvent.ServerEndPoint)) { bool showIPAddress = ShowIPAddress(remoteIPAddress) || ShowIPAddress(dstIPAddress); bool showUsername = ShowUsername(consoleEvent.Username); bool showServerIP = ShowServerIPAddress(serverAddress); bool showRegex = ShowRegex(consoleEvent.Message); bool showServer = ShowServer(consoleEvent.ServerType); if (showUsername && showServerIP && showRegex && showIPAddress && showServer) { return(true); } } return(false); } }
private void CompleteTrace() { try { SIPMonitorConsoleEvent traceCompleteEvent = new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dialplan trace completed at " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss:fff") + ".", Owner); TraceLog.AppendLine(traceCompleteEvent.EventType + "=> " + traceCompleteEvent.Message); if (!m_traceDirectory.IsNullOrBlank() && Directory.Exists(m_traceDirectory)) { string traceFilename = m_traceDirectory + Owner + "-" + DateTime.Now.ToString("ddMMMyyyyHHmmss") + ".txt"; StreamWriter traceSW = new StreamWriter(traceFilename); traceSW.Write(TraceLog.ToString()); traceSW.Close(); } if (TraceEmailAddress != null) { logger.Debug("Emailing trace to " + TraceEmailAddress + "."); SIPSorcerySMTP.SendEmail(TraceEmailAddress, TRACE_FROM_ADDRESS, TRACE_SUBJECT, TraceLog.ToString()); } } catch (Exception traceExcp) { logger.Error("Exception DialPlanContext CompleteTrace. " + traceExcp.Message); } }
public List<string> GetNotifications(string address, out string sessionId, out string sessionError) { sessionId = null; sessionError = null; try { //logger.Debug("SIPMonitorClientManager GetNotifications for address " + address + "."); /*lock (m_clientsWaiting) { // If there is a callback set for this address the consumer has now received it and it can be removed. if (m_clientsWaiting.ContainsKey(address)) { m_clientsWaiting.Remove(address); } }*/ List<SIPMonitorClientSession> sessions = (m_clientSessions.ContainsKey(address)) ? m_clientSessions[address] : null; if (sessions != null) { sessions = sessions.OrderBy(s => s.LastGetNotificationsRequest).ToList(); for (int index = 0; index < sessions.Count; index++) { SIPMonitorClientSession session = sessions[index]; session.LastGetNotificationsRequest = DateTime.Now; if (!session.FilterDescriptionNotificationSent && session.SessionType == SIPMonitorClientTypesEnum.Console) { //logger.Debug("First notifications request after new console client filter set."); session.FilterDescriptionNotificationSent = true; sessionId = session.SessionID; SIPMonitorConsoleEvent filterDescriptionEvent = new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Monitor, SIPMonitorEventTypesEnum.Monitor, session.Filter.GetFilterDescription(), session.CustomerUsername); return new List<string>() { filterDescriptionEvent.ToConsoleString(session.AdminId) }; } else if (session.Events.Count > 0) { List<string> eventList = new List<string>(); sessionId = session.SessionID; lock (session.Events) { while (session.Events.Count > 0) { SIPMonitorEvent monitorEvent = session.Events.Dequeue(); if (monitorEvent is SIPMonitorConsoleEvent) { eventList.Add(((SIPMonitorConsoleEvent)monitorEvent).ToConsoleString(session.AdminId)); } else { eventList.Add(monitorEvent.ToCSV()); } } } return eventList; } } } return null; } catch (Exception excp) { logger.Error("Exception SIPMonitorClientManager GetNotifications. " + excp.Message); sessionError = "Exception SIPMonitorClientManager GetNotifications. " + excp.Message; return null; //throw; } }
private void LogSecondarySTUNRequestReceived(IPEndPoint localSIPEndPoint, IPEndPoint remoteEndPoint, byte[] buffer, int bufferLength) { SIPMonitorEvent stunEvent = new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.SIPProxy, SIPMonitorEventTypesEnum.STUNSecondary, "Secondary STUN request recevied from " + remoteEndPoint + ".", null); FireSIPMonitorEvent(stunEvent); }