private void UACInviteTransaction_TransactionFinalResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { // BranchId for 2xx responses needs to be a new one, non-2xx final responses use same one as original request. if (sipResponse.StatusCode >= 200 && sipResponse.StatusCode < 299) { if (_sendOkAckManually == false) { Send2xxAckRequest(null, null); } } else { // ACK for non 2xx response is part of the INVITE transaction and gets routed to the same endpoint as the INVITE. var ackRequest = GetInTransactionACKRequest(sipResponse, m_transactionRequest.URI, LocalSIPEndPoint); base.SendRequest(RemoteEndPoint, ackRequest); } UACInviteTransactionFinalResponseReceived?.Invoke(localSIPEndPoint, remoteEndPoint, sipTransaction, sipResponse); if (CDR != null) { SIPEndPoint localEP = SIPEndPoint.TryParse(sipResponse.Header.ProxyReceivedOn) ?? localSIPEndPoint; SIPEndPoint remoteEP = SIPEndPoint.TryParse(sipResponse.Header.ProxyReceivedFrom) ?? remoteEndPoint; CDR.Answered(sipResponse.StatusCode, sipResponse.Status, sipResponse.ReasonPhrase, localEP, remoteEP); } } catch (Exception excp) { logger.Error("Exception UACInviteTransaction_TransactionFinalResponseReceived. " + excp.Message); } }
/// <param name="sendOkAckManually">If set an ACK request for the 2xx response will NOT be sent and it will be up to the application to explicitly call the SendACK request.</param> internal UACInviteTransaction(SIPTransport sipTransport, SIPRequest sipRequest, SIPEndPoint dstEndPoint, SIPEndPoint localSIPEndPoint, SIPEndPoint outboundProxy, bool sendOkAckManually = false) : base(sipTransport, sipRequest, dstEndPoint, localSIPEndPoint, outboundProxy) { TransactionType = SIPTransactionTypesEnum.Invite; m_localTag = sipRequest.Header.From.FromTag; SIPEndPoint localEP = SIPEndPoint.TryParse(sipRequest.Header.ProxySendFrom) ?? localSIPEndPoint; CDR = new SIPCDR(SIPCallDirection.Out, sipRequest.URI, sipRequest.Header.From, sipRequest.Header.CallId, localEP, dstEndPoint); _sendOkAckManually = sendOkAckManually; TransactionFinalResponseReceived += UACInviteTransaction_TransactionFinalResponseReceived; TransactionInformationResponseReceived += UACInviteTransaction_TransactionInformationResponseReceived; TransactionTimedOut += UACInviteTransaction_TransactionTimedOut; TransactionRequestReceived += UACInviteTransaction_TransactionRequestReceived; TransactionRemoved += UACInviteTransaction_TransactionRemoved; }
private void UACInviteTransaction_TransactionInformationResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) { try { UACInviteTransactionInformationResponseReceived?.Invoke(localSIPEndPoint, remoteEndPoint, sipTransaction, sipResponse); if (CDR != null) { SIPEndPoint localEP = SIPEndPoint.TryParse(sipResponse.Header.ProxyReceivedOn) ?? localSIPEndPoint; SIPEndPoint remoteEP = SIPEndPoint.TryParse(sipResponse.Header.ProxyReceivedFrom) ?? remoteEndPoint; CDR.Progress(sipResponse.Status, sipResponse.ReasonPhrase, localEP, remoteEP); } } catch (Exception excp) { logger.Error("Exception UACInviteTransaction_TransactionInformationResponseReceived. " + excp.Message); } }
public UASInviteTransaction( SIPTransport sipTransport, SIPRequest sipRequest, SIPEndPoint dstEndPoint, SIPEndPoint localSIPEndPoint, SIPEndPoint outboundProxy, IPAddress contactIPAddress, bool noCDR = false) : base(sipTransport, sipRequest, dstEndPoint, localSIPEndPoint, outboundProxy) { TransactionType = SIPTransactionTypesEnum.Invite; m_remoteTag = sipRequest.Header.From.FromTag; m_contactIPAddress = contactIPAddress; if (sipRequest.Header.To.ToTag == null) { // This UAS needs to set the To Tag. m_localTag = CallProperties.CreateNewTag(); } else { // This is a re-INVITE. m_localTag = sipRequest.Header.To.ToTag; } //logger.Debug("New UASTransaction (" + TransactionId + ") for " + TransactionRequest.URI.ToString() + " to " + RemoteEndPoint + "."); SIPEndPoint localEP = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedOn) ?? localSIPEndPoint; SIPEndPoint remoteEP = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedFrom) ?? dstEndPoint; if (!noCDR) { CDR = new SIPCDR(SIPCallDirection.In, sipRequest.URI, sipRequest.Header.From, sipRequest.Header.CallId, localEP, remoteEP); } //UpdateTransactionState(SIPTransactionStatesEnum.Proceeding); TransactionRequestReceived += UASInviteTransaction_TransactionRequestReceived; TransactionInformationResponseReceived += UASInviteTransaction_TransactionResponseReceived; TransactionFinalResponseReceived += UASInviteTransaction_TransactionResponseReceived; TransactionTimedOut += UASInviteTransaction_TransactionTimedOut; TransactionRemoved += UASInviteTransaction_TransactionRemoved; }
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 = toHeader.ToURI.Host; int requestedExpiry = GetRequestedExpiry(sipRequest); if (canonicalDomain == null) { SIPResponse noDomainResponse = GetErrorResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced"); registerTransaction.SendFinalResponse(noDomainResponse); return(RegisterResultEnum.DomainNotServiced); } SIPAccount sipAccount = new SIPAccount { Id = Guid.NewGuid(), Owner = "admin", SIPUsername = toUser, SIPDomain = canonicalDomain }; SIPRequestAuthenticationResult authenticationResult = _sipRequestAuthenticator_External?.Invoke(registerTransaction.LocalSIPEndPoint, registerTransaction.RemoteEndPoint, sipRequest, sipAccount); if (!_needAuthentication) { SIPResponse okRes = GetOkResponse(sipRequest); registerTransaction.SendFinalResponse(okRes); if (requestedExpiry > 0) { CacheDeviceItem(sipRequest); RegisterReceived?.Invoke(sipRequest, _localSipAccount); } if (requestedExpiry == 0) { RemoveDeviceItem(sipRequest); UnRegisterReceived?.Invoke(sipRequest, _localSipAccount); } return(RegisterResultEnum.AuthenticationRequired); } 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) { return(RegisterResultEnum.Forbidden); } else { return(RegisterResultEnum.AuthenticationRequired); } } else { if (sipRequest.Header.Contact == null || sipRequest.Header.Contact.Count == 0) { SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendFinalResponse(okResponse); if (requestedExpiry > 0) { CacheDeviceItem(sipRequest); RegisterReceived?.Invoke(sipRequest, _localSipAccount); } if (requestedExpiry == 0) { RemoveDeviceItem(sipRequest); UnRegisterReceived?.Invoke(sipRequest, _localSipAccount); } } 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; DateTime startTime = DateTime.Now; TimeSpan duration = DateTime.Now.Subtract(startTime); if (updateResult == SIPResponseStatusCodesEnum.Ok) { string proxySocketStr = (proxySIPEndPoint != null) ? " (proxy=" + proxySIPEndPoint.ToString() + ")" : null; SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendFinalResponse(okResponse); if (requestedExpiry > 0) { CacheDeviceItem(sipRequest); RegisterReceived?.Invoke(sipRequest, _localSipAccount); } if (requestedExpiry == 0) { RemoveDeviceItem(sipRequest); UnRegisterReceived?.Invoke(sipRequest, _localSipAccount); } } else { 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 + "->" + registerTransaction.TransactionRequest.ToString(); Logger.Logger.Error(regErrorMessage); try { SIPResponse errorResponse = GetErrorResponse(registerTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null); registerTransaction.SendFinalResponse(errorResponse); } catch { } return(RegisterResultEnum.Error); } }
private RegisterResultEnum Register(SIPNonInviteTransaction registerTransaction) { try { SIPRequest sipRequest = registerTransaction.TransactionRequest; SIPURI registerURI = sipRequest.URI; SIPToHeader toHeader = sipRequest.Header.To; string toUser = toHeader.ToURI.User; string canonicalDomain = m_sipDomainManager.GetCanonicalDomain(toHeader.ToURI.HostAddress); int requestedExpiry = GetRequestedExpiry(sipRequest); if (canonicalDomain == null) { Logger.LogWarning($"Register request for {toHeader.ToURI.HostAddress} rejected as no matching domain found."); SIPResponse noDomainResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced"); registerTransaction.SendResponse(noDomainResponse); return(RegisterResultEnum.DomainNotServiced); } else { SIPAccount sipAccount = m_sipAccountsDataLayer.GetSIPAccount(toUser, canonicalDomain).Result; if (sipAccount == null) { Logger.LogWarning($"RegistrarCore SIP account {toUser}@{canonicalDomain} does not exist."); SIPResponse forbiddenResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, null); registerTransaction.SendResponse(forbiddenResponse); return(RegisterResultEnum.Forbidden); } else { SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator.AuthenticateSIPRequest( registerTransaction.TransactionRequest.LocalSIPEndPoint, registerTransaction.TransactionRequest.RemoteSIPEndPoint, sipRequest, sipAccount.ToSIPAccountModel()); if (!authenticationResult.Authenticated) { // 401 Response with a fresh nonce needs to be sent. SIPResponse authReqdResponse = SIPResponse.GetResponse(sipRequest, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; registerTransaction.SendResponse(authReqdResponse); if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden) { Logger.LogWarning($"Forbidden {sipAccount.AOR} does not exist, {sipRequest.Header.ProxyReceivedFrom}, {sipRequest.Header.UserAgent}."); return(RegisterResultEnum.Forbidden); } else { return(RegisterResultEnum.AuthenticationRequired); } } else { 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(sipAccount.ID); List <SIPRegistrarBinding> bindings = m_sipRegistrarBindingDataLayer.GetForSIPAccount(new Guid(sipAccount.ID)).ToList(); //List<SIPContactHeader> contactsList = m_registrarBindingsManager.GetContactHeader(); // registration.GetContactHeader(true, null); if (bindings != null) { sipRequest.Header.Contact = GetContactHeader(bindings); } SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendResponse(okResponse); Logger.LogDebug($"Empty registration request successful for {sipAccount.AOR} from {sipRequest.Header.ProxyReceivedFrom}."); } else { SIPEndPoint uacRemoteEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedFrom) ?? registerTransaction.TransactionRequest.RemoteSIPEndPoint; SIPEndPoint proxySIPEndPoint = SIPEndPoint.TryParse(sipRequest.Header.ProxyReceivedOn); SIPEndPoint registrarEndPoint = registerTransaction.TransactionRequest.LocalSIPEndPoint; SIPResponseStatusCodesEnum updateResult = SIPResponseStatusCodesEnum.Ok; string updateMessage = null; DateTime startTime = DateTime.Now; List <SIPRegistrarBinding> bindingsList = m_registrarBindingsManager.UpdateBindings( sipAccount, proxySIPEndPoint, uacRemoteEndPoint, registrarEndPoint, sipRequest.Header.Contact, sipRequest.Header.CallId, sipRequest.Header.CSeq, sipRequest.Header.Expires, sipRequest.Header.UserAgent, out updateResult, out updateMessage); TimeSpan duration = DateTime.Now.Subtract(startTime); Logger.LogDebug($"Binding update time for {sipAccount.AOR} took {duration.TotalMilliseconds}ms."); if (updateResult == SIPResponseStatusCodesEnum.Ok) { string proxySocketStr = (proxySIPEndPoint != null) ? " (proxy=" + proxySIPEndPoint.ToString() + ")" : null; Logger.LogDebug($"Bindings for {sipAccount.AOR}:"); for (int i = 0; i < bindingsList.Count(); i++) { var binding = bindingsList[i]; Logger.LogDebug($" {i}: {binding.ContactURI}, expiry {binding.Expiry}s."); } sipRequest.Header.Contact = GetContactHeader(bindingsList); SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendResponse(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. Logger.LogError($"Registration request successful but binding update failed for {sipAccount.AOR} from {registerTransaction.TransactionRequest.RemoteSIPEndPoint}."); sipRequest.Header.Contact[0].Expires = m_minimumBindingExpiry; SIPResponse okResponse = GetOkResponse(sipRequest); registerTransaction.SendResponse(okResponse); } } return(RegisterResultEnum.Authenticated); } } } } catch (Exception excp) { string regErrorMessage = "Exception registrarcore registering. " + excp.Message + "\r\n" + registerTransaction.TransactionRequest.ToString(); Logger.LogError(regErrorMessage); SIPResponse errorResponse = SIPResponse.GetResponse(registerTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null); registerTransaction.SendResponse(errorResponse); return(RegisterResultEnum.Error); } }
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); } }
/// <summary> /// From RFC3261: Stateless Proxy Request Processing: /// /// For each target, the proxy forwards the request following these /// 1. Make a copy of the received request /// 2. Update the Request-URI /// 3. Update the Max-Forwards header field /// 4. Optionally add a Record-route header field value /// 5. Optionally add additional header fields /// 6. Postprocess routing information /// 7. Determine the next-hop address, port, and transport /// 8. Add a Via header field value /// 9. Add a Content-Length header field if necessary /// 10. Forward the new request /// /// See sections 12.2.1.1 and 16.12.1.2 in the SIP RFC for the best explanation on the way the Route header works. /// </summary> /// <param name="sipRequest"></param> /// <param name="inEndPoint">End point the request was received on.</param> /// <param name="sipChannel"></param> private void GotRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { // Calculate the proxy branch parameter for this request. The branch parameter has to be calculated so that INVITE's and CANCEL's generate the same branchid. //string toTag = (sipRequest.Header.To != null) ? sipRequest.Header.To.ToTag : null; //string fromTag = (sipRequest.Header.From != null) ? sipRequest.Header.From.FromTag : null; string route = (sipRequest.Header.Routes != null) ? sipRequest.Header.Routes.ToString() : null; //string authHeader = (sipRequest.Header.AuthenticationHeader != null) ? sipRequest.Header.AuthenticationHeader.ToString() : null; string proxyBranch = CallProperties.CreateBranchId(SIPConstants.SIP_BRANCH_MAGICCOOKIE, null, null, sipRequest.Header.CallId, sipRequest.URI.ToString(), null, sipRequest.Header.CSeq, route, null, null); // Check whether the branch parameter already exists in the Via list. One instance of an already added Via header will be allowed to support a single spiral. int loopedViaCount = 0; foreach (SIPViaHeader viaHeader in sipRequest.Header.Vias.Via) { //if (viaHeader.Branch == proxyBranch) SIPEndPoint sentFromEndPoint = SIPEndPoint.TryParse(viaHeader.Transport + ":" + viaHeader.ContactAddress); if (sentFromEndPoint != null && m_sipTransport.IsLocalSIPEndPoint(sentFromEndPoint)) { loopedViaCount++; } if (loopedViaCount >= 2) { SendMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.SIPProxy, SIPMonitorEventTypesEnum.Warn, "Loop detected on request from " + remoteEndPoint + " to " + sipRequest.URI.ToString() + ".", null)); m_sipTransport.SendResponse(SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.LoopDetected, null)); return; } } // Used in the proxy monitor messages only, plays no part in request routing. string fromUser = (sipRequest.Header.From != null) ? sipRequest.Header.From.FromURI.User : null; string toUser = (sipRequest.Header.To != null) ? sipRequest.Header.To.ToURI.User : null; string summaryStr = "req " + sipRequest.Method + " from=" + fromUser + ", to=" + toUser + ", " + remoteEndPoint.ToString(); bool isFromAppServer = (m_sipCallDispatcherFile != null) ? m_sipCallDispatcherFile.IsAppServerEndPoint(remoteEndPoint) : false; lock (this) { m_compiledScript.DefaultScope.RemoveVariable("sys"); m_compiledScript.DefaultScope.RemoveVariable("localEndPoint"); m_compiledScript.DefaultScope.RemoveVariable("isreq"); m_compiledScript.DefaultScope.RemoveVariable("req"); m_compiledScript.DefaultScope.RemoveVariable("remoteEndPoint"); m_compiledScript.DefaultScope.RemoveVariable("summary"); m_compiledScript.DefaultScope.RemoveVariable("proxyBranch"); m_compiledScript.DefaultScope.RemoveVariable("sipMethod"); m_compiledScript.DefaultScope.RemoveVariable("publicip"); m_compiledScript.DefaultScope.RemoveVariable("IsFromAppServer"); m_compiledScript.DefaultScope.SetVariable("sys", m_proxyScriptFacade); m_compiledScript.DefaultScope.SetVariable("localEndPoint", localSIPEndPoint); m_compiledScript.DefaultScope.SetVariable("isreq", true); m_compiledScript.DefaultScope.SetVariable("req", sipRequest); m_compiledScript.DefaultScope.SetVariable("remoteEndPoint", remoteEndPoint); m_compiledScript.DefaultScope.SetVariable("summary", summaryStr); m_compiledScript.DefaultScope.SetVariable("proxyBranch", proxyBranch); m_compiledScript.DefaultScope.SetVariable("sipMethod", sipRequest.Method.ToString()); m_compiledScript.DefaultScope.SetVariable("publicip", PublicIPAddress); m_compiledScript.DefaultScope.SetVariable("IsFromAppServer", isFromAppServer); m_compiledScript.Execute(); } //if (requestStopwatch.ElapsedMilliseconds > 20) //{ // logger.Debug("GotRequest processing time=" + requestStopwatch.ElapsedMilliseconds + "ms, script time=" + scriptStopwatch.ElapsedMilliseconds + "ms."); //} } catch (SIPValidationException) { throw; } catch (Exception excp) { string remoteEndPointStr = (remoteEndPoint != null) ? remoteEndPoint.ToString() : null; string reqExcpError = "Exception SIPProxyCore GotRequest (from " + remoteEndPointStr + "). " + excp.Message; logger.Error(reqExcpError); SIPMonitorEvent reqExcpEvent = new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.SIPProxy, SIPMonitorEventTypesEnum.Error, reqExcpError, localSIPEndPoint, remoteEndPoint, null); SendMonitorEvent(reqExcpEvent); throw excp; } }