[OpenSIPS-Devel] Idea: Linking CPL with OpenSIPS' route scripts

Rick van Rein rick at openfortress.nl
Fri Dec 7 12:59:25 CET 2012


Hello,

I'm looking into the possibilities of the CPL module.  Some
thinking (included below) leads me to the conclusion that it
would be ideal to have a better integration between CPL and
the normal routing scripts, to simplify local extensions to
the CPL syntax through additional XML namespaces.

I can see two modular ways of supporting CPL extensions:
 1. call main script routes from CPL to implement extensions;
 2. map CPL to OpenSIPS' bytecode for normal routing scripts

(I cannot find this bytecode for normal routing scripts in the
 source code, but assume it exists -- where should I look?)

Being able to extend CPL without doing it in its module means
that the flexibility of OpenSIPS' scripts is available to the
administrator, and that CPL extensions are possible for local
use.  This gives the admin good control over a language with
which users can flexibly specify their call routing.


I'm very curious to your reactions to this line of thought!


Best wishes,

Rick van Rein
OpenFortress


    ------- 8< ------- 8< ------- 8< ------- 8< ------- 8< -------


Specific Problems
-----------------

There are many extensions to CPL that might be useful, and the RFC
permits those through the use of name spaces...

 * SDP matching (Video?  IPv6 and/or IPv4?  blacklisted media IP?)
 * CPL-configured client authentication
 * Handle messaging through CPL

All these could be made as CPL extensions, and could be implemented
in the module.


General Problem
---------------

The CPL module in OpenSIPS could be expanded, but that would
either be difficult to maintain, or it would mean publishing
local wishes to the rest of the world.  This could easily lead
to an incredibly big CPL module...

The functionality of the CPL module would end up replicating
much of what is already part of OpenSIPS.  Except that it lacked
the flexibility that OpenSIPS has due to its scripts.  The only
advantage of the CPL form would be that it is per-user and that
only those namespaces would be selected that implement what the
administrator will permit.


General Solution
----------------

A better solution would seem to be to let CPL handling jump out
to parts of the scripts.  The already existing routes (including
those for failure and reply) are well suited for this.  Given
an XML node, the configuration of the CPL module could then
relay handling it to a main script route.  It could pass arguments
as script variables of some sort.

modparam ("cpl-c", "xmlns", "urn:ietf:params:xml:ns:cpl cpl.xsd")
modparam ("cpl-c", "hook xmpp:messaging", "CPLMESSAGE")
modparam ("cpl-c", "failure_hook location", "CPLAUTH($userid,$realm)")
modparam ("cpl-c", "xmlns:sdp", "http://what/ev/er")
modparam ("cpl-c", "hook sdp:address-family-switch", "SDPMATCH($patn):all-ipv6,all-ipv4,otherwise")

An example of using the last structure would be (of course
limited by the XML Schema for xmlns:sdp):

This would enable CPL structures like:

	<sdp:address-family-switch field="destination">
		<all-ipv6>...</all-ipv6>
		<otherwise>...</otherwise>
	</sdp:address-family-switch>

The hook, failure_hook and reply_hook options could be very
generally applied by the CPL compiler by matching them with
an XML Path expression, and then executed as the equivalent of:

	$patn = "$od";
	route (SDPMATCH);
	if ($cplnext == "all-ipv6") {
		...
	} elif ($cplnext == "all-ipv4") {
		...
	} else {
		...
	}

An example of a useful XML Path to implement a route could be
"/cpl/incoming//sdp:match" or "/cpl/incoming//location/busy".

The variable $cplnext is defined as the CPL instruction variable
to be used on returns,

modparam ("cpl-c", "instruction_return_variable", "$cplnext")

It is probably useful to handle a route return by simply
moving on to the single next node.


Specific Solutions
------------------

To match against SDP, a hook could invoke a route, and return
the result in a script variable.  The handling in this route
could use pattern matching, existing modules like the NAT helper,
or define its own SDP-processing module that could even include
loops over the SDP content (for all c= there should be an m= so
that...)

To provide client authentication, a failure route is invoked
with parameters that specify the authentication triplet, with
the username, realm and password.  This makes an invocation of
uac_client possible, and does not risk sharing credentials
among CPL scripts.  Alternately, one could define separate
password entries within the incoming and outgoing sections, and
use those to pass information to a route that stores them.

To handle messaging, one could introduce a namespace with the
corresponding routing statements, next to incoming and outgoing
declarations.


Remaining problems
------------------

* Stored (binary) CPL scripts may be invalidated when the support
  for a facility is dropped from a script.  This is difficult to
  relay to the users/creators of those scripts.




More information about the Devel mailing list