<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>