Login | Register

Documentation

Documentation -> Tutorials -> Scaling registrations with an OpenSIPS mid-registrar

This page has been visited 2562 times.

Scaling registrations with an OpenSIPS mid-registrar

written by Liviu Chircu


1.  Tutorial Overview

This tutorial will teach you how to configure an OpenSIPS mid-registrar in front of an existing SIP PBX or registrar. We will configure this new component to take over most of the SIP registrations and all call forking for the existing server. This will allow you to leverage existing infrastructure in order to continue to grow (as subscribers and as registration traffic) while keeping the current low-resources registrar server.

2.  How does the mid-registrar work?

The OpenSIPS mid-registrar is capable of throttling the amount of SIP registrations flowing through it, on the way to the main registrar. This is possible by configuring it to extend the SIP Contact expirations on the way out, and then accurately keeping track of both initial and extended values.


The module may also handle SIP call forking. Both serial/parallel forking can be achieved with the mid-registrar, potentially freeing up even more resources for the existing servers. This, in turn, will allow you to expand your user base with no additional software costs, minimal configuration of the current components and close to no additional hardware.

3.  Scenario


This is our initial example VoIP platform. Its services are provided by a layer of multi-purpose servers (represented as the main registrar box). To name a few services of this current platform: conferencing, call pickup and internet messaging (IM). Currently, the platform servers seem to reach peak usage when handling around 50,000 mobile device subscribers.


Our task is to find a solution to scale the platform to 500,000 subscribers. We first do an assessment of the types of VoIP traffic being handled by the platform, only to reach an interesting conclusion: 80%+ of the traffic that is hitting our servers is made up of REGISTER requests! Is this correct? Well, it might be, as mobile devices have short registration lifetimes (60 seconds). With this conclusion, we have spotted a potential bottleneck: registration traffic handling!


After several phases of testing, we later find out that registration processing is rather expensive on the current system, which immediately turns it into a bottleneck. A cheap solution to this problem is to integrate an OpenSIPS mid-registrar into our platform, since it is capable of converting incoming high-rate registration traffic (mobile users to mid-registrar) into a low-rate variant (mid-registrar to main registrar). Its main jobs will include soaking up most of this registration traffic, as well as handling parallel forking.


By adding this inexpensive mid-registrar traffic conversion front-end for our servers, we will reduce their incoming rate of registrations. This, in turn, will free up a lot of platform resources, allowing it to redirect its resources to handling more subscribers. The resulting architecture will resemble the following:


4.  OpenSIPS script

In the following, we will extend the default OpenSIPS script with mid-registrar capabilities in two steps. By doing this, we will actually go through two working modes of the module: contact throttling and AOR throttling.

4.1  Throttling registrations

First, we will configure the mid-registrar to greatly increase the outgoing Contact expiration values. After doing so, it will internally keep track of the initial expirations as well as the extended ones, in order to decide if a REGISTER should be forwarded to the main registrar or not.

Module configuration
loadmodule "mid_registrar.so"
modparam("mid_registrar", "mode", 1) /* 0 = mirror / 1 = ct / 2 = AoR */
modparam("mid_registrar", "outgoing_expires", 7200)
modparam("mid_registrar", "insertion_mode", 0) /* 0 = contact; 1 = path */


We first load the mid_registrar module and set its parameters. Going through each parameter:

  • "mode" - the working mode of the module. In this case, "1" means "Contact throttling", where the module will reduce the amount of registration traffic sent to the main registrar
  • "outgoing_expires" - the default value for the expirations of the contacts that the mid-registrar relays to the main registrar. The mid_registrar_save() function also has a similar optional parameter, for more fine grained control.
  • "insertion_mode" - specifies how the mid-registrar will insert itself on the call flow. Insertion mode "0" leads to rewrite of the Contact header field "host" part, while in insertion mode "1", the mid-registrar will append a Path header field to all REGISTER requests. In both cases, the header field values will contain the network interface used to relay the request.
REGISTER handling
    if (is_method("REGISTER")) {
        mid_registrar_save("location");
        switch ($retcode) {
        case 1:
            xlog("forwarding REGISTER to main registrar ($$ci=$ci)\n");
            $ru = "sip:10.0.0.3:5070";
            t_relay();
            break;
        case 2:
            xlog("absorbing REGISTER! ($$ci=$ci)\n");
            break;
        default:
            xlog("failed to save registration! ($$ci=$ci)\n");
        }

        exit;
    }


For all registrations, we make sure to call mid_registrar_save(). As stated in its documentation, it will not process the contacts immediately, but rather do the necessary changes to the REGISTER request before it is relayed to the main registrar, while also preparing to transparently handle its replies. The above code stays the same regardless of the module's working mode or insertion mode. We are now done with REGISTER request handling!

INVITE handling

Next, we proceed with contact lookup during calls or instant messages:


    # initial requests from main registrar, need to look them up!
    if (is_method("INVITE|MESSAGE") && $si == "10.0.0.3" && $sp == 5070) {
        xlog("looking up $ru!\n");
        if (!mid_registrar_lookup("location")) {
            t_reply("404", "Not Found");
            exit;
        }

        t_relay();

        exit;
    }


Contact lookup is almost identical to the stock OpenSIPS script. The only big difference is that we are using mid_registrar_lookup() instead of lookup(). Note that mid_registrar_lookup() will behave according to the insertion and working modes. In our case, it will only populate the Request-URI variable (see $ru) since the module is in working "mode = 1".

Call flow (throttling registrations by Contact)

The diagram below shows two devices of the same user (A and B) periodically registering to the platform. In "Contact throttling" mode, the main registrar will be notified about the presence of each SIP contact on the mid-registrar. When receiving a call, the mid-registrar will simply relay it to the user.



Notice how each of Alice's devices first registers with both registrars, after which subsequent registrations are absorbed at mid-registrar level.

4.2  Parallel forking support

The mid-registrar can additionally take over all call forking responsibilities. In order to enable this, we only need to switch it to "mode = 2" (AOR throttling).

Module configuration
loadmodule "mid_registrar.so"
modparam("mid_registrar", "mode", 2) /* 0 = mirror / 1 = ct / 2 = AoR */
modparam("mid_registrar", "outgoing_expires", 7200)
modparam("mid_registrar", "insertion_mode", 0) /* 0 = contact; 1 = path */


Additional explanations:

  • "mode" - the working mode of the module. In this case, "2" means "AOR throttling", where the module will both reduce the amount of registration traffic sent to the main registrar and also aggregate contacts into a single one when forwarding registrations to it. The latter will allow it to do parallel forking.


Although the rest of the script stays the same, the mid_registrar_save() and mid_registrar_lookup() functions will behave differently. For example, when saving contacts, all Contact header fields of REGISTER requests will be aggregated into a single one. When looking up contacts, the entire branch set will be populated (see $branch), thus preparing to fork calls in parallel.

Call flow (throttling registrations by AOR)


In AOR throttling mode, the mid-registrar is aggregating both Alice's contacts (A and B) into a single contact (alice@mid-registrar) when forwarding registrations to the main registrar.

Call flow (parallel forking)


This call flow shows how the mid-registrar's "AOR throttling" mode allows it to take over all call forking responsibilities, freeing up even more resources for the main registrar.

5.  SIP Authentication

User authentication is a mandatory requirement for any real-world VoIP service, so we assume it is enabled for our platform as well. However, doing so will require additional configuration in order for the mid-registrar to properly work. We will have to whitelist the mid-registrar's IP address on the main registrar, thus skipping SIP authentication for all requests it may generate.


The explanation for this is that in working modes "1" and "2", the mid-registrar may generate De-REGISTER requests in order to avoid stale registrations on the main registrar. The problem is that by default, it will not be able to authenticate itself to the main registrar since it is not provisioned with any credentials, so the mid-registrar IP address should simply be whitelisted on the main registrar in order for these de-registrations to properly go through.

6.  Downloads

The full script used in this tutorial is available here.


Page last modified on December 20, 2016, at 12:33 PM