Hello,
I thought I would update this based on today's feedback... Please let me
know if anything is incorrect or missing.
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
- path and rr modules will be updated to support Outbound (see API
details below)
- NAT keep-alive from section 5.4 support required
- STUN stuff from section 8
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.
- registrar and usrloc modules will be updated to support Outbound (see
API details below)
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 430 response handling - can just loop through the list of
matching connections locally until a good one is found.
Note: Double-Path and advertised address...
* Double-Path is not required as, unlike Record-Route, Path is only used
for routing in the server to client direction.
* 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.
Proposed API
------------
* Either new module (outbound) or additions to an existing utils module that:
- Contains either an exposed function (force_outbound()) or has a
modparam that indicates which flag is used to specify when Outbound
should be forced for a request.
- Contains a modparam that specifies the string to be used as the
encryption key for the flow-token
- Contains a C-API function to perform the Outbound check (deciding
based on message or flag whether to put Outbound stuff in Path: or
Record-Route:)
- Contains a C-API function to generate a flow token string from a set
of connection details (using mechanism recommended in Outbound
specification)
- Contains a C-API function to generate a set of connection details from
a flow token string
* Add new modparam to path and rr module to enable outbound. When
outbound is enabled these modules bind to module providing the Outbound
C-API functions.
- They then use these functions add Outbound Path: and Record-Route:
compatible headers when needed.
- loose_route() function updated to set $du based on decoded flow token
when present [1].
* Add new modparam to enable outbound on registrar and usrloc.
- When outbound is used lookup() populates an AVP (specified as another
modparam) with the ordered list (by reg ID) of contacts
- New lookup_next_dest() API to remove "dead" contact and try the next
[1] If flow token has been tampered with, or indicates a connection that
does not exist (so not active WS, WSS, TCP, TLS, or SCTP connection) then
an error is returned from loose_route() and a 430 should be generated.
Other connection errors (for example, time-outs) handled in
failure_route[] on the EDGE server and converted to 430 where needed.
Token/connection map maintenance
--------------------------------
Map not required. Token is calculated from source address, port, and
protocol and these can be recovered from the token.
Questions
---------
* NAT keep-alive from section 5.4 support... does this need to be handled
in the core before things like the sanity module are called?
* STUN stuff from section 8... again, in the core?