There are three use cases for Kamailio with Outbound: * 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 module - Existing path module does (most of) what is required when called for REGISTER requests - Received parameters are not needed on Path-URIs because we will use Outbound flow tokens now - Flow token and ;ob parameter must be added to the Path-URI when Outbound is in use - Must use advertised_address for the interface if set - Attempt to bind to outbound module. If successful perform Outbound, if unsuccessful maintain current behaviour * rr module - Existing rr module does (most of) what is required when called for requests - Flow token and ;ob parameter must be added to the Record-Route-URI when Outbound is in use - loose_route() function updated to set $du based on decoded flow token when present in Route-URI that belongs to the server [1] - Attempt to bind to outbound module. If successful perform Outbound, if unsuccessful maintain current behaviour * Kamailio core - Make compiling with STUN the default - Make default for stun_allow_stun 0 (off) * Kamailio configuration - When routing to a client using Outbound fails catch this in a failure_route[] and return 430 to registrar * outbound module (new) - Need to be able to generate/add flow token and ;ob parameter to the Path-URI and Record-Route-URI when it's an initial request (out-of-dialog INVITE, REGISTER, SUBSCRIBE, or REFER) with a single Via: and any of the following conditions are met: # The top Route-URI points to us and has ;ob parameter # The Contact-URI has ;ob parameter # It's a REGISTER request with a ;reg-id on the Contact-URI # Outbound is being forced - Has a modparam that indicates which branch 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 contents or branch flag whether to put Outbound stuff in Path-URI or Record-Route-URI) - 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 Registrar --------- * registrar and usrloc modules - +sip.instance and reg-id Contact-URI parameters already supported - multiple registrations with the same instance ID but different reg IDs must be allowed (may be already) - Parallel and serial forking behaviour must be preserved, when forking branch to each unique +sip.instance but not reg-id - Ignore received field/parameter/AVP when Outbound is use - New modparam for registrar specifying an AVP to populate when Outbound is in use. If modparam not set Outbound is disabled. - When AVP is specified lookup() populates the AVP with the ordered list (by reg-id) of contacts to try (similar to dispatcher) and sets $du based on the first contact - New API lookup_next_dest() removes the first contact from the AVP and the usrloc table and sets $du based on the new first contact * Kamailio configuration - failure_route[] to check for 430 responses and re-route to the next contact based on reg-id using lookup_next_dest() * outbound module (new) - Not required on a registrar that is used with separate EDGE servers Single server ------------- * path module - EDGE server behaviour from above required - Use this to add single (local) Path header - needed to get the Outbound flow token into the usrloc table * rr module - EDGE server behaviour from above required * registrar module - Registrar behaviour from above required - When the top Path-URI is an interface on the server with a flow token and a ;ob parameter set $du based on the decoded flow token - Attempt to bind to outbound module. If successful allow single-server Outbound, if unsuccessful maintain current behaviour * Kamailio core - EDGE server behaviour from above required * Kamailio configuration - When routing to a client using Outbound fails catch this in a failure_route[] and re-route to the next contact based on reg-id using lookup_next_dest() [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. Token/connection map maintenance -------------------------------- A map of flow tokens to connections is not required. The flow token is calculated from the source address, port, and protocol and these can be recovered from the flow token. Example: registration via Outbound EDGE server - forced Outbound (from Inaki) ----------------------------------------------------------------------------- Full trace available at: https://gist.github.com/3517204 T 2012/08/29 20:53:09.645476 CLIENT_PUBLIC_IP:44221 -> EDGE_PROXY_IP:5060 [AP] REGISTER sip:aliax.net SIP/2.0 Via: SIP/2.0/TCP CLIENT_PRIVATE_IP:5060;rport;branch=z9hG4bKoifvnizs Max-Forwards: 70 To: "IBC" From: "IBC" ;tag=ekrjn Call-ID: eebhtzmdmzvfhzz@ibc-HP-620 CSeq: 521 REGISTER Contact: ;expires=3600 Allow: INVITE,ACK,BYE,CANCEL,OPTIONS,PRACK,REFER,NOTIFY,SUBSCRIBE,INFO,MESSAGE User-Agent: Twinkle/1.4.2 Content-Length: 0 U 2012/08/29 20:53:09.646749 EDGE_PROXY_IP:5060 -> REGISTRAR_IP:5062 REGISTER sip:aliax.net SIP/2.0 Path: Path: Via: SIP/2.0/UDP EDGE_PROXY_IP:5060;branch=z9hG4bKc139c42ff0b28f6b1b5f632f5... Via: SIP/2.0/TCP CLIENT_PRIVATE_IP:5060;branch=z9hG4bKoifvnizs;received=CLI... Max-Forwards: 10 To: "IBC" From: "IBC" ;tag=ekrjn Call-ID: eebhtzmdmzvfhzz@ibc-HP-620 CSeq: 521 REGISTER Contact: ;expires=3600 Allow: INVITE,ACK,BYE,CANCEL,OPTIONS,PRACK,REFER,NOTIFY,SUBSCRIBE,INFO,MESSAGE User-Agent: Twinkle/1.4.2 Content-Length: 0 U 2012/08/29 20:53:09.689407 REGISTRAR_IP:5062 -> EDGE_PROXY_IP:5060 SIP/2.0 401 Unauthorized Via: SIP/2.0/UDP EDGE_PROXY_IP:5060;branch=z9hG4bKc139c42ff0b28f6b1b5f632f5... Via: SIP/2.0/TCP CLIENT_PRIVATE_IP:5060;branch=z9hG4bKoifvnizs;received=CLI... To: "IBC" ;tag=79b60ccc0e144bee60eb097fa92de92d.e619 From: "IBC" ;tag=ekrjn Call-ID: eebhtzmdmzvfhzz@ibc-HP-620 CSeq: 521 REGISTER WWW-Authenticate: Digest realm="aliax.net", nonce="503e65290000017577cbf7c4... Server: Kamailio (1.6.0-dev0-notls (x86_64/linux)) Content-Length: 0 T 2012/08/29 20:53:09.689867 EDGE_PROXY_IP:5060 -> CLIENT_PUBLIC_IP:44221 [AP] SIP/2.0 401 Unauthorized Via: SIP/2.0/TCP CLIENT_PRIVATE_IP:5060;branch=z9hG4bKoifvnizs;received=CLI... To: "IBC" ;tag=79b60ccc0e144bee60eb097fa92de92d.e619 From: "IBC" ;tag=ekrjn Call-ID: eebhtzmdmzvfhzz@ibc-HP-620 CSeq: 521 REGISTER WWW-Authenticate: Digest realm="aliax.net", nonce="503e65290000017577cbf7c4... Server: Kamailio (1.6.0-dev0-notls (x86_64/linux)) Content-Length: 0 Other useful flow examples: http://tools.ietf.org/html/draft-ietf-sipcore-sip-websocket#section-8