src/modules/outbound/doc/outbound_admin.xml
82de81e6
 <?xml version="1.0" encoding='ISO-8859-1'?>
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
 "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
 
 <!-- Include general documentation entities -->
6deb5fcf
 <!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
82de81e6
 %docentities;
 
 ]>
 <!-- Module User's Guide -->
 
 <chapter>
ad2341ab
 
82de81e6
 	<title>&adminguide;</title>
ad2341ab
 
82de81e6
 	<section>
 	<title>Overview</title>
4a418276
 	<para>This module provides C-API functions to enable &kamailio; to be
a84dee56
 	used as an outbound Edge Proxy (see &rfc5626; section 5).</para>
86f1b1c1
 	<para>The <emphasis>path</emphasis> and <emphasis>rr</emphasis> modules will
4a418276
 	bind to this module if it is loaded before they are.</para>
 	<section>
 		<title>Edge Proxy Keep-Alives (STUN)</title>
 		<para>Outbound Edge Proxies MUST support STUN NAT keep-alives
e090a714
 		on their SIP UDP ports. &kamailio; supports this though the
 		<quote>stun</quote> module.</para>
4a418276
 	</section>
 	<section>
 		<title>Flow Timer</title>
 		<para>The maximum interval at which a User Agent must send a
 		keep-alive may be specified by the Registrar using the
 		Flow-Timer: header in 2xx responses to REGISTERs.</para>
 		<para>When using TCP or TLS as the SIP transport care should
 		be taken to set the <quote>tcp_connection_lifetime</quote>
 		on the Edge Proxy to a value slightly larger than the interval
 		the Registrar is using for flow timer. Setting
 		<quote>tcp_connection_lifetime</quote> to less than the
 		interval could cause connections to be lost, and setting it
 		to a value much larger than the interval will keep connections
 		open far longer than is required (which is wasteful).</para>
 		<para>Application-layer keep-alives are optional when the
 		underlying transport already has a keep-alive mechanism. The
 		WebSocket transport has a transport-layer keep-alive. When
 		using the WebSocket transport the
 		<quote>keepalive_timeout</quote> should be set to a value
 		a little greater than the Registrar flow timer interval and a
 		little less than the <quote>tcp_connection_lifetime</quote>.
 		</para>
 	</section>
 	<example>
 	<title>Edge Proxy Configuration</title>
 	<programlisting><![CDATA[
60953cd8
 #!KAMAILIO
 #
 # Edge proxy configuration
 #
 
 #!subst "/REGISTRAR_IP/192.168.122.3/"
 #!subst "/REGISTRAR_PORT/5060/"
 #!substdef "/FLOW_TIMER/20/"
 
 ####### Global Parameters #########
 
 debug=2
 log_stderror=no
 log_facility=LOG_LOCAL0
 fork=yes
 children=4
 alias="example.com"
 mpath="/usr/lib64/kamailio/modules"
 tcp_connection_lifetime=30 # FLOW_TIMER + 10
cf908dc5
 force_rport=yes
60953cd8
 
 
 ####### Modules Section ########
 
 loadmodule "tm.so"
 loadmodule "sl.so"
4a418276
 loadmodule "outbound.so"
 loadmodule "rr.so"
 loadmodule "path.so"
60953cd8
 loadmodule "pv.so"
 loadmodule "maxfwd.so"
 loadmodule "xlog.so"
 loadmodule "sanity.so"
 loadmodule "ctl.so"
 loadmodule "textops.so"
 loadmodule "siputils.so"
030d591a
 loadmodule "stun.so"
60953cd8
 
 # ----------------- setting module-specific parameters ---------------
 
 # ----- tm params -----
 modparam("tm", "failure_reply_mode", 3)
 
 # ----- rr params -----
 modparam("rr", "append_fromtag", 0)
 
 
 ####### Routing Logic ########
 
 request_route {
9f636841
 	route(REQINIT);
60953cd8
 
 	if (is_method("CANCEL")) {
 		if (t_check_trans()) {
 			route(RELAY);
 		}
 		exit;
 	}
 
 	route(WITHINDLG);
 
9f636841
 	t_check_trans();
 
60953cd8
 	if (is_method("REGISTER")) {
 		remove_hf("Route");
 		add_path();
 		$du = "sip:REGISTRAR_IP:REGISTRAR_PORT";
 	} else {
 		if (is_method("INVITE|SUBSCRIBE"))
 			record_route();
9f636841
 
cf908dc5
 		if (@via[2] == "") {
 			# From client so route to registrar...
 
 			if ($rU == $null) {
 				sl_send_reply("484", "Address Incomplete");
 				exit;
 			}
 			remove_hf("Route");
 			$du = "sip:REGISTRAR_IP:REGISTRAR_PORT";
 		} else {
 			# From registrar so route using "Route:" headers...
 
60953cd8
 			if (!loose_route()) {
 				switch($rc) {
 				case -2:
 					sl_send_reply("403", "Forbidden");
 					exit;
 				default:
cf908dc5
 					xlog("L_ERR", "in request_route\n");
60953cd8
 					sl_reply_error();
 					exit;
 				}
 			}
9f636841
 
60953cd8
 			t_on_failure("FAIL_OUTBOUND");
9f636841
 		}
 	}
60953cd8
 
 	route(RELAY);
9f636841
 }
 
 route[RELAY] {
 	if (!t_relay()) {
60953cd8
 		sl_reply_error();
9f636841
 	}
 	exit;
 }
60953cd8
 
 route[REQINIT] {
 	if (!mf_process_maxfwd_header("10")) {
 		sl_send_reply("483","Too Many Hops");
 		exit;
 	}
 
 	if(!sanity_check("1511", "7"))
 	{
 		xlog("Malformed SIP message from $si:$sp\n");
 		exit;
 	}
 }
 
9f636841
 route[WITHINDLG] {
 	if (has_totag()) {
 		if (!loose_route()) {
 			switch($rc) {
 			case -2:
 				sl_send_reply("403", "Forbidden");
 				exit;
60953cd8
 			default:
9f636841
 				if (is_method("ACK")) {
60953cd8
 					if ( t_check_trans() ) {
 						route(RELAY);
9f636841
 						exit;
 					} else {
 						exit;
 					}
 				}
60953cd8
 				sl_send_reply("404","Not Found");
9f636841
 			}
 		} else {
60953cd8
 			if (is_method("NOTIFY")) {
 				record_route();
 			}
9f636841
 			route(RELAY);
 		}
 		exit;
 	}
a117147b
 }
60953cd8
 
a117147b
 onreply_route {
 	if (!t_check_trans()) {
 		drop;
 	}
 
60953cd8
 	if ($rm == "REGISTER" && $rs >= 200 && $rs <= 299) {
 		remove_hf("Flow-Timer");
a117147b
 		if ($(hdr(Require)[*])=~"outbound")
 			insert_hf("Flow-Timer: FLOW_TIMER\r\n", "Call-ID");
 	}
 }
9f636841
 
cf908dc5
 failure_route[FAIL_OUTBOUND] {
9f636841
 	if (t_branch_timeout() || !t_branch_replied()) {
 		send_reply("430", "Flow Failed");
 	}
 }
4a418276
 ]]></programlisting>
 	</example>
 	<example>
 	<title>Registrar Configuration</title>
 	<programlisting><![CDATA[
cf908dc5
 MAILIO
 #
 # Registrar configuration
 #
 
 
 ####### Global Parameters #########
 
 debug=2
 log_stderror=no
 log_facility=LOG_LOCAL0
 fork=yes
 children=4
 alias="example.com"
 mpath="/usr/lib64/kamailio/modules"
 
 
 ####### Modules Section ########
 
82303dfa
 loadmodule "tm.so"
cf908dc5
 loadmodule "tmx.so"
 loadmodule "sl.so"
 loadmodule "rr.so"
 loadmodule "pv.so"
 loadmodule "maxfwd.so"
 loadmodule "xlog.so"
 loadmodule "sanity.so"
 loadmodule "ctl.so"
 loadmodule "textops.so"
 loadmodule "siputils.so"
 loadmodule "usrloc.so"
4a418276
 loadmodule "registrar.so"
cf908dc5
 
 # ----------------- setting module-specific parameters ---------------
 
 
 # ----- tm params -----
 modparam("tm", "failure_reply_mode", 3)
 modparam("tm", "restart_fr_on_each_reply", 0)
82303dfa
 modparam("tm", "contact_flows_avp", "tm_contact_flows")
cf908dc5
 modparam("tm", "contacts_avp", "tm_contacts")
 
 # ----- rr params -----
 modparam("rr", "append_fromtag", 0)
 
 # ----- registrar params -----
82303dfa
 modparam("registrar", "use_path", 1)
cf908dc5
 modparam("registrar", "gruu_enabled", 1)
 modparam("registrar", "outbound_mode", 1)
 
 
 ####### Routing Logic ########
 
 request_route {
 	route(REQINIT);
 
 	if (is_method("CANCEL")) {
 		if (t_check_trans()) {
 			route(RELAY);
 		}
 		exit;
 	}
 
 	route(WITHINDLG);
 
 	t_check_trans();
 
 	remove_hf("Route");
 	if (is_method("INVITE|SUBSCRIBE"))
 		record_route();
 
 	route(REGISTRAR);
 
 	if ($rU==$null) {
 		xlog("L_INFO", "Address Incomplete\n");
 		send_reply("484","Address Incomplete");
 		exit;
 	}
 
 	route(LOCATION);
 }
 
 
 route[RELAY] {
 	if (!t_relay()) {
 		xlog("L_ERR", "t_relay() failed\n");
 		sl_reply_error();
 	}
 	exit;
 }
 
 route[REQINIT] {
 	if (!mf_process_maxfwd_header("10")) {
 		xlog("L_INFO", "Too Many Hops\n");
 		send_reply("483","Too Many Hops");
 		exit;
 	}
 
 	if(!sanity_check("1511", "7"))
 	{
 		xlog("Malformed SIP message from $si:$sp\n");
 		exit;
 	}
 }
 
 route[WITHINDLG] {
 	if (has_totag()) {
 		if (loose_route()) {
 			if (is_method("NOTIFY")) {
 				record_route();
 			}
 			route(RELAY);
 		} else {
 			if (is_method("ACK")) {
 				if (t_check_trans()) {
 					route(RELAY);
 					exit;
 				} else {
 					exit;
 				}
 			}
 			xlog("L_INFO", "Not Found");
 			send_reply("404","Not Found");
 		}
 		exit;
 	}
 }
 
 route[REGISTRAR] {
 	if (is_method("REGISTER"))
 	{
 		if (!save("location")) {
 			xlog("L_ERR", "Unable to save location\n");
 			sl_reply_error();
 		}
 		exit;
 	}
 }
 
82303dfa
 route[LOCATION] {
 	if (!lookup("location")) {
 		$var(rc) = $rc;
 		t_newtran();
 		switch ($var(rc)) {
 			case -1:
 			case -3:
 				send_reply("404", "Not Found");
 				exit;
 			case -2:
 				send_reply("405", "Method Not Allowed");
 				exit;
 		}
 	}
 
cf908dc5
 	if (!t_load_contacts() || !t_next_contacts()) {
 		xlog("L_ERR", "t_(load|next)_contacts() failed\n");
 		sl_reply_error();
82303dfa
 		exit;
 	}
 
cf908dc5
 	t_on_failure("FAIL_TRANSACTION");
 	t_on_branch_failure("FAIL-BRANCH");
 	route(RELAY);
 	exit;
 }
82303dfa
 
cf908dc5
 onreply_route {
 	if (!t_check_trans()) {
 		drop;
 	}
82303dfa
 }
cf908dc5
 
 failure_route[FAIL_TRANSACTION] {
 	if (!t_check_status("6[0-9][0-9]")) {
 		if (t_next_contacts()) {
 			t_relay();
82303dfa
 			exit;
 		}
cf908dc5
 	}
 
 	if (t_check_status("430")) {
 		t_reply("480", "Temporarily Unavailable");
82303dfa
 		exit;
 	}
cf908dc5
 }
82303dfa
 
cf908dc5
 event_route[tm:branch-failure:FAIL-BRANCH] {
 	if (t_check_status("403|430")
 			|| (t_branch_timeout() && !t_branch_replied())) {
 		unregister("location", "$tu", "$T_reply_ruid");
 
 		if (t_next_contact_flow()) {
 			t_on_branch_failure("FAIL-BRANCH");
 			t_relay();
 		}
 	}
82303dfa
 }
4a418276
 ]]></programlisting>
 	</example>
82de81e6
 	</section>
 
 	<section>
 	<title>Dependencies</title>
 	<section>
 		<title>&kamailio; Modules</title>
4a418276
 		<para>
 		The following modules must be loaded before this module:
 		<itemizedlist>
 		<listitem>
 		<para><emphasis>None</emphasis></para>
 		</listitem>
 		</itemizedlist>
 		</para>
20438793
 		<para>
 		The following modules are required to make proper use of this
 		module:
 		<itemizedlist>
 		<listitem>
 		<para><emphasis>stun</emphasis>.</para>
 		</listitem>
 		</itemizedlist>
 		</para>
82de81e6
 	</section>
 
 	<section>
 		<title>External Libraries or Applications</title>
 		<para>
 		The following libraries must be installed before running
 		&kamailio; with this module loaded:
 		<itemizedlist>
 		<listitem>
a84dee56
 		<para><emphasis>&openssl;</emphasis>.</para>
82de81e6
 		</listitem>
 		</itemizedlist>
 		</para>
 	</section>
 	</section>
 
 
 	<section>
 	<title>Parameters</title>
4a418276
 	<section>
a117147b
 		<title><varname>force_outbound_flag</varname> (integer)</title>
 		<para>A flag which, if set for a request, will force
4a418276
 		<emphasis>path</emphasis> and <emphasis>rr</emphasis> to add
 		flow tokens to Path: and Record-Route: headers regardless of
 		the request contents.</para>
 		<para><emphasis>Default value is -1.</emphasis></para>
 		<example>
a117147b
 		<title>Set <varname>force_outbound_flag</varname> parameter
4a418276
 		</title>
 		<programlisting format="linespecific">
66560d5a
 ...
a117147b
 modparam("outbound", "force_outbound_flag", 1)
66560d5a
 ...
4a418276
 </programlisting>
 		</example>
 	</section>
744a8d31
 
 	<section>
 		<title><varname>force_no_outbound_flag</varname> (integer)</title>
 		<para>A flag which, if set for a request, will force
 		<emphasis>path</emphasis> and <emphasis>rr</emphasis> not
 		to add flow tokens to Path: and Record-Route: headers
 		regardless of the request contents.</para>
 		<para><emphasis>Default value is -1.</emphasis></para>
 		<example>
 		<title>Set <varname>force_no_outbound_flag</varname> parameter
 		</title>
 		<programlisting format="linespecific">
 ...
 modparam("outbound", "force_no_outbound_flag", 2)
 ...
 </programlisting>
 		</example>
 	</section>
 
ca887b6d
 	<section>
 		<title><varname>flow_token_secret</varname> (string)</title>
 		<para>
 			Secret phrase used to calculate the outbound key value
 			used for flow tokens validation.
 			Allows to set persistent outbound key.
 		</para>
 		<para>
 			If not specified, <emphasis>outbound</emphasis> will use randomly generated outbound key
 		</para>
 		<example>
 			<title>
 				Set <varname>flow_token_secret</varname> parameter
 			</title>
 			<programlisting format="linespecific">
 ...
 modparam("outbound", "flow_token_secret", "johndoessecretphrase")
 ...
 			</programlisting>
 		</example>
 	</section>
 
82de81e6
 	</section>
 
 </chapter>