/// <summary> /// Handles responses to our re-INVITE requests. /// </summary> /// <param name="localSIPEndPoint">The local end point the response was received on.</param> /// <param name="remoteEndPoint">The remote end point the response came from.</param> /// <param name="sipTransaction">The UAS transaction the response is part of.</param> /// <param name="sipResponse">The SIP response.</param> private Task <SocketError> ReinviteRequestFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok) { // Update the remote party's SDP. Dialogue.RemoteSDP = sipResponse.Body; MediaSession.SetRemoteDescription(SDP.ParseSDPDescription(sipResponse.Body)); } else { logger.LogWarning($"Re-INVITE request failed with response {sipResponse.ShortDescription}."); } return(Task.FromResult(SocketError.Success)); }
private void NotifyTransactionFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse, SIPEventSubscription subscription) { try { if (sipResponse.StatusCode >= 300) { // The NOTIFY request was met with an error response. MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "A notify request received an error response of " + sipResponse.Status + " " + sipResponse.ReasonPhrase + ".", subscription.SubscriptionDialogue.Owner)); StopSubscription(subscription); } } catch (Exception excp) { logger.Error("Exception NotifyTransactionFinalResponseReceived. " + excp.Message); } }
private void RegistrationTimedOut(SIPTransaction sipTransaction) { m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration transaction to " + m_registrarHost + " for " + m_sipAccountAOR.ToString() + " timed out."); m_waitForRegistrationMRE.Set(); }
void m_serverTransaction_NonInviteTransactionTimedOut(SIPTransaction sipTransaction) { FireReferFailed(this, "SIP timeout for REFER message to " + sipTransaction.TransactionRequestURI.ToString()); }
/// <summary> /// The event handler for responses to the authenticated register request. /// </summary> private void AuthResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok) { if (m_expiry > 0) { m_isRegistered = true; m_expiry = GetUpdatedExpiry(sipResponse); //if (sipResponse.Header.SwitchboardToken != null && m_lastServerNonce != null) //{ // SwitchboardToken = Crypto.SymmetricDecrypt(m_password, m_lastServerNonce, sipResponse.Header.SwitchboardToken); //} if (RegistrationSuccessful != null) { RegistrationSuccessful(m_sipAccountAOR); } } else { m_isRegistered = false; if (RegistrationRemoved != null) { RegistrationRemoved(m_sipAccountAOR); } } m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0) { m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse); SendInitialRegister(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden || sipResponse.Status == SIPResponseStatusCodesEnum.NotFound || sipResponse.Status == SIPResponseStatusCodesEnum.PaymentRequired) { // SIP account does not appear to exist. string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; if (RegistrationFailed != null) { RegistrationFailed(m_sipAccountAOR, "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + "."); } m_exit = true; m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { // SIP account credentials failed. string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; if (RegistrationFailed != null) { RegistrationFailed(m_sipAccountAOR, "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + "."); } m_exit = true; m_waitForRegistrationMRE.Set(); } else { m_isRegistered = false; if (RegistrationTemporaryFailure != null) { RegistrationTemporaryFailure(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + "."); } m_waitForRegistrationMRE.Set(); } } catch (Exception excp) { Logger.Logger.Error("Exception SIPRegistrationUserAgent AuthResponseReceived. ->" + excp.Message); } }
private void SIPNonInviteTransaction_TransactionRequestRetransmit(SIPTransaction sipTransaction, SIPRequest sipRequest, int retransmitNumber) { NonInviteTransactionRequestRetransmit?.Invoke(sipTransaction, sipRequest, retransmitNumber); }
private void UASTransaction_TransactionRemoved(SIPTransaction sipTransaction) { TransactionComplete?.Invoke(this); }
private void ClientTimedOut(SIPTransaction sipTransaction) { try { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentServer, SIPMonitorEventTypesEnum.DialPlan, "UAS for " + m_uasTransaction.TransactionRequest.URI.ToString() + " timed out in transaction state " + m_uasTransaction.TransactionState + ".", null)); //SIPResponse rejectResponse = SIPTransport.GetResponse(m_uasTransaction.TransactionRequest, SIPResponseStatusCodesEnum.ServerTimeout, "No info or final response received within timeout"); //m_uasTransaction.SendFinalResponse(rejectResponse); if (m_uasTransaction.TransactionState == SIPTransactionStatesEnum.Calling && NoRingTimeout != null) { NoRingTimeout(this); } } catch (Exception excp) { logger.Error("Exception ClientTimedOut. " + excp.Message); } }
private void UASTransactionCancelled(SIPTransaction sipTransaction) { logger.Debug("SIPServerUserAgent got cancellation request."); m_isCancelled = true; if (CallCancelled != null) { CallCancelled(this); } }
private void ServerTimedOut(SIPTransaction sipTransaction) { if (!m_callCancelled) { FireCallFailed(this, "Timeout, no response from server"); } }
private void ClientTimedOut(SIPTransaction sipTransaction) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentServer, SIPMonitorEventTypesEnum.Refer, "ReferUAS for " + m_sipTransaction.TransactionRequest.URI.ToString() + " timed out in transaction state " + m_sipTransaction.TransactionState + ".", null)); }
private void ServerInformationResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Information response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + m_serverTransaction.TransactionRequest.URI.ToString() + ".", Owner)); if (m_callCancelled) { // Call was cancelled in the interim. Cancel(); } else { if (sipResponse.Status == SIPResponseStatusCodesEnum.Ringing || sipResponse.Status == SIPResponseStatusCodesEnum.SessionProgress) { FireCallRinging(this, sipResponse); } else { FireCallTrying(this, sipResponse); } } }
private void ServerFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { //if (Thread.CurrentThread.Name.IsNullOrBlank()) //{ // Thread.CurrentThread.Name = THREAD_NAME + DateTime.Now.ToString("HHmmss") + "-" + Crypto.GetRandomString(3); //} Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + m_serverTransaction.TransactionRequest.URI.ToString() + ".", Owner)); //m_sipTrace += "Received " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss") + " " + localEndPoint + "<-" + remoteEndPoint + "\r\n" + sipResponse.ToString(); m_serverTransaction.UACInviteTransactionInformationResponseReceived -= ServerInformationResponseReceived; m_serverTransaction.UACInviteTransactionFinalResponseReceived -= ServerFinalResponseReceived; m_serverTransaction.TransactionTraceMessage -= TransactionTraceMessage; if (m_callCancelled && sipResponse.Status == SIPResponseStatusCodesEnum.RequestTerminated) { // No action required. Correctly received request terminated on an INVITE we cancelled. } else if (m_callCancelled) { #region Call has been cancelled, hangup. if (m_hungupOnCancel) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "A cancelled call to " + m_sipCallDescriptor.Uri + " has been answered AND has already been hungup, no further action being taken.", Owner)); } else { m_hungupOnCancel = true; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "A cancelled call to " + m_sipCallDescriptor.Uri + " has been answered, hanging up.", Owner)); if (sipResponse.Header.Contact != null && sipResponse.Header.Contact.Count > 0) { SIPURI byeURI = sipResponse.Header.Contact[0].ContactURI; SIPRequest byeRequest = GetByeRequest(sipResponse, byeURI, localSIPEndPoint); //SIPEndPoint byeEndPoint = m_sipTransport.GetRequestEndPoint(byeRequest, m_outboundProxy, true); // if (byeEndPoint != null) // { SIPNonInviteTransaction byeTransaction = m_sipTransport.CreateNonInviteTransaction(byeRequest, null, localSIPEndPoint, m_outboundProxy); byeTransaction.SendReliableRequest(); // } // else // { // Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Could not end BYE on cancelled call as request end point could not be determined " + byeRequest.URI.ToString(), Owner)); //} } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "No contact header provided on response for cancelled call to " + m_sipCallDescriptor.Uri + " no further action.", Owner)); } } #endregion } else if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { #region Authenticate client call to third party server. if (!m_callCancelled) { if (m_sipCallDescriptor.Password.IsNullOrBlank()) { // No point trying to authenticate if there is no password to use. Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Forward leg failed, authentication was requested but no credentials were available.", Owner)); FireCallFailed(this, "Authentication requested when no credentials available"); } else if (m_serverAuthAttempts == 0) { m_serverAuthAttempts = 1; // Resend INVITE with credentials. string username = (m_sipCallDescriptor.AuthUsername != null && m_sipCallDescriptor.AuthUsername.Trim().Length > 0) ? m_sipCallDescriptor.AuthUsername : m_sipCallDescriptor.Username; SIPAuthorisationDigest authRequest = sipResponse.Header.AuthenticationHeader.SIPDigest; authRequest.SetCredentials(username, m_sipCallDescriptor.Password, m_sipCallDescriptor.Uri, SIPMethodsEnum.INVITE.ToString()); SIPRequest authInviteRequest = m_serverTransaction.TransactionRequest; authInviteRequest.Header.AuthenticationHeader = new SIPAuthenticationHeader(authRequest); authInviteRequest.Header.AuthenticationHeader.SIPDigest.Response = authRequest.Digest; authInviteRequest.Header.Vias.TopViaHeader.Branch = CallProperties.CreateBranchId(); authInviteRequest.Header.CSeq = authInviteRequest.Header.CSeq + 1; // Create a new UAC transaction to establish the authenticated server call. var originalCallTransaction = m_serverTransaction; m_serverTransaction = m_sipTransport.CreateUACTransaction(authInviteRequest, m_serverEndPoint, localSIPEndPoint, m_outboundProxy); if (m_serverTransaction.CDR != null) { m_serverTransaction.CDR.Owner = Owner; m_serverTransaction.CDR.AdminMemberId = AdminMemberId; m_serverTransaction.CDR.DialPlanContextID = m_sipCallDescriptor.DialPlanContextID; m_serverTransaction.CDR.Updated(); if (AccountCode != null) { #if !SILVERLIGHT RtccUpdateCdr_External?.Invoke(originalCallTransaction.CDR?.CDRId.ToString(), m_serverTransaction.CDR); #endif } logger.Debug("RTCC reservation was reallocated from CDR " + originalCallTransaction.CDR?.CDRId + " to " + m_serverTransaction.CDR?.CDRId + " for owner " + Owner + "."); } m_serverTransaction.UACInviteTransactionInformationResponseReceived += ServerInformationResponseReceived; m_serverTransaction.UACInviteTransactionFinalResponseReceived += ServerFinalResponseReceived; m_serverTransaction.UACInviteTransactionTimedOut += ServerTimedOut; m_serverTransaction.TransactionTraceMessage += TransactionTraceMessage; m_serverTransaction.SendInviteRequest(m_serverEndPoint, authInviteRequest); } else { FireCallFailed(this, "Authentication with provided credentials failed"); } } #endregion } else { if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299) { if (sipResponse.Body.IsNullOrBlank()) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Body on UAC response was empty.", Owner)); } else if (m_sipCallDescriptor.ContentType == m_sdpContentType) { if (!m_sipCallDescriptor.MangleResponseSDP) { IPEndPoint sdpEndPoint = SDP.GetSDPRTPEndPoint(sipResponse.Body); string sdpSocket = (sdpEndPoint != null) ? sdpEndPoint.ToString() : "could not determine"; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response was set to NOT mangle, RTP socket " + sdpEndPoint.ToString() + ".", Owner)); } else { //m_callInProgress = false; // the call is now established //logger.Debug("Final response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + ForwardedTransaction.TransactionRequest.URI.ToString() + "."); // Determine of response SDP should be mangled. IPEndPoint sdpEndPoint = SDP.GetSDPRTPEndPoint(sipResponse.Body); //Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "UAC response SDP was mangled from sdp=" + sdpEndPoint.Address.ToString() + ", proxyfrom=" + sipResponse.Header.ProxyReceivedFrom + ", mangle=" + m_sipCallDescriptor.MangleResponseSDP + ".", null)); if (sdpEndPoint != null) { if (!IPSocket.IsPrivateAddress(sdpEndPoint.Address.ToString())) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response had public IP not mangled, RTP socket " + sdpEndPoint.ToString() + ".", Owner)); } else { bool wasSDPMangled = false; string publicIPAddress = null; if (!sipResponse.Header.ProxyReceivedFrom.IsNullOrBlank()) { IPAddress remoteUASAddress = SIPEndPoint.ParseSIPEndPoint(sipResponse.Header.ProxyReceivedFrom).Address; if (IPSocket.IsPrivateAddress(remoteUASAddress.ToString()) && m_sipCallDescriptor.MangleIPAddress != null) { // If the response has arrived here on a private IP address then it must be // for a local version install and an incoming call that needs it's response mangled. if(!IPSocket.IsPrivateAddress(m_sipCallDescriptor.MangleIPAddress.ToString())) { publicIPAddress = m_sipCallDescriptor.MangleIPAddress.ToString(); } } else { publicIPAddress = remoteUASAddress.ToString(); } } else if (!IPSocket.IsPrivateAddress(remoteEndPoint.Address.ToString()) && remoteEndPoint.Address != IPAddress.Any) { publicIPAddress = remoteEndPoint.Address.ToString(); } else if (m_sipCallDescriptor.MangleIPAddress != null) { publicIPAddress = m_sipCallDescriptor.MangleIPAddress.ToString(); } if (publicIPAddress != null) { sipResponse.Body = SIPPacketMangler.MangleSDP(sipResponse.Body, publicIPAddress, out wasSDPMangled); } if (wasSDPMangled) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response had RTP socket mangled from " + sdpEndPoint.ToString() + " to " + publicIPAddress + ":" + sdpEndPoint.Port + ".", Owner)); } else if (sdpEndPoint != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP on UAC response could not be mangled, RTP socket " + sdpEndPoint.ToString() + ".", Owner)); } } } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "SDP RTP socket on UAC response could not be determined.", Owner)); } } } m_sipDialogue = new SIPDialogue(m_serverTransaction, Owner, AdminMemberId); m_sipDialogue.CallDurationLimit = m_sipCallDescriptor.CallDurationLimit; // Set switchboard dialogue values from the answered response or from dialplan set values. //m_sipDialogue.SwitchboardCallerDescription = sipResponse.Header.SwitchboardCallerDescription; m_sipDialogue.SwitchboardLineName = sipResponse.Header.SwitchboardLineName; m_sipDialogue.CRMPersonName = sipResponse.Header.CRMPersonName; m_sipDialogue.CRMCompanyName = sipResponse.Header.CRMCompanyName; m_sipDialogue.CRMPictureURL = sipResponse.Header.CRMPictureURL; if (m_sipCallDescriptor.SwitchboardHeaders != null) { //if (!m_sipCallDescriptor.SwitchboardHeaders.SwitchboardDialogueDescription.IsNullOrBlank()) //{ // m_sipDialogue.SwitchboardDescription = m_sipCallDescriptor.SwitchboardHeaders.SwitchboardDialogueDescription; //} m_sipDialogue.SwitchboardLineName = m_sipCallDescriptor.SwitchboardHeaders.SwitchboardLineName; m_sipDialogue.SwitchboardOwner = m_sipCallDescriptor.SwitchboardHeaders.SwitchboardOwner; } } FireCallAnswered(this, sipResponse); } } catch (Exception excp) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.Error, "Exception ServerFinalResponseReceived. " + excp.Message, Owner)); } }
private void TransactionTraceMessage(SIPTransaction sipTransaction, string message) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.ReferUserAgentClient, SIPMonitorEventTypesEnum.SIPTransaction, message, Owner)); }
/// <summary> /// The event handler for responses to the authenticated register request. /// </summary> private void AuthResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { logger.LogDebug("Server auth response " + sipResponse.Status + " received for " + m_sipAccountAOR.ToString() + "."); if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok) { if (m_expiry > 0) { m_isRegistered = true; m_expiry = GetUpdatedExpiry(sipResponse); RegistrationSuccessful?.Invoke(m_sipAccountAOR); } else { m_isRegistered = false; RegistrationRemoved?.Invoke(m_sipAccountAOR); } m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0) { m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse); logger.LogDebug("Registration for " + m_sipAccountAOR.ToString() + " had a too short expiry, updated to +" + m_expiry + " and trying again."); SendInitialRegister(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden || sipResponse.Status == SIPResponseStatusCodesEnum.NotFound || sipResponse.Status == SIPResponseStatusCodesEnum.PaymentRequired) { // SIP account does not appear to exist. logger.LogWarning("Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + ", no further registration attempts will be made."); string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; RegistrationFailed?.Invoke(m_sipAccountAOR, "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + "."); m_exit = true; m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { // SIP account credentials failed. logger.LogWarning("Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + ", no further registration attempts will be made."); string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; RegistrationFailed?.Invoke(m_sipAccountAOR, "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + "."); m_exit = true; m_waitForRegistrationMRE.Set(); } else { logger.LogWarning("Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + "."); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + "."); m_waitForRegistrationMRE.Set(); } } catch (Exception excp) { logger.LogError("Exception SIPRegistrationUserAgent AuthResponseReceived. " + excp.Message); } }
private void UASTransaction_TransactionRemoved(SIPTransaction sipTransaction) { if (TransactionComplete != null) { TransactionComplete(this); } }
private void SIPNonInviteTransaction_TransactionRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPRequest sipRequest) { NonInviteRequestReceived?.Invoke(localSIPEndPoint, remoteEndPoint, this, sipRequest); }
/*[OperationContract] public List<SIPRegistrationAgentRecord> GetRegistrationAgentRegistrations(string owner) { try { return m_regAgent.GetOwnerRegistrations(owner); } catch (Exception excp) { logger.Error("Exception GetRegistrationAgentRegistrations. " + excp.Message); throw excp; } } [OperationContract] public void RemoveRegistrationAgentContact(Guid registrationId, string contactToRemove) { try { logger.Debug("RemoveRegistrarContact webservice called for " + registrationId + " and " + contactToRemove + "."); SIPRegistrationAgentRecord registration = m_regAgent.Get(registrationId); if (registration != null) { // Look through the current contacts to try and find one to match this contact. foreach (SIPContactHeader contact in registration.ContactsList) { logger.Debug("Comparing: " + contact.ContactURI.ToString() + " to " + contactToRemove); if (contactToRemove == null || contact.ContactURI.ToString() == contactToRemove) { logger.Debug("Attempting removal of registrar contact " + contact.ContactURI.ToString() + "."); m_regAgent.SendContactRemovalRequest(registrationId, contact.ContactURI); } } } else { logger.Warn("Could not find the registration record for " + registrationId + " in RemoveSIPContact."); } } catch (Exception excp) { logger.Error("Exception RemoveRegistrarContact. " + excp.Message); throw excp; } } [OperationContract] public void RefreshRegistrationAgentContact(Guid registrationId) { try { logger.Debug("RefreshRegistrationView webservice called for " + registrationId + "."); UserRegistration registration = m_regAgent.Get(registrationId); if (registration != null) { m_regAgent.SendEmptyRegistrationRequest(registrationId); } else { logger.Warn("Could not find the registration record for " + registrationId + " in RefreshRegistrationView."); } } catch (Exception excp) { logger.Error("Exception RefreshRegistrationView. " + excp.Message); throw excp; } }*/ /// <summary> /// Send a Message Waiting Indicator request to the specified user agent URI. If setMWI is true the number of messages indicated will /// be one otherwise 0. /// </summary> /*[OperationContract] public void SendMWIRequest(string userAgentURI, bool setMWI, string username) { try { logger.Debug("Attempting SendMWIRequest for " + userAgentURI + " as " + setMWI + "."); SIPURI clientURI = SIPURI.ParseSIPURI(userAgentURI); SIPRequest mwiRequest = SIPNotificationAgent.GetNotifyRequest(m_sipTransport.GetTransportContact(null), null, clientURI, username, setMWI); SIPNonInviteTransaction mwiTransaction = m_sipTransport.CreateNonInviteTransaction(mwiRequest, clientURI.GetURIEndPoint(), m_sipTransport.GetTransportContact(null), SIPProtocolsEnum.UDP); mwiTransaction.NonInviteTransactionFinalResponseReceived += new SIPTransactionResponseReceivedDelegate(MWIFinalResponseReceived); FireProxyLogEvent(new ProxyMonitorEvent(ProxyServerTypesEnum.StatefulProxy, ProxyEventTypesEnum.MWI, "Sending " + setMWI + " mwi to " + SIPURI.ParseSIPURI(userAgentURI).CanonicalAddress, username)); m_sipTransport.SendRequest(mwiRequest, SIPProtocolsEnum.UDP); } catch (Exception excp) { logger.Error("Exception SendMWIRequest. " + excp.Message + "."); } }*/ /*private void MWIFinalResponseReceived(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { string username = sipResponse.Header.From.FromURI.User; logger.Debug("MWI response received from " + IPSocket.GetSocketString(remoteEndPoint) + " " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + username + "."); FireProxyLogEvent(new ProxyMonitorEvent(ProxyServerTypesEnum.StatefulProxy, ProxyEventTypesEnum.MWI, "MWI response received from " + IPSocket.GetSocketString(remoteEndPoint) + " " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase, username)); } catch (Exception excp) { logger.Error("Exception MWIFinalResponseReceived. " + excp.Message); } }*/ /// <summary> /// Send a Message Waiting Indicator request to the specified user agent URI. If setMWI is true the number of messages indicated will /// be one otherwise 0. /// </summary> /*[OperationContract] public void SendInviteRequest(string userAgentURI, string callerIdName, string callerIdUser, string username) { try { logger.Debug("Attempting SendInviteRequest for " + userAgentURI + " as " + callerIdName + " and " + callerIdUser + "."); SIPURI clientURI = SIPURI.ParseSIPURI(userAgentURI); SIPRequest inviteRequest = GetInviteRequest(clientURI, callerIdName, callerIdUser, SERVER_STRING); UACInviteTransaction inviteTransaction = m_sipTransport.CreateUACTransaction(inviteRequest, clientURI.GetURIEndPoint(), m_sipTransport.GetTransportContact(null), SIPProtocolsEnum.UDP); inviteTransaction.UACInviteTransactionFinalResponseReceived += new SIPTransactionResponseReceivedDelegate(InviteFinalResponseReceived); FireProxyLogEvent(new ProxyMonitorEvent(ProxyServerTypesEnum.StatefulProxy, ProxyEventTypesEnum.NewCall, "Sending INVITE to " + SIPURI.ParseSIPURI(userAgentURI).ToString(), username)); inviteTransaction.SendInviteRequest(inviteRequest.GetRequestEndPoint(), inviteRequest); } catch (Exception excp) { logger.Error("Exception SendInviteRequest. " + excp.Message + "."); } }*/ private void InviteFinalResponseReceived(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { logger.Debug("FinalResponseReceived for INVITE to " + sipTransaction.TransactionRequest.URI.ToString() + " " + sipResponse.Status + " " + sipResponse.ReasonPhrase + "."); } catch (Exception excp) { logger.Error("Exception InviteFinalResponseReceived. " + excp.Message); } }
private Task <SocketError> OnAckAnswerReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPRequest sipRequest) { SIPDialogue = new SIPDialogue(m_uasTransaction); SIPDialogue.TransferMode = m_transferMode; OnDialogueCreated?.Invoke(SIPDialogue); return(Task.FromResult(SocketError.Success)); }
private void TransactionInformationResponseReceived(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { m_lastInfoResponse = sipResponse; m_waitForSIPInfoResponse.Set(); }
private void UASTransactionCancelled(SIPTransaction sipTransaction) { logger.LogDebug("SIPServerUserAgent got cancellation request."); m_isCancelled = true; CallCancelled?.Invoke(this); }
private void TransactionFinalResponseReceived(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { m_lastFinalResponse = sipResponse; m_waitForSIPFinalResponse.Set(); }
/// <summary> /// The event handler for responses to the initial register request. /// </summary> private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { if (sipResponse.Header.AuthenticationHeader != null) { if (m_attempts >= MAX_REGISTER_ATTEMPTS) { m_isRegistered = false; if (RegistrationTemporaryFailure != null) { RegistrationTemporaryFailure(m_sipAccountAOR, "Registration reached the maximum number of allowed attempts."); } m_waitForRegistrationMRE.Set(); } else { m_attempts++; SIPRequest authenticatedRequest = GetAuthenticatedRegistrationRequest(sipTransaction.TransactionRequest, sipResponse); SIPNonInviteTransaction regAuthTransaction = m_sipTransport.CreateNonInviteTransaction(authenticatedRequest, sipTransaction.RemoteEndPoint, localSIPEndPoint, m_outboundProxy); regAuthTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) => { ThreadPool.QueueUserWorkItem(delegate { AuthResponseReceived(lep, rep, tn, rsp); }); }; regAuthTransaction.NonInviteTransactionTimedOut += (tn) => { ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); }); }; m_sipTransport.SendSIPReliable(regAuthTransaction); } } else { m_isRegistered = false; if (RegistrationTemporaryFailure != null) { RegistrationTemporaryFailure(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + " but no authentication header was supplied."); } m_waitForRegistrationMRE.Set(); } } else { if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok) { if (m_expiry > 0) { m_isRegistered = true; m_expiry = GetUpdatedExpiry(sipResponse); //if (sipResponse.Header.SwitchboardToken != null && m_lastServerNonce != null) //{ // SwitchboardToken = Crypto.SymmetricDecrypt(m_password, m_lastServerNonce, sipResponse.Header.SwitchboardToken); //} RegistrationSuccessful(m_sipAccountAOR); } else { m_isRegistered = false; RegistrationRemoved(m_sipAccountAOR); } m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden || sipResponse.Status == SIPResponseStatusCodesEnum.NotFound) { // SIP account does not appear to exist. string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; if (RegistrationFailed != null) { RegistrationFailed(m_sipAccountAOR, "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + "."); } m_exit = true; m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0) { m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse); SendInitialRegister(); } else { m_isRegistered = false; if (RegistrationTemporaryFailure != null) { RegistrationTemporaryFailure(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + "."); } m_waitForRegistrationMRE.Set(); } } } catch (Exception excp) { Logger.Logger.Error("Exception SIPRegistrationUserAgent ServerResponseReceived (" + remoteEndPoint + "). ->" + excp.Message); } }
private void TransactionTraceMessage(SIPTransaction sipTransaction, string message) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentServer, SIPMonitorEventTypesEnum.SIPTransaction, message, null)); }
private RegisterResultEnum Register(SIPTransaction registerTransaction) { try { SIPRequest sipRequest = registerTransaction.TransactionRequest; SIPURI registerURI = sipRequest.URI; SIPToHeader toHeader = sipRequest.Header.To; string toUser = toHeader.ToURI.User; string canonicalDomain = (m_strictRealmHandling) ? GetCanonicalDomain_External(toHeader.ToURI.Host, true) : toHeader.ToURI.Host; int requestedExpiry = GetRequestedExpiry(sipRequest); if (canonicalDomain == null) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Warn, "Register request for " + toHeader.ToURI.Host + " rejected as no matching domain found.", null)); SIPResponse noDomainResponse = GetErrorResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced"); registerTransaction.SendFinalResponse(noDomainResponse); return(RegisterResultEnum.DomainNotServiced); } SIPAccountAsset sipAccountAsset = GetSIPAccount_External(s => s.SIPUsername == toUser && s.SIPDomain == canonicalDomain); SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator_External(registerTransaction.LocalSIPEndPoint, registerTransaction.RemoteEndPoint, sipRequest, sipAccountAsset.SIPAccount, FireProxyLogEvent); if (!authenticationResult.Authenticated) { // 401 Response with a fresh nonce needs to be sent. SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; registerTransaction.SendFinalResponse(authReqdResponse); if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Warn, "Forbidden " + toUser + "@" + canonicalDomain + " does not exist, " + sipRequest.Header.ProxyReceivedFrom + ", " + sipRequest.Header.UserAgent + ".", null)); return(RegisterResultEnum.Forbidden); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Registrar, "Authentication required for " + toUser + "@" + canonicalDomain + " from " + sipRequest.Header.ProxyReceivedFrom + ".", toUser)); return(RegisterResultEnum.AuthenticationRequired); } } else { // Authenticated. //if (!sipRequest.Header.UserAgent.IsNullOrBlank() && !m_switchboarduserAgentPrefix.IsNullOrBlank() && sipRequest.Header.UserAgent.StartsWith(m_switchboarduserAgentPrefix)) //{ // // Check that the switchboard user is authorised. // var customer = CustomerPersistor_External.Get(x => x.CustomerUsername == sipAccount.Owner); // if (!(customer.ServiceLevel == CustomerServiceLevels.Switchboard.ToString() || customer.ServiceLevel == CustomerServiceLevels.Gold.ToString())) // { // FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Warn, "Register request for switchboard from " + toHeader.ToURI.Host + " rejected as not correct service level.", sipAccount.Owner)); // SIPResponse payReqdResponse = GetErrorResponse(sipRequest, SIPResponseStatusCodesEnum.PaymentRequired, "You need to purchase a Switchboard service"); // registerTransaction.SendFinalResponse(payReqdResponse); // return RegisterResultEnum.SwitchboardPaymentRequired; // } //} if (sipRequest.Header.Contact == null || sipRequest.Header.Contact.Count == 0) { // No contacts header to update bindings with, return a list of the current bindings. List <SIPRegistrarBinding> bindings = m_registrarBindingsManager.GetBindings(sipAccountAsset.Id); //List<SIPContactHeader> contactsList = m_registrarBindingsManager.GetContactHeader(); // registration.GetContactHeader(true, null); if (bindings != null) { sipRequest.Header.Contact = GetContactHeader(bindings); } SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendFinalResponse(okResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegisterSuccess, "Empty registration request successful for " + toUser + "@" + canonicalDomain + " from " + sipRequest.Header.ProxyReceivedFrom + ".", toUser)); } else { SIPEndPoint uacRemoteEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedFrom) ?? registerTransaction.RemoteEndPoint; SIPEndPoint proxySIPEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedOn); SIPEndPoint registrarEndPoint = registerTransaction.LocalSIPEndPoint; SIPResponseStatusCodesEnum updateResult = SIPResponseStatusCodesEnum.Ok; string updateMessage = null; DateTime startTime = DateTime.Now; List <SIPRegistrarBinding> bindingsList = m_registrarBindingsManager.UpdateBindings( sipAccountAsset.SIPAccount, proxySIPEndPoint, uacRemoteEndPoint, registrarEndPoint, //sipRequest.Header.Contact[0].ContactURI.CopyOf(), sipRequest.Header.Contact, sipRequest.Header.CallId, sipRequest.Header.CSeq, //sipRequest.Header.Contact[0].Expires, sipRequest.Header.Expires, sipRequest.Header.UserAgent, out updateResult, out updateMessage); //int bindingExpiry = GetBindingExpiry(bindingsList, sipRequest.Header.Contact[0].ContactURI.ToString()); TimeSpan duration = DateTime.Now.Subtract(startTime); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegistrarTiming, "Binding update time for " + toUser + "@" + canonicalDomain + " took " + duration.TotalMilliseconds + "ms.", null)); if (updateResult == SIPResponseStatusCodesEnum.Ok) { string proxySocketStr = (proxySIPEndPoint != null) ? " (proxy=" + proxySIPEndPoint.ToString() + ")" : null; int bindingCount = 1; foreach (SIPRegistrarBinding binding in bindingsList) { string bindingIndex = (bindingsList.Count == 1) ? String.Empty : " (" + bindingCount + ")"; //FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegisterSuccess, "Registration successful for " + toUser + "@" + canonicalDomain + " from " + uacRemoteEndPoint + proxySocketStr + ", binding " + binding.ContactSIPURI.ToParameterlessString() + ";expiry=" + binding.Expiry + bindingIndex + ".", toUser)); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.RegisterSuccess, "Registration successful for " + toUser + "@" + canonicalDomain + " from " + uacRemoteEndPoint + ", binding " + binding.ContactSIPURI.ToParameterlessString() + ";expiry=" + binding.Expiry + bindingIndex + ".", toUser)); //FireProxyLogEvent(new SIPMonitorMachineEvent(SIPMonitorMachineEventTypesEnum.SIPRegistrarBindingUpdate, toUser, uacRemoteEndPoint, sipAccount.Id.ToString())); bindingCount++; } // The standard states that the Ok response should contain the list of current bindings but that breaks some UAs. As a // compromise the list is returned with the Contact that UAC sent as the first one in the list. bool contactListSupported = m_userAgentConfigs.GetUserAgentContactListSupport(sipRequest.Header.UserAgent); if (contactListSupported) { sipRequest.Header.Contact = GetContactHeader(bindingsList); } else { // Some user agents can't match the contact header if the expiry is added to it. sipRequest.Header.Contact[0].Expires = GetBindingExpiry(bindingsList, sipRequest.Header.Contact[0].ContactURI.ToString());; } SIPResponse okResponse = GetOkResponse(sipRequest); // If a request was made for a switchboard token and a certificate is available to sign the tokens then generate it. //if (sipRequest.Header.SwitchboardTokenRequest > 0 && m_switchbboardRSAProvider != null) //{ // SwitchboardToken token = new SwitchboardToken(sipRequest.Header.SwitchboardTokenRequest, sipAccount.Owner, uacRemoteEndPoint.Address.ToString()); // lock (m_switchbboardRSAProvider) // { // token.SignedHash = Convert.ToBase64String(m_switchbboardRSAProvider.SignHash(Crypto.GetSHAHash(token.GetHashString()), null)); // } // string tokenXML = token.ToXML(true); // logger.Debug("Switchboard token set for " + sipAccount.Owner + " with expiry of " + token.Expiry + "s."); // okResponse.Header.SwitchboardToken = Crypto.SymmetricEncrypt(sipAccount.SIPPassword, sipRequest.Header.AuthenticationHeader.SIPDigest.Nonce, tokenXML); //} registerTransaction.SendFinalResponse(okResponse); } else { // The binding update failed even though the REGISTER request was authorised. This is probably due to a // temporary problem connecting to the bindings data store. Send Ok but set the binding expiry to the minimum so // that the UA will try again as soon as possible. FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Error, "Registration request successful but binding update failed for " + toUser + "@" + canonicalDomain + " from " + registerTransaction.RemoteEndPoint + ".", toUser)); sipRequest.Header.Contact[0].Expires = m_minimumBindingExpiry; SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendFinalResponse(okResponse); } } return(RegisterResultEnum.Authenticated); } } catch (Exception excp) { string regErrorMessage = "Exception registrarcore registering. " + excp.Message + "\r\n" + registerTransaction.TransactionRequest.ToString(); logger.Error(regErrorMessage); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Registrar, SIPMonitorEventTypesEnum.Error, regErrorMessage, null)); try { SIPResponse errorResponse = GetErrorResponse(registerTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null); registerTransaction.SendFinalResponse(errorResponse); } catch { } return(RegisterResultEnum.Error); } }
private void RequestTimedOut(SIPTransaction sipTransaction) { logger.Error("Exception SIPNonInviteClientUserAgent ReqeustTimeOut (" + sipTransaction.RemoteEndPoint + "). "); }
/// <summary> /// The event handler for responses to the initial register request. /// </summary> private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterInProgress, "Server response " + sipResponse.Status + " received for " + m_sipAccountAOR.ToString() + ".", m_owner)); if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { if (sipResponse.Header.AuthenticationHeader != null) { if (m_attempts >= MAX_REGISTER_ATTEMPTS) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration to " + m_sipAccountAOR.ToString() + " reached the maximum number of allowed attempts without a failure condition.", m_owner)); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration reached the maximum number of allowed attempts."); m_waitForRegistrationMRE.Set(); } else { m_attempts++; SIPRequest authenticatedRequest = GetAuthenticatedRegistrationRequest(sipTransaction.TransactionRequest, sipResponse); SIPNonInviteTransaction regAuthTransaction = m_sipTransport.CreateNonInviteTransaction(authenticatedRequest, sipTransaction.RemoteEndPoint, localSIPEndPoint, m_outboundProxy); regAuthTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) => { ThreadPool.QueueUserWorkItem(delegate { AuthResponseReceived(lep, rep, tn, rsp); }); }; regAuthTransaction.NonInviteTransactionTimedOut += (tn) => { ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); }); }; m_sipTransport.SendSIPReliable(regAuthTransaction); } } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " but no authentication header was supplied for " + m_sipAccountAOR.ToString() + ".", m_owner)); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + " but no authentication header was supplied."); m_waitForRegistrationMRE.Set(); } } else { if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok) { if (m_expiry > 0) { m_isRegistered = true; m_expiry = GetUpdatedExpiry(sipResponse); RegistrationSuccessful?.Invoke(m_sipAccountAOR); } else { m_isRegistered = false; RegistrationRemoved?.Invoke(m_sipAccountAOR); } m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden || sipResponse.Status == SIPResponseStatusCodesEnum.NotFound) { // SIP account does not appear to exist. Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + ", no further registration attempts will be made.", m_owner)); string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; RegistrationFailed?.Invoke(m_sipAccountAOR, "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + "."); m_exit = true; m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0) { m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse); Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterInProgress, "Registration for " + m_sipAccountAOR.ToString() + " had a too short expiry, updated to +" + m_expiry + " and trying again.", m_owner)); SendInitialRegister(); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + ".", m_owner)); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + "."); m_waitForRegistrationMRE.Set(); } } } catch (Exception excp) { logger.Error("Exception SIPRegistrationUserAgent ServerResponseReceived (" + remoteEndPoint + "). " + excp.Message); } }
private void Subscribe(SIPTransaction subscribeTransaction) { try { SIPRequest sipRequest = subscribeTransaction.TransactionRequest; string fromUser = sipRequest.Header.From.FromURI.User; string fromHost = sipRequest.Header.From.FromURI.Host; string canonicalDomain = GetCanonicalDomain_External(fromHost, true); if (canonicalDomain == null) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Subscribe request for " + fromHost + " rejected as no matching domain found.", null)); SIPResponse noDomainResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced"); subscribeTransaction.SendFinalResponse(noDomainResponse); return; } /** AGL */ SIPAccount sipAccount = m_sipAssetPersistor.Get(s => s.SIPUsername == fromUser && s.SIPDomain == canonicalDomain); //SIPAccount sipAccount = SipServicesSimul.Services.SipHelper.ServerAccount; SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator_External(subscribeTransaction.LocalSIPEndPoint, subscribeTransaction.RemoteEndPoint, sipRequest, sipAccount, FireProxyLogEvent); if (!authenticationResult.Authenticated) { // 401 Response with a fresh nonce needs to be sent. SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; subscribeTransaction.SendFinalResponse(authReqdResponse); if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Forbidden " + fromUser + "@" + canonicalDomain + " does not exist, " + sipRequest.Header.ProxyReceivedFrom.ToString() + ", " + sipRequest.Header.UserAgent + ".", null)); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Authentication required for " + fromUser + "@" + canonicalDomain + " from " + subscribeTransaction.RemoteEndPoint + ".", sipAccount.Owner)); } return; } else { if (sipRequest.Header.To.ToTag != null) { // Request is to renew an existing subscription. SIPResponseStatusCodesEnum errorResponse = SIPResponseStatusCodesEnum.None; string errorResponseReason = null; string sessionID = m_subscriptionsManager.RenewSubscription(sipRequest, out errorResponse, out errorResponseReason); if (errorResponse != SIPResponseStatusCodesEnum.None) { // A subscription renewal attempt failed SIPResponse renewalErrorResponse = SIPTransport.GetResponse(sipRequest, errorResponse, errorResponseReason); subscribeTransaction.SendFinalResponse(renewalErrorResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription renewal failed for event type " + sipRequest.Header.Event + " " + sipRequest.URI.ToString() + ", " + errorResponse + " " + errorResponseReason + ".", sipAccount.Owner)); } else if (sipRequest.Header.Expires == 0) { // Existing subscription was closed. SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); subscribeTransaction.SendFinalResponse(okResponse); } else { // Existing subscription was found. SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); subscribeTransaction.SendFinalResponse(okResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeRenew, "Subscription renewal for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + " and expiry " + sipRequest.Header.Expires + ".", sipAccount.Owner)); m_subscriptionsManager.SendFullStateNotify(sessionID); } } else { // Authenticated but the this is a new subscription request and authorisation to subscribe to the requested resource also needs to be checked. SIPURI canonicalResourceURI = sipRequest.URI.CopyOf(); string resourceCanonicalDomain = GetCanonicalDomain_External(canonicalResourceURI.Host, true); canonicalResourceURI.Host = resourceCanonicalDomain; SIPAccount resourceSIPAccount = null; if (resourceCanonicalDomain == null) { SIPResponse notFoundResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Domain " + resourceCanonicalDomain + " not serviced"); subscribeTransaction.SendFinalResponse(notFoundResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", domain not serviced.", sipAccount.Owner)); return; } if (canonicalResourceURI.User != m_wildcardUser) { /** AGL */ resourceSIPAccount = SipServicesSimul.Services.SipHelper.ServerAccount; //resourceSIPAccount = m_sipAssetPersistor.Get(s => s.SIPUsername == canonicalResourceURI.User && s.SIPDomain == canonicalResourceURI.Host); if (resourceSIPAccount == null) { SIPResponse notFoundResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Requested resource does not exist"); subscribeTransaction.SendFinalResponse(notFoundResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", SIP account does not exist.", sipAccount.Owner)); return; } } // Check the owner permissions on the requesting and subscribed resources. bool authorised = false; string adminID = null; if (canonicalResourceURI.User == m_wildcardUser || sipAccount.Owner == resourceSIPAccount.Owner) { authorised = true; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to common owner.", sipAccount.Owner)); } else { // Lookup the customer record for the requestor and check the administrative level on it. Customer requestingCustomer = GetCustomer_External(c => c.CustomerUsername == sipAccount.Owner); adminID = requestingCustomer.AdminId; if (!resourceSIPAccount.AdminMemberId.IsNullOrBlank() && requestingCustomer.AdminId == resourceSIPAccount.AdminMemberId) { authorised = true; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to requestor admin permissions for domain " + resourceSIPAccount.AdminMemberId + ".", sipAccount.Owner)); } else if (requestingCustomer.AdminId == m_topLevelAdminID) { authorised = true; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to requestor having top level admin permissions.", sipAccount.Owner)); } } if (authorised) { // Request is to create a new subscription. SIPResponseStatusCodesEnum errorResponse = SIPResponseStatusCodesEnum.None; string errorResponseReason = null; string toTag = CallProperties.CreateNewTag(); string sessionID = m_subscriptionsManager.SubscribeClient(sipAccount.Owner, adminID, sipRequest, toTag, canonicalResourceURI, out errorResponse, out errorResponseReason); if (errorResponse != SIPResponseStatusCodesEnum.None) { SIPResponse subscribeErrorResponse = SIPTransport.GetResponse(sipRequest, errorResponse, errorResponseReason); subscribeTransaction.SendFinalResponse(subscribeErrorResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", " + errorResponse + " " + errorResponseReason + ".", sipAccount.Owner)); } else { SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); okResponse.Header.To.ToTag = toTag; okResponse.Header.Expires = sipRequest.Header.Expires; okResponse.Header.Contact = new List <SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, subscribeTransaction.LocalSIPEndPoint)) }; subscribeTransaction.SendFinalResponse(okResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "Subscription accepted for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + " and expiry " + sipRequest.Header.Expires + ".", sipAccount.Owner)); if (sessionID != null) { m_subscriptionsManager.SendFullStateNotify(sessionID); } } } else { SIPResponse forbiddenResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Requested resource not authorised"); subscribeTransaction.SendFinalResponse(forbiddenResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", requesting account " + sipAccount.Owner + " was not authorised.", sipAccount.Owner)); } } } } catch (Exception excp) { logger.Error("Exception notifiercore subscribing. " + excp.Message + "\r\n" + subscribeTransaction.TransactionRequest.ToString()); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Error, "Exception notifiercore subscribing. " + excp.Message, null)); SIPResponse errorResponse = SIPTransport.GetResponse(subscribeTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null); subscribeTransaction.SendFinalResponse(errorResponse); } }
private void TransactionTraceMessage(SIPTransaction sipTransaction, string message) { }
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, true); //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; } }
/// <summary> /// The event handler for responses to the initial register request. /// </summary> private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { logger.LogDebug("Server response " + sipResponse.Status + " received for " + m_sipAccountAOR.ToString() + "."); if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { if (sipResponse.Header.AuthenticationHeader != null) { if (m_attempts >= m_maxRegisterAttempts) { logger.LogDebug("Registration to " + m_sipAccountAOR.ToString() + " reached the maximum number of allowed attempts without a failure condition."); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration reached the maximum number of allowed attempts."); m_waitForRegistrationMRE.Set(); } else { m_attempts++; SIPRequest authenticatedRequest = GetAuthenticatedRegistrationRequest(sipTransaction.TransactionRequest, sipResponse); SIPEndPoint registrarSIPEndPoint = m_outboundProxy; if (registrarSIPEndPoint == null) { //SIPDNSLookupResult lookupResult = m_sipTransport.GetHostEndPoint(m_registrarHost, false); SIPURI uri = SIPURI.ParseSIPURIRelaxed(m_registrarHost); var lookupResult = m_sipTransport.ResolveSIPUriAsync(uri).ConfigureAwait(false) .GetAwaiter().GetResult(); if (lookupResult == null) { logger.LogWarning("Could not resolve " + m_registrarHost + "."); } else { registrarSIPEndPoint = lookupResult; } } if (registrarSIPEndPoint == null) { logger.LogWarning("SIPRegistrationAgent could not resolve " + m_registrarHost + "."); RegistrationFailed?.Invoke(m_sipAccountAOR, "Could not resolve " + m_registrarHost + "."); } else { SIPNonInviteTransaction regAuthTransaction = new SIPNonInviteTransaction(m_sipTransport, authenticatedRequest, registrarSIPEndPoint); regAuthTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) => { ThreadPool.QueueUserWorkItem(delegate { AuthResponseReceived(lep, rep, tn, rsp); }); return(Task.FromResult(SocketError.Success)); }; regAuthTransaction.NonInviteTransactionTimedOut += (tn) => { ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); }); }; m_sipTransport.SendTransaction(regAuthTransaction); } } } else { logger.LogWarning("Registration failed with " + sipResponse.Status + " but no authentication header was supplied for " + m_sipAccountAOR.ToString() + "."); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + " but no authentication header was supplied."); m_waitForRegistrationMRE.Set(); } } else { if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok) { if (m_expiry > 0) { m_isRegistered = true; m_expiry = GetUpdatedExpiry(sipResponse); RegistrationSuccessful?.Invoke(m_sipAccountAOR); } else { m_isRegistered = false; RegistrationRemoved?.Invoke(m_sipAccountAOR); } m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden || sipResponse.Status == SIPResponseStatusCodesEnum.NotFound) { // SIP account does not appear to exist. logger.LogWarning("Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + ", no further registration attempts will be made."); string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; RegistrationFailed?.Invoke(m_sipAccountAOR, "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + "."); m_exit = true; m_waitForRegistrationMRE.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0) { m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse); logger.LogWarning("Registration for " + m_sipAccountAOR.ToString() + " had a too short expiry, updated to +" + m_expiry + " and trying again."); SendInitialRegister(); } else { logger.LogWarning("Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + "."); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + "."); m_waitForRegistrationMRE.Set(); } } } catch (Exception excp) { logger.LogError("Exception SIPRegistrationUserAgent ServerResponseReceived (" + remoteEndPoint + "). " + excp.Message); } }
private void SubscribeTransactionFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief) { // The expiry interval used was too small. Adjust and try again. m_expiry = (sipResponse.Header.MinExpires > 0) ? sipResponse.Header.MinExpires : m_expiry * 2; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.NotifierClient, SIPMonitorEventTypesEnum.SubscribeFailed, "A subscribe request was rejected with IntervalTooBrief, adjusting expiry to " + m_expiry + " and trying again.", null)); Subscribe(m_resourceURI, m_expiry, m_sipEventPackage, m_subscribeCallID, null); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden) { // The susbcription is never going to succeed so ccancel it. SubscriptionFailed(m_resourceURI, sipResponse.Status, "A Forbidden response was received on a subscribe attempt to " + m_resourceURI.ToString() + " for user " + m_authUsername + "."); m_exit = true; m_waitForSubscribeResponse.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.BadEvent) { // The susbcription is never going to succeed so ccancel it. SubscriptionFailed(m_resourceURI, sipResponse.Status, "A BadEvent response was received on a subscribe attempt to " + m_resourceURI.ToString() + " for event package " + m_sipEventPackage.ToString() + "."); m_exit = true; m_waitForSubscribeResponse.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist) { // The notifier server does not have a record for the existing subscription. SubscriptionFailed(m_resourceURI, sipResponse.Status, "Subscribe failed with response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + "."); m_waitForSubscribeResponse.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { if (m_authUsername.IsNullOrBlank() || m_authPassword.IsNullOrBlank()) { // No point trying to authenticate if there are no credentials to use. SubscriptionFailed(m_resourceURI, sipResponse.Status, "Authentication requested on subscribe request when no credentials available."); m_waitForSubscribeResponse.Set(); } else if (sipResponse.Header.AuthenticationHeader != null) { if (m_attempts >= MAX_SUBSCRIBE_ATTEMPTS) { m_subscribed = false; SubscriptionFailed(m_resourceURI, SIPResponseStatusCodesEnum.InternalServerError, "Subscription reached the maximum number of allowed attempts."); m_waitForSubscribeResponse.Set(); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.NotifierClient, SIPMonitorEventTypesEnum.SubscribeAuth, "Attempting authentication for subscribe request for event package " + m_sipEventPackage.ToString() + " and " + m_resourceURI.ToString() + ".", null)); m_attempts++; // Resend SUBSCRIBE with credentials. SIPAuthorisationDigest authRequest = sipResponse.Header.AuthenticationHeader.SIPDigest; authRequest.SetCredentials(m_authUsername, m_authPassword, m_resourceURI.ToString(), SIPMethodsEnum.SUBSCRIBE.ToString()); SIPRequest authSubscribeRequest = sipTransaction.TransactionRequest; authSubscribeRequest.Header.AuthenticationHeader = new SIPAuthenticationHeader(authRequest); authSubscribeRequest.Header.AuthenticationHeader.SIPDigest.Response = authRequest.Digest; authSubscribeRequest.Header.Vias.TopViaHeader.Branch = CallProperties.CreateBranchId(); m_localCSeq = sipTransaction.TransactionRequest.Header.CSeq + 1; authSubscribeRequest.Header.CSeq = m_localCSeq; authSubscribeRequest.Header.CallId = m_subscribeCallID; if (!m_filter.IsNullOrBlank()) { authSubscribeRequest.Body = m_filter; authSubscribeRequest.Header.ContentLength = m_filter.Length; authSubscribeRequest.Header.ContentType = m_filterTextType; } // Create a new transaction to establish the authenticated server call. SIPNonInviteTransaction subscribeTransaction = m_sipTransport.CreateNonInviteTransaction(authSubscribeRequest, sipTransaction.RemoteEndPoint, sipTransaction.LocalSIPEndPoint, m_outboundProxy); subscribeTransaction.NonInviteTransactionFinalResponseReceived += SubscribeTransactionFinalResponseReceived; subscribeTransaction.NonInviteTransactionTimedOut += SubsribeTransactionTimedOut; m_sipTransport.SendSIPReliable(subscribeTransaction); } } else { SubscriptionFailed(sipTransaction.TransactionRequestURI, sipResponse.Status, "Subscribe requested authentication but did not provide an authentication header."); m_waitForSubscribeResponse.Set(); } } else if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.NotifierClient, SIPMonitorEventTypesEnum.SubscribeAuth, "Authenticating subscribe request for event package " + m_sipEventPackage.ToString() + " and " + m_resourceURI.ToString() + " was successful.", null)); m_subscribed = true; m_subscriptionToTag = sipResponse.Header.To.ToTag; SubscriptionSuccessful(m_resourceURI); m_waitForSubscribeResponse.Set(); } else { SubscriptionFailed(m_resourceURI, sipResponse.Status, "Subscribe failed with response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + "."); m_waitForSubscribeResponse.Set(); } } catch (Exception excp) { logger.Error("Exception SubscribeTransactionFinalResponseReceived. " + excp.Message); SubscriptionFailed(m_resourceURI, SIPResponseStatusCodesEnum.InternalServerError, "Exception processing subscribe response. " + excp.Message); m_waitForSubscribeResponse.Set(); } }
private void SIPNonInviteTransaction_TransactionTimedOut(SIPTransaction sipTransaction) { NonInviteTransactionTimedOut?.Invoke(this); }
/// <summary> /// Handler for processing incoming SIP requests. /// </summary> /// <param name="localSIPEndPoint">The end point the request was received on.</param> /// <param name="remoteEndPoint">The end point the request came from.</param> /// <param name="sipRequest">The SIP request received.</param> private void SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { if (sipRequest.Method == SIPMethodsEnum.BYE) { if (m_uac != null && m_uac.SIPDialogue != null && sipRequest.Header.CallId == m_uac.SIPDialogue.CallId) { // Call has been hungup by remote end. StatusMessage("Call hungup by remote end."); SIPNonInviteTransaction byeTransaction = m_sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse byeResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); byeTransaction.SendFinalResponse(byeResponse); CallFinished(); } else if (m_uas != null && m_uas.SIPDialogue != null && sipRequest.Header.CallId == m_uas.SIPDialogue.CallId) { // Call has been hungup by remote end. StatusMessage("Call hungup."); SIPNonInviteTransaction byeTransaction = m_sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse byeResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); byeTransaction.SendFinalResponse(byeResponse); CallFinished(); } else { logger.Debug("Unmatched BYE request received for " + sipRequest.URI.ToString() + "."); SIPResponse noCallLegResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); m_sipTransport.SendResponse(noCallLegResponse); } } else if (sipRequest.Method == SIPMethodsEnum.INVITE) { StatusMessage("Incoming call request: " + localSIPEndPoint + "<-" + remoteEndPoint + " " + sipRequest.URI.ToString() + "."); UASInviteTransaction uasTransaction = m_sipTransport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); m_uas = new SIPServerUserAgent(m_sipTransport, null, null, null, SIPCallDirection.In, null, null, null, uasTransaction); m_uas.CallCancelled += UASCallCancelled; m_uas.Progress(SIPResponseStatusCodesEnum.Trying, null, null, null, null); m_uas.Progress(SIPResponseStatusCodesEnum.Ringing, null, null, null, null); IncomingCall(); } else if (sipRequest.Method == SIPMethodsEnum.CANCEL) { UASInviteTransaction inviteTransaction = (UASInviteTransaction)m_sipTransport.GetTransaction(SIPTransaction.GetRequestTransactionId(sipRequest.Header.Vias.TopViaHeader.Branch, SIPMethodsEnum.INVITE)); if (inviteTransaction != null) { StatusMessage("Call was cancelled by remote end."); SIPCancelTransaction cancelTransaction = m_sipTransport.CreateCancelTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, inviteTransaction); cancelTransaction.GotRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else { logger.Debug("No matching transaction was found for CANCEL to " + sipRequest.URI.ToString() + "."); SIPResponse noCallLegResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); m_sipTransport.SendResponse(noCallLegResponse); } CallFinished(); } else { logger.Debug("SIP " + sipRequest.Method + " request received but no processing has been set up for it, rejecting."); SIPResponse notAllowedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); m_sipTransport.SendResponse(notAllowedResponse); } }
private void SIPNonInviteTransaction_TransactionFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { NonInviteTransactionFinalResponseReceived?.Invoke(localSIPEndPoint, remoteEndPoint, this, sipResponse); }
/// <summary> /// The event handler for responses to the authenticated register request. /// </summary> private void AuthResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Server response " + sipResponse.Status + " " + reasonPhrase + " received for authenticated " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + ".", m_owner)); if (ResponseReceived != null) { ResponseReceived(sipResponse); } }
private Task <SocketError> SubscribeTransactionFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief) { // The expiry interval used was too small. Adjust and try again. m_expiry = (sipResponse.Header.MinExpires > 0) ? sipResponse.Header.MinExpires : m_expiry * 2; logger.LogWarning("A subscribe request was rejected with IntervalTooBrief, adjusting expiry to " + m_expiry + " and trying again."); Subscribe(m_resourceURI, m_expiry, m_sipEventPackage, m_subscribeCallID, null); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden) { // The subscription is never going to succeed so cancel it. SubscriptionFailed?.Invoke(m_resourceURI, sipResponse.Status, "A Forbidden response was received on a subscribe attempt to " + m_resourceURI.ToString() + " for user " + m_authUsername + "."); m_exit = true; m_waitForSubscribeResponse.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.BadEvent) { // The subscription is never going to succeed so cancel it. SubscriptionFailed?.Invoke(m_resourceURI, sipResponse.Status, "A BadEvent response was received on a subscribe attempt to " + m_resourceURI.ToString() + " for event package " + m_sipEventPackage.ToString() + "."); m_exit = true; m_waitForSubscribeResponse.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist) { // The notifier server does not have a record for the existing subscription. SubscriptionFailed?.Invoke(m_resourceURI, sipResponse.Status, "Subscribe failed with response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + "."); m_waitForSubscribeResponse.Set(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { if (m_authUsername.IsNullOrBlank() || m_authPassword.IsNullOrBlank()) { // No point trying to authenticate if there are no credentials to use. SubscriptionFailed?.Invoke(m_resourceURI, sipResponse.Status, "Authentication requested on subscribe request when no credentials available."); m_waitForSubscribeResponse.Set(); } else if (sipResponse.Header.HasAuthenticationHeader) { if (m_attempts >= MAX_SUBSCRIBE_ATTEMPTS) { m_subscribed = false; SubscriptionFailed?.Invoke(m_resourceURI, SIPResponseStatusCodesEnum.InternalServerError, "Subscription reached the maximum number of allowed attempts."); m_waitForSubscribeResponse.Set(); } else { logger.LogDebug("Attempting authentication for subscribe request for event package " + m_sipEventPackage.ToString() + " and " + m_resourceURI.ToString() + "."); m_attempts++; // Resend SUBSCRIBE with credentials. var authSubscribeRequest = sipTransaction.TransactionRequest.DuplicateAndAuthenticate( sipResponse.Header.AuthenticationHeaders, m_authUsername, m_authPassword); m_localCSeq = authSubscribeRequest.Header.CSeq; if (!m_filter.IsNullOrBlank()) { authSubscribeRequest.Body = m_filter; authSubscribeRequest.Header.ContentLength = m_filter.Length; authSubscribeRequest.Header.ContentType = m_filterTextType; } // Create a new transaction to establish the authenticated server call. SIPNonInviteTransaction subscribeTransaction = new SIPNonInviteTransaction(m_sipTransport, authSubscribeRequest, m_outboundProxy); subscribeTransaction.NonInviteTransactionFinalResponseReceived += SubscribeTransactionFinalResponseReceived; subscribeTransaction.NonInviteTransactionFailed += SubscribeTransactionFailed; //m_sipTransport.SendTransaction(subscribeTransaction); subscribeTransaction.SendRequest(); } } else { SubscriptionFailed?.Invoke(sipTransaction.TransactionRequestURI, sipResponse.Status, "Subscribe requested authentication but did not provide an authentication header."); m_waitForSubscribeResponse.Set(); } } else if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode <= 299) { logger.LogDebug("Authenticating subscribe request for event package " + m_sipEventPackage.ToString() + " and " + m_resourceURI.ToString() + " was successful."); m_subscribed = true; m_subscriptionToTag = sipResponse.Header.To.ToTag; SubscriptionSuccessful?.Invoke(m_resourceURI); m_waitForSubscribeResponse.Set(); } else { SubscriptionFailed?.Invoke(m_resourceURI, sipResponse.Status, "Subscribe failed with response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + "."); m_waitForSubscribeResponse.Set(); } return(Task.FromResult(SocketError.Success)); } catch (Exception excp) { logger.LogError("Exception SubscribeTransactionFinalResponseReceived. " + excp.Message); SubscriptionFailed?.Invoke(m_resourceURI, SIPResponseStatusCodesEnum.InternalServerError, "Exception processing subscribe response. " + excp.Message); m_waitForSubscribeResponse.Set(); return(Task.FromResult(SocketError.Fault)); } }
private void RequestTimedOut(SIPTransaction sipTransaction) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Attempt to send " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + " timed out.", m_owner)); }
private Task <SocketError> ByeServerFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { logger.LogDebug("Response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + sipTransaction.TransactionRequest.URI.ToString() + "."); SIPNonInviteTransaction byeTransaction = sipTransaction as SIPNonInviteTransaction; if ((sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) && SIPAccount != null) { var authRequest = sipTransaction.TransactionRequest.DuplicateAndAuthenticate(sipResponse.Header.AuthenticationHeaders, SIPAccount.SIPUsername, SIPAccount.SIPPassword); SIPNonInviteTransaction authByeTransaction = new SIPNonInviteTransaction(m_sipTransport, authRequest, null); authByeTransaction.SendRequest(); } return(Task.FromResult(SocketError.Success)); } catch (Exception excp) { logger.LogError("Exception ByServerFinalResponseReceived. " + excp.Message); return(Task.FromResult(SocketError.Fault)); } }
private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Server response " + sipResponse.StatusCode + " " + reasonPhrase + " received for " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + ".", m_owner)); if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { if (sipResponse.Header.AuthenticationHeader != null) { if ((m_callDescriptor.Username != null || m_callDescriptor.AuthUsername != null) && m_callDescriptor.Password != null) { SIPRequest authenticatedRequest = GetAuthenticatedRequest(sipTransaction.TransactionRequest, sipResponse); SIPNonInviteTransaction authTransaction = m_sipTransport.CreateNonInviteTransaction(authenticatedRequest, m_outboundProxy); authTransaction.NonInviteTransactionFinalResponseReceived += AuthResponseReceived; authTransaction.NonInviteTransactionTimedOut += RequestTimedOut; m_sipTransport.SendSIPReliable(authTransaction); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Send request received an authentication required response but no credentials were available.", m_owner)); ResponseReceived?.Invoke(sipResponse); } } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "Send request failed with " + sipResponse.StatusCode + " but no authentication header was supplied for " + sipTransaction.TransactionRequest.Method + " to " + m_callDescriptor.Uri + ".", m_owner)); ResponseReceived?.Invoke(sipResponse); } } else { ResponseReceived?.Invoke(sipResponse); } } catch (Exception excp) { logger.LogError("Exception SIPNonInviteClientUserAgent ServerResponseReceived (" + remoteEndPoint + "). " + excp.Message); } }
private Task <SocketError> ByeServerFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentServer, SIPMonitorEventTypesEnum.DialPlan, "Response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + " for " + sipTransaction.TransactionRequest.URI.ToString() + ".", Owner)); SIPNonInviteTransaction byeTransaction = sipTransaction as SIPNonInviteTransaction; if ((sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) && SIPAccount != null) { // Resend BYE with credentials. SIPAuthorisationDigest authRequest = sipResponse.Header.AuthenticationHeader.SIPDigest; SIPURI contactUri = sipResponse.Header.Contact.Any() ? sipResponse.Header.Contact[0].ContactURI : sipResponse.Header.From.FromURI; authRequest.SetCredentials(SIPAccount.SIPUsername, SIPAccount.SIPPassword, contactUri.ToString(), SIPMethodsEnum.BYE.ToString()); SIPRequest authByeRequest = byeTransaction.TransactionRequest; authByeRequest.Header.AuthenticationHeader = new SIPAuthenticationHeader(authRequest); authByeRequest.Header.AuthenticationHeader.SIPDigest.Response = authRequest.Digest; authByeRequest.Header.Vias.TopViaHeader.Branch = CallProperties.CreateBranchId(); authByeRequest.Header.CSeq = authByeRequest.Header.CSeq + 1; SIPNonInviteTransaction authByeTransaction = new SIPNonInviteTransaction(m_sipTransport, authByeRequest, null); authByeTransaction.SendRequest(); } return(Task.FromResult(SocketError.Success)); } catch (Exception excp) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.Error, "Exception ByServerFinalResponseReceived. " + excp.Message, Owner)); return(Task.FromResult(SocketError.Fault)); } }
private static void SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { if (sipRequest.Method == SIPMethodsEnum.BYE) { var rtpJob = (from job in m_rtpJobs.Values where job.UAS.CallRequest.Header.CallId == sipRequest.Header.CallId select job).FirstOrDefault(); if (rtpJob != null) { rtpJob.Stop(); // Call has been hungup by remote end. Console.WriteLine("Call hungup by client: " + localSIPEndPoint + "<-" + remoteEndPoint + " " + sipRequest.URI.ToString() + ".\n"); Publish(rtpJob.QueueName, "BYE request received from " + remoteEndPoint + " for " + sipRequest.URI.ToString() + "."); //Console.WriteLine("Request Received " + localSIPEndPoint + "<-" + remoteEndPoint + "\n" + sipRequest.ToString()); //m_uas.SIPDialogue.Hangup(m_sipTransport, null); SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); m_sipTransport.SendResponse(okResponse); } else { Console.WriteLine("Unmatched BYE request received for " + sipRequest.URI.ToString() + ".\n"); SIPResponse noCallLegResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); m_sipTransport.SendResponse(noCallLegResponse); } } else if (sipRequest.Method == SIPMethodsEnum.INVITE) { Console.WriteLine("Incoming call request: " + localSIPEndPoint + "<-" + remoteEndPoint + " " + sipRequest.URI.ToString() + ".\n"); Publish(sipRequest.URI.User, "INVITE request received from " + remoteEndPoint + " for " + sipRequest.URI.ToString() + "."); Console.WriteLine(sipRequest.Body); SIPPacketMangler.MangleSIPRequest(SIPMonitorServerTypesEnum.Unknown, sipRequest, null, LogTraceMessage); UASInviteTransaction uasTransaction = m_sipTransport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); var uas = new SIPServerUserAgent(m_sipTransport, null, null, null, SIPCallDirection.In, null, null, LogTraceMessage, uasTransaction); uas.CallCancelled += UASCallCancelled; RTPDiagnosticsJob rtpJob = new RTPDiagnosticsJob(m_rtpListenIPAddress, m_publicIPAddress, uas, sipRequest); string sdpAddress = SDP.GetSDPRTPEndPoint(sipRequest.Body).Address.ToString(); // Only mangle if there is something to change. For example the server could be on the same private subnet in which case it can't help. IPEndPoint expectedRTPEndPoint = new IPEndPoint(rtpJob.RemoteRTPEndPoint.Address, rtpJob.RemoteRTPEndPoint.Port); if (IPSocket.IsPrivateAddress(rtpJob.RemoteRTPEndPoint.Address.ToString())) { expectedRTPEndPoint.Address = remoteEndPoint.Address; } Publish(sipRequest.URI.User, "Advertised RTP remote socket " + rtpJob.RemoteRTPEndPoint + ", expecting from " + expectedRTPEndPoint + "."); m_rtpJobs.Add(rtpJob.RTPListenEndPoint.Port, rtpJob); //ThreadPool.QueueUserWorkItem(delegate { StartRTPListener(rtpJob); }); Console.WriteLine(rtpJob.LocalSDP.ToString()); uas.Answer("application/sdp", rtpJob.LocalSDP.ToString(), CallProperties.CreateNewTag(), null, SIPDialogueTransferModesEnum.NotAllowed); var hangupTimer = new Timer(delegate { if (!rtpJob.StopJob) { if (uas != null && uas.SIPDialogue != null) { if (rtpJob.RTPPacketReceived && !rtpJob.ErrorOnRTPSend) { Publish(sipRequest.URI.User, "Test completed. There were no RTP send or receive errors."); } else if (!rtpJob.RTPPacketReceived) { Publish(sipRequest.URI.User, "Test completed. An error was identified, no RTP packets were received."); } else { Publish(sipRequest.URI.User, "Test completed. An error was identified, there was a problem when attempting to send an RTP packet."); } rtpJob.Stop(); uas.SIPDialogue.Hangup(m_sipTransport, null); } } }, null, HANGUP_TIMEOUT, Timeout.Infinite); } else if (sipRequest.Method == SIPMethodsEnum.CANCEL) { UASInviteTransaction inviteTransaction = (UASInviteTransaction)m_sipTransport.GetTransaction(SIPTransaction.GetRequestTransactionId(sipRequest.Header.Vias.TopViaHeader.Branch, SIPMethodsEnum.INVITE)); if (inviteTransaction != null) { Console.WriteLine("Matching CANCEL request received " + sipRequest.URI.ToString() + ".\n"); Publish(sipRequest.URI.User, "CANCEL request received from " + remoteEndPoint + " for " + sipRequest.URI.ToString() + "."); SIPCancelTransaction cancelTransaction = m_sipTransport.CreateCancelTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, inviteTransaction); cancelTransaction.GotRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else { Console.WriteLine("No matching transaction was found for CANCEL to " + sipRequest.URI.ToString() + ".\n"); SIPResponse noCallLegResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); m_sipTransport.SendResponse(noCallLegResponse); } } else { Console.WriteLine("SIP " + sipRequest.Method + " request received but no processing has been set up for it, rejecting.\n"); Publish(sipRequest.URI.User, sipRequest.Method + " request received from " + remoteEndPoint + " for " + sipRequest.URI.ToString() + "."); SIPResponse notAllowedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); m_sipTransport.SendResponse(notAllowedResponse); } }
void m_serverTransaction_NonInviteTransactionFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { if (sipResponse.Status == SIPResponseStatusCodesEnum.Accepted) { FireReferAccepted(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.Decline) { FireReferDenied(); } else if (sipResponse.Status == SIPResponseStatusCodesEnum.MethodNotAllowed) { FireReferDenied(); } }