/// <summary> /// Raises an error (Service unavailable etc) /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="error">The error.</param> public override void Error(Transaction transaction, string error) { if (transaction == null) { Transaction = null; if (!Request.Method.ToUpper().Contains("ACK")) { Message response = Message.CreateResponse(503, "Service unavailable - " + error, null, null, Request); SendResponse(response); return; } Debug.Assert(false, "Warning, dropping ACK"); } ProxyBranch branch = GetBranch(transaction); if (branch == null) { return; } Transaction = null; branch.Transaction = null; if (branch.RemoteCandidates != null && branch.RemoteCandidates.Count > 0) { RetryNextCandidate(branch); } else { ReceivedResponse(null, Message.CreateResponse(503, "Service unavailable - " + error, null, null, branch.Request)); } }
/// <summary> /// Receives the SIP response /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="response">The response.</param> public override void ReceivedResponse(Transaction transaction, Message response) { ProxyBranch branch = GetBranch(transaction); if (branch == null) { Debug.Assert(false, "Invalid transaction received " + transaction); return; } if (response.Is1XX() && branch.CancelRequest != null) { Transaction cancel = Transaction.CreateClient(Stack, this, branch.CancelRequest, transaction.Transport, transaction.Remote); branch.CancelRequest = null; } else { if (response.IsFinal()) { branch.Response = response; Stack.ReceivedResponse(this, response); //SendResponseIfPossible(); } else { response.Headers["Via"].RemoveAt(0); if (response.Headers["Via"].Count <= 0) { response.Headers.Remove("Via"); } SendResponse(response); Stack.ReceivedResponse(this, response); } } }
/// <summary> /// Retries the next candidate to send to. /// </summary> /// <param name="branch">The branch.</param> private void RetryNextCandidate(ProxyBranch branch) { if ((RemoteCandidates == null) || (RemoteCandidates.Count == 0)) { Debug.Assert(false, String.Format("No more DNS resolved address to try")); } SIPURI target = RemoteCandidates.First(); RemoteCandidates.RemoveAt(0); branch.Request.First("Via").Attributes["branch"] += "A"; branch.Transaction = Transaction.CreateClient(Stack, this, branch.Request, Stack.Transport, target.Host + ":" + target.Port); }
/// <summary> /// Handles request timeouts /// </summary> /// <param name="transaction">The transaction.</param> private void TimeOut(Transaction transaction) { ProxyBranch branch = GetBranch(transaction); if (branch == null) { return; } branch.Transaction = null; if (branch.RemoteCandidates != null && branch.RemoteCandidates.Count > 0) { RetryNextCandidate(branch); } else { ReceivedResponse(null, Message.CreateResponse(408, "Request timeout", null, null, branch.Request)); } }
/// <summary> /// Retries the next candidate to send to. /// </summary> /// <param name="branch">The branch.</param> private void RetryNextCandidate(ProxyBranch branch) { if ((RemoteCandidates == null) || (RemoteCandidates.Count == 0)) { Debug.Assert(false, String.Format("No more DNS resolved address to try")); } SIPURI target = RemoteCandidates.First(); RemoteCandidates.RemoveAt(0); branch.Request.First("Via").Attributes["branch"] += "A"; branch.Transaction = Transaction.CreateClient(Stack, this, branch.Request, Stack.Transport, target.Host + ":" + target.Port); }
/// <summary> /// Sends the SIP request. /// </summary> /// <param name="request">The request.</param> public override void SendRequest(Message request) { SIPURI target = null; if (request.First("Route") == null) { target = request.Uri; } else { var routes = request.Headers["Route"]; if (routes.Count > 0) { try { target = ((Address)routes[0].Value).Uri; string test = target.Parameters["lr"]; } catch (Exception) { routes.RemoveAt(0); if (routes.Count > 0) { routes.Add(new Header(request.Uri.ToString(), "Route")); } request.Headers["Route"] = routes; request.Uri = target; } } } Stack.Sending(this, request); ProxyBranch branch = new ProxyBranch(); SIPURI dest = target.Dup(); if (target.Port <= 0) { dest.Port = 5060; } else { dest.Port = target.Port; } if (!Helpers.IsIPv4(dest.Host)) { try { IPAddress[] addresses = Dns.GetHostAddresses(dest.Host); dest.Host = addresses[0].ToString(); } catch (Exception) { } } if (Helpers.IsIPv4(dest.Host)) { branch.RemoteCandidates = new List<SIPURI> { dest }; } if (branch.RemoteCandidates == null || branch.RemoteCandidates.Count == 0) { Error(null, "Cannot resolve DNS target"); return; } target = branch.RemoteCandidates.First(); branch.RemoteCandidates.RemoveAt(0); if (!request.Method.ToUpper().Contains("ACK")) { branch.Transaction = Transaction.CreateClient(Stack, this, request, Stack.Transport, target.HostPort()); branch.Request = request; _branches.Add(branch); } else { Stack.Send(request, target.HostPort()); } }
/// <summary> /// Sends the SIP request. /// </summary> /// <param name="request">The request.</param> public override void SendRequest(Message request) { SIPURI target = null; if (request.First("Route") == null) { target = request.Uri; } else { var routes = request.Headers["Route"]; if (routes.Count > 0) { try { target = ((Address)routes[0].Value).Uri; string test = target.Parameters["lr"]; } catch (Exception) { routes.RemoveAt(0); if (routes.Count > 0) { routes.Add(new Header(request.Uri.ToString(), "Route")); } request.Headers["Route"] = routes; request.Uri = target; } } } Stack.Sending(this, request); ProxyBranch branch = new ProxyBranch(); SIPURI dest = target.Dup(); if (target.Port <= 0) { dest.Port = 5060; } else { dest.Port = target.Port; } if (!Helpers.IsIPv4(dest.Host)) { try { IPAddress[] addresses = Dns.GetHostAddresses(dest.Host); dest.Host = addresses[0].ToString(); } catch (Exception) { } } if (Helpers.IsIPv4(dest.Host)) { branch.RemoteCandidates = new List <SIPURI> { dest }; } if (branch.RemoteCandidates == null || branch.RemoteCandidates.Count == 0) { Error(null, "Cannot resolve DNS target"); return; } target = branch.RemoteCandidates.First(); branch.RemoteCandidates.RemoveAt(0); if (!request.Method.ToUpper().Contains("ACK")) { branch.Transaction = Transaction.CreateClient(Stack, this, request, Stack.Transport, target.HostPort()); branch.Request = request; _branches.Add(branch); } else { Stack.Send(request, target.HostPort()); } }