public static SIPMethodsEnum GetMethod(string method) { SIPMethodsEnum sipMethod = SIPMethodsEnum.UNKNOWN; try { sipMethod = (SIPMethodsEnum)Enum.Parse(typeof(SIPMethodsEnum), method, true); } catch { } return(sipMethod); }
/// <summary> /// Builds a very basic SIP request. In most cases additional headers will need to be added in order for it to be useful. /// When this method is called the channel used for sending the request has not been decided. The headers below depend on /// the sending channel. By setting them to "0.0.0.0:0" the send request methods will substitute in the appropriate value /// at send time: /// - Top Via header. /// - From header. /// - Contact header. /// </summary> /// <param name="method">The method for the SIP request.</param> /// <param name="uri">The destination URI for the request.</param> /// <param name="to">The To header for the request.</param> /// <param name="from">The From header for the request.</param> /// <param name="localIpEndPoint">本地端点设置</param> /// <returns>A SIP request object.</returns> public static SIPRequest GetRequest(SIPMethodsEnum method, SIPURI uri, SIPToHeader to, SIPFromHeader from, SIPEndPoint localSipEndPoint = null) { SIPRequest request = new SIPRequest(method, uri); SIPHeader header = new SIPHeader(from, to, 1, CallProperties.CreateNewCallId()); request.Header = header; header.CSeqMethod = method; header.Allow = m_allowedSIPMethods; header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader(localSipEndPoint)); return(request); }
public SIPRequest(SIPMethodsEnum method, string uri) { try { Method = method; URI = SIPURI.ParseSIPURI(uri); SIPVersion = m_sipFullVersion; } catch (Exception excp) { logger.LogError("Exception SIPRequest ctor. " + excp.Message); throw; } }
/// <summary> /// Attempts to generate a SIP request authentication header from the most appropriate digest challenge. /// </summary> /// <param name="authenticationChallenges">The challenges to authenticate the request against. Typically the challenges come from a /// SIP response.</param> /// <param name="uri">The URI of the SIP request being authenticated.</param> /// <param name="method">The method of the SIP request being authenticated.</param> /// <param name="username">The username to authenticate with.</param> /// <param name="password">The password to authenticate with.</param> /// <param name="digestAlgorithm">The digest algorithm to use in the authentication header.</param> /// <returns>An authentication header that can be added to a SIP header.</returns> public static SIPAuthenticationHeader GetAuthenticationHeader(List <SIPAuthenticationHeader> authenticationChallenges, SIPURI uri, SIPMethodsEnum method, string username, string password, DigestAlgorithmsEnum digestAlgorithm = DigestAlgorithmsEnum.MD5) { var challenge = authenticationChallenges.First().SIPDigest.CopyOf(); challenge.DigestAlgorithm = digestAlgorithm; challenge.SetCredentials(username, password, uri.ToString(), method.ToString()); var authHeader = new SIPAuthenticationHeader(challenge); authHeader.SIPDigest.Response = challenge.GetDigest(); return(authHeader); }
public void SendRequest(SIPMethodsEnum method) { try { SIPRequest req = GetRequest(method); SIPNonInviteTransaction tran = m_sipTransport.CreateNonInviteTransaction(req, null, m_sipTransport.GetDefaultSIPEndPoint(), m_outboundProxy); ManualResetEvent waitForResponse = new ManualResetEvent(false); tran.NonInviteTransactionTimedOut += RequestTimedOut; tran.NonInviteTransactionFinalResponseReceived += ServerResponseReceived; tran.SendReliableRequest(); } catch (Exception excp) { logger.LogError("Exception SIPNonInviteClientUserAgent SendRequest to " + m_callDescriptor.Uri + ". " + excp.Message); throw; } }
public void SendRequest(SIPMethodsEnum method) { try { SIPRequest req = GetRequest(method); SIPNonInviteTransaction tran = new SIPNonInviteTransaction(m_sipTransport, req, m_outboundProxy); ManualResetEvent waitForResponse = new ManualResetEvent(false); tran.NonInviteTransactionFailed += TransactionFailed; tran.NonInviteTransactionFinalResponseReceived += ServerResponseReceived; tran.SendRequest(); } catch (Exception excp) { logger.LogError("Exception SIPNonInviteClientUserAgent SendRequest to " + m_callDescriptor.Uri + ". " + excp.Message); throw; } }
/// <summary> /// Builds a basic SIP request with the header fields set to correctly identify it as an /// in dialog request. Calling this method also increments the dialog's local CSeq counter. /// This is safe to do even if the request does not end up being sent. /// </summary> /// <param name="method">The method of the SIP request to create.</param> /// <returns>An in dialog SIP request.</returns> public SIPRequest GetInDialogRequest(SIPMethodsEnum method) { CSeq++; SIPRequest inDialogRequest = new SIPRequest(method, RemoteTarget); SIPFromHeader fromHeader = SIPFromHeader.ParseFromHeader(LocalUserField.ToString()); SIPToHeader toHeader = SIPToHeader.ParseToHeader(RemoteUserField.ToString()); int cseq = CSeq; SIPHeader header = new SIPHeader(fromHeader, toHeader, cseq, CallId); header.CSeqMethod = method; inDialogRequest.Header = header; inDialogRequest.Header.Routes = RouteSet; inDialogRequest.Header.ProxySendFrom = ProxySendFrom; inDialogRequest.Header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader()); return(inDialogRequest); }
public bool ShowRequest(SIPMethodsEnum sipMethod) { if (SIPRequestFilter == WILDCARD) { return(true); } else { if (SIPRequestFilter == SIPREQUEST_INVITE_VALUE) { return(sipMethod == SIPMethodsEnum.INVITE || sipMethod == SIPMethodsEnum.ACK || sipMethod == SIPMethodsEnum.BYE || sipMethod == SIPMethodsEnum.CANCEL); } else if (SIPRequestFilter == SIPREQUEST_REGISTER_VALUE) { return(sipMethod == SIPMethodsEnum.REGISTER); } return(false); } }
/// <summary> /// Generates the ACK or PRACK request to acknowledge a response. This method generates the ACK requests /// for INVITE 2xx and PRACK for 1xx responses. The request needs to be sent as part of a new transaction. /// Note for constructing the ACK for INVITE >= 300 responses is <seealso cref="GetInTransactionACKRequest"/>. /// </summary> /// <param name="ackResponse">The response being acknowledged.</param> /// <param name="ackMethod">The acknowledgement request method, either ACK or PRACK.</param> /// <param name="cseq">The SIP CSeq header value to set on the acknowledge request.</param> /// <param name="content">The optional content body for the ACK request.</param> /// <param name="contentType">The optional content type.</param> private SIPRequest GetAcknowledgeRequest(SIPResponse ackResponse, SIPMethodsEnum ackMethod, int cseq, string content, string contentType) { if (ackResponse.Header.To != null) { m_remoteTag = ackResponse.Header.To.ToTag; } SIPURI requestURI = m_transactionRequest.URI.CopyOf(); if (ackResponse.Header.Contact?.Count > 0) { requestURI = ackResponse.Header.Contact[0].ContactURI; // Don't mangle private contacts if there is a Record-Route header. If a proxy is putting private IP's // in a Record-Route header that's its problem. if ((ackResponse.Header.RecordRoutes == null || ackResponse.Header.RecordRoutes.Length == 0) && IPSocket.IsPrivateAddress(requestURI.Host) && !ackResponse.Header.ProxyReceivedFrom.IsNullOrBlank()) { // Setting the Proxy-ReceivedOn header is how an upstream proxy will let an agent know it should // mangle the contact. SIPEndPoint remoteUASSIPEndPoint = SIPEndPoint.ParseSIPEndPoint(ackResponse.Header.ProxyReceivedFrom); requestURI.Host = remoteUASSIPEndPoint.GetIPEndPoint().ToString(); } } // ACK for 2xx response needs to be a new transaction and gets routed based on SIP request fields. var ackRequest = GetNewTxACKRequest(ackMethod, cseq, ackResponse, requestURI); if (content.NotNullOrBlank()) { ackRequest.Body = content; ackRequest.Header.ContentLength = ackRequest.Body.Length; ackRequest.Header.ContentType = contentType; } return(ackRequest); }
/// <summary> /// New transaction ACK requests are for 2xx responses, i.e. INVITE accepted and /// dialogue being created. /// </summary> /// <remarks> /// From RFC 3261 Chapter 13.2.2.4 - ACK for 2xx final responses /// /// IMPORTANT: /// an ACK for a 2xx final response is a new transaction and has a new branch ID. /// /// The UAC core MUST generate an ACK request for each 2xx received from /// the transaction layer. The header fields of the ACK are constructed /// in the same way as for any request sent within a dialog (see Section /// 12) with the exception of the CSeq and the header fields related to /// authentication. The sequence number of the CSeq header field MUST be /// the same as the INVITE being acknowledged, but the CSeq method MUST /// be ACK. The ACK MUST contain the same credentials as the INVITE. If /// the 2xx contains an offer (based on the rules above), the ACK MUST /// carry an answer in its body. If the offer in the 2xx response is not /// acceptable, the UAC core MUST generate a valid answer in the ACK and /// then send a BYE immediately. /// </remarks> private SIPRequest GetNewTxACKRequest(SIPMethodsEnum method, int cseq, SIPResponse sipResponse, SIPURI ackURI) { SIPRequest acknowledgeRequest = new SIPRequest(method, ackURI.ToString()); acknowledgeRequest.SetSendFromHints(sipResponse.LocalSIPEndPoint); SIPHeader header = new SIPHeader(TransactionRequest.Header.From, sipResponse.Header.To, cseq, sipResponse.Header.CallId); header.CSeqMethod = method; header.AuthenticationHeaders = TransactionRequest.Header.AuthenticationHeaders; header.ProxySendFrom = TransactionRequest.Header.ProxySendFrom; // If the UAS supplies a desired Record-Route list use that first. Otherwise fall back to any Route list used in the original transaction. if (sipResponse.Header.RecordRoutes != null) { header.Routes = sipResponse.Header.RecordRoutes.Reversed(); } else if (TransactionRequest.Header.Routes != null) { header.Routes = TransactionRequest.Header.Routes; } acknowledgeRequest.Header = header; acknowledgeRequest.Header.Vias.PushViaHeader(SIPViaHeader.GetDefaultSIPViaHeader(null)); if (method == SIPMethodsEnum.PRACK) { m_sentPrack = true; acknowledgeRequest.Header.RAckRSeq = sipResponse.Header.RSeq; acknowledgeRequest.Header.RAckCSeq = sipResponse.Header.CSeq; acknowledgeRequest.Header.RAckCSeqMethod = sipResponse.Header.CSeqMethod; } return(acknowledgeRequest); }
/// <summary> /// Transaction matching see RFC3261 17.1.3 & 17.2.3 for matching client and server transactions respectively. /// IMPORTANT NOTE this transaction matching applies to all requests and responses EXCEPT ACK requests to 2xx responses see 13.2.2.4. /// For ACK's to 2xx responses the ACK represents a separate transaction. However for a UAS sending an INVITE response the ACK still has to be /// matched to an existing server transaction in order to transition it to a Confirmed state. /// /// ACK's: /// - The ACK for a 2xx response will have the same CallId, From Tag and To Tag. /// - An ACK for a non-2xx response will have the same branch ID as the INVITE whose response it acknowledges. /// </summary> /// <param name="sipRequest"></param> /// <returns></returns> public SIPTransaction GetTransaction(SIPRequest sipRequest) { // The branch is mandatory but it doesn't stop some UA's not setting it. if (sipRequest.Header.Vias.TopViaHeader.Branch == null || sipRequest.Header.Vias.TopViaHeader.Branch.Trim().Length == 0) { return(null); } SIPMethodsEnum transactionMethod = (sipRequest.Method != SIPMethodsEnum.ACK) ? sipRequest.Method : SIPMethodsEnum.INVITE; string transactionId = SIPTransaction.GetRequestTransactionId(sipRequest.Header.Vias.TopViaHeader.Branch, transactionMethod); string contactAddress = (sipRequest.Header.Contact != null && sipRequest.Header.Contact.Count > 0) ? sipRequest.Header.Contact[0].ToString() : "no contact"; lock (m_transactions) { //if (transactionMethod == SIPMethodsEnum.ACK) //{ //logger.LogInformation("Matching ACK with contact=" + contactAddress + ", cseq=" + sipRequest.Header.CSeq + "."); //} if (transactionId != null && m_transactions.ContainsKey(transactionId)) { //if (transactionMethod == SIPMethodsEnum.ACK) //{ //logger.LogInformation("ACK for contact=" + contactAddress + ", cseq=" + sipRequest.Header.CSeq + " was matched by branchid."); //} return(m_transactions[transactionId]); } else { // No normal match found so look fo a 2xx INVITE response waiting for an ACK. if (sipRequest.Method == SIPMethodsEnum.ACK) { //logger.LogDebug("Looking for ACK transaction, branchid=" + sipRequest.Header.Via.TopViaHeader.Branch + "."); foreach (SIPTransaction transaction in m_transactions.Values) { // According to the standard an ACK should only not get matched by the branchid on the original INVITE for a non-2xx response. However // my Cisco phone created a new branchid on ACKs to 487 responses and since the Cisco also used the same Call-ID and From tag on the initial // unauthenticated request and the subsequent authenticated request the condition below was found to be the best way to match the ACK. /*if (transaction.TransactionType == SIPTransactionTypesEnum.Invite && transaction.TransactionFinalResponse != null && transaction.TransactionState == SIPTransactionStatesEnum.Completed) * { * if (transaction.TransactionFinalResponse.Header.CallId == sipRequest.Header.CallId && * transaction.TransactionFinalResponse.Header.To.ToTag == sipRequest.Header.To.ToTag && * transaction.TransactionFinalResponse.Header.From.FromTag == sipRequest.Header.From.FromTag) * { * return transaction; * } * }*/ // As an experiment going to try matching on the Call-ID. This field seems to be unique and therefore the chance // of collisions seemingly very slim. As a safeguard if there happen to be two transactions with the same Call-ID in the list the match will not be made. // One case where the Call-Id match breaks down is for in-Dialogue requests in that case there will be multiple transactions with the same Call-ID and tags. //if (transaction.TransactionType == SIPTransactionTypesEnum.Invite && transaction.TransactionFinalResponse != null && transaction.TransactionState == SIPTransactionStatesEnum.Completed) if (transaction.TransactionType == SIPTransactionTypesEnum.Invite && transaction.TransactionFinalResponse != null) { if (transaction.TransactionRequest.Header.CallId == sipRequest.Header.CallId && transaction.TransactionFinalResponse.Header.To.ToTag == sipRequest.Header.To.ToTag && transaction.TransactionFinalResponse.Header.From.FromTag == sipRequest.Header.From.FromTag && transaction.TransactionFinalResponse.Header.CSeq == sipRequest.Header.CSeq) { //logger.LogInformation("ACK for contact=" + contactAddress + ", cseq=" + sipRequest.Header.CSeq + " was matched by callid, tags and cseq."); return(transaction); } else if (transaction.TransactionRequest.Header.CallId == sipRequest.Header.CallId && transaction.TransactionFinalResponse.Header.CSeq == sipRequest.Header.CSeq && IsCallIdUniqueForPending(sipRequest.Header.CallId)) { string requestEndPoint = (sipRequest.RemoteSIPEndPoint != null) ? sipRequest.RemoteSIPEndPoint.ToString() : " ? "; //logger.LogInformation("ACK for contact=" + contactAddress + ", cseq=" + sipRequest.Header.CSeq + " was matched using Call-ID mechanism (to tags: " + transaction.TransactionFinalResponse.Header.To.ToTag + "=" + sipRequest.Header.To.ToTag + ", from tags:" + transaction.TransactionFinalResponse.Header.From.FromTag + "=" + sipRequest.Header.From.FromTag + ")."); return(transaction); } } } //logger.LogInformation("ACK for contact=" + contactAddress + ", cseq=" + sipRequest.Header.CSeq + " was not matched."); } return(null); } } }
public static string GetRequestTransactionId(string branchId, SIPMethodsEnum method) { return Crypto.GetSHAHashAsString(branchId + method.ToString()); }
private SIPRequest GetRequest(SIPMethodsEnum method) { try { SIPURI uri = SIPURI.ParseSIPURIRelaxed(m_callDescriptor.Uri); SIPRequest request = new SIPRequest(method, uri); SIPFromHeader fromHeader = m_callDescriptor.GetFromHeader(); fromHeader.FromTag = CallProperties.CreateNewTag(); SIPToHeader toHeader = new SIPToHeader(null, uri, null); int cseq = Crypto.GetRandomInt(10000, 20000); SIPHeader header = new SIPHeader(fromHeader, toHeader, cseq, CallProperties.CreateNewCallId()); header.CSeqMethod = method; header.UserAgent = m_userAgent; request.Header = header; SIPViaHeader viaHeader = new SIPViaHeader(m_sipTransport.GetDefaultSIPEndPoint(), CallProperties.CreateBranchId()); request.Header.Vias.PushViaHeader(viaHeader); try { if (m_callDescriptor.CustomHeaders != null && m_callDescriptor.CustomHeaders.Count > 0) { foreach (string customHeader in m_callDescriptor.CustomHeaders) { if (customHeader.IsNullOrBlank()) { continue; } else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_USERAGENT)) { request.Header.UserAgent = customHeader.Substring(customHeader.IndexOf(":") + 1).Trim(); } else { request.Header.UnknownHeaders.Add(customHeader); } } } } catch (Exception excp) { logger.Error("Exception Parsing CustomHeader for SIPNonInviteClientUserAgent GetRequest. " + excp.Message + m_callDescriptor.CustomHeaders); } if (!m_callDescriptor.Content.IsNullOrBlank()) { request.Body = m_callDescriptor.Content; request.Header.ContentType = m_callDescriptor.ContentType; request.Header.ContentLength = request.Body.Length; } return request; } catch (Exception excp) { logger.Error("Exception SIPNonInviteClientUserAgent GetRequest. " + excp.Message); throw excp; } }
public SIPRequest(SIPMethodsEnum method, SIPURI uri) { //Created++; Method = method; URI = uri; SIPVersion = m_sipFullVersion; }
public SIPRequest GetRequest(SIPMethodsEnum method, SIPURI uri, SIPToHeader to, SIPEndPoint localSIPEndPoint) { if (localSIPEndPoint == null) { localSIPEndPoint = GetDefaultSIPEndPoint(); } SIPRequest request = new SIPRequest(method, uri); request.LocalSIPEndPoint = localSIPEndPoint; SIPContactHeader contactHeader = new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, localSIPEndPoint)); SIPFromHeader fromHeader = new SIPFromHeader(null, contactHeader.ContactURI, CallProperties.CreateNewTag()); SIPHeader header = new SIPHeader(contactHeader, fromHeader, to, 1, CallProperties.CreateNewCallId()); request.Header = header; header.CSeqMethod = method; header.Allow = ALLOWED_SIP_METHODS; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); header.Vias.PushViaHeader(viaHeader); return request; }
public SIPRequest(SIPMethodsEnum method, SIPURI uri) { Method = method; URI = uri; SIPVersion = m_sipFullVersion; }
public static string GetRequestTransactionId(string branchId, SIPMethodsEnum method) { return(Crypto.GetSHAHashAsString(branchId + method.ToString())); }
public SIPRequest GetSIPRequest(SIPMethodsEnum sipMethod, string requestURIStr, string fromURIStr, int cseq, string callId) { return(GetSIPRequest(sipMethod, requestURIStr, fromURIStr, cseq, callId, null, null)); }
public void UpdateGraph() { try { try { DateTime startTime = DateTime.Now; // Take a copy of the metrics file. if (File.Exists(m_metricsFileCopyName)) { File.Delete(m_metricsFileCopyName); } logger.Debug("Copying " + m_metricsFileName + " to " + m_metricsFileCopyName); File.Copy(m_metricsFileName, m_metricsFileCopyName); StreamReader metricsReader = new StreamReader(m_metricsFileCopyName); m_totalSIPPacketsList.Clear(); m_sipRequestsInList.Clear(); m_sipResponsesInList.Clear(); m_sipRequestsOutList.Clear(); m_sipResponsesOutList.Clear(); m_pendingTransactionsList.Clear(); m_discardsList.Clear(); m_unrecognisedList.Clear(); m_tooLargeList.Clear(); m_badSIPList.Clear(); m_stunList.Clear(); m_totalParseTimeList.Clear(); m_avgParseTimeList.Clear(); m_sipMethodsLists = new Dictionary <SIPMethodsEnum, RollingPointPairList>(); m_topTalkersLists.Clear(); m_topTalkersCount.Clear(); string metricsLine = metricsReader.ReadLine(); int sampleCount = 0; while (metricsLine != null) { #region Process metrics line. if (metricsLine.Trim().Length != 0 && Regex.Match(metricsLine, ",").Success) { string[] fields = metricsLine.Split(','); XDate sampleDate = new XDate(DateTime.Parse(fields[1])); int samplePeriod = Convert.ToInt32(fields[2]); // Sample period in seconds. if (samplePeriod == 0) { throw new ApplicationException("The sample period for a measurement was 0 in SIPTransportMetricsGraphAgent."); } if (metricsLine.StartsWith(m_trafficMetrics)) { try { m_totalSIPPacketsList.Add(sampleDate, Convert.ToDouble(fields[3]) / samplePeriod); m_sipRequestsInList.Add(sampleDate, Convert.ToDouble(fields[4]) / samplePeriod); m_sipResponsesInList.Add(sampleDate, Convert.ToDouble(fields[5]) / samplePeriod); m_sipRequestsOutList.Add(sampleDate, Convert.ToDouble(fields[6]) / samplePeriod); m_sipResponsesOutList.Add(sampleDate, Convert.ToDouble(fields[7]) / samplePeriod); m_pendingTransactionsList.Add(sampleDate, Convert.ToDouble(fields[8])); m_unrecognisedList.Add(sampleDate, Convert.ToDouble(fields[9]) / samplePeriod); m_badSIPList.Add(sampleDate, Convert.ToDouble(fields[10]) / samplePeriod); m_stunList.Add(sampleDate, Convert.ToDouble(fields[11]) / samplePeriod); m_discardsList.Add(sampleDate, Convert.ToDouble(fields[12]) / samplePeriod); m_tooLargeList.Add(sampleDate, Convert.ToDouble(fields[13]) / samplePeriod); m_totalParseTimeList.Add(sampleDate, Convert.ToDouble(fields[14]) / samplePeriod); m_avgParseTimeList.Add(sampleDate, Convert.ToDouble(fields[15])); sampleCount++; } catch (Exception sampleExcp) { logger.Warn("Could not process metrics sample: " + metricsLine + ". " + sampleExcp.Message); } } else if (metricsLine.StartsWith(m_methodMetrics)) { for (int index = 3; index < fields.Length; index++) { string[] methodSplit = fields[index].Split('='); SIPMethodsEnum method = SIPMethods.GetMethod(methodSplit[0]); int methodPackets = Convert.ToInt32(methodSplit[1]) / samplePeriod; if (!m_sipMethodsLists.ContainsKey(method)) { m_sipMethodsLists.Add(method, new RollingPointPairList(GRAPH_SAMPLES)); } m_sipMethodsLists[method].Add(sampleDate, methodPackets); } } else if (metricsLine.StartsWith(m_topTalkerMetrics)) { for (int index = 3; index < fields.Length; index++) { string[] talkersSplit = fields[index].Split('='); string topTalkerSocket = talkersSplit[0]; int topTalkerPackets = Convert.ToInt32(talkersSplit[1]) / samplePeriod; if (!m_topTalkersLists.ContainsKey(topTalkerSocket)) { m_topTalkersLists.Add(topTalkerSocket, new RollingPointPairList(GRAPH_SAMPLES)); m_topTalkersCount.Add(topTalkerSocket, 0); } //logger.Debug("Adding point for " + topTalkerSocket + " and " + topTalkerPackets + "."); m_topTalkersLists[topTalkerSocket].Add(sampleDate, topTalkerPackets); m_topTalkersCount[topTalkerSocket] = m_topTalkersCount[topTalkerSocket] + topTalkerPackets; } } } #endregion metricsLine = metricsReader.ReadLine(); } metricsReader.Close(); #region Create the traffic graphs. GraphPane totalSIPPacketsGraphPane = new GraphPane(new Rectangle(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT), "Total SIP Packets per Second", "Time", "Packets/s"); GraphPane pendingSIPTransactionsGraphPane = new GraphPane(new Rectangle(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT), "Pending SIP Transactions", "Time", "Total"); GraphPane breakdownGraphPane = new GraphPane(new Rectangle(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT), "SIP Request and Responses per Second", "Time", "Packets/s"); GraphPane anomaliesGraphPane = new GraphPane(new Rectangle(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT), "Anomalous Packets per Second", "Time", "Packets/s"); GraphPane totalParseTimesGraphPane = new GraphPane(new Rectangle(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT), "SIP Packet Parse Time per Second", "Time", "Total Parse Tme (ms)/s"); GraphPane averageParseTimesGraphPane = new GraphPane(new Rectangle(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT), "Average SIP Packet Parse Time", "Time", "Average Parse Tme (ms)"); totalSIPPacketsGraphPane.Legend.IsVisible = false; totalSIPPacketsGraphPane.XAxis.Type = AxisType.Date; totalSIPPacketsGraphPane.XAxis.Scale.Format = "HH:mm:ss"; pendingSIPTransactionsGraphPane.Legend.IsVisible = false; pendingSIPTransactionsGraphPane.XAxis.Type = AxisType.Date; pendingSIPTransactionsGraphPane.XAxis.Scale.Format = "HH:mm:ss"; breakdownGraphPane.Legend.Location.AlignH = AlignH.Right; breakdownGraphPane.XAxis.Type = AxisType.Date; breakdownGraphPane.XAxis.Scale.Format = "HH:mm:ss"; anomaliesGraphPane.XAxis.Type = AxisType.Date; anomaliesGraphPane.XAxis.Scale.Format = "HH:mm:ss"; totalParseTimesGraphPane.XAxis.Type = AxisType.Date; totalParseTimesGraphPane.Legend.IsVisible = false; totalParseTimesGraphPane.XAxis.Scale.Format = "HH:mm:ss"; averageParseTimesGraphPane.XAxis.Type = AxisType.Date; averageParseTimesGraphPane.Legend.IsVisible = false; averageParseTimesGraphPane.XAxis.Scale.Format = "HH:mm:ss"; LineItem totalSIPPacketsCurve = totalSIPPacketsGraphPane.AddCurve("Total SIP Packets", m_totalSIPPacketsList, Color.Black, SymbolType.None); LineItem pendingTransactionsCurve = pendingSIPTransactionsGraphPane.AddCurve("Pending SIP Transactions", m_pendingTransactionsList, Color.Black, SymbolType.None); LineItem sipRequestsInCurve = breakdownGraphPane.AddCurve("Requests In", m_sipRequestsInList, Color.Blue, SymbolType.None); LineItem sipResponsesInCurve = breakdownGraphPane.AddCurve("Responses In", m_sipResponsesInList, Color.DarkGreen, SymbolType.None); LineItem sipRequestsOutCurve = breakdownGraphPane.AddCurve("Requests Out", m_sipRequestsOutList, Color.BlueViolet, SymbolType.None); LineItem sipResponsesOutCurve = breakdownGraphPane.AddCurve("Responses Out", m_sipResponsesOutList, Color.DarkKhaki, SymbolType.None); LineItem discardsCurve = anomaliesGraphPane.AddCurve("Discards", m_discardsList, Color.Red, SymbolType.None); LineItem badSIPCurve = anomaliesGraphPane.AddCurve("Bad SIP", m_badSIPList, Color.Purple, SymbolType.None); LineItem unrecognisedCurve = anomaliesGraphPane.AddCurve("Unrecognised", m_unrecognisedList, Color.Green, SymbolType.None); LineItem tooLargeCurve = anomaliesGraphPane.AddCurve("Too Large", m_tooLargeList, Color.Coral, SymbolType.None); LineItem stunCurve = anomaliesGraphPane.AddCurve("STUN", m_stunList, Color.Blue, SymbolType.None); LineItem totalParseTimeCurve = totalParseTimesGraphPane.AddCurve("Total Parse Time", m_totalParseTimeList, Color.Black, SymbolType.None); LineItem averageParseTimeCurve = averageParseTimesGraphPane.AddCurve("Average Parse Time", m_avgParseTimeList, Color.Black, SymbolType.None); totalSIPPacketsGraphPane.AxisChange(m_g); pendingSIPTransactionsGraphPane.AxisChange(m_g); breakdownGraphPane.AxisChange(m_g); anomaliesGraphPane.AxisChange(m_g); totalParseTimesGraphPane.AxisChange(m_g); averageParseTimesGraphPane.AxisChange(m_g); Bitmap totalsGraphBitmap = totalSIPPacketsGraphPane.GetImage(); totalsGraphBitmap.Save(m_localGraphsDir + "siptotals.png", ImageFormat.Png); Bitmap pendingTransactionsGraphBitmap = pendingSIPTransactionsGraphPane.GetImage(); pendingTransactionsGraphBitmap.Save(m_localGraphsDir + "siptransactions.png", ImageFormat.Png); Bitmap breakdownGraphBitmap = breakdownGraphPane.GetImage(); breakdownGraphBitmap.Save(m_localGraphsDir + "sipmessagetypes.png", ImageFormat.Png); Bitmap anomaliesGraphBitmap = anomaliesGraphPane.GetImage(); anomaliesGraphBitmap.Save(m_localGraphsDir + "anomalies.png", ImageFormat.Png); Bitmap totalParseTimeGraphBitmap = totalParseTimesGraphPane.GetImage(); totalParseTimeGraphBitmap.Save(m_localGraphsDir + "siptotalparse.png", ImageFormat.Png); Bitmap averageParseTimeGraphBitmap = averageParseTimesGraphPane.GetImage(); averageParseTimeGraphBitmap.Save(m_localGraphsDir + "sipaverageparse.png", ImageFormat.Png); #endregion #region Create SIP methods graph. GraphPane methodsGraphPane = new GraphPane(new Rectangle(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT), "SIP Packets for Method per Second", "Time", "SIP Packets/s"); methodsGraphPane.XAxis.Type = AxisType.Date; methodsGraphPane.XAxis.Scale.Format = "HH:mm:ss"; foreach (KeyValuePair <SIPMethodsEnum, RollingPointPairList> entry in m_sipMethodsLists) { Color methodColor = (m_methodColours.ContainsKey(entry.Key)) ? m_methodColours[entry.Key] : Color.Black; LineItem methodCurve = methodsGraphPane.AddCurve(entry.Key.ToString(), entry.Value, methodColor, SymbolType.None); } methodsGraphPane.AxisChange(m_g); Bitmap methodsGraphBitmap = methodsGraphPane.GetImage(); methodsGraphBitmap.Save(m_localGraphsDir + "sipmethods.png", ImageFormat.Png); #endregion #region Create top talkers graph. // Get the top 10 talkers. if (m_topTalkersCount.Count > 0) { string[] topTalkerSockets = new string[m_topTalkersCount.Count]; int[] topTalkerValues = new int[m_topTalkersCount.Count]; m_topTalkersCount.Keys.CopyTo(topTalkerSockets, 0); m_topTalkersCount.Values.CopyTo(topTalkerValues, 0); Array.Sort <int, string>(topTalkerValues, topTalkerSockets); GraphPane toptalkersGraphPane = new GraphPane(new Rectangle(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT), "SIP Top Talkers", "Time", "SIP Packets/s"); toptalkersGraphPane.XAxis.Type = AxisType.Date; toptalkersGraphPane.XAxis.Scale.Format = "HH:mm:ss"; //foreach (KeyValuePair<string, RollingPointPairList> entry in m_topTalkersLists) for (int index = topTalkerSockets.Length - 1; (index >= topTalkerSockets.Length - NUMBER_TOPTALKERS_TOPPLOT && index >= 0); index--) { string socket = topTalkerSockets[index]; RollingPointPairList topTalkerPoints = m_topTalkersLists[socket]; Color topTalkerColor = m_topTalkerColours[topTalkerSockets.Length - 1 - index]; //logger.Debug("Adding curve for " + socket + " (count=" + topTalkerValues[index] + ")."); LineItem topTalkersCurve = toptalkersGraphPane.AddCurve(socket, topTalkerPoints, topTalkerColor, SymbolType.None); //break; } toptalkersGraphPane.AxisChange(m_g); Bitmap topTalkersGraphBitmap = toptalkersGraphPane.GetImage(); topTalkersGraphBitmap.Save(m_localGraphsDir + "siptoptalkers.png", ImageFormat.Png); } #endregion logger.Debug("Metrics graph for " + m_metricsFileCopyName + " completed in " + DateTime.Now.Subtract(startTime).TotalMilliseconds.ToString("0.##") + "ms, " + sampleCount + " samples."); #region Uplodad file to server. /*if (m_serverFilename != null && m_serverFilename.Trim().Length > 0) * { * Uri target = new Uri(m_serverFilename); * FtpWebRequest request = (FtpWebRequest)WebRequest.Create(target); * request.Method = WebRequestMethods.Ftp.UploadFile; * request.Credentials = new NetworkCredential("anonymous", "*****@*****.**"); * * FileStream localStream = File.OpenRead(m_totalsGraphFilename); * Stream ftpStream = request.GetRequestStream(); * byte[] buffer = new byte[localStream.Length]; * localStream.Read(buffer, 0, buffer.Length); * localStream.Close(); * ftpStream.Write(buffer, 0, buffer.Length); * ftpStream.Close(); * * FtpWebResponse response = (FtpWebResponse)request.GetResponse(); * response.Close(); * //logger.Debug("Result of ftp upload to " + m_serverFilename + " is " + response.StatusDescription + "."); * }*/ #endregion } catch (Exception graphExcp) { logger.Error("Exception Saving Graph. " + graphExcp.Message); } } catch (Exception excp) { logger.Debug("Exception UpdateGraph. " + excp.Message); } }
public SIPRequest GetRequest(SIPMethodsEnum method, SIPURI uri, SIPToHeader to, SIPEndPoint localSIPEndPoint) { if (localSIPEndPoint == null) { localSIPEndPoint = GetDefaultSIPEndPoint(); } SIPRequest request = new SIPRequest(method, uri); request.LocalSIPEndPoint = localSIPEndPoint; SIPContactHeader contactHeader = new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, localSIPEndPoint)); if (!String.IsNullOrWhiteSpace(m_contactGruu)) { contactHeader.ContactURI.Parameters.Set("gr", m_contactGruu); } SIPFromHeader fromHeader = new SIPFromHeader(null, contactHeader.ContactURI, CallProperties.CreateNewTag()); SIPHeader header = new SIPHeader(contactHeader, fromHeader, to, 1, CallProperties.CreateNewCallId()); request.Header = header; header.CSeqMethod = method; header.Allow = ALLOWED_SIP_METHODS; if (m_serviceRoute != null) header.Routes.AddBottomRoute(m_serviceRoute); SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); header.Vias.PushViaHeader(viaHeader); return request; }
public SIPRequest GetSIPRequest(SIPMethodsEnum sipMethod, string requestURIStr, string fromURIStr, int cseq, string callId, string contentType, string body) { SIPURI requestURI = (requestURIStr.StartsWith("sip:")) ? SIPURI.ParseSIPURI(requestURIStr) : SIPURI.ParseSIPURI("sip:" + requestURIStr); SIPURI fromURI = (fromURIStr.StartsWith("sip:")) ? SIPURI.ParseSIPURI(fromURIStr) : SIPURI.ParseSIPURI("sip:" + fromURIStr); SIPFromHeader fromHeader = new SIPFromHeader(null, fromURI, CallProperties.CreateNewTag()); SIPToHeader toHeader = new SIPToHeader(null, requestURI, null); SIPRequest sipRequest = new SIPRequest(sipMethod, requestURI); IPEndPoint localSIPEndPoint = m_sipTransport.GetIPEndPointsList()[0]; SIPHeader sipHeader = new SIPHeader(fromHeader, toHeader, cseq, callId); sipHeader.Contact = SIPContactHeader.ParseContactHeader("sip:" + localSIPEndPoint.ToString()); sipHeader.CSeqMethod = sipMethod; sipRequest.Header = sipHeader; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint.Address.ToString(), localSIPEndPoint.Port, CallProperties.CreateBranchId()); sipRequest.Header.Via.PushViaHeader(viaHeader); if (body != null && body.Trim().Length > 0) { sipRequest.Body = body; //sipRequest.Body = "Signal=5\r\nDuration=250"; //sipRequest.Body = "<rtcp>blah blah blah</rtcp>"; sipRequest.Header.ContentLength = sipRequest.Body.Length; sipRequest.Header.ContentType = contentType; } return sipRequest; }
public SIPRequest GetSIPRequest(SIPMethodsEnum sipMethod, string requestURIStr, string fromURIStr, int cseq, string callId) { return GetSIPRequest(sipMethod, requestURIStr, fromURIStr, cseq, callId, null, null); }
public SIPRequest GetSIPRequest(SIPMethodsEnum sipMethod, string requestURIStr, string fromURIStr) { return GetSIPRequest(sipMethod, requestURIStr, fromURIStr, 1, CallProperties.CreateNewCallId(), null, null); }
private SIPRequest GetRequest(SIPMethodsEnum method) { try { SIPURI uri = SIPURI.ParseSIPURIRelaxed(m_callDescriptor.Uri); SIPRequest request = new SIPRequest(method, uri); SIPFromHeader fromHeader = m_callDescriptor.GetFromHeader(); fromHeader.FromTag = CallProperties.CreateNewTag(); SIPToHeader toHeader = new SIPToHeader(null, uri, null); int cseq = Crypto.GetRandomInt(10000, 20000); SIPHeader header = new SIPHeader(fromHeader, toHeader, cseq, CallProperties.CreateNewCallId()); header.CSeqMethod = method; header.UserAgent = m_userAgent; request.Header = header; SIPViaHeader viaHeader = new SIPViaHeader(m_sipTransport.GetDefaultSIPEndPoint(), CallProperties.CreateBranchId()); request.Header.Vias.PushViaHeader(viaHeader); try { if (m_callDescriptor.CustomHeaders != null && m_callDescriptor.CustomHeaders.Count > 0) { foreach (string customHeader in m_callDescriptor.CustomHeaders) { if (customHeader.IsNullOrBlank()) { continue; } else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_USERAGENT)) { request.Header.UserAgent = customHeader.Substring(customHeader.IndexOf(":") + 1).Trim(); } else { request.Header.UnknownHeaders.Add(customHeader); } } } } catch (Exception excp) { logger.LogError("Exception Parsing CustomHeader for SIPNonInviteClientUserAgent GetRequest. " + excp.Message + m_callDescriptor.CustomHeaders); } if (!m_callDescriptor.Content.IsNullOrBlank()) { request.Body = m_callDescriptor.Content; request.Header.ContentType = m_callDescriptor.ContentType; request.Header.ContentLength = request.Body.Length; } return(request); } catch (Exception excp) { logger.LogError("Exception SIPNonInviteClientUserAgent GetRequest. " + excp.Message); throw excp; } }
/// <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) { string serverAddress = (proxyEvent.ServerEndPoint != null) ? proxyEvent.ServerEndPoint.SocketEndPoint.Address.ToString() : null; string remoteIPAddress = (proxyEvent.RemoteEndPoint != null) ? proxyEvent.RemoteEndPoint.SocketEndPoint.Address.ToString() : null; string dstIPAddress = (proxyEvent.DestinationEndPoint != null) ? proxyEvent.DestinationEndPoint.SocketEndPoint.Address.ToString() : null; SIPMethodsEnum sipMethod = SIPMethodsEnum.NONE; if (SIPRequestFilter != WILDCARD && proxyEvent.Message != null && proxyEvent.EventType == SIPMonitorEventTypesEnum.FullSIPTrace) { if (ShowEvent(proxyEvent.EventType, proxyEvent.ServerEndPoint)) { if (SIPRequestFilter == SIPREQUEST_INVITE_VALUE) { // Do a regex to pick out ACK's, BYE's , CANCEL's and INVITES. if (Regex.Match(proxyEvent.Message, "(ACK|BYE|CANCEL|INVITE) +?sips?:", RegexOptions.IgnoreCase).Success || Regex.Match(proxyEvent.Message, @"CSeq: \d+ (ACK|BYE|CANCEL|INVITE)(\r|\n)", RegexOptions.IgnoreCase).Success) { return(ShowRegex(proxyEvent.Message)); } else { string reqPattern = SIPRequestFilter + " +?sips?:"; string respPattern = @"CSeq: \d+ " + SIPRequestFilter; if (Regex.Match(proxyEvent.Message, reqPattern, RegexOptions.IgnoreCase).Success || Regex.Match(proxyEvent.Message, respPattern, RegexOptions.IgnoreCase).Success) { return(ShowRegex(proxyEvent.Message)); } } } return(false); } } if (ShowEvent(proxyEvent.EventType, proxyEvent.ServerEndPoint) && ShowServer(proxyEvent.ServerType)) { if (IPAddress != WILDCARD) { if (ShowIPAddress(remoteIPAddress)) { return(true); } else if (ShowIPAddress(dstIPAddress)) { return(true); } else { return(false); } } bool showUsername = ShowUsername(proxyEvent.Username); bool showServerIP = ShowServerIPAddress(serverAddress); bool showRequest = ShowRequest(sipMethod); bool showRegex = ShowRegex(proxyEvent.Message); if (showUsername && showServerIP && showRequest && showRegex) { return(true); } } return(false); }
public bool ShowRequest(SIPMethodsEnum sipMethod) { if (SIPRequestFilter == WILDCARD) { return true; } else { if (SIPRequestFilter == SIPREQUEST_INVITE_VALUE) { return (sipMethod == SIPMethodsEnum.INVITE || sipMethod == SIPMethodsEnum.ACK || sipMethod == SIPMethodsEnum.BYE || sipMethod == SIPMethodsEnum.CANCEL); } else if (SIPRequestFilter == SIPREQUEST_REGISTER_VALUE) { return (sipMethod == SIPMethodsEnum.REGISTER); } return false; } }
public SIPRequest(SIPMethodsEnum method, string uri) : this(method, SIPURI.ParseSIPURI(uri)) { }
public SIPRequest(SIPMethodsEnum method, string uri) { Method = method; URI = SIPURI.ParseSIPURI(uri); SIPVersion = m_sipFullVersion; }
public SIPRequest(SIPMethodsEnum method, SIPURI uri, Encoding sipEncoding, Encoding sipBodyEncoding) : base(sipEncoding, sipBodyEncoding) { Method = method; URI = uri; SIPVersion = m_sipFullVersion; }
public SIPRequest GetRequest(SIPMethodsEnum method, SIPURI uri) { return GetRequest(method, uri, new SIPToHeader(null, uri, null), null); }
public void SendRequest(SIPMethodsEnum method) { try { SIPRequest req = GetRequest(method); SIPNonInviteTransaction tran = m_sipTransport.CreateNonInviteTransaction(req, null, m_sipTransport.GetDefaultSIPEndPoint(), m_outboundProxy); ManualResetEvent waitForResponse = new ManualResetEvent(false); tran.NonInviteTransactionTimedOut += RequestTimedOut; tran.NonInviteTransactionFinalResponseReceived += ServerResponseReceived; tran.SendReliableRequest(); } catch (Exception excp) { logger.Error("Exception SIPNonInviteClientUserAgent SendRequest to " + m_callDescriptor.Uri + ". " + excp.Message); throw; } }
public SIPRequest GetSIPRequest(SIPMethodsEnum sipMethod, string requestURIStr, string fromURIStr) { return(GetSIPRequest(sipMethod, requestURIStr, fromURIStr, 1, CallProperties.CreateNewCallId(), null, null)); }
public SIPRequest(SIPMethodsEnum method, string uri) { try { Method = method; URI = SIPURI.ParseSIPURI(uri); SIPVersion = m_sipFullVersion; } catch (Exception excp) { logger.Error("Exception SIPRequest ctor. " + excp.Message); throw; } }