<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Thanks Matt for all the valuable details -- even quite some time
since your answer, I still have to digest parts of it, given that I
had some tough cold to deal with and then a bit of traveling. But
that gave time to think more about and I have an idea that I will
present in a near future to make the trust relationship between
Kamailio and Asterisk instance a bit more dynamic.<br>
<br>
For now, I want to comment on your suggestion, pasted next:<br>
<br>
"""<br>
From Kamailio's perspective, you could:<br>
<br>
<div>* Receive an inbound request<br>
</div>
<div>* Pick some Asterisk resource in your pool of available servers<br>
</div>
<div>* (Assuming this is done using a REST API) PUT the
configuration of the endpoint on the specific destination server<br>
</div>
<div>* Route the call to that server<br>
</div>
* Later, DELETE the configuration off the server<br>
"""<br>
<br>
I would prefer to avoid any extra network communication between
Kamailio and Asterisk, we have to send a sip package anyhow. It can
add delays and also complexity in dealing with transmission errors
of the PUT operation.<br>
<br>
Given you suggestion, maybe we can loop that internally in Asterisk
somehow. Have kind of SIP message pre-processing callback where to
do the PUT operation for configuration of the endpoint, then do the
normal diaplan routing. I am quite sure should be possible somehow
with the new ARI, I just need time to dig into it.<br>
<br>
My target is to make it easy for integration in existing
deployments, not to have to rewrite the call routing configuration
completely, just to change somehow the source of endpoint profiles.<br>
<br>
Cheers,<br>
Daniel<br>
<br>
<br>
<br>
<div class="moz-cite-prefix">On 13/01/15 06:18, Matthew Jordan
wrote:<br>
</div>
<blockquote
cite="mid:CAN2PU+4YpExOB6L1KTGezt8SvXxLnVQ_E_Gob18Ub+0eN0wbHA@mail.gmail.com"
type="cite">
<div dir="ltr">
<div class="gmail_extra"><br>
<div class="gmail_quote">On Mon, Jan 12, 2015 at 10:53 AM,
Daniel-Constantin Mierla <span dir="ltr"><<a
moz-do-not-send="true" href="mailto:miconda@gmail.com"
target="_blank">miconda@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">Hey guys,<br>
<br>
I hope everyone here enjoyed nice time during the winter
(or summer for<br>
lucky ones at this time of the year) holidays break!<br>
<br>
Being rather busy after AstriDevCon, but I also postponed
starting the<br>
discussion, given that I expected low activity ahead and
didn't want to<br>
get it lost in the archive ... so back to the topic ...
and expect large<br>
message below ...<br>
</blockquote>
<div><br>
</div>
<div>No worries at all! I'm still digging through the list
of items from AstriDevCon as well - the holidays always
slows down progress on these kinds of things.<br>
</div>
<div> <br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
During AstriDevCon sessions in Las Vegas, we discussed
briefly of what<br>
can be done for a better integration between Asterisk (as
media server)<br>
and Kamailio (as a front end SIP singling server/proxy). I
said I would<br>
follow up on mailing list, so here we are. Obviously, many
are using the<br>
two together, therefore any improvement to make it simpler
could make a<br>
very good impact on both sides.<br>
<br>
To be honest, I lost track of many new 'cool' things
happening lately in<br>
Asterisk with the newer APIs, I will have to catch up very
soon,<br>
meanwhile, if any of my ideas are already there, then even
better.<br>
<br>
The typical integration of Asterisk and Kamailio was to
share somehow<br>
user profiles via database -- relying on Asterisk
realtime, either using<br>
Asterisk database structure with kamailio connecting to
it, or making<br>
SQL views to suit the two applications. I wrote some
tutorials over the<br>
time -- for reference, just in case anyone wants to get
the idea better:<br>
<br>
- <a moz-do-not-send="true"
href="http://kb.asipto.com/asterisk:index"
target="_blank">http://kb.asipto.com/asterisk:index</a><br>
<br>
The approach works very well when dealing in a more or
less static<br>
deployment. However, there is a lot to benefit on top of
elasticity of<br>
the cloud networks, where the nodes could be fired on
demand, in<br>
different locations of the world. In such situations,
sharing the<br>
database can become really slow, adds issues with
replications, etc.<br>
<br>
To set the specifics of a deployment:<br>
- kamailio takes care of signaling 'heavy' processing
(authentication,<br>
user location, filtering DoS attacks, etc.)<br>
- asterisk takes care of 'heavy' pbx features and media
processing<br>
<br>
When I fire a new asterisk, I want to give it (e.g., in
config file) one<br>
or many IP addresses that belong to kamailios and asterisk
should<br>
consider them trusted, no other authentication should be
done for<br>
traffic originating from those IPs. The rest of
integration would<br>
hopefully automagically just work.<br>
<br>
One of my ideas was to be able to define subscriber
(phone) profile<br>
templates and the proxy will indicate which template to
use for caller<br>
and callee (when they are local subscribers). Attributes
of the template<br>
can be taken from SIP message or be statically defined. I
know about the<br>
config templates with [name](!), but that is still quite
static,<br>
extension have to be defined and templates associated with
them. It<br>
could be on same direction, but more dynamic.<br>
</blockquote>
<div><br>
</div>
<div>This gets into the notion of having a "push"
configuration model instead of a "pull" configuration
model that was discussed at AstriDevCon. Note that this is
just one method of solving this problem - as you mention
later, there are others which may be better - but it's
probably worth discussing push configuration here.<br>
<br>
A fuller explanation follows:<br>
<br>
</div>
<div>In Asterisk 12, the notion of a generic data access
layer was introduced that wraps up the traditional
configuration approaches (static conf files, static
Asterisk Realtime, and dynamic Asterisk Realtime) as well
as some internal data providers (memory, AstDB). This was
done for quite a few reasons:<br>
</div>
<div>(1) Using the ARA had quite a few deficiencies, as
evidenced by the SQL statements littering chan_sip and
other portions of the code base. It was quite common for
logic to diverge based on what provided the configuration,
which led to all sorts of difficult bugs to test and fix.
That being said, the actual ARA drivers themselves could
fit behind a new API, and so they were mostly left alone.
This lets older modules continue to use ARA as they
previously did, and newer modules to take advantage of the
existing backends.<br>
</div>
<div>(2) A new generic data access layer allowed us to take
advantage of work done in Asterisk 11's configuration
framework. The configuration framework in Asterisk 11
provides type conversion from configuration data to in
memory objects, default value application and object
construction, documentation checking, object lifetime
management, as well as thread safety during reloads. All
of this makes modules that use the configuration data a
lot safer and more consistent.<br>
</div>
<div>(3) Because data can also be provided by an in memory
cache or the AstDB, we can now provide caching for ARA
backends. A user can also modify via configuration where
data is stored, pushing data out to a more permanent
storage if the AstDB isn't desired.<br>
<br>
</div>
<div>On top of it, this is a pluggable architecture, where
data providers are simply dynamically loadable modules.
The method of providing configuration is very 'ad hoc',
wherein a user of the new data access layer does not care
where the data comes from, so long as something can
provide it.<br>
<br>
</div>
<div>In the end, Josh called this "sorcery", presumably
because there is an awful lot of magic that happens under
the hood in that API.<br>
<br>
</div>
<div>Today, all of the providers - called "wizards" - use a
pull model of providing data. Taking the PJSIP stack as an
example (this is a very high level view, there's a lot of
details removed):<br>
<br>
</div>
<div>* An inbound request is received and passed up the
stack into res_pjsip<br>
</div>
<div>* res_pjsip, which has a pluggable architecture of its
own, looks for an endpoint identifier module<br>
</div>
<div>* res_pjip_endpoint_identifier_user picks up the
request, and look at the user portion of the SIP URI in
the From header<br>
</div>
<div>* res_pjsip_endpoint_identifier_user queries sorcery
for an endpoint that matches the user<br>
</div>
<div>* sorcery (via configuration) maps this to some
configuration provider. This could be a static file (such
as pjsip.conf), a database, or something else. It converts
the key/value pairs into an ast_sip_endpoint ao2 ref
counted object.<br>
</div>
<div>* res_pjsip_endpoint_identifier_user gets back the
ast_sip_endpoint object, passing it back to res_pjsip -
which now has an endpoint to use for the request.<br>
<br>
</div>
<div>Now, we could just as easily *not* pull for the
configuration data. Instead, we could do something like
the following:<br>
<br>
</div>
<div>* An API call is made which pushes a JSON blob into
Asterisk containing the necessary information for a PJSIP
endpoint. A sorcery wizard picks this up and stores it in
the in-memory sorcery wizard.<br>
</div>
<div>* An inbound request is received and passed up the
stack into res_pjsip<br>
</div>
<div>... and all the rest is actually the same - as sorcery
simply uses the in-memory cache of the received
information from the API.<br>
<br>
</div>
<div>Since caching is tricky, the lifetime of the PJSIP
endpoint in this Asterisk instance could just as easily be
managed by the external application. A different API call
could tell the Asterisk instance to purge the endpoint
from memory.<br>
<br>
From Kamailio's perspective, you could:<br>
<br>
</div>
<div>* Receive an inbound request<br>
</div>
<div>* Pick some Asterisk resource in your pool of available
servers<br>
</div>
<div>* (Assuming this is done using a REST API) PUT the
configuration of the endpoint on the specific destination
server<br>
</div>
<div>* Route the call to that server<br>
</div>
<div>* Later, DELETE the configuration off the server<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<br>
For better exemplification, in pseudo code:<br>
<br>
[template-match]<br>
template-as-caller=${header(X-Caller-Template)<br>
template-as-callee=${header(X-Callee-Template)<br>
<br>
[template-user-x]<br>
userid-as-caller=${From-Header-URI-Username}<br>
userid-as-caller=${Request-URI-Username}<br>
codecs=g711,g729<br>
mwi=yes<br>
maiboxid=${header(X-MailBoxId)}<br>
maiboxpin=${header(X-MailBoxPin)}<br>
location =<br>
<a class="moz-txt-link-rfc2396E" href="sip:${From-Header-URI-Username}@${Source-IP}:${Source-Port};transport={Transport-Protocol}">"sip:${From-Header-URI-Username}@${Source-IP}:${Source-Port};transport={Transport-Protocol}"</a><br>
publish-dialog-info=yes<br>
...<br>
<br>
The proxy has to set the header X-Caller-Template if the
caller is local<br>
and X-Callee-Template if the callee is local, plus other
headers than<br>
are necessary/used in templates.<br>
</blockquote>
<div><br>
</div>
<div>This is another way of identifying inbound requests
without requiring any API interaction whatsoever. You'd
certainly have the advantage of being even more performant
- no push configuration necessary whatsoever - but at the
cost of some of the flexibility that the push
configuration affords.<br>
<br>
</div>
<div>As mentioned earlier, the PJSIP stack has a very
flexible architecture that lets you "plug-in" how
endpoints are identified. In the existing stack, there are
three different endpoint identifiers:<br>
</div>
<div>* res_pjsip_endpoint_identifier_user - associate
inbound requests based on the user portion of the SIP URI
in the From header<br>
</div>
<div>* res_pjsip_endpoint_identifier_ip - associate inbound
requests based on a static IP address<br>
</div>
<div>* res_pjsip_endpoint_identifier_anonymous - associate
inbound requests with one particular endpoint. If present,
all unmatched requests are matched to this endpoint.<br>
<br>
</div>
<div>You could just as easily have
res_pjsip_endpoint_identifier_header. It could do what you
said: look for a custom header (which, itself, could be
configurable) and, if the header is present, match it to a
single specific endpoint in the same fashion as
res_pjsip_endpoint_identifier_anonymous.<br>
</div>
<div><br>
</div>
<div>The downside of this approach is that all devices must
support all configuration parameters of a single
configured endpoint. That is, if you have something like:<br>
<br>
</div>
<div>[header-identifier]<br>
type=header-identifier<br>
</div>
<div>endpoint=caller-endpoint<br>
</div>
<div>X-Caller-Template=foo<br>
<br>
</div>
<div>[header-identifier]<br>
</div>
<div>type=header-identifier<br>
</div>
<div>endpoint=callee-endpoint<br>
</div>
<div>X-Callee-Template=bar<br>
</div>
<div><br>
</div>
<div>[endpoint-template](!)<br>
</div>
<div>type=endpoint<br>
</div>
<div>allow=!all.g722,ulaw<br>
</div>
<div><br>
</div>
<div>[caller-endpoint](endpoint-template)</div>
<div>context=from-kamailio-local<br>
</div>
<div>identify_by=header<br>
</div>
<div><br>
</div>
<div>[callee-endpoint](endpoint-template)<br>
</div>
<div>context=from-kamailio-remote<br>
</div>
<div>identify_by=header<br>
</div>
<div><br>
</div>
<div>Then you could have your endpoint identifier match all
requests with a header of X-Caller-Template to
caller-endpoint and all requests with a header of
X-Callee-Template to callee-endpoint. However, all devices
would have to support g722 and ulaw, and - if NAT settings
were necessary - then all devices would have to share the
same NAT settings. This may not be must of a concern in a
well defined system front-ended by Kamailio.<br>
<br>
</div>
<div>Writing this module would not be terribly difficult -
it would look a lot like a combination of
res_pjsip_endpoint_identifier_ip and
res_pjsip_endpoint_identifier_anonymous. (Not that SLOC is
a good measurement of difficulty, but
res_pjsip_endpoint_identifier_ip tops out at 540 lines of
code, and it is by far the largest of the endpoint
identifiers).<br>
</div>
<div><br>
</div>
<div>Note that this approach is not mutually exclusive with
a push configuration, or with using a database. With
sorcery, the configuration shown above could come from a
database - it's just that Asterisk won't need to obtain it
often.<br>
</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<br>
Practically, Asterisk would have to build the user profile
on demand,<br>
without needing to interogate any database or other
resource over the<br>
network (I know APIs can be used everywhere :-), but they
fail also, or<br>
in other words, SIP is an API as well). It can reuse the
variable<br>
already available on the SIP channel, I used pseudo-code
to make it<br>
easier to understand.<br>
</blockquote>
<div><br>
</div>
<div>Yup! And as I mentioned, the idea of having an endpoint
identifier that looks at custom SIP headers is not
mutually exclusive with an API. One could foresee having a
small set of SIP headers that Kamailio uses to 'tag'
allowed requests, particularly if there were a variety of
devices that it was passing to Asterisk (different codec
sets, etc.) It could have all of these pre-configured on
its pool of servers; have the templates defined in a
database; or it could use a push model to provide the
configuration on the fly to Asterisk servers as they are
spun up.<br>
</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<br>
For the moment I would stop here, already long message.
And might be<br>
already possible ... if not, before going on other
directions, lets see<br>
the interest and maybe other proposals for a better media<br>
server/signaling server integration.<br>
</blockquote>
<div><br>
</div>
<div>I think it's very possible to add a new endpoint
identifier.<br>
<br>
The push configuration model is a bit more work, but also
very doable.<br>
<br>
I'd be happy to provide more details on either approach if
someone were interested in contributing it!<br>
</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<br>
Before the real end, some questions for the larger devel
community that<br>
should help deciding on how to get the two projects
working smoother<br>
together:<br>
- what would you like from the proxy (signaling server)
to be exposed<br>
easier?<br>
- if already using the two, what parts you would like to
simplify?<br>
- how would you split the workload? In other words, what
services you<br>
would prefer to be done better in one or the other, given
that some<br>
features overlap?<br>
</blockquote>
<div><br>
<div>I'm going to defer to Olle on those questions for now
- as he uniquely has a lot of experience with both
Asterisk and Kamailio - but I'll think some more on
those questions this week.<br>
<br>
</div>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
Have a great 2015 coding Asterisk and Kamailio! Looking
forward to<br>
meeting some of you around the globe this year!<br>
Daniel<br>
<span class=""></span></blockquote>
<div><br>
</div>
Thanks for the e-mail and suggestions! I'm looking forward
to what else we can come up with.<br>
<br>
</div>
<div class="gmail_quote">Matt<br>
</div>
<br>
</div>
<div class="gmail_extra">-- <br>
<div class="gmail_signature">
<div dir="ltr">
<div>Matthew Jordan<br>
</div>
<div>Digium, Inc. | Engineering Manager</div>
<div>445 Jan Davis Drive NW - Huntsville, AL 35806 - USA</div>
<div>Check us out at: <a moz-do-not-send="true"
href="http://digium.com" target="_blank">http://digium.com</a>
& <a moz-do-not-send="true"
href="http://asterisk.org" target="_blank">http://asterisk.org</a></div>
</div>
</div>
</div>
</div>
</blockquote>
<br>
<pre class="moz-signature" cols="72">--
Daniel-Constantin Mierla
<a class="moz-txt-link-freetext" href="http://twitter.com/#!/miconda">http://twitter.com/#!/miconda</a> - <a class="moz-txt-link-freetext" href="http://www.linkedin.com/in/miconda">http://www.linkedin.com/in/miconda</a></pre>
</body>
</html>