private void DoSubscribe(SIPNonInviteTransaction subTx) { SIPRequest req = subTx.TransactionRequest; string user = req.Header.From.FromURI.User; string domain = req.Header.From.FromURI.HostAddress; string canonicalDomain = m_sipDomainManager.GetCanonicalDomain(domain); if (canonicalDomain == null) { Logger.LogWarning($"Subscribe Register request for {req.Header.From.FromURI.Host} rejected as no matching domain found."); SIPResponse noDomainResponse = SIPResponse.GetResponse(req, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced"); subTx.SendResponse(noDomainResponse); } else { SIPAccount sipAccount = m_sipAccountsDataLayer.GetSIPAccount(user, canonicalDomain).Result; if (sipAccount == null) { Logger.LogWarning($"SubscriberCore SIP account {user}@{canonicalDomain} does not exist."); SIPResponse forbiddenResponse = SIPResponse.GetResponse(req, SIPResponseStatusCodesEnum.Forbidden, null); subTx.SendResponse(forbiddenResponse); } else { SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator.AuthenticateSIPRequest(req.LocalSIPEndPoint, req.RemoteSIPEndPoint, req, sipAccount); if (!authenticationResult.Authenticated) { // 401 Response with a fresh nonce needs to be sent. SIPResponse authReqdResponse = SIPResponse.GetResponse(req, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; subTx.SendResponse(authReqdResponse); if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden) { Logger.LogWarning($"Forbidden {sipAccount.AOR} does not exist, received from {req.RemoteSIPEndPoint}, user agent {req.Header.UserAgent}."); } } else { SIPResponse okResponse = SIPResponse.GetResponse(req, SIPResponseStatusCodesEnum.Ok, null); subTx.SendResponse(okResponse); Logger.LogDebug($"Subscription request for {user}@{domain} was successful."); // Give the subscribe response time to be sent. Thread.Sleep(500); if (req.Header.Expires > 0) { SendInitialNotification(req, sipAccount); } } } } }
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); } }