5.13. Advanced Use Cases with Provisioned Data

The ABC SBC can be integrated with external or internal sources of data and logic. This allows to complement its rigid rules-based logic with richer and more complex applications provisioned by the administrator.

The following methods are available:

  • Generic RESTful queries to an external server using the Read call variables over REST action. Using this interface allows to drive the ABC SBC behaviour using in-house developed business logic located in external web programming environments. see Section RESTful Interface for more details.
  • Provisioned tables. Solving some problems with tabular nature, like Least-Cost-Routing, Blacklisting, Dial Plan Normalization or SIP Connect Bulk Registration is much easier if tables are provisioned separately from the rules. For this reason the ABC SBC supports on-board provider-provisioned databases. See Section Provisioned Tables for more details.
  • ENUM queries using the Enum query action , as described in the section Enum Queries. This method allows for a number-to-URI translation using the DNS-based ENUM queries.

5.13.1. RESTful Interface

The RESTful interface embedded in the ABC SBC allows high programmability of the SIP Sesion Border Controller.

The interface addresses an important dilemma for operators: how to introduce new scenarios, while preserving the existing ones intact. Hardwired product logic compels the operators to request code changes from vendors. Change requests result in unavoidably tedious process, weeks or months of negotiation, changes of changes and delays regardless how small and reasonable the changes are. Therefore ABC SBC comes with the possibility to implement business logic outside the product in an operator-controlled environment.

This capability follows a general trend in which the business logic is concentrated in a single place that defines behavior of relatively “dumb” network elements. The business logic defines security policies (who can call whom), marketing campaigns (at what price), and network behavior (how to route the calls). Placing this logic in a web server relieves operators from inadequate vendor dependencies and allows PHP, Perl, and virtually any web programmer to implement new SIP scenarios in a well understood programming environment.

The operation of a RESTful application is simple and consists of three steps characteristic for any computer program. The steps are depicted in Figure RESTFul Call Flow: The ABC SBC receives an incoming INVITE on input in the first step A, processes it in step B, and generates a correctly processed INVITE on the output in step C. The processing in step B is split in three phases: - B.1: RestFul query is formulated that contains all pieces of SIP information needed to execute the web-based logic. The information is passed in form of URI parameters to the RESTful server. - B.2: The RESTful server performs the application logic. - B.3: Eventually the RESTful server sends an answer back to the ABC SBC. The answer contains an array of variables that represent an advice to the ABC SBC how to handle the message in the final step C.


Figure 1: RESTFul Call Flow RESTful Interface using Digest Authentication Example

In this example we show how to outsource digest authentication to the external RESTful server. This relieves the ABC SBC of implementing a user:password database. It is even designed in a way that leaves the ABC SBC unaware of the cryptographic authentication protocol: all it does is it shuffles header-fields back and forth.

Background: digest authentication in SIP works by conveying shared password from client to server in a hashed form. If both client and server hash the password and obtain the same result, identity of client is proven without sending the password in clear-text.

The whole process follows the steps outlined above. It begins when a SIP request comes in. (only fragment shown):

INVITE sip:music@abcsbc.com SIP/2.0.
 Via: SIP/2.0/tcp
 From: "foo" <sip:foo@abcsbc.com>;tag=0omQsGfHsCtP8-5k2.t4uJI3ekc66bGZ.
 To: <sip:music@abcsbc.com>.
 CSeq: 14693 INVITE.
 Proxy-Authorization: Digest username="foo", realm="abcsbc.com",
   nonce="UP6CiVD+gk0Uyu4WHAv+48ypPC2vjH+6", uri="sip:music@abcsbc.com",

The INVITE request signals a call from user with address sip:foo@abcsbc.com to address sip:music@abcsbc.com The ABC SBC checks the request against its rules and initates the RESTful logic. (see Figure Rule for Evoking a RESTful query).


Figure 2: Rule for Evoking a RESTful query

The rule in ABC SBC’s configuration matches by From domain, method and request URI, and therefore processing is passed to the action “Read Call variables over REST”. ABC SBC is configured to pass several headerfields as URI parameters to the RESTful application. Particularly, the user information relevant to authentication are passed: Authorization and Proxy-authorization header fields ($H(Proxy-authorization)), request method ($m) and realm. The domain in From URI ($fh) is used as realm – this way you can build up a multidomain hosted service, which will work same for any domain without change.

Now the SBC has received a call, chosen to process it using a web server, the REST can begin by sending an HTTP query. Let’s see how the query looks on wire. It simply conveys the values chosen in SBC configuration as URI parameters. Symbols contained in the values are substituted using the escape code %:

GET /2auth.php?method=INVITE&www_auth=&proxy_auth=Digest+username%3d%22foo%22%2c+realm%3d%22abcsbc.com%22%2c+nonce%3d%22685f3174-6aaf-4337-a9f4-4cf4d1f150ab%22%2c+uri%3d%22sip%3amusic%40abcsbc.com%22%2c+response%3d%225b3cc376e815c949bbc084c747a3a55f%22&realm=abcsbc.com HTTP/1.1.
User-Agent: REST-in-peace/0.1.
Host: www.abcsbc.com

When the web server receives this query, it starts an application. In our example we have chosen to build it using PHP, it could be done same well using Perl, Java, python or any other popular web programming language. In its own way the interpreter passed the URI parameters to application’s variable and processing begins.

The following PHP code shows key steps during computation. Not all are shown. For a given user, it calculates her hashed password stored in database and checks it against one coming in the request. If they are equal, it answers with a 200 answer suggestion, otherwise it advises the SIP server to reauthenticate the user:

// simulation of a database query … ask username and password
$users = array('foo' => '12', 'guest' => 'guest');
// prepare challenge for the case credentials are invalid
// or missing
$challenge='Digest realm="'.$realm.'",nonce="'.new_nonce().'"'

// no credentials supplied? Request some!
if (empty($proxy_auth)) {
  print_answer("407", "Authenticate",
         "Proxy-Authenticate: ".$challenge,$cmt);
// parse the credentials
// calculate expected answer
if ($data['response'] != $expected_response) {
  print_answer(“407”, “authenticate”, “Proxy-authenticate”,
// otherwise proceed with OK
print_answer(“200”, “ok”);

Now we have an answer: either a positive 200, or a negative 407 with authentication challenge to be passed to the SIP client through the ABC SBC. If you observe the wire you will see the following HTTP answer:

HTTP/1.1 200 OK.
Date: Tue, 22 Jan 2013 11:58:47 GMT.
Server: Apache/2.2.3 (Debian) PHP/4.4.4-8+etch6 mod_ssl/2.2.3 OpenSSL/0.9.8c.
X-Powered-By: PHP/4.4.4-8+etch6.
Content-Length: 214.
Content-Type: text/html.
headers=Proxy-Authenticate: Digest realm="abcsbc.com",

What you see here in clear-text is, that the programmer has stored the processing results into several variables that are passed back to the ABC SBC rule-base.

We are in the final stage now – the web application has returned processing results back to ABC SBC, the SBC will evaluate the parameters in its rules and use them in further SIP processing. Particularly, the rule in Figure Rule for processing result of RESTful query says, if processing ended up with variable code not being equal to 200, the call will be refused. The negative answer will include parameters determined in the HTTP answer.


Figure 3: Rule for processing result of RESTful query

Here is the final outcome of our effort: SIP answer calculated in the RESTful server and challenging SIP client to submit proper credentials:

SIP/2.0 407 Authenticate.
Via: SIP/2.0/tcp;received=
From: <sip:foo@abcsbc.com>;tag=0omQsGfHsCtP8-5k2.t4uJI3ekc66bGZ.
To: <sip:music@abcsbc.com>;tag=50123210ee9d5f0f8df05cf1f196cfeb-c5a6.
CSeq: 14692 INVITE.
Proxy-Authenticate: Digest realm="abcsbc.com", nonce="UP6CiVD+gk0Uyu4WHAv+48ypPC2vjH+6"

5.13.2. Provisioned Tables

The ABC SBC rules can refer to an internal database maintained separately from the rules logic. This greatly simplifies use-cases which would have to be implemented using a large numbers of almost identical rules otherwise. The typical use-cases include tests if a URI is on a blacklist or list of monitored users, static SIP registrations, Least Cost Routing tables, definition of dialing plan normalization and more.

The tables are physically located on the ABC SBC machine for highest performance, can be provisioned using the web interface and can include any number of administrator-chosen attributes in addition to the lookup key. There is also a possibility to provision the data remotely via RPC.

There are two types of tables:

  • data - general purpose data tables can be queried to fetch specific data associated with a key. The structure of such tables can be freely defined by the administrator, thus allowing great flexibility. The data tables are used from A-rules and C-rules.
  • routing - specialized routing tables have a list of mandatory attributes that define routing behaviour and are always present. Additional attributes may be added. The routing tables can only be used from B-rules.

Using the tables is as simple as creating a table with the desired structure, filling it with data, looking up a result in the table from A,B or C-rules by a selected value, and processing the found data entry. The data entry is returned to the script processing as variables bearing the names of the table columns. The whole process is described in the following subsections in detail. Configuring Tables

The process of setting up a new provisioned table consists of the following steps:

  • Analysis of the problem to be solved. You need to specify what data you are going to lookup in a table by what key and how you are going to use the resulting table record.
  • Definition of the table structure. This is started from the Web menu under Provisioned Tables ‣ configure ‣ Insert new. There you must identify:
    • key lookup operator which is one of equal, range, and prefix. The operator defines the method by which a key is looked up in a table. It is not possible to lookup in the same table using some other method. If range is chosen, the resulting table will include two key columns for begin and end of a range. If prefix is used and overlapping choices are found, the longest match is selected.
    • a table key type, which is one of uri, number, call-agent, string. The type is used for syntactical checking when the actual data is entered later. Even more importantly it is used to determine how the lookup operator is used. Particularly, prefix lookup is sensible for string types as it discriminates between “0” and “00”. For nummerical types, these two values would be the same.
    • and type of table data or route, as explained above.
    • There is also Group-by, which can be none or string. The option string allows to add an informational tag to each entry so that tables can be viewed by groups.
    • Optionally, any number of additional table named columns can be added, whose type must be chosen from uri, number, call-agent, string. When the “save” button is pressed, the table structure is created and becomes instantly ready for filling with data.
  • Filling tables with data. This is started from the Web menu under Provisioned Tables ‣ (table name). On the webpage that opens, the link Insert new rules opens a dialog for inserting a new data entry. When editing the new entry is complete, pressing the “Save” button will store it. A Version 4 UUID (RFC 4122) is automatically added to every entry for sake of internal data maintenance.
  • Completing data entry. To make the ABC SBC understand that the newly created records can be used, the button Activate Changes must be pressed. This allows editing the tables without interfering with the table as currently being used by the ABC SBC. Activate Changes activates the current version of the table for use by the ABC SBC, and creates a new table version which is used for further provisioning.
  • Introducing the table lookup in the rules. This requires adding the action Read Call Variables. The action takes the table name as the first parameter and lookup value as the second. The lookup value is typically formed using substitution expressions (see Section Using Replacements in Rules for a reference.) Provisioned Table Example: Static Registration

We will start with a relatively simple example: static registration. Similarly to how SIP devices use SIP REGISTER messages to create a temporary binding between SIP Address of Record and actual Contact URI, administrators can provision a similar association manually and permanently. That means that a table is provisioned and used the following way:

  • The table is keyed by an Adress of Record URI and includes the next-hop URI as attribute.
  • When a SIP INVITE comes in, its request URI is checked against the table and if the next-hop is found, replaced with it.

Note that this structure can be used to implement static call-forwarding.

Screenshots of the resulting table structure, table content and rules using the table are shown in the Figures Structure of Static Registrations, Static Registration Records, and Static Registration Rules respectively.

You can make several observations about the table lookup rule:

  • The rule conditions make sure the lookup is only executed for authenticated INVITEs, which helps to eliminiate unnecessary database queries - there is no point in making the table query for other than INVITE requests. If authentication is requested, the lookup for the first unauthenticated request would be also useless.
  • The table entry is looked up by the replacement expression “$r.” which stands for the current request URI. The result is returned in variable next_hop, as defined in the table column name.
  • If no result is found, the table lookup placed in the rule’s condition will return FALSE and no action will not be performed.
  • If a result is found, we apply two actions: change request-URI and add a header-field for troubleshooting purposes. Its presence in the outgoing INVITE shows a lookup was performed, the request-URI which was used as key and the returned value.

Figure 4: Structure of Static Registrations


Figure 5: Static Registration Records


Figure 6: Static Registration Rules Provisioned Table Example: URI Blacklist

Simple tables can have a great use. In this example we test presence of a SIP element value on a list. That means that the table only includes keys, with which no additional values are associated. We then look up the elements in the keys. That can be used to implement scenarios inolving all kind of disrimination like:

  • Call recording: is a call coming from a user whose calls shall be recorded?
  • Domain discrimination: is a call being routed to a listed domain for which some header fields must be removed or appended?
  • URI Blacklisting: is the caller blacklisted?

The following screenshots show the configuration of the URI-blacklisting example: Figure URI Blacklist Structure, Figure URI Blacklist Content, and Figure Blacklisting Rule. The rule is simple: If the SIP URI in the From header-field matches a URI in the blacklist table, the request is declined using a 403 response. Note that the lookup key is concatenated using “sip:” and “$fu”, because the replacement expression $fu does not include a protocol discriminator.


Figure 7: URI Blacklist Structure


Figure 8: URI Blacklist Content


Figure 9: Blacklisting Rule Table Example: Dialing Plan Normalization and Least-Cost-Routing

This is a two-in-one example showing two tables that are usually cascaded behind each other: normalization of a PBX dialing plan and least-cost routing.

Telephone numbers as used within a PBX can have different forms, following local national conventions and enterprise policies. For example, a typical user of a PBX in Munich dials with three leading zeros followed by international and area code to reach an international destination, two zeros followed by area code to reach destinations within Germany, one zero to reach destinations within Munich metropolitan area, and phone numbers without leading zeros to reach other PBX users. Using this dialing convention is convenient, the number length only grows with distance. However, these numbers loose signifiance if one tried to use them globally say to reach an international PSTN gateway. Therefore it is useful to normalize them in the E.164 format by stripping leading digits and introducing an appropriate prefix.

The following table shows examples of telephone numbers and how they are normalized for calls from a Munich PBX:

local number number E.164 equivalent digits to be stripped prefix to be introduced
000140433345678 (US destination) +1-404-333-45678 3 +
003034567000 (German number) +49-30-3456-7000 2 +49
078781234 (Munich number) +49-89-7878-1234 1 +4989

The following screenshots show the configuration of dialing plan normalization: Figure Dialplan Structure, Figure Dialplan Content, and Figure Dialplan Rules.

Note that the key is defined as string to make sure that prefix “00” in request URI doesnt match all of “0”, “00” and “000” as it would if the data type would be nummerical.


Figure 10: Dialplan Structure


Figure 11: Dialplan Content


Figure 12: Dialplan Rules

Once the numbers are normalized in the E.164 form, it is also easy to check the destination against a least-cost routing table to find the most economic PSTN gateway. The table may have the following content: prefix that is used to march phone numbers, and DNS name of a gateway chosen to serve the matched destination. Longest match applies which means that the shortest-match is taking lowest precedence and is used as “default route”.

prefix destination comment
+1 us-gateways.com US destinations
+43 austrian-united.com German destinations
+ cheap-pstn.net Everything else

The provisioning proces is shown in the following three Figures: Creating an LCR Table, Creating LCR Table Entries, and Calling the Routing table from routing rules.


Figure 13: Creating an LCR Table


Figure 14: Creating LCR Table Entries


Figure 15: Calling the Routing table from routing rules Table Example: Bulk Registration

Thanks to an extensions of the SIP standard, it is now possible for a PBX to have one digest identity under which it can serve a whole range of telephone numbers. The extension emerged out of SIP Forum’s effort to create a profile for PBX interoperability, that became known as “SIP Connect” and standardized as RFC 6140.

The ABC SBC supports these scenarios and it even makes the deployment scenario much simpler than contemplated in the RFC. It allows an arbitrary SIP client, PBX, softphone or any other SIP device to authenticate under a single URI and receive calls for a whole range of telephone numbers. It works “as is” without requiring any of the “bnc”, “gin” or GRUU extensions.

The following example call flow assumes a network topology in which the ABC SBC guards an internal network, in which a combined proxy/registrar is located. The administrator has provisioned the telephone number range 7200-7400 to be server be PBX reachable under the URI sip:pbx@abcsbc.com. Note that a similar scenario could also be implemented using the ABC SBC‘s built-in registrar.

The call flow starts with a SIP registration using digest authentication (1)-(4). When an INVITE comes in (5), the telephone number in the Request URI is translated to that of the PBX (6). This allows the proxy/registrar behind the SBC to perform user-location lookup and forward to the PBX through the ABC SBC (7). The SBC then, as usual, retrieves the original URI, whose username is fixed eventually to be the target telephone number (8):

Internet        |SBC|             registar            |SBC|               SIP PBX
|                 |                     |                   |
|                 |                     |(2) REGISTER       |(1) REGISTER          |
|                 |                     |To: pbx@abcsbc.com |To: pbx@abcsbc.com    |
|                 |                     |m:<sip:a47b6@abc>  |Contact:<pbx@>|
|                 |                     |<------------------|<---------------------|
|                 |                     |                   |                      |
|                 |                     |(3) 200 OK         |(4) 200 OK            |
|                 |                     |------------------>|--------------------->|
|(5) INVITE       |(6) INVITE           |                   |                      |
|sip:7271@any.com |sip:pbx@abcsbc.com   |(7) INVITE         |                      |
|---------------->|x-pbx-user: 7271     |sip:a47b6@abc      |                      |
|                 |-------------------->|x-pbx-user: 7271   |(8) INVITE            |
|                 |                     |------------------>|sip:7271@     |
|                 |                     |                   |--------------------->|

To orchestrate this call-flow, the following configuration steps must be taken:

  • A number range must be defined and assigned to the URI the PBX owns. This is done using the table-provisioning feature. The screenshots showing this process are in the Figure Definition of the Number Range Association and Figure Assignment of a Number Range to a URI.
  • In a rule, incoming INVITEs (5) must be tested against the available ranges. If such a range is found, the request URI must be translated to that owned by the PBX. At the same time the telephone number must be preserved in a request-URI parameter and/or proprietary header-field (x-pbx-user here), whichever the registrar behind the SBC can better deal with. (6) The configuration is shown in Figure Assignment of a Number Range to a URI.
  • Before the INVITE is eventually sent to the PBX, it must include the destination telephone number in the request URI. This is done in a rule that retrieves the phone number from the request URI parameter or header-field, in which it was stored in the previous step. The configuration is shown in Figure Retrieving the Telephone number back in request URI.

Figure 16: Definition of the Number Range Association


Figure 17: Assignment of a Number Range to a URI


Figure 18: Placing PBX’s Address in request URI and Storing the Original Telephone Number


Figure 19: Retrieving the Telephone number back in request URI Provisioning Tables Using RPC

In the case that the ABC SBC administrator already has a table available, it will be easier to transfer it automatically to the ABC SBC as opposed to typing it in using the the web-interace. This can be accomplished using the ABC SBC‘s XML-RPC data provisioning interface.

The following example shows a python code fragment for accessing the built-in XML-RPC provisioning server:

import xmlrpclib;
server = xmlrpclib.Server('https://username:password@');

Note that for the python client, a question mark (?) in the password does not work, so e.g. change the default password for sbcadmin if not already done.

For the XML-RPC access the IP address of the configuration master node has be used. After commiting the updated data, all ABC SBC nodes pull the new version of the priviosoned tables from the configuration master.

The XML-RPC is accessible on the XMI interface address, or on all interfaces addresses, depending on global config setting “Block HTTPS GUI access to other than XMI interface”, which can be found under the Firewall tab of the Global Config section.

The following RPC commands are available:

  • rpc.help($function)
  • tables.fetch_rules($table_name)
  • tables.fetch_rule($table_name, $key_value)
  • tables.insert_rule($table_name, $data)
  • tables.update_rule($table_name, $data) // must include UUID or key_value
  • tables.delete_rule($table_name, $uuid)
  • tables.delete_all_rules($table_name)
  • tables.commit($table_name, $msg)

For example, to introduce a new entry to the blacklist and check the outcome, the following three RPC commands must be called: insert_rule, commit and fetch_rules:

data = {"key_value":"sip:restricted@abc.com"};
print server.tables.insert_rule('test_uri_bl',data);
print server.tables.commit('test_uri_bl', 'new restricted used introduced');
print server.tables.fetch_rules('test_uri_bl');

This script will result in the following list of URIs shown on the command-line output:

[{'key_value': 'sip:banned@abcsbc.com', 'uuid': '6c01a834-9d32-df09-0217-000000f074ee'},
{'key_value': 'sip:forbidden@abcsbc.com', 'uuid': '54d15a12-62bc-73c9-8313-000012f8ae1b'},
{'key_value': 'sip:restricted@abc.com', 'uuid': '6d831a12-88bc-7fa9-7483-000083ff992a'}]

Note that the routing tables have several predefined mandatory elements that must use the following conventions:

  • cagent takes name or UUID of a call-agent
  • outbound_proxy and next_hop is passed as string
  • boolean parameters next_hop_1st_rq, upd_ruri_host, and upd_ruri_dns_ip take either 0 or 1 as value
  • the enumerative parameters route_via takes one of the following values: outbound_proxy, next_hop or ruri

Consult Frafos professional services for more information.

5.13.3. Enum Queries

ENUM (RFC 3761) is a DNS-based phone number database that translates telephone numbers into URIs. For example, the telephone number +1-405-456-1234 can be translated to sip:mrs.somone@abcsbc.com. This is often used to find SIP address for a VoIP user when she receives a call from the PSTN under her telephone number.

An ENUM query can be run using the  Enum query action. This action queries the default DNS resolvers configured in the SBC host with an Enum query, and sets the request URI to the result.


Figure 20: Using Enum queries

By using a different domain suffix than the default one (e164.arpa), private enum servers can be queried. This is in fact the way ENUM is widely used – as of today, no public ENUM service with global coverage has emerged.

The result of the Enum query can be tested using the Last Action Result condition. If it returns true, the ENUM query returned a URI, false is returned otherwise. In case of success, the ENUM-returned URI has rewritten the request-URI and may be rewritten using the ($rU) replacement expression.