sipsorcery's blog

Occassional posts about VoIP, SIP, WebRTC and Bitcoin. response times SIP Sorcery Last 3 Hours
daily weekly status

Redirect Processing

Recently I had a request from a user on how to get redirect processing working with their SIPSorcery dial plan. Redirects are when the destination of a call responds with a specific type of response, appropriately called a redirect response, that indicates that the called destination is unavailable and that the caller should instead try and call an alternative destination. The alternative destination is specified in one of the SIP headers on the redirect response. The most common scenario for redirects is the do not disturb (DND) or call forward buttons on IP phones. IP phones typically allow a user to press the DND button, enter a call forwarding destination and then have the phone redirect all that calls to that destination.

Redirect responses are potentially very dangerous if appropriate precautions are not taken. The reason being that the alternative destination specified in the response could be anything including a premium rate number in some far away country. For that reason redirects are disabled by default within SIPSorcery dial plans and it is only if they are explicitly enabled using a dial string option that they will be acted on.

After a redirect response is accepted the next question is how to process it? A well as blocking undesirable numbers the alternative destination could be a safe PSTN number and the caller will want to make a decision about which of their providers to use for the call. This presented a bit of a quandary for a while as a dial plan would potentially need to contain the same call processing logic in multiple locations, once in the main dial plan and then everywhere a redirect response was being accepted. The solution to that problem was to allow a new second instance of a dial plan to be executed for a redirect response. However while that approach provided for the most flexibility it was also a bit complicated so a simpler approach that did allow the redirect response to be processed within the same dial plan instance was also implemented. The two different approaches are outlined below.

Approach 1 – Inline redirect processing

This is the simplest of the two approaches and allows redirect responses to be processed inline within the currently executing dial plan. It also does not require a redirect option to be set in a dial string since specific dial plan logic is required to employ it. An example of this approach is shown below.

if sys.Dial("myaccount@sipsorcery").to_s == "Redirect" then
  sys.Log("Redirect was requested to #{sys.RedirectURI.ToString()}.")

In the example the key point is that the sys.Dial method will return a result of “Redirect” if one of the call legs within it receives a redirect response. At the same time the alternative destination will be set in sys.RedirectURI (which is a SIP URI object the same as req.URI).

Approach 2 – New dial plan instance redirect processing

The second approach causes a new instance of the current dial plan to be executed for the redirect destination. Some additional variables are set in the new dial plan execution which are sys.Redirect, sys.RedirectURI and sys.RedirectResponse. The sys.Redirect property is a boolean that gets set to true for a dial plan instance initiated by a redirect, sys.RedirectURI property holds the alternative destination set in the redirect response and sys.RedirectResponse holds the full response.

if sys.Out
  sys.Log("Out call")
elsif sys.Redirect
  sys.Log("Redirect call")
  case sys.RedirectURI.User
    when / ^ 300$ / then sys.Dial("#{sys.RedirectURI.User}@someprovider")
    else sys.Log("Sorry, redirect destination not permitted")
  sys.Log("In call")

In the example above the dial plan has separate logic for In, Out and Redirect calls. The rm=n dial string option translates as redirect mode should be processed with a new dial plan.