How To Proxy SIP Registrations

280px-sip-registration-flow1SIP registration is the process through which SIP user devices (desk phones, soft phones, etc.) periodically announce or refresh their network location to a SIP registrar, for an upcoming period of time. Once registered with the VoIP platform, the device is able to receive calls or messages from other devices.

Proxying SIP registrations

In some cases, we may want to add functionality to an existing VoIP service while being restricted in modifying its software components. For example, we may be given the task of adding instant messaging (IM) capabilities to a SIP PBX platform which does not have any support for this feature.

So how do we go about implementing this? Well, we need to add a new SIP component, in front of the existing PBX, to deal with the IM related traffic. This new component will act as a SIP proxy for the original voice (non-IM) traffic that is handled by the PBX (to preserve the current platform services).

Now, both IM and voice require knowledge of “which users are online and which are offline”. We can solve this by adding registration handling on the new component as well (to be used for routing of the IM traffic).

In other words, we need an in-between SIP registrar clone (sitting between the user and main registrar), capable of both adding IM capabilities to the platform (i.e. being able to process SIP MESSAGE requests), and proxying all other requests to the existing registrar.  Once this registrar clone/proxy is in place, we could easily change the DNS records of our VoIP platform to point to it, instead of the main registrar.

Doing it the right way

SIP is complex, and, in many cases, making it work does not necessarily mean it also works in the right way! Here is a correct way of dealing with SIP registration proxying (explanations below):

call_flow

- receive REGISTER with contact S
- proxy REGISTER to main registrar
- receive reply
- if 2xx reply code, update local registrar with contact S from the reply

Although we have cloned the platform’s registrar, the two resulting registrars will handle registration traffic quite differently. The cloned registrar has much less authority than the main registrar, so it must respect its decisions on accepting/rejecting the contact or on the lifetime of the contact. You can think of it as a master-slave setup.

Processing contacts upon receiving the registration reply, rather than request, may not seem like a big deal, but it actually makes the two registrars a lot more consistent with each other, by avoiding stale registrations (registrations which only exist on one registrar).

Here are some possible ways which may lead to stale registrations if we were to process the contacts of the REGISTER request immediately, without waiting for a reply:

  • the main registrar may reject registrations – due to various reasons. Examples include: contact limit exceeded, expiration too low, auth failed, blacklists, etc.
  • the main registrar may change expiration values – by saving the contacts too early, we will miss any change in the contact expiration interval done by the main registrar

OpenSIPS script example

As is often the case with OpenSIPS script, a lot of SIP protocol quirks, headaches and corner-cases that take days to grasp, end up being solved with a single function call. Our scenario is no exception to the above, as the registrar module’s save() function behaves accordingly when called from an “onreply” route.

In the proxy registrar OpenSIPS script, we first make sure to relay all REGISTER requests to the main instead of processing them. We then update the user location with matching contacts from the replies.

/*
 * proxy registrar - REGISTER handling
 */ 
route [handle_reg] {
    if (is_method("REGISTER")) {
        t_on_reply("handle_reply_reg");
        t_relay();
    }
}

/*
 * proxy registrar - REGISTER reply handling
 */
onreply_route [handle_reply_reg] {
    if (t_check_status("2[0-9][0-9]")) {
        save("location");
    }
}

/*
 * proxy registrar - MESSAGE handling
 */
route [handle_message] {
    /* if the user is online, deliver the message! */
    if (lookup("location")) {
        t_relay();
    } else {
        send_reply("404", "Not Found");
    }
}

And we are done! The next step would be to finish implementing SIP MESSAGE handling in our cloned registrar, but that is out of the scope of this discussion.

More to come!

Adding platform functionalities by inserting OpenSIPS as a front-end with proxy registration opens the door to a series of mid-registration scenarios, which are now available in the mid_registrar module of OpenSIPS 2.3 (development branch).

In the next articles, we will go through these scenarios in detail, showing how adding an OpenSIPS mid_registrar to your platform may* enable it to handle a lot more registration traffic with no additional hardware investments.

* unless it’s already running on OpenSIPS!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s