private SIPRequest GetCancelRequest(SIPRequest inviteRequest) { SIPRequest cancelRequest = new SIPRequest(SIPMethodsEnum.CANCEL, inviteRequest.URI); cancelRequest.LocalSIPEndPoint = inviteRequest.LocalSIPEndPoint; SIPHeader inviteHeader = inviteRequest.Header; SIPHeader cancelHeader = new SIPHeader(inviteHeader.From, inviteHeader.To, inviteHeader.CSeq, inviteHeader.CallId); cancelRequest.Header = cancelHeader; cancelHeader.CSeqMethod = SIPMethodsEnum.CANCEL; cancelHeader.Routes = inviteHeader.Routes; cancelHeader.ProxySendFrom = inviteHeader.ProxySendFrom; cancelHeader.Vias = inviteHeader.Vias; return cancelRequest; }
/// <summary> /// 录像文件查询 /// </summary> /// <param name="startTime">开始时间</param> /// <param name="endTime">结束时间</param> public int RecordFileQuery(DateTime startTime, DateTime endTime) { //lock (_msgCore.RemoteTrans) //{ // if (!_msgCore.RemoteTrans.ContainsKey(_remoteEndPoint.ToString())) // { // OnSIPServiceChange(_deviceName + "-" + _deviceId + _remoteEndPoint.ToString(), SipServiceStatus.Wait); // return 0; // } //} if (!_initComplate) { OnSIPServiceChange(_deviceName + "-" + _deviceId + _remoteEndPoint.ToString(), SipServiceStatus.Wait); return(0); } this.Stop(); SIPURI remoteUri = new SIPURI(_deviceId, _remoteEndPoint.ToHost(), ""); SIPURI localUri = new SIPURI(_msgCore.LocalSIPId, _msgCore.LocalEndPoint.ToHost(), ""); SIPFromHeader from = new SIPFromHeader(null, localUri, CallProperties.CreateNewTag()); SIPToHeader to = new SIPToHeader(null, remoteUri, CallProperties.CreateNewTag()); SIPRequest recordFileReq = _msgCore.Transport.GetRequest(SIPMethodsEnum.MESSAGE, remoteUri); SIPContactHeader contactHeader = new SIPContactHeader(null, localUri); recordFileReq.Header.Contact.Clear(); recordFileReq.Header.Contact.Add(contactHeader); recordFileReq.Header.Allow = null; recordFileReq.Header.From = from; recordFileReq.Header.To = to; recordFileReq.Header.UserAgent = _msgCore.UserAgent; recordFileReq.Header.CSeq = CallProperties.CreateNewCSeq(); recordFileReq.Header.CallId = CallProperties.CreateNewCallId(); recordFileReq.Header.ContentType = "application/MANSCDP+xml"; string bTime = startTime.ToString("yyyy-MM-ddTHH:mm:ss"); string eTime = endTime.ToString("yyyy-MM-ddTHH:mm:ss"); RecordQuery record = new RecordQuery() { DeviceID = _deviceId, SN = new Random().Next(1, 3000), CmdType = CommandType.RecordInfo, Secrecy = 0, StartTime = bTime, EndTime = eTime, Type = "time" }; _recordTotal = -1; string xmlBody = RecordQuery.Instance.Save <RecordQuery>(record); recordFileReq.Body = xmlBody; _msgCore.Transport.SendRequest(_remoteEndPoint, recordFileReq); DateTime recordQueryTime = DateTime.Now; while (_recordTotal < 0) { Thread.Sleep(50); if (DateTime.Now.Subtract(recordQueryTime).TotalSeconds > 2) { logger.Debug(_deviceName + "[" + _deviceId + "] 等待录像查询超时"); _recordTotal = 0; break; } } return(_recordTotal); }
private SIPRequest GetReferRequest(SIPEndPoint localSIPEndPoint, SIPURI referTo, ReplacesCallDescriptor sipReplacesCallDescriptor) { SIPRequest referRequest = new SIPRequest(SIPMethodsEnum.REFER, m_sipCallDescriptor.Uri); SIPFromHeader referFromHeader = SIPFromHeader.ParseFromHeader(m_sipCallDescriptor.From); SIPToHeader referToHeader = SIPToHeader.ParseToHeader(m_sipCallDescriptor.Uri); int cseq = ++CSeq; CallId = CallProperties.CreateNewCallId(); SIPHeader referHeader = new SIPHeader(referFromHeader, referToHeader, cseq, CallId); referHeader.CSeqMethod = SIPMethodsEnum.REFER; referRequest.Header = referHeader; referRequest.Header.Routes = RouteSet; referRequest.Header.ProxySendFrom = m_sipCallDescriptor.ProxySendFrom; if (sipReplacesCallDescriptor != null) { referTo.Headers.Set("Replaces", sipReplacesCallDescriptor.GetUrlEncodedReplacesUriHeader()); referRequest.Header.ReferTo = referTo.ToString(); } else { referRequest.Header.ReferTo = referTo.ToString(); } // "Requires" Header referRequest.Header.Require = (String.IsNullOrWhiteSpace(referRequest.Header.Require)) ? "replaces" : referRequest.Header.Require + ",replaces"; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); referRequest.Header.Vias.PushViaHeader(viaHeader); return referRequest; }
public void SendSIPRequest(SIPRequest sipRequest, string dstSocket) { //ResetSIPResponse(); if (sipRequest.Method == SIPMethodsEnum.INVITE) { //m_inviteRequest = sipRequest; UACInviteTransaction inviteTransaction = m_sipTransport.CreateUACTransaction(sipRequest, IPSocket.GetIPEndPoint(dstSocket), m_sipTransport.GetTransportContact(null), SIPProtocolsEnum.UDP); inviteTransaction.UACInviteTransactionInformationResponseReceived += new SIPTransactionResponseReceivedDelegate(TransactionInformationResponseReceived); inviteTransaction.UACInviteTransactionFinalResponseReceived += new SIPTransactionResponseReceivedDelegate(TransactionFinalResponseReceived); m_sipTransport.SendSIPReliable(inviteTransaction); } else { SIPNonInviteTransaction sipTransaction = m_sipTransport.CreateNonInviteTransaction(sipRequest, IPSocket.GetIPEndPoint(dstSocket), m_sipTransport.GetTransportContact(null), SIPProtocolsEnum.UDP); sipTransaction.NonInviteTransactionFinalResponseReceived += new SIPTransactionResponseReceivedDelegate(TransactionFinalResponseReceived); m_sipTransport.SendSIPReliable(sipTransaction); } }
public SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum serverType, SIPMonitorEventTypesEnum eventType, string message, SIPRequest sipRequest, SIPResponse sipResponse, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, SIPCallDirection callDirection) { m_serialisationPrefix = SERIALISATION_PREFIX; ClientType = SIPMonitorClientTypesEnum.Console; ServerType = serverType; EventType = eventType; Message = message; RemoteEndPoint = remoteEndPoint; ServerEndPoint = localEndPoint; Created = DateTimeOffset.UtcNow; #if !SILVERLIGHT ProcessID = Process.GetCurrentProcess().Id; #endif string dirn = (callDirection == SIPCallDirection.In) ? CALLDIRECTION_IN_STRING : CALLDIRECTION_OUT_STRING; if (sipRequest != null) { Message = "REQUEST (" + Created.ToString("HH:mm:ss:fff") + "): " + localEndPoint + dirn + remoteEndPoint + "\r\n" + sipRequest.ToString(); } else if (sipResponse != null) { Message = "RESPONSE (" + Created.ToString("HH:mm:ss:fff") + "): " + localEndPoint + dirn + remoteEndPoint + "\r\n" + sipResponse.ToString(); } }
public SIPRequest GetInviteRequest(string inviteURIStr, string fromURIStr, string body, int rtpPort) { SIPURI inviteURI = (inviteURIStr.StartsWith("sip:")) ? SIPURI.ParseSIPURI(inviteURIStr) : SIPURI.ParseSIPURI("sip:" + inviteURIStr); SIPFromHeader fromHeader = SIPFromHeader.ParseFromHeader(fromURIStr); // (fromURIStr.StartsWith("sip:")) ? SIPFromHeader.ParseFromHeader(fromURIStr) : SIPFromHeader.ParseFromHeader("sip:" + fromURIStr); SIPToHeader toHeader = new SIPToHeader(null, inviteURI, null); SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, inviteURI); IPEndPoint localSIPEndPoint = m_sipTransport.GetIPEndPointsList()[0]; SIPHeader inviteHeader = new SIPHeader(fromHeader, toHeader, 1, CallProperties.CreateNewCallId()); inviteHeader.From.FromTag = CallProperties.CreateNewTag(); inviteHeader.Contact = SIPContactHeader.ParseContactHeader("sip:" + localSIPEndPoint.ToString()); inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE; //inviteHeader.UnknownHeaders.Add("BlueFace-Test: 12324"); inviteRequest.Header = inviteHeader; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint.Address.ToString(), localSIPEndPoint.Port, CallProperties.CreateBranchId()); inviteRequest.Header.Via.PushViaHeader(viaHeader); rtpPort = (rtpPort != 0) ? rtpPort : Crypto.GetRandomInt(10000, 20000); string sessionId = Crypto.GetRandomInt(1000, 5000).ToString(); if (body != null && body.Trim().Length > 0) { inviteRequest.Body = body; } else { inviteRequest.Body = "v=0" + CRLF + "o=- " + sessionId + " " + sessionId + " IN IP4 " + localSIPEndPoint.Address.ToString() + CRLF + "s=session" + CRLF + "c=IN IP4 " + localSIPEndPoint.Address.ToString() + CRLF + "t=0 0" + CRLF + "m=audio " + rtpPort + " RTP/AVP 0 101" + CRLF + "a=rtpmap:0 PCMU/8000" + CRLF + "a=rtpmap:101 telephone-event/8000" + CRLF + "a=fmtp:101 0-16" + CRLF + "a=sendrecv"; } inviteRequest.Header.ContentLength = inviteRequest.Body.Length; inviteRequest.Header.ContentType = "application/sdp"; return inviteRequest; }
public SIPRequest GetReferRequest(SIPRequest inviteRequest, SIPResponse inviteResponse, string referToURI) { SIPRequest referRequest = new SIPRequest(SIPMethodsEnum.REFER, inviteRequest.URI); SIPHeader referHeader = new SIPHeader(inviteResponse.Header.From, inviteResponse.Header.To, inviteRequest.Header.CSeq + 1, inviteRequest.Header.CallId); referHeader.Contact = inviteRequest.Header.Contact; referHeader.CSeqMethod = SIPMethodsEnum.REFER; referHeader.ReferTo = referToURI; SIPFromHeader referredBy = new SIPFromHeader(inviteRequest.Header.From.FromName, inviteRequest.Header.From.FromURI, null); referHeader.ReferredBy = referredBy.ToString(); referHeader.AuthenticationHeader = inviteRequest.Header.AuthenticationHeader; IPEndPoint localSIPEndPoint = m_sipTransport.GetIPEndPointsList()[0]; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint.Address.ToString(), localSIPEndPoint.Port, CallProperties.CreateBranchId()); referHeader.Via.PushViaHeader(viaHeader); referRequest.Header = referHeader; return referRequest; }
private static void SIPRequestOutTraceEvent(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { logger.LogDebug("REQUEST OUT {0}->{1}", localSIPEndPoint.ToString(), remoteEndPoint.ToString()); logger.LogDebug(sipRequest.ToString()); }
public async Task HangupUserAgentUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); SIPTransport transport = new SIPTransport(); MockSIPChannel mockChannel = new MockSIPChannel(new System.Net.IPEndPoint(IPAddress.Any, 0)); transport.AddSIPChannel(mockChannel); SIPUserAgent userAgent = new SIPUserAgent(transport, null); string inviteReqStr = "INVITE sip:192.168.11.50:5060 SIP/2.0" + m_CRLF + "Via: SIP/2.0/UDP 192.168.11.50:60163;rport;branch=z9hG4bKPj869f70960bdd4204b1352eaf242a3691" + m_CRLF + "To: <sip:[email protected]>;tag=ZUJSXRRGXQ" + m_CRLF + "From: <sip:[email protected]>;tag=4a60ce364b774258873ff199e5e39938" + m_CRLF + "Call-ID: 17324d6df8744d978008c8997bfd208d" + m_CRLF + "CSeq: 3532 INVITE" + m_CRLF + "Contact: <sip:[email protected]:60163;ob>" + m_CRLF + "Max-Forwards: 70" + m_CRLF + "User-Agent: MicroSIP/3.19.22" + m_CRLF + "Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS" + m_CRLF + "Supported: replaces, 100rel, timer, norefersub" + m_CRLF + "Content-Length: 343" + m_CRLF + "Content-Type: application/sdp" + m_CRLF + "Session-Expires: 1800" + m_CRLF + "Min-SE: 90" + m_CRLF + "" + m_CRLF + "v=0" + m_CRLF + "o=- 3785527268 3785527269 IN IP4 192.168.11.50" + m_CRLF + "s=pjmedia" + m_CRLF + "t=0 0" + m_CRLF + "m=audio 4032 RTP/AVP 0 101" + m_CRLF + "c=IN IP4 192.168.11.50" + m_CRLF + "a=rtpmap:0 PCMU/8000" + m_CRLF + "a=rtpmap:101 telephone-event/8000" + m_CRLF + "a=fmtp:101 0-16" + m_CRLF + "a=sendrecv"; SIPEndPoint dummySipEndPoint = new SIPEndPoint(new IPEndPoint(IPAddress.Loopback, 0)); SIPMessageBuffer sipMessageBuffer = SIPMessageBuffer.ParseSIPMessage(inviteReqStr, dummySipEndPoint, dummySipEndPoint); SIPRequest inviteReq = SIPRequest.ParseSIPRequest(sipMessageBuffer); UASInviteTransaction uasTx = new UASInviteTransaction(transport, inviteReq, null); SIPServerUserAgent mockUas = new SIPServerUserAgent(transport, null, null, null, SIPCallDirection.In, null, null, uasTx); await userAgent.Answer(mockUas, CreateMediaSession()); // Incremented Cseq and modified Via header from original request. Means the request is the same dialog but different tx. string inviteReqStr2 = "BYE sip:192.168.11.50:5060 SIP/2.0" + m_CRLF + "Via: SIP/2.0/UDP 192.168.11.50:60163;rport;branch=z9hG4bKPj869f70960bdd4204b1352eaf242a3700" + m_CRLF + "To: <sip:[email protected]>;tag=ZUJSXRRGXQ" + m_CRLF + "From: <sip:[email protected]>;tag=4a60ce364b774258873ff199e5e39938" + m_CRLF + "Call-ID: 17324d6df8744d978008c8997bfd208d" + m_CRLF + "CSeq: 3533 BYE" + m_CRLF + "Contact: <sip:[email protected]:60163;ob>" + m_CRLF + "Max-Forwards: 70" + m_CRLF + "User-Agent: MicroSIP/3.19.22" + m_CRLF + "Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS" + m_CRLF + "Supported: replaces, 100rel, timer, norefersub" + m_CRLF + ""; mockChannel.FireMessageReceived(dummySipEndPoint, dummySipEndPoint, Encoding.UTF8.GetBytes(inviteReqStr2)); }
private static Task OnSIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { if (sipRequest.Method == SIPMethodsEnum.INFO) { var notImplResp = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotImplemented, null); return(_sipTransport.SendResponseAsync(notImplResp)); } return(Task.CompletedTask); }
/// <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 static void SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { if (sipRequest.Method == SIPMethodsEnum.BYE) { throw new NotImplementedException(); } else if (sipRequest.Method == SIPMethodsEnum.CANCEL) { throw new NotImplementedException(); } else if (sipRequest.Method == SIPMethodsEnum.INVITE) { throw new NotImplementedException(); } else if (sipRequest.Method == SIPMethodsEnum.OPTIONS) { SIPNonInviteTransaction optionsTransaction = _sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse optionsResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); optionsTransaction.SendFinalResponse(optionsResponse); } else if (sipRequest.Method == SIPMethodsEnum.REGISTER) { SIPResponse tryingResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Trying, null); _sipTransport.SendResponse(tryingResponse); SIPResponseStatusCodesEnum registerResponse = SIPResponseStatusCodesEnum.Ok; if (sipRequest.Header.Contact != null && sipRequest.Header.Contact.Count > 0) { int expiry = sipRequest.Header.Contact[0].Expires > 0 ? sipRequest.Header.Contact[0].Expires : sipRequest.Header.Expires; var sipAccount = new SIPAccount(null, sipRequest.Header.From.FromURI.Host, sipRequest.Header.From.FromURI.User, null, null); SIPAccountBinding binding = new SIPAccountBinding(sipAccount, sipRequest.Header.Contact[0].ContactURI, remoteEndPoint, localSIPEndPoint, expiry); if (_sipRegistrations.ContainsKey(sipAccount.SIPUsername)) { _sipRegistrations.Remove(sipAccount.SIPUsername); } _sipRegistrations.Add(sipAccount.SIPUsername, binding); logger.LogDebug("Registered contact for " + sipAccount.SIPUsername + " as " + binding.RegisteredContact.ToString() + "."); } else { registerResponse = SIPResponseStatusCodesEnum.BadRequest; } SIPNonInviteTransaction registerTransaction = _sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, registerResponse, null); registerTransaction.SendFinalResponse(okResponse); } else { logger.LogDebug("SIP " + sipRequest.Method + " request received but no processing has been set up for it, rejecting."); } } catch (NotImplementedException) { logger.LogDebug(sipRequest.Method + " request processing not implemented for " + sipRequest.URI.ToParameterlessString() + " from " + remoteEndPoint + "."); SIPNonInviteTransaction notImplTransaction = _sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse notImplResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotImplemented, null); notImplTransaction.SendFinalResponse(notImplResponse); } }
/// <summary> /// Because this is a server user agent the SIP transport must start listening for client user agents. /// </summary> private async Task OnRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { var banResult = _sipFail2Ban.IsBanned(remoteEndPoint); if (banResult == BanReasonsEnum.None) { if (sipRequest.Header.From != null && sipRequest.Header.From.FromTag != null && sipRequest.Header.To != null && sipRequest.Header.To.ToTag != null) { _sipCallManager.ProcessInDialogueRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else { switch (sipRequest.Method) { case SIPMethodsEnum.BYE: case SIPMethodsEnum.CANCEL: // BYE's and CANCEL's should always have dialog fields set. SIPResponse badResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.BadRequest, null); await _sipTransport.SendResponseAsync(badResponse); break; case SIPMethodsEnum.INVITE: if (!await WasRejected(sipRequest)) { _logger.LogInformation($"Incoming call request: {localSIPEndPoint}<-{remoteEndPoint} {sipRequest.URI}."); _b2bUserAgentCore.AddInviteRequest(sipRequest); } break; case SIPMethodsEnum.OPTIONS: SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); optionsResponse.Header.Contact = new List <SIPContactHeader> { SIPContactHeader.GetDefaultSIPContactHeader(sipRequest.URI.Scheme) }; optionsResponse.Header.Server = SIPConstants.SIP_USERAGENT_STRING; await _sipTransport.SendResponseAsync(optionsResponse); break; case SIPMethodsEnum.REGISTER: if (!await WasRejected(sipRequest)) { _registrarCore.AddRegisterRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } break; case SIPMethodsEnum.SUBSCRIBE: if (!await WasRejected(sipRequest)) { _subscriberCore.AddSubscribeRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } break; default: var notAllowedResp = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); await _sipTransport.SendResponseAsync(notAllowedResp); break; } } } else { _logger.LogWarning($"Ban list hit for {remoteEndPoint} and {banResult} dropped request {sipRequest.StatusLine}, user agent {sipRequest.Header.UserAgent}."); } } catch (Exception reqExcp) { _logger.LogWarning($"Exception handling {sipRequest.Method}. {reqExcp.Message}"); } }
private SIPRequest GetRequest(SIPMethodsEnum method) { try { SIPURI uri = SIPURI.ParseSIPURIRelaxed(m_callDescriptor.Uri); SIPRequest request = new SIPRequest(method, uri); SIPFromHeader fromHeader = m_callDescriptor.GetFromHeader(); fromHeader.FromTag = CallProperties.CreateNewTag(); SIPToHeader toHeader = new SIPToHeader(null, uri, null); int cseq = Crypto.GetRandomInt(10000, 20000); SIPHeader header = new SIPHeader(fromHeader, toHeader, cseq, CallProperties.CreateNewCallId()); header.CSeqMethod = method; header.UserAgent = m_userAgent; request.Header = header; SIPViaHeader viaHeader = new SIPViaHeader(m_sipTransport.GetDefaultSIPEndPoint(), CallProperties.CreateBranchId()); request.Header.Vias.PushViaHeader(viaHeader); try { if (m_callDescriptor.CustomHeaders != null && m_callDescriptor.CustomHeaders.Count > 0) { foreach (string customHeader in m_callDescriptor.CustomHeaders) { if (customHeader.IsNullOrBlank()) { continue; } else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_USERAGENT)) { request.Header.UserAgent = customHeader.Substring(customHeader.IndexOf(":") + 1).Trim(); } else { request.Header.UnknownHeaders.Add(customHeader); } } } } catch (Exception excp) { logger.Error("Exception Parsing CustomHeader for SIPNonInviteClientUserAgent GetRequest. " + excp.Message + m_callDescriptor.CustomHeaders); } if (!m_callDescriptor.Content.IsNullOrBlank()) { request.Body = m_callDescriptor.Content; request.Header.ContentType = m_callDescriptor.ContentType; request.Header.ContentLength = request.Body.Length; } return(request); } catch (Exception excp) { logger.Error("Exception SIPNonInviteClientUserAgent GetRequest. " + excp.Message); throw excp; } }
private void SIPRequestOutTraceEvent(SIPEndPoint localEP, SIPEndPoint remoteEP, SIPRequest sipRequest) { logger.LogDebug($"Request Sent {localEP}<-{remoteEP}: {sipRequest.StatusLine}."); if (_homerSIPClient != null) { var hepBuffer = HepPacket.GetBytes(localEP, remoteEP, DateTime.Now, 333, "myHep", sipRequest.ToString()); _homerSIPClient.SendAsync(hepBuffer, hepBuffer.Length, HOMER_SERVER_ADDRESS, HOMER_SERVER_PORT); } }
private SIPRequest GetUpdateRequest(SIPRequest inviteRequest, CRMHeaders crmHeaders) { SIPRequest updateRequest = new SIPRequest(SIPMethodsEnum.UPDATE, inviteRequest.URI); updateRequest.LocalSIPEndPoint = inviteRequest.LocalSIPEndPoint; SIPHeader inviteHeader = inviteRequest.Header; SIPHeader updateHeader = new SIPHeader(inviteHeader.From, inviteHeader.To, inviteHeader.CSeq + 1, inviteHeader.CallId); inviteRequest.Header.CSeq++; updateRequest.Header = updateHeader; updateHeader.CSeqMethod = SIPMethodsEnum.UPDATE; updateHeader.Routes = inviteHeader.Routes; updateHeader.ProxySendFrom = inviteHeader.ProxySendFrom; SIPViaHeader viaHeader = new SIPViaHeader(inviteRequest.LocalSIPEndPoint, CallProperties.CreateBranchId()); updateHeader.Vias.PushViaHeader(viaHeader); // Add custom CRM headers. if (crmHeaders != null) { updateHeader.CRMPersonName = crmHeaders.PersonName; updateHeader.CRMCompanyName = crmHeaders.CompanyName; updateHeader.CRMPictureURL = crmHeaders.AvatarURL; } return updateRequest; }
public async Task IncomingCallNoSdpWithACKUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); SIPTransport transport = new SIPTransport(); transport.AddSIPChannel(new MockSIPChannel(new System.Net.IPEndPoint(IPAddress.Any, 0))); var dummySep = SIPEndPoint.ParseSIPEndPoint("udp:127.0.0.1:5060"); SIPUserAgent userAgent = new SIPUserAgent(transport, null); string inviteReqStr = @"INVITE sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP 127.0.0.1:51200;branch=z9hG4bKbeed9b0cde8d43cc8a2aae91526b6a1d;rport To: <sip:[email protected]> From: <sip:[email protected]>;tag=GCLNRILCDU Call-ID: 7265e19f53a146a1bacdf4f4f8ea70b2 CSeq: 1 INVITE Contact: <sip:127.0.0.1:51200> Max-Forwards: 70 User-Agent: www.sipsorcery.com Content-Length: 0 Content-Type: application/sdp" + m_CRLF + m_CRLF; SIPEndPoint dummySipEndPoint = new SIPEndPoint(new IPEndPoint(IPAddress.Loopback, 0)); SIPMessageBuffer sipMessageBuffer = SIPMessageBuffer.ParseSIPMessage(inviteReqStr, dummySipEndPoint, dummySipEndPoint); SIPRequest inviteReq = SIPRequest.ParseSIPRequest(sipMessageBuffer); var uas = userAgent.AcceptCall(inviteReq); var mediaSession = CreateMediaSession(); _ = Task.Run(() => { Task.Delay(2000).Wait(); string ackReqStr = @"ACK sip:127.0.0.1:5060 SIP/2.0 Via: SIP/2.0/UDP 127.0.0.1:51200;branch=z9hG4bK76dfb1480ea14f778bd24afed1c8ded0;rport To: <sip:[email protected]>;tag=YWPNZPMLPB From: <sip:[email protected]>;tag=GCLNRILCDU Call-ID: 7265e19f53a146a1bacdf4f4f8ea70b2 CSeq: 1 ACK Max-Forwards: 70 Content-Length: 160 v=0 o=- 67424 0 IN IP4 127.0.0.1 s=- c=IN IP4 127.0.0.1 t=0 0 m=audio 16976 RTP/AVP 8 101 a=rtpmap:101 telephone-event/8000 a=fmtp:101 0-16 a=sendrecv" + m_CRLF + m_CRLF; uas.ClientTransaction.ACKReceived(dummySep, dummySep, SIPRequest.ParseSIPRequest(ackReqStr)); }); await userAgent.Answer(uas, mediaSession); Assert.True(userAgent.IsCallActive); }
public SIPTransferServerUserAgent( SIPMonitorLogDelegate logDelegate, BlindTransferDelegate blindTransfer, SIPTransport sipTransport, SIPEndPoint outboundProxy, SIPDialogue dialogueToReplace, SIPDialogue oppositeDialogue, string callDestination, string owner, string adminID) { Log_External = logDelegate; BlindTransfer_External = blindTransfer; m_sipTransport = sipTransport; m_outboundProxy = outboundProxy; m_dialogueToReplace = dialogueToReplace; m_oppositeDialogue = oppositeDialogue; m_callDestination = callDestination; m_owner = owner; m_adminID = adminID; m_dummyRequest = CreateDummyRequest(m_dialogueToReplace, m_callDestination); }
private Task <SocketError> OnAckAnswerReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPRequest sipRequest) { SIPDialogue = new SIPDialogue(m_uasTransaction, m_owner, m_adminMemberId); SIPDialogue.TransferMode = m_transferMode; OnDialogueCreated?.Invoke(SIPDialogue); return(Task.FromResult(SocketError.Success)); }
public SIPRequest GetCancelRequest(SIPRequest inviteRequest) { SIPRequest cancelRequest = new SIPRequest(SIPMethodsEnum.CANCEL, inviteRequest.URI); SIPHeader cancelHeader = new SIPHeader(inviteRequest.Header.From, inviteRequest.Header.To, inviteRequest.Header.CSeq, inviteRequest.Header.CallId); cancelHeader.Via = inviteRequest.Header.Via; cancelHeader.CSeqMethod = SIPMethodsEnum.CANCEL; cancelRequest.Header = cancelHeader; return cancelRequest; }
public bool AuthenticateCall() { m_isAuthenticated = false; try { if (SIPAuthenticateRequest_External == null) { // No point trying to authenticate if we haven't been given an authentication delegate. Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null); } else if (GetSIPAccount_External == null) { // No point trying to authenticate if we haven't been given a delegate to load the SIP account. Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null); } else { m_sipAccount = GetSIPAccount_External(m_sipUsername, m_sipDomain); if (m_sipAccount == null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Rejecting authentication required call for " + m_sipUsername + "@" + m_sipDomain + ", SIP account not found.", null)); Reject(SIPResponseStatusCodesEnum.Forbidden, null, null); } else { SIPRequest sipRequest = m_uasTransaction.TransactionRequest; SIPEndPoint localSIPEndPoint = (!sipRequest.Header.ProxyReceivedOn.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedOn) : sipRequest.LocalSIPEndPoint; SIPEndPoint remoteEndPoint = (!sipRequest.Header.ProxyReceivedFrom.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedFrom) : sipRequest.RemoteSIPEndPoint; SIPRequestAuthenticationResult authenticationResult = SIPAuthenticateRequest_External(localSIPEndPoint, remoteEndPoint, sipRequest, m_sipAccount, Log_External); if (authenticationResult.Authenticated) { if (authenticationResult.WasAuthenticatedByIP) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "New call from " + remoteEndPoint.ToString() + " successfully authenticated by IP address.", m_sipAccount.Owner)); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "New call from " + remoteEndPoint.ToString() + " successfully authenticated by digest.", m_sipAccount.Owner)); } SetOwner(m_sipAccount.Owner, m_sipAccount.AdminMemberId); m_isAuthenticated = true; } else { // Send authorisation failure or required response SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Call not authenticated for " + m_sipUsername + "@" + m_sipDomain + ", responding with " + authenticationResult.ErrorResponse + ".", null)); m_uasTransaction.SendFinalResponse(authReqdResponse); } } } } catch (Exception excp) { logger.LogError("Exception SIPServerUserAgent AuthenticateCall. " + excp.Message); Reject(SIPResponseStatusCodesEnum.InternalServerError, null, null); } return(m_isAuthenticated); }
public SIPRequest GetSIPRequest(SIPMethodsEnum sipMethod, string requestURIStr, string fromURIStr, int cseq, string callId, string contentType, string body) { SIPURI requestURI = (requestURIStr.StartsWith("sip:")) ? SIPURI.ParseSIPURI(requestURIStr) : SIPURI.ParseSIPURI("sip:" + requestURIStr); SIPURI fromURI = (fromURIStr.StartsWith("sip:")) ? SIPURI.ParseSIPURI(fromURIStr) : SIPURI.ParseSIPURI("sip:" + fromURIStr); SIPFromHeader fromHeader = new SIPFromHeader(null, fromURI, CallProperties.CreateNewTag()); SIPToHeader toHeader = new SIPToHeader(null, requestURI, null); SIPRequest sipRequest = new SIPRequest(sipMethod, requestURI); IPEndPoint localSIPEndPoint = m_sipTransport.GetIPEndPointsList()[0]; SIPHeader sipHeader = new SIPHeader(fromHeader, toHeader, cseq, callId); sipHeader.Contact = SIPContactHeader.ParseContactHeader("sip:" + localSIPEndPoint.ToString()); sipHeader.CSeqMethod = sipMethod; sipRequest.Header = sipHeader; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint.Address.ToString(), localSIPEndPoint.Port, CallProperties.CreateBranchId()); sipRequest.Header.Via.PushViaHeader(viaHeader); if (body != null && body.Trim().Length > 0) { sipRequest.Body = body; //sipRequest.Body = "Signal=5\r\nDuration=250"; //sipRequest.Body = "<rtcp>blah blah blah</rtcp>"; sipRequest.Header.ContentLength = sipRequest.Body.Length; sipRequest.Header.ContentType = contentType; } return sipRequest; }
public void AddSubscribeRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest subscribeRequest) { try { if (subscribeRequest.Method != SIPMethodsEnum.SUBSCRIBE) { SIPResponse notSupportedResponse = SIPTransport.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, "Subscribe requests only"); m_sipTransport.SendResponse(notSupportedResponse); } else { #region Do as many validation checks as possible on the request before adding it to the queue. if (subscribeRequest.Header.Event.IsNullOrBlank() || !(subscribeRequest.Header.Event.ToLower() == SIPEventPackage.Dialog.ToString().ToLower() || subscribeRequest.Header.Event.ToLower() == SIPEventPackage.Presence.ToString().ToLower())) { SIPResponse badEventResponse = SIPTransport.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.BadEvent, null); m_sipTransport.SendResponse(badEventResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Event type " + subscribeRequest.Header.Event + " not supported for " + subscribeRequest.URI.ToString() + ".", null)); } else if (subscribeRequest.Header.Expires > 0 && subscribeRequest.Header.Expires < MIN_SUBSCRIPTION_EXPIRY) { SIPResponse tooBriefResponse = SIPTransport.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.IntervalTooBrief, null); tooBriefResponse.Header.MinExpires = MIN_SUBSCRIPTION_EXPIRY; m_sipTransport.SendResponse(tooBriefResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Subscribe request was rejected as interval too brief " + subscribeRequest.Header.Expires + ".", null)); } else if (subscribeRequest.Header.Contact == null || subscribeRequest.Header.Contact.Count == 0) { SIPResponse noContactResponse = SIPTransport.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing Contact header"); m_sipTransport.SendResponse(noContactResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Subscribe request was rejected due to no Contact header.", null)); } #endregion else { if (m_notifierQueue.Count < MAX_NOTIFIER_QUEUE_SIZE) { SIPNonInviteTransaction subscribeTransaction = m_sipTransport.CreateNonInviteTransaction(subscribeRequest, remoteEndPoint, localSIPEndPoint, m_outboundProxy); lock (m_notifierQueue) { m_notifierQueue.Enqueue(subscribeTransaction); } FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeQueued, "Subscribe queued for " + subscribeRequest.Header.To.ToURI.ToString() + ".", null)); } else { logger.Error("Subscribe queue exceeded max queue size " + MAX_NOTIFIER_QUEUE_SIZE + ", overloaded response sent."); SIPResponse overloadedResponse = SIPTransport.GetResponse(subscribeRequest, SIPResponseStatusCodesEnum.TemporarilyUnavailable, "Notifier overloaded, please try again shortly"); m_sipTransport.SendResponse(overloadedResponse); } m_notifierARE.Set(); } } } catch (Exception excp) { logger.Error("Exception AddNotifierRequest (" + remoteEndPoint.ToString() + "). " + excp.Message); } }
public SIPResponse WaitForFinalResponse(int waitSeconds, SIPRequest sipRequest) { DateTime startWaitTime = DateTime.Now; m_waitForSIPFinalResponse.Reset(); m_lastFinalResponse = null; while (m_lastFinalResponse == null && DateTime.Now.Subtract(startWaitTime).TotalSeconds < waitSeconds) { m_waitForSIPFinalResponse.WaitOne(Convert.ToInt32((waitSeconds - DateTime.Now.Subtract(startWaitTime).TotalSeconds) * 1000), false); if (m_lastFinalResponse != null && m_lastFinalResponse.Header.CallId == sipRequest.Header.CallId) { break; } else { m_lastFinalResponse = null; } } return m_lastFinalResponse; }
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; } SIPAccountAsset sipAccountAsset = m_sipAssetPersistor.Get(s => s.SIPUsername == fromUser && s.SIPDomain == canonicalDomain); SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator_External(subscribeTransaction.LocalSIPEndPoint, subscribeTransaction.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; 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 + ".", sipAccountAsset.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 + ".", sipAccountAsset.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 + ".", sipAccountAsset.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; SIPAccountAsset 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.", sipAccountAsset.Owner)); return; } if (canonicalResourceURI.User != m_wildcardUser) { 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.", sipAccountAsset.Owner)); return; } } // Check the owner permissions on the requesting and subscribed resources. bool authorised = false; string adminID = null; if (canonicalResourceURI.User == m_wildcardUser || sipAccountAsset.Owner == resourceSIPAccount.Owner) { authorised = true; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to common owner.", sipAccountAsset.Owner)); } else { // Lookup the customer record for the requestor and check the administrative level on it. Customer requestingCustomer = GetCustomer_External(c => c.CustomerUsername == sipAccountAsset.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 + ".", sipAccountAsset.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.", sipAccountAsset.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(sipAccountAsset.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 + ".", sipAccountAsset.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 + ".", sipAccountAsset.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 " + sipAccountAsset.Owner + " was not authorised.", sipAccountAsset.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); } }
/// <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 Task SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { if (sipRequest.Method == SIPMethodsEnum.INFO) { logger.LogDebug("SIP " + sipRequest.Method + " request received but no processing has been set up for it, rejecting."); SIPResponse notAllowedResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); return(SIPTransport.SendResponseAsync(notAllowedResponse)); } else if (sipRequest.Header.From != null && sipRequest.Header.From.FromTag != null && sipRequest.Header.To != null && sipRequest.Header.To.ToTag != null) { // This is an in-dialog request that will be handled directly by a user agent instance. } else if (sipRequest.Method == SIPMethodsEnum.INVITE) { bool?callAccepted = IncomingCall?.Invoke(sipRequest); if (callAccepted == false) { // All user agents were already on a call return a busy response. UASInviteTransaction uasTransaction = new UASInviteTransaction(SIPTransport, sipRequest, null); SIPResponse busyResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.BusyHere, null); uasTransaction.SendFinalResponse(busyResponse); } } else { logger.LogDebug("SIP " + sipRequest.Method + " request received but no processing has been set up for it, rejecting."); SIPResponse notAllowedResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); return(SIPTransport.SendResponseAsync(notAllowedResponse)); } return(Task.FromResult(0)); }
public void AddRegisterRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest registerRequest) { if (registerRequest.Method != SIPMethodsEnum.REGISTER) { SIPResponse notSupportedResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, "Registration requests only"); m_sipTransport.SendResponseAsync(notSupportedResponse).Wait(); } else { int requestedExpiry = GetRequestedExpiry(registerRequest); if (requestedExpiry > 0 && requestedExpiry < m_minimumBindingExpiry) { Logger.LogDebug("Bad register request, no expiry of " + requestedExpiry + " to small from " + remoteEndPoint + "."); SIPResponse tooFrequentResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.IntervalTooBrief, null); tooFrequentResponse.Header.MinExpires = m_minimumBindingExpiry; m_sipTransport.SendResponseAsync(tooFrequentResponse).Wait(); } else { if (m_registerQueue.Count < MAX_REGISTER_QUEUE_SIZE) { SIPNonInviteTransaction regTx = new SIPNonInviteTransaction(m_sipTransport, registerRequest, null); m_registerQueue.Enqueue(regTx); } else { Logger.LogError("Register queue exceeded maximum queue size " + MAX_REGISTER_QUEUE_SIZE + ", overloaded response sent."); SIPResponse overloadedResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.TemporarilyUnavailable, "Registrar overloaded, please try again shortly"); m_sipTransport.SendResponseAsync(overloadedResponse).Wait(); } m_registerARE.Set(); } } }
private void DeviceDmsRegister(SIPTransaction sipTransaction, string gbname) { try { //Device insert into database Device _device = new Device(); SIPRequest sipRequest = sipTransaction.TransactionRequest; _device.Guid = Guid.NewGuid().ToString(); _device.IP = sipTransaction.TransactionRequest.RemoteSIPEndPoint.Address.ToString();//IPC _device.Name = gbname; _device.LoginUser.Add(new LoginUser() { LoginName = _SIPAccount.SIPUsername ?? "admin", LoginPwd = _SIPAccount.SIPPassword ?? "123456" }); //same to GB config service _device.Port = Convert.ToUInt32(sipTransaction.TransactionRequest.RemoteSIPEndPoint.Port); //5060 _device.GBID = sipTransaction.TransactionRequestFrom.URI.User; //42010000001180000184 _device.PtzType = 0; _device.ProtocolType = 0; _device.ShapeType = ShapeType.Dome; //var options = new List<ChannelOption> { new ChannelOption(ChannelOptions.MaxMessageLength, int.MaxValue) }; //devicemanagementservice 是预留的服务标识(暂命名为设备管理服务).目前没有这个服务. //需要你的微服务架构中实现一个设备资产以及一个配置管理服务(或者二合一的资源管服务) //以达到两个目的:1、用来为当前GB服务提供启动配置,2、为GB收到注册的设备/平台信息,提供全平台的统一的存储服务. var channel = GrpcChannel.ForAddress(EnvironmentVariables.DeviceManagementServiceAddress ?? "devicemanagementservice:8080"); //, ChannelCredentials.Insecure); logger.Debug("Device Management Service Address: " + (EnvironmentVariables.DeviceManagementServiceAddress ?? "devicemanagementservice:8080")); var client = new DevicesManager.DevicesManagerClient(channel); //if (!_sipCoreMessageService.NodeMonitorService.ContainsKey(_device.GBID)) //{ // AddDeviceRequest _AddDeviceRequest = new AddDeviceRequest(); // _AddDeviceRequest.Device.Add(_device); // _AddDeviceRequest.LoginRoleId = "XXXX"; // var reply = client.AddDevice(_AddDeviceRequest); // if (reply.Status == OP_RESULT_STATUS.OpSuccess) // { // logger.Debug("Device[" + sipTransaction.TransactionRequest.RemoteSIPEndPoint + "] have added registering DMS service."); // DeviceEditEvent(_device.GBID, "add"); // } // else // { // logger.Error("_sipRegistrarCore_RPCDmsRegisterReceived.AddDevice: " + reply.Status.ToString()); // } //} //else //{ // UpdateDeviceRequest _UpdateDeviceRequest = new UpdateDeviceRequest(); // _UpdateDeviceRequest.DeviceItem.Add(_device); // _UpdateDeviceRequest.LoginRoleId = "XXXX"; // var reply = client.UpdateDevice(_UpdateDeviceRequest); // if (reply.Status == OP_RESULT_STATUS.OpSuccess) // { // logger.Debug("Device[" + sipTransaction.TransactionRequest.RemoteSIPEndPoint + "] have updated registering DMS service."); // } // else // { // logger.Error("_sipRegistrarCore_RPCDmsRegisterReceived.UpdateDevice: " + reply.Status.ToString()); // } //} //add & update device AddDeviceRequest _AddDeviceRequest = new AddDeviceRequest(); _AddDeviceRequest.Device.Add(_device); _AddDeviceRequest.LoginRoleId = "XXXX"; var reply = client.AddDevice(_AddDeviceRequest); if (reply.Status == OP_RESULT_STATUS.OpSuccess) { logger.Debug("Device added into DMS service: " + JsonConvert.SerializeObject(_device)); } else { logger.Warn("DeviceDmsRegister.AddDevice: " + reply.Status.ToString()); } } catch (Exception ex) { logger.Error("DeviceDmsRegister Exception: " + ex.Message); } }
private SIPRequest GetByeRequest(SIPResponse inviteResponse, SIPURI byeURI, SIPEndPoint localSIPEndPoint) { SIPRequest byeRequest = new SIPRequest(SIPMethodsEnum.BYE, byeURI); byeRequest.LocalSIPEndPoint = localSIPEndPoint; SIPFromHeader byeFromHeader = inviteResponse.Header.From; SIPToHeader byeToHeader = inviteResponse.Header.To; int cseq = inviteResponse.Header.CSeq + 1; SIPHeader byeHeader = new SIPHeader(byeFromHeader, byeToHeader, cseq, inviteResponse.Header.CallId); byeHeader.CSeqMethod = SIPMethodsEnum.BYE; byeHeader.ProxySendFrom = m_serverTransaction.TransactionRequest.Header.ProxySendFrom; byeRequest.Header = byeHeader; byeRequest.Header.Routes = (inviteResponse.Header.RecordRoutes != null) ? inviteResponse.Header.RecordRoutes.Reversed() : null; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, CallProperties.CreateBranchId()); byeRequest.Header.Vias.PushViaHeader(viaHeader); return byeRequest; }
public void GotRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { if (sipRequest.Method == SIPMethodsEnum.NOTIFY) { if (sipRequest.Header.UnknownHeaders.Exists(s => s.Contains("Event: keep-alive"))) { // If this is a NOTIFY request that's being sent for NAT keep-alive purposes repond with Ok. SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); m_sipTransport.SendResponse(okResponse); } if (GetCanonicalDomain_External(sipRequest.URI.Host, true) != null && !sipRequest.URI.User.IsNullOrBlank()) { m_notifyManager.QueueNotification(sipRequest); } else { // Send Not Serviced response to server. SIPResponse notServicedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Domain not serviced"); m_sipTransport.SendResponse(notServicedResponse); } } else if (sipRequest.Method == SIPMethodsEnum.SUBSCRIBE) { m_notifierCore.AddSubscribeRequest(localSIPEndPoint, remoteEndPoint, sipRequest); } else { SIPResponse methodNotSupportedResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); m_sipTransport.SendResponse(methodNotSupportedResponse); } } catch (Exception excp) { logger.Error("Exception SIPNotifierDaemon GotRequest. " + excp.Message); } }
//private void ByeFinalResponseReceived(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse) //{ // Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.DialPlan, "BYE response " + sipResponse.StatusCode + " " + sipResponse.ReasonPhrase + ".", Owner)); //} private SIPRequest GetInviteRequest(SIPCallDescriptor sipCallDescriptor, string branchId, string callId, SIPEndPoint localSIPEndPoint, SIPRouteSet routeSet, string content, string contentType) { SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, sipCallDescriptor.Uri); inviteRequest.LocalSIPEndPoint = localSIPEndPoint; SIPHeader inviteHeader = new SIPHeader(sipCallDescriptor.GetFromHeader(), SIPToHeader.ParseToHeader(sipCallDescriptor.To), 1, callId); inviteHeader.From.FromTag = CallProperties.CreateNewTag(); // For incoming calls forwarded via the dial plan the username needs to go into the Contact header. inviteHeader.Contact = new List<SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(inviteRequest.URI.Scheme, localSIPEndPoint)) }; inviteHeader.Contact[0].ContactURI.User = sipCallDescriptor.Username; inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE; inviteHeader.UserAgent = m_userAgent; inviteHeader.Routes = routeSet; inviteRequest.Header = inviteHeader; if (!sipCallDescriptor.ProxySendFrom.IsNullOrBlank()) { inviteHeader.ProxySendFrom = sipCallDescriptor.ProxySendFrom; } SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint, branchId); inviteRequest.Header.Vias.PushViaHeader(viaHeader); inviteRequest.Body = content; inviteRequest.Header.ContentLength = (inviteRequest.Body != null) ? inviteRequest.Body.Length : 0; inviteRequest.Header.ContentType = contentType; // Add custom switchboard headers. if (CallDescriptor.SwitchboardHeaders != null) { inviteHeader.SwitchboardOriginalCallID = CallDescriptor.SwitchboardHeaders.SwitchboardOriginalCallID; //inviteHeader.SwitchboardCallerDescription = CallDescriptor.SwitchboardHeaders.SwitchboardCallerDescription; inviteHeader.SwitchboardLineName = CallDescriptor.SwitchboardHeaders.SwitchboardLineName; //inviteHeader.SwitchboardOwner = CallDescriptor.SwitchboardHeaders.SwitchboardOwner; //inviteHeader.SwitchboardOriginalFrom = CallDescriptor.SwitchboardHeaders.SwitchboardOriginalFrom; } // Add custom CRM headers. if (CallDescriptor.CRMHeaders != null) { inviteHeader.CRMPersonName = CallDescriptor.CRMHeaders.PersonName; inviteHeader.CRMCompanyName = CallDescriptor.CRMHeaders.CompanyName; inviteHeader.CRMPictureURL = CallDescriptor.CRMHeaders.AvatarURL; } try { if (sipCallDescriptor.CustomHeaders != null && sipCallDescriptor.CustomHeaders.Count > 0) { foreach (string customHeader in sipCallDescriptor.CustomHeaders) { if (customHeader.IsNullOrBlank()) { continue; } else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_USERAGENT)) { inviteRequest.Header.UserAgent = customHeader.Substring(customHeader.IndexOf(":") + 1).Trim(); } else { inviteRequest.Header.UnknownHeaders.Add(customHeader); } } } } catch (Exception excp) { logger.Error("Exception Parsing CustomHeader for GetInviteRequest. " + excp.Message + sipCallDescriptor.CustomHeaders); } return inviteRequest; }
private void SendInitialRegister() { try { if (m_attempts >= m_maxRegisterAttempts) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration to " + m_sipAccountAOR.ToString() + " reached the maximum number of allowed attempts without a failure condition.", null)); m_isRegistered = false; RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration reached the maximum number of allowed attempts."); m_waitForRegistrationMRE.Set(); } else { m_attempts++; SIPEndPoint registrarSIPEndPoint = m_outboundProxy; if (registrarSIPEndPoint == null) { SIPDNSLookupResult lookupResult = m_sipTransport.GetHostEndPoint(m_registrarHost, false); if (lookupResult.LookupError != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Could not resolve " + m_registrarHost + ", " + lookupResult.LookupError, null)); } else { registrarSIPEndPoint = lookupResult.GetSIPEndPoint(); } } if (registrarSIPEndPoint == null) { logger.LogWarning("SIPRegistrationAgent could not resolve " + m_registrarHost + "."); RegistrationFailed?.Invoke(m_sipAccountAOR, "Could not resolve " + m_registrarHost + "."); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterInProgress, "Initiating registration to " + m_registrarHost + " at " + registrarSIPEndPoint.ToString() + " for " + m_sipAccountAOR.ToString() + ".", null)); SIPRequest regRequest = GetRegistrationRequest(); SIPNonInviteTransaction regTransaction = new SIPNonInviteTransaction(m_sipTransport, regRequest, registrarSIPEndPoint); // These handlers need to be on their own threads to take the processing off the SIP transport layer. regTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) => { ThreadPool.QueueUserWorkItem(delegate { ServerResponseReceived(lep, rep, tn, rsp); }); return(Task.FromResult(SocketError.Success)); }; regTransaction.NonInviteTransactionTimedOut += (tn) => { ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); }); }; m_sipTransport.SendTransaction(regTransaction); } } } catch (Exception excp) { logger.LogError("Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message); RegistrationFailed?.Invoke(m_sipAccountAOR, "Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message); } }
private SIPRequest CreateDummyRequest(SIPDialogue dialogueToReplace, string callDestination) { SIPRequest dummyInvite = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURIRelaxed(callDestination + "@sipsorcery.com")); SIPHeader dummyHeader = new SIPHeader("<sip:[email protected]>", "<sip:[email protected]>", 1, CallProperties.CreateNewCallId()); dummyHeader.CSeqMethod = SIPMethodsEnum.INVITE; dummyHeader.Vias.PushViaHeader(new SIPViaHeader(new IPEndPoint(SIPTransport.BlackholeAddress, 0), CallProperties.CreateBranchId())); dummyInvite.Header = dummyHeader; dummyInvite.Header.ContentType = "application/sdp"; dummyInvite.Body = dialogueToReplace.SDP; return dummyInvite; }
/// <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() + ".", null)); if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised) { if (sipResponse.Header.AuthenticationHeader != null) { if (m_attempts >= m_maxRegisterAttempts) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration to " + m_sipAccountAOR.ToString() + " reached the maximum number of allowed attempts without a failure condition.", null)); 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); if (lookupResult.LookupError != null) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Could not resolve " + m_registrarHost + ", " + lookupResult.LookupError, null)); } else { registrarSIPEndPoint = lookupResult.GetSIPEndPoint(); } } 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 { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " but no authentication header was supplied for " + m_sipAccountAOR.ToString() + ".", null)); 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.", null)); 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.", null)); SendInitialRegister(); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + ".", null)); 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 SIPRequest GetInviteRequest(string callURI, SIPCallDescriptor sipCallDescriptor) { SIPFromHeader fromHeader = sipCallDescriptor.GetFromHeader(); SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURI(callURI)); inviteRequest.LocalSIPEndPoint = m_blackhole; SIPHeader inviteHeader = new SIPHeader(fromHeader, new SIPToHeader(null, inviteRequest.URI, null), 1, CallProperties.CreateNewCallId()); inviteHeader.From.FromTag = CallProperties.CreateNewTag(); // For incoming calls forwarded via the dial plan the username needs to go into the Contact header. inviteHeader.Contact = new List<SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(inviteRequest.URI.Scheme, m_blackhole)) }; inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE; inviteRequest.Header = inviteHeader; SIPViaHeader viaHeader = new SIPViaHeader(m_blackhole, CallProperties.CreateBranchId()); inviteRequest.Header.Vias.PushViaHeader(viaHeader); try { if (sipCallDescriptor.CustomHeaders != null && sipCallDescriptor.CustomHeaders.Count > 0) { foreach (string customHeader in sipCallDescriptor.CustomHeaders) { if (customHeader.IsNullOrBlank()) { continue; } else if (customHeader.Trim().StartsWith(SIPHeaders.SIP_HEADER_USERAGENT)) { inviteRequest.Header.UserAgent = customHeader.Substring(customHeader.IndexOf(":") + 1).Trim(); } else { inviteRequest.Header.UnknownHeaders.Add(customHeader); } } } } catch (Exception excp) { logger.Error("Exception Parsing CustomHeader for GetInviteRequest. " + excp.Message + sipCallDescriptor.CustomHeaders); } return inviteRequest; }
private void LogSIPRequestOut(SIPEndPoint localSIPEndPoint, SIPEndPoint endPoint, SIPRequest sipRequest) { string message = "App Svr Sent: " + localSIPEndPoint.ToString() + "->" + endPoint.ToString() + "\r\n" + sipRequest.ToString(); //logger.Debug("as: request out " + sipRequest.Method + " " + localSIPEndPoint.ToString() + "->" + endPoint.ToString() + ", callid=" + sipRequest.Header.CallId + "."); string fromUser = (sipRequest.Header.From != null && sipRequest.Header.From.FromURI != null) ? sipRequest.Header.From.FromURI.User : "******"; FireSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.FullSIPTrace, message, fromUser, localSIPEndPoint, endPoint)); }
public SIPRequest GetAuthenticatedRequest(SIPRequest origRequest, SIPResponse authReqdResponse, string username, string password) { SIPRequest authRequest = origRequest; authRequest.Header.Via.TopViaHeader.Branch = CallProperties.CreateBranchId(); authRequest.Header.From.FromTag = CallProperties.CreateNewTag(); authRequest.Header.CSeq = origRequest.Header.CSeq + 1; AuthorizationRequest authorizationRequest = authReqdResponse.Header.AuthenticationHeader.AuthRequest; authorizationRequest.SetCredentials(username, password, origRequest.URI.ToString(), origRequest.Method.ToString()); authRequest.Header.AuthenticationHeader = new SIPAuthenticationHeader(authorizationRequest); authRequest.Header.AuthenticationHeader.AuthRequest.Response = authorizationRequest.Digest; return authRequest; }
/// <summary> /// Because this is a server user agent the SIP transport must start listening for client user agents. /// </summary> private static async Task OnRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { if (sipRequest.Header.From != null && sipRequest.Header.From.FromTag != null && sipRequest.Header.To != null && sipRequest.Header.To.ToTag != null) { // This is an in-dialog request that will be handled directly by a user agent instance. } else if (sipRequest.Method == SIPMethodsEnum.INVITE) { Log.LogInformation($"Incoming call request: {localSIPEndPoint}<-{remoteEndPoint} {sipRequest.URI}."); SIPUserAgent ua = new SIPUserAgent(_sipTransport, null); ua.OnCallHungup += OnHangup; ua.ServerCallCancelled += (uas) => Log.LogDebug("Incoming call cancelled by remote party."); ua.OnDtmfTone += (key, duration) => OnDtmfTone(ua, key, duration); ua.OnRtpEvent += (evt, hdr) => Log.LogDebug($"rtp event {evt.EventID}, duration {evt.Duration}, end of event {evt.EndOfEvent}, timestamp {hdr.Timestamp}, marker {hdr.MarkerBit}."); ua.OnTransactionTraceMessage += (tx, msg) => Log.LogDebug($"uas tx {tx.TransactionId}: {msg}"); ua.ServerCallRingTimeout += (uas) => { Log.LogWarning($"Incoming call timed out in {uas.ClientTransaction.TransactionState} state waiting for client ACK, terminating."); ua.Hangup(); }; var uas = ua.AcceptCall(sipRequest); var rtpSession = CreateRtpSession(ua, sipRequest.URI.User); // Insert a brief delay to allow testing of the "Ringing" progress response. // Without the delay the call gets answered before it can be sent. await Task.Delay(500); await ua.Answer(uas, rtpSession); if (ua.IsCallActive) { await rtpSession.Start(); _calls.TryAdd(ua.Dialogue.CallId, ua); } } else if (sipRequest.Method == SIPMethodsEnum.BYE) { SIPResponse byeResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); await _sipTransport.SendResponseAsync(byeResponse); } else if (sipRequest.Method == SIPMethodsEnum.SUBSCRIBE) { SIPResponse notAllowededResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); await _sipTransport.SendResponseAsync(notAllowededResponse); } else if (sipRequest.Method == SIPMethodsEnum.OPTIONS || sipRequest.Method == SIPMethodsEnum.REGISTER) { SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); await _sipTransport.SendResponseAsync(optionsResponse); } } catch (Exception reqExcp) { Log.LogWarning($"Exception handling {sipRequest.Method}. {reqExcp.Message}"); } }
public SIPRequest GetByeRequest(SIPResponse inviteResponse) { SIPRequest byeRequest = new SIPRequest(SIPMethodsEnum.BYE, inviteResponse.Header.Contact[0].ContactURI); SIPHeader byeHeader = new SIPHeader(inviteResponse.Header.From, inviteResponse.Header.To, inviteResponse.Header.CSeq + 1, inviteResponse.Header.CallId); byeHeader.CSeqMethod = SIPMethodsEnum.BYE; IPEndPoint localSIPEndPoint = m_sipTransport.GetIPEndPointsList()[0]; SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint.Address.ToString(), localSIPEndPoint.Port, CallProperties.CreateBranchId()); byeHeader.Via.PushViaHeader(viaHeader); byeRequest.Header = byeHeader; return byeRequest; }
public void AddRegisterRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest registerRequest) { try { if (registerRequest.Method != SIPMethodsEnum.REGISTER) { SIPResponse notSupportedResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, "Registration requests only"); m_sipTransport.SendResponseAsync(notSupportedResponse).Wait(); } else { int requestedExpiry = GetRequestedExpiry(registerRequest); if (registerRequest.Header.To == null) { Logger.LogDebug("Bad register request, no To header from " + remoteEndPoint + "."); SIPResponse badReqResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing To header"); m_sipTransport.SendResponseAsync(badReqResponse).Wait(); } else if (registerRequest.Header.To.ToURI.User.IsNullOrBlank()) { Logger.LogDebug("Bad register request, no To user from " + remoteEndPoint + "."); SIPResponse badReqResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing username on To header"); m_sipTransport.SendResponseAsync(badReqResponse).Wait(); } else if (registerRequest.Header.Contact == null || registerRequest.Header.Contact.Count == 0) { Logger.LogDebug("Bad register request, no Contact header from " + remoteEndPoint + "."); SIPResponse badReqResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.BadRequest, "Missing Contact header"); m_sipTransport.SendResponseAsync(badReqResponse).Wait(); } else if (requestedExpiry > 0 && requestedExpiry < m_minimumBindingExpiry) { Logger.LogDebug("Bad register request, no expiry of " + requestedExpiry + " to small from " + remoteEndPoint + "."); SIPResponse tooFrequentResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.IntervalTooBrief, null); tooFrequentResponse.Header.MinExpires = m_minimumBindingExpiry; m_sipTransport.SendResponseAsync(tooFrequentResponse).Wait(); } else { if (m_registerQueue.Count < MAX_REGISTER_QUEUE_SIZE) { SIPNonInviteTransaction regTx = new SIPNonInviteTransaction(m_sipTransport, registerRequest, null); m_registerQueue.Enqueue(regTx); } else { Logger.LogError("Register queue exceeded max queue size " + MAX_REGISTER_QUEUE_SIZE + ", overloaded response sent."); SIPResponse overloadedResponse = SIPResponse.GetResponse(registerRequest, SIPResponseStatusCodesEnum.TemporarilyUnavailable, "Registrar overloaded, please try again shortly"); m_sipTransport.SendResponseAsync(overloadedResponse).Wait(); } m_registerARE.Set(); } } } catch (Exception excp) { Logger.LogError("Exception AddRegisterRequest (" + remoteEndPoint.ToString() + "). " + excp.Message); } }
public SIPRequest GetRegisterRequest(string server, string toURIStr, string contactStr) { try { IPEndPoint localSIPEndPoint = m_sipTransport.GetDefaultTransportContact(SIPProtocolsEnum.UDP); SIPRequest registerRequest = new SIPRequest(SIPMethodsEnum.REGISTER, "sip:" + server); SIPHeader registerHeader = new SIPHeader(SIPFromHeader.ParseFromHeader(toURIStr), SIPToHeader.ParseToHeader(toURIStr), 1, CallProperties.CreateNewCallId()); registerHeader.From.FromTag = CallProperties.CreateNewTag(); registerHeader.Contact = SIPContactHeader.ParseContactHeader(contactStr); SIPViaHeader viaHeader = new SIPViaHeader(localSIPEndPoint.Address.ToString(), localSIPEndPoint.Port, CallProperties.CreateBranchId()); registerHeader.Via.PushViaHeader(viaHeader); registerHeader.CSeqMethod = SIPMethodsEnum.REGISTER; registerHeader.Expires = SIPConstants.DEFAULT_REGISTEREXPIRY_SECONDS; registerRequest.Header = registerHeader; return registerRequest; } catch (Exception excp) { logger.Error("Exception GetRegisterRequest. " + excp.Message); throw new ApplicationException("GetRegisterRequest " + excp.GetType().ToString() + ". " + excp.Message); } }
private int GetRequestedExpiry(SIPRequest registerRequest) { int contactHeaderExpiry = (registerRequest.Header.Contact != null && registerRequest.Header.Contact.Count > 0) ? registerRequest.Header.Contact[0].Expires : -1; return((contactHeaderExpiry == -1) ? registerRequest.Header.Expires : contactHeaderExpiry); }
public void SendSIPRequest(SIPRequest sipRequest) { SendSIPRequest(sipRequest, sipRequest.URI.GetURIEndPoint().ToString()); }
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_strictRealmHandling) ? m_sipDomainDataLayer.GetCanonicalDomain(toHeader.ToURI.Host, true) : toHeader.ToURI.Host; int requestedExpiry = GetRequestedExpiry(sipRequest); if (canonicalDomain == null) { Logger.LogWarning("Register request for " + toHeader.ToURI.Host + " 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); 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); 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(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); } }
public void SIPTransportRequestReceived(SIPProtocolsEnum protocol, IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, SIPRequest sipRequest) { if (sipRequest.Method == SIPMethodsEnum.BYE) { // Send an Ok response. SIPResponse okResponse = GetResponse(sipRequest.Header, SIPResponseStatusCodesEnum.Ok); m_sipTransport.SendResponseFrom(localEndPoint, remoteEndPoint, protocol, okResponse); } else if (sipRequest.Method == SIPMethodsEnum.NOTIFY) { // Send an not supported response. //SIPResponse notSupportedResponse = GetResponse(sipRequest.Header, SIPResponseStatusCodesEnum.MethodNotAllowed); //SIPTransport.SendResponseFrom(localEndPoint, remoteEndPoint, notSupportedResponse); // Send an Ok response. SIPResponse okResponse = GetResponse(sipRequest.Header, SIPResponseStatusCodesEnum.Ok); okResponse.Header.Contact = null; m_sipTransport.SendResponseFrom(localEndPoint, remoteEndPoint, protocol, okResponse); } else { m_lastRequest = sipRequest; m_waitForSIPRequest.Set(); } }
private void SendInitialRegister() { try { 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++; SIPEndPoint registrarSIPEndPoint = m_outboundProxy; if (registrarSIPEndPoint == null) { SIPDNSLookupResult lookupResult = m_sipTransport.GetHostEndPoint(m_registrarHost, false); if (lookupResult.LookupError != null) { } else { registrarSIPEndPoint = lookupResult.GetSIPEndPoint(); } } if (registrarSIPEndPoint == null && RegistrationFailed != null) { RegistrationFailed(m_sipAccountAOR, "Could not resolve " + m_registrarHost + "."); } else { SIPRequest regRequest = GetRegistrationRequest(m_localEndPoint); SIPNonInviteTransaction regTransaction = m_sipTransport.CreateNonInviteTransaction(regRequest, registrarSIPEndPoint, m_localEndPoint, m_outboundProxy); // These handlers need to be on their own threads to take the processing off the SIP transport layer. regTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) => { ThreadPool.QueueUserWorkItem(delegate { ServerResponseReceived(lep, rep, tn, rsp); }); }; regTransaction.NonInviteTransactionTimedOut += (tn) => { ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); }); }; m_sipTransport.SendSIPReliable(regTransaction); } } } catch (Exception excp) { logger.Error("Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message); if (RegistrationFailed != null) { RegistrationFailed(m_sipAccountAOR, "Exception SendInitialRegister to " + m_registrarHost + ". " + excp.Message); } } }
private SIPRequest GetInviteRequest(string callURI, SIPFromHeader fromHeader) { SIPRequest inviteRequest = new SIPRequest(SIPMethodsEnum.INVITE, SIPURI.ParseSIPURI(callURI)); inviteRequest.LocalSIPEndPoint = m_blackhole; SIPHeader inviteHeader = new SIPHeader(fromHeader, new SIPToHeader(null, inviteRequest.URI, null), 1, CallProperties.CreateNewCallId()); inviteHeader.From.FromTag = CallProperties.CreateNewTag(); // For incoming calls forwarded via the dial plan the username needs to go into the Contact header. inviteHeader.Contact = new List<SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(inviteRequest.URI.Scheme, m_blackhole)) }; inviteHeader.CSeqMethod = SIPMethodsEnum.INVITE; inviteRequest.Header = inviteHeader; SIPViaHeader viaHeader = new SIPViaHeader(m_blackhole, CallProperties.CreateBranchId()); inviteRequest.Header.Vias.PushViaHeader(viaHeader); return inviteRequest; }
/// <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.Error("Exception SIPRegistrationUserAgent ServerResponseReceived (" + remoteEndPoint + "). " + excp.Message); } }
/// <summary> /// Authenticates a SIP request. /// </summary> public static SIPRequestAuthenticationResult AuthenticateSIPRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest, SIPAccount sipAccount, SIPMonitorLogDelegate logSIPMonitorEvent) { try { if (sipAccount == null) { return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Forbidden, null); } else if (sipAccount.IsDisabled) { if (logSIPMonitorEvent != null) { logSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.DialPlan, "SIP account " + sipAccount.SIPUsername + "@" + sipAccount.SIPDomain + " is disabled for " + sipRequest.Method + ".", sipAccount.Owner)); } return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Forbidden, null); } else { SIPAuthenticationHeader reqAuthHeader = sipRequest.Header.AuthenticationHeader; if (reqAuthHeader == null) { // Check for IP address authentication. if (!sipAccount.IPAddressACL.IsNullOrBlank()) { SIPEndPoint uaEndPoint = (!sipRequest.Header.ProxyReceivedFrom.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedFrom) : remoteEndPoint; if (Regex.Match(uaEndPoint.GetIPEndPoint().ToString(), sipAccount.IPAddressACL).Success) { // Successfully authenticated return new SIPRequestAuthenticationResult(true, true); } } SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, sipAccount.SIPDomain, GetNonce()); return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Unauthorised, authHeader); } else { // Check for IP address authentication. if (!sipAccount.IPAddressACL.IsNullOrBlank()) { SIPEndPoint uaEndPoint = (!sipRequest.Header.ProxyReceivedFrom.IsNullOrBlank()) ? SIPEndPoint.ParseSIPEndPoint(sipRequest.Header.ProxyReceivedFrom) : remoteEndPoint; if (Regex.Match(uaEndPoint.GetIPEndPoint().ToString(), sipAccount.IPAddressACL).Success) { // Successfully authenticated return new SIPRequestAuthenticationResult(true, true); } } string requestNonce = reqAuthHeader.SIPDigest.Nonce; string uri = reqAuthHeader.SIPDigest.URI; string response = reqAuthHeader.SIPDigest.Response; // Check for stale nonces. if (IsNonceStale(requestNonce)) { if (logSIPMonitorEvent != null) { logSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.Warn, "Authentication failed stale nonce for realm=" + sipAccount.SIPDomain + ", username="******", uri=" + uri + ", nonce=" + requestNonce + ", method=" + sipRequest.Method + ".", null)); } SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, sipAccount.SIPDomain, GetNonce()); return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Unauthorised, authHeader); } else { SIPAuthorisationDigest checkAuthReq = reqAuthHeader.SIPDigest; checkAuthReq.SetCredentials(sipAccount.SIPUsername, sipAccount.SIPPassword, uri, sipRequest.Method.ToString()); string digest = checkAuthReq.Digest; if (digest == response) { // Successfully authenticated return new SIPRequestAuthenticationResult(true, false); } else { if (logSIPMonitorEvent != null) { logSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.Warn, "Authentication token check failed for realm=" + sipAccount.SIPDomain + ", username="******", uri=" + uri + ", nonce=" + requestNonce + ", method=" + sipRequest.Method + ".", sipAccount.Owner)); } SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, sipAccount.SIPDomain, GetNonce()); return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.Unauthorised, authHeader); } } } } } catch (Exception excp) { if (logSIPMonitorEvent != null) { logSIPMonitorEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Authoriser, SIPMonitorEventTypesEnum.Error, "Exception AuthoriseSIPRequest. " + excp.Message, null)); } return new SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum.InternalServerError, null); } }
private void Transport_SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { var endpoint = new SIPEndPoint(SIPProtocolsEnum.udp, publicIPAddress, localSIPEndPoint.Port); if (sipRequest.Method == SIPMethodsEnum.INVITE) { if (transaction != null) { return; } logger.DebugFormat("{0} Incoming call from {1}", prefix, sipRequest.Header.From.FromURI.User); transaction = transport.CreateUASTransaction(sipRequest, remoteEndPoint, endpoint, null); agent = new SIPServerUserAgent( transport, null, sipRequest.Header.From.FromURI.User, null, SIPCallDirection.In, null, null, null, transaction); agent.CallCancelled += Agent_CallCancelled; agent.TransactionComplete += Agent_TransactionComplete; agent.Progress(SIPResponseStatusCodesEnum.Trying, null, null, null, null); agent.Progress(SIPResponseStatusCodesEnum.Ringing, null, null, null, null); var answer = SDP.ParseSDPDescription(agent.CallRequest.Body); var address = IPAddress.Parse(answer.Connection.ConnectionAddress); var port = answer.Media.FirstOrDefault(m => m.Media == SDPMediaTypesEnum.audio).Port; var random = Crypto.GetRandomInt(5).ToString(); var sdp = new SDP { Version = 2, Username = "******", SessionId = random, Address = localIPEndPoint.Address.ToString(), SessionName = "redfox_" + random, Timing = "0 0", Connection = new SDPConnectionInformation(publicIPAddress.ToString()) }; rtpChannel = new RTPChannel { DontTimeout = true, RemoteEndPoint = new IPEndPoint(address, port) }; rtpChannel.SetFrameType(FrameTypesEnum.Audio); // TODO Fix hardcoded ports rtpChannel.ReservePorts(15000, 15090); rtpChannel.OnFrameReady += Channel_OnFrameReady; rtpChannel.Start(); // Send some setup parameters to punch a hole in the firewall/router rtpChannel.SendRTPRaw(new byte[] { 80, 95, 198, 88, 55, 96, 225, 141, 215, 205, 185, 242, 00 }); rtpChannel.OnControlDataReceived += (b) => { logger.Debug($"{prefix} Control Data Received; {b.Length} bytes"); }; rtpChannel.OnControlSocketDisconnected += () => { logger.Debug($"{prefix} Control Socket Disconnected"); }; var announcement = new SDPMediaAnnouncement { Media = SDPMediaTypesEnum.audio, MediaFormats = new List <SDPMediaFormat>() { new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU, "PCMU", 8000) }, Port = rtpChannel.RTPPort }; sdp.Media.Add(announcement); SetState(State.Listening, sipRequest.Header.From.FromURI.User); agent.Progress(SIPResponseStatusCodesEnum.Accepted, null, null, null, null); agent.Answer(SDP.SDP_MIME_CONTENTTYPE, sdp.ToString(), null, SIPDialogueTransferModesEnum.NotAllowed); SetState(State.Busy, ""); return; } if (sipRequest.Method == SIPMethodsEnum.BYE) { if (State != State.Busy) { return; } logger.DebugFormat("{0} Hangup from {1}", prefix, sipRequest.Header.From.FromURI.User); var noninvite = transport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, endpoint, null); var response = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); noninvite.SendFinalResponse(response); SetState(State.Finished, Endpoint); rtpChannel.OnFrameReady -= Channel_OnFrameReady; rtpChannel.Close(); agent.TransactionComplete -= Agent_TransactionComplete; agent.CallCancelled -= Agent_CallCancelled; agent = null; transaction = null; SetState(State.Ready, Endpoint); return; } if (sipRequest.Method == SIPMethodsEnum.ACK) { } if (sipRequest.Method == SIPMethodsEnum.CANCEL) { } }