[sr-dev] Outbound summary

Olle E. Johansson oej at edvina.net
Thu Aug 9 08:31:05 CEST 2012


9 aug 2012 kl. 00:32 skrev Peter Dunkley:

> Hello,
> 
> I thought I would try and produce a short summary (basically just bullet
> points) of what is required for Outbound just to make sure I haven't
> missed anything.
> 
> There are three use cases for Kamailio with Outbound/Path:
> * EDGE server between client and registrar
> * Registrar with EDGE server between it and client
> * Single server (EDGE server and registrar combined) using Outbound
> instead of aliasing for NAT traversal
> 
> 
> EDGE server
> -----------
> * Path
>  - Existing Path module does (most of) what is required when called for
> REGISTER requests
>  - Received parameters are not needed on Path: headers because we will
> use Outbound flow tokens now
> * Outbound
>  - Need to generate/add flow token and ;ob parameter to the
> Path/Record-Route headers when:
>    # It's an initial request (out-of-dialog INVITE, REGISTER, SUBSCRIBE,
> or REFER), with
>    # A single Via:, and
>    # Top Route: points to us and has ;ob parameter or Contact: has ;ob
> parameter or it's a REGISTER with ;+sip.instance, or
>    # force_outbound() API has been called
>  - Need to maintain mapping of flow tokens to connections (flow token
> to/from source address and port)
>  - Need an Outbound routing API (related to loose_route()) that sets $du
> correctly based on flow token in Route: header (R-URI no longer used)
>  - If the flow token doesn't match a connection send 430 response
> (response sending in kamailio.cfg, but Outbound routing API needs to
> return an appropriate error to support this)
> 
I would say "active connection". In the case of UDP, a failed UDP transmit could be an indication.
There's a NAT keepalive protocol - very simple cr and cr+lf - to check the status
of the connection.
> 
> Registrar
> ---------
> * Path
>  - Path already supported in usrloc
> * Outbound
>  - instance and reg IDs already stored in usrloc
>  - multiple registrations with the same instance ID but different reg IDs
> must be supported (may be already)
>  - Parallel and serial forking behaviour must be preserved, when forking
> branch to each unique instance ID not reg ID.
>  - Need a new/improved lookup() API that returns the location for the
> best reg ID and populates an AVP with the other instance IDs in order
> they should be tried
>  - On receipt of 430 response to a request the failed location should be
> removed from the usrloc table and the next location (from the AVP)
> tried.  Similar to the way dispatcher works.
> 
> 
> Single server
> -------------
> * Path
>  - Use this to add single (local) Path header - just needed to get the
> Outbound flow token into the usrloc table
>  - Received parameters are not needed on Path: headers because we will
> use Outbound flow tokens now
> * Outbound
>  - Similar to the combined behaviour of EDGE server and Registrar, but
> because the mapping of flow token to connection is local there is no
> need for the 430 response stuff - can just loop through the list of
> matching connections locally until a good one is found.
A locally generated 408 should be treated as a 430 - right?

> 
> 
> Note: Double-Path and advertised address...
> *  Talking to one of my colleagues he thought that double-Path headers
> wouldn't be required.  Double-RR is used to make sure the route-set is
> good in both directions when there are transport/network changes.  Because
> Path is just used in the one direction this shouldn't be required.  Does
> this make sense?
> * Because the Path header needs to show the address of the outbound
> interface it should use the advertised address for that interface, not the
> listening address of the interface.  Is this correct?
> 
> 
> Proposed API
> ------------
> Right thing to do might be a new outbound module which provides both the
> EDGE server and registrar functions.  The module would bind (through C-API
> - which might need extended/tweaked for each of the modules) to path, rr,
> registrar, and location modules to make use of the functions already
> implemented there.  Probably (when Outbound is used) path, rr, and
> registrar will not be called from kamailio.cfg directly - the outbound
> wrapper functions will be used instead:
> * outbound_route(): use instead of rr.loose_route() (may well call
> rr.loose_route() internally but will also use flow token to work out value
> for $du)
> * outbound_record_route(): use instead of rr.record_route() (may well call
> rr.record_route() internally - but will also add the flow token (if the
> requirements for Outbound are met in the request))
> * outbound_add_path(): use instead of path.add_path() (may well call
> path.add_path() internally - but will also add the flow token and generate
> it (and add to token/connection mapping table) for new connections (if the
> requirements for Outbound are met in the request))
> * outbound_lookup(): use instead of registrar.lookup() (may well call
> registrar.lookup() internally - but will select the contact(s) with the
> best reg IDs and fill in AVP)
> * outbound_next_contact(): new API which will remove the first contact
> from the AVP _and_ location table and select the best remaining reg ID
> * force_outbound(): new API which will make sure flow tokens are added by
> outbound_record_route() and outbound_add_path() even if the request
> doesn't indicate client support
> 
> 
> Token/connection map maintenance
> ----------------------------------
> * Is there a need to add an event_route[] to catch connection closes (and
> a corresponding outbound module API to remove a token/connection mapping)
> as previously suggested by OEJ?
Think UDP too. "Connection close" => "connection failures" :-)
In some cases, you might want to do external things when this happens,
alert a system, change iptables mappings or something else. 

> * Is it OK for the outbound.outbound_route() function just to check that a
> connection found in the mapping table is valid when attempting to route a
> request (and removing the mapping and returning that there was no mapping
> when it isn't) - or would this lead to stuck entries in the mapping table?

> * Perhaps entries in the map should expire automatically anyway (so no
> catching of closes required) - they will be created when a client
> registers so there is an expiry time available?

Since we reuse the connection, the connection and the registration should
not be assumed to have the same expiry. When registration expires there may
still be an active dialog on that connection. Mapping these would be hard,
like a phone with one registration, five subscriptions and an active call dialog
on the same connection. We can't assume that the phone call should be hung up
because the registred contact expires.

/O






More information about the sr-dev mailing list