Browse Source

modules/rtpproxy: Add 'b' flag to add a branch specific string tot the call-id

In a forking call, sometimes it is needed that each branch uses different
options to the rtpproxy. This patch adds a parameter that makes each
rtpproxy session unique to a branch by appending the value of a PV to the
call-id rtpproxy parameter.
Alex Hermann 13 năm trước cách đây
mục cha
commit
a2d09db983
3 tập tin đã thay đổi với 168 bổ sung48 xóa
  1. 77 46
      modules/rtpproxy/README
  2. 37 0
      modules/rtpproxy/doc/rtpproxy_admin.xml
  3. 54 2
      modules/rtpproxy/rtpproxy.c

+ 77 - 46
modules/rtpproxy/README

@@ -30,13 +30,13 @@ Carsten Bock
 
    ng-voice GmbH
 
-   Copyright © 2003-2008 Sippy Software, Inc.
+   Copyright (c) 2003-2008 Sippy Software, Inc.
 
-   Copyright © 2005 Voice Sistem SRL
+   Copyright (c) 2005 Voice Sistem SRL
 
-   Copyright © 2009-2012 TuTPro Inc.
+   Copyright (c) 2009-2012 TuTPro Inc.
 
-   Copyright © 2010 VoIPEmbedded Inc.
+   Copyright (c) 2010 VoIPEmbedded Inc.
      __________________________________________________________________
 
    Table of Contents
@@ -59,6 +59,7 @@ Carsten Bock
               4.5. nortpproxy_str (string)
               4.6. timeout_socket (string)
               4.7. ice_candidate_priority_avp (string)
+              4.8. extra_id_pv (string)
 
         5. Functions
 
@@ -94,16 +95,17 @@ Carsten Bock
    1.5. Set nortpproxy_str parameter
    1.6. Set timeout_socket parameter
    1.7. Set ice_candidate_priority_avp parameter
-   1.8. set_rtp_proxy_set usage
-   1.9. rtpproxy_offer usage
-   1.10. rtpproxy_answer usage
-   1.11. rtpproxy_destroy usage
-   1.12. rtpproxy_manage usage
-   1.13. rtpproxy_stream2xxx usage
-   1.14. start_recording usage
-   1.15. $rtpstat-Usage
-   1.16. nh_enable_rtpp usage
-   1.17. nh_show_rtpp usage
+   1.8. Set extra_id_pv parameter
+   1.9. set_rtp_proxy_set usage
+   1.10. rtpproxy_offer usage
+   1.11. rtpproxy_answer usage
+   1.12. rtpproxy_destroy usage
+   1.13. rtpproxy_manage usage
+   1.14. rtpproxy_stream2xxx usage
+   1.15. start_recording usage
+   1.16. $rtpstat-Usage
+   1.17. nh_enable_rtpp usage
+   1.18. nh_show_rtpp usage
 
 Chapter 1. Admin Guide
 
@@ -125,6 +127,7 @@ Chapter 1. Admin Guide
         4.5. nortpproxy_str (string)
         4.6. timeout_socket (string)
         4.7. ice_candidate_priority_avp (string)
+        4.8. extra_id_pv (string)
 
    5. Functions
 
@@ -166,7 +169,7 @@ Chapter 1. Admin Guide
    The module allows definition of several sets of rtpproxies.
    Load-balancing will be performed over a set and the admin has the
    ability to choose what set should be used. The set is selected via its
-   id - the id being defined with the set. Refer to the “rtpproxy_sock”
+   id - the id being defined with the set. Refer to the "rtpproxy_sock"
    module parameter definition for syntax description.
 
    The balancing inside a set is done automatically by the module based on
@@ -209,13 +212,14 @@ Chapter 1. Admin Guide
    4.5. nortpproxy_str (string)
    4.6. timeout_socket (string)
    4.7. ice_candidate_priority_avp (string)
+   4.8. extra_id_pv (string)
 
 4.1. rtpproxy_sock (string)
 
    Definition of socket(s) used to connect to (a set) RTPProxy. It may
    specify a UNIX socket or an IPv4/IPv6 UDP socket.
 
-   Default value is “NONE” (disabled).
+   Default value is "NONE" (disabled).
 
    Example 1.1. Set rtpproxy_sock parameter
 ...
@@ -237,7 +241,7 @@ modparam("rtpproxy", "rtpproxy_sock",
    rtpproxy module will not attempt to establish communication to RTPProxy
    for rtpproxy_disable_tout seconds.
 
-   Default value is “60”.
+   Default value is "60".
 
    Example 1.2. Set rtpproxy_disable_tout parameter
 ...
@@ -248,7 +252,7 @@ modparam("rtpproxy", "rtpproxy_disable_tout", 20)
 
    Timeout value in waiting for reply from RTPProxy.
 
-   Default value is “1”.
+   Default value is "1".
 
    Example 1.3. Set rtpproxy_tout parameter
 ...
@@ -260,7 +264,7 @@ modparam("rtpproxy", "rtpproxy_tout", 2)
    How many times the module should retry to send and receive after
    timeout was generated.
 
-   Default value is “5”.
+   Default value is "5".
 
    Example 1.4. Set rtpproxy_retr parameter
 ...
@@ -279,7 +283,7 @@ Note
 
    The string must be a complete SDP line, including the EOH (\r\n).
 
-   Default value is “a=nortpproxy:yes\r\n”.
+   Default value is "a=nortpproxy:yes\r\n".
 
    Example 1.5. Set nortpproxy_str parameter
 ...
@@ -295,7 +299,7 @@ modparam("rtpproxy", "nortpproxy_str", "a=sdpmangled:yes\r\n")
    If it is an empty string, no timeout socket will be transmitted to the
    RTP-Proxy.
 
-   Default value is “” (nothing).
+   Default value is "" (nothing).
 
    Example 1.6. Set timeout_socket parameter
 ...
@@ -319,6 +323,19 @@ modparam("nathelper", "timeout_socket", "xmlrpc:http://127.0.0.1:8000/RPC2")
 modparam("rtpproxy", "ice_candidate_priority_avp", "$avp(ice_priority)")
 ...
 
+4.8. extra_id_pv (string)
+
+   The parameter sets the PV defination to use when the "b" parameter is
+   used on unforce_rtp_proxy(), rtpproxy_offer(), rtpproxy_answer() or
+   rtpproxy_manage() command.
+
+   Default is empty, the "b" parameter may not be used then.
+
+   Example 1.8. Set extra_id_pv parameter
+...
+modparam("rtpproxy", "extra_id_pv", "$avp(extra_id)")
+...
+
 5. Functions
 
    5.1. set_rtp_proxy_set(setid)
@@ -343,7 +360,7 @@ modparam("rtpproxy", "ice_candidate_priority_avp", "$avp(ice_priority)")
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
    BRANCH_ROUTE.
 
-   Example 1.8. set_rtp_proxy_set usage
+   Example 1.9. set_rtp_proxy_set usage
 ...
 set_rtp_proxy_set("2");
 rtpproxy_offer();
@@ -359,16 +376,16 @@ rtpproxy_offer();
      * flags - flags to turn on some features.
           + 1 - append first Via branch to Call-ID when sending command to
             rtpproxy. This can be used to create one media session per
-            branch on the rtpproxy. When sending a subsequent “delete”
+            branch on the rtpproxy. When sending a subsequent "delete"
             command to the rtpproxy, you can then stop just the session
             for a specific branch when passing the flag '1' or '2' in the
-            “unforce_rtpproxy”, or stop all sessions for a call when not
+            "unforce_rtpproxy", or stop all sessions for a call when not
             passing one of those two flags there. This is especially
             useful if you have serially forked call scenarios where
-            rtpproxy gets an “update” command for a new branch, and then a
-            “delete” command for the previous branch, which would
+            rtpproxy gets an "update" command for a new branch, and then a
+            "delete" command for the previous branch, which would
             otherwise delete the full call, breaking the subsequent
-            “lookup” for the new branch. This flag is only supported by
+            "lookup" for the new branch. This flag is only supported by
             the ngcp-mediaproxy-ng rtpproxy at the moment!
           + 2 - append second Via branch to Call-ID when sending command
             to rtpproxy. See flag '1' for its meaning.
@@ -376,7 +393,18 @@ rtpproxy_offer();
             set for a reply.
           + a - flags that UA from which message is received doesn't
             support symmetric RTP. (automatically sets the 'r' flag)
-          + l - force “lookup”, that is, only rewrite SDP when
+          + b - append branch specific variable to Call-ID when sending
+            command to rtpproxy. This creates one rtpproxy session per
+            unique variable. Works similar to the 1, 2 and 3 parameter,
+            but is usefull when forking to multiple destinations on
+            different address families or network segments, requiring
+            different rtpproxy parameters. The variable value is taken
+            from the "extra_id_pv". When used, it must be used in every
+            call to rtpproxy_manage(), rtpproxy_offer(), rtpproxy_answer()
+            and rtpproxy_destroy() with the same contents of the PV. The b
+            parameter may not be used in conjunction with the 1, 2 or 3
+            parameter to use the Via branch in the Call-ID.
+          + l - force "lookup", that is, only rewrite SDP when
             corresponding session already exists in the RTP proxy. By
             default is on when the session is to be completed.
           + i, e - these flags specify the direction of the SIP message.
@@ -437,7 +465,7 @@ rtpproxy_offer();
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.9. rtpproxy_offer usage
+   Example 1.10. rtpproxy_offer usage
 route {
 ...
     if (is_method("INVITE")) {
@@ -481,7 +509,7 @@ onreply_route[2]
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
    FAILURE_ROUTE, BRANCH_ROUTE.
 
-   Example 1.10. rtpproxy_answer usage
+   Example 1.11. rtpproxy_answer usage
 
    See rtpproxy_offer() function example above for example.
 
@@ -495,25 +523,28 @@ onreply_route[2]
      * flags - flags to turn on some features.
           + 1 - append first Via branch to Call-ID when sending command to
             rtpproxy. This can be used to create one media session per
-            branch on the rtpproxy. When sending a subsequent “delete”
+            branch on the rtpproxy. When sending a subsequent "delete"
             command to the rtpproxy, you can then stop just the session
             for a specific branch when passing the flag '1' or '2' in the
-            “unforce_rtpproxy”, or stop all sessions for a call when not
+            "unforce_rtpproxy", or stop all sessions for a call when not
             passing one of those two flags there. This is especially
             useful if you have serially forked call scenarios where
-            rtpproxy gets an “update” command for a new branch, and then a
-            “delete” command for the previous branch, which would
+            rtpproxy gets an "update" command for a new branch, and then a
+            "delete" command for the previous branch, which would
             otherwise delete the full call, breaking the subsequent
-            “lookup” for the new branch. This flag is only supported by
+            "lookup" for the new branch. This flag is only supported by
             the ngcp-mediaproxy-ng rtpproxy at the moment!
           + 2 - append second Via branch to Call-ID when sending command
             to rtpproxy. See flag '1' for its meaning.
-          + t - do not include To tag to “delete” command to rtpproxy thus
+          + b - append branch number to Call-ID when sending command to
+            rtpproxy. <listitem>
+            </listitem>
+            t - do not include To tag to "delete" command to rtpproxy thus
             causing full call to be deleted. Useful for deleting unused
             rtpproxy call when 200 OK is received on a branch, where
             rtpproxy is not needed.
 
-   Example 1.11. rtpproxy_destroy usage
+   Example 1.12. rtpproxy_destroy usage
 ...
 rtpproxy_destroy();
 ...
@@ -545,7 +576,7 @@ rtpproxy_destroy();
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.12. rtpproxy_manage usage
+   Example 1.13. rtpproxy_manage usage
 ...
 rtpproxy_manage();
 ...
@@ -581,7 +612,7 @@ rtpproxy_manage();
        -1 means that it will be streaming in a loop indefinitely, until
        the appropriate rtpproxy_stop_stream2xxx is issued.
 
-   Example 1.13. rtpproxy_stream2xxx usage
+   Example 1.14. rtpproxy_stream2xxx usage
 ...
     if (is_method("INVITE")) {
         rtpproxy_offer();
@@ -614,7 +645,7 @@ rtpproxy_manage();
 
    This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE.
 
-   Example 1.14. start_recording usage
+   Example 1.15. start_recording usage
 ...
 start_recording();
 ...
@@ -634,7 +665,7 @@ start_recording();
    packet-counters. The statistics must be retrieved before the session is
    deleted (before unforce_rtpproxy()).
 
-   Example 1.15. $rtpstat-Usage
+   Example 1.16. $rtpstat-Usage
 ...
     append_hf("X-RTP-Statistics: $rtpstat\r\n");
 ...
@@ -657,7 +688,7 @@ start_recording();
    NOTE: if a rtpproxy is defined multiple times (in the same or diferente
    sete), all of its instances will be enables/disabled.
 
-   Example 1.16.  nh_enable_rtpp usage
+   Example 1.17.  nh_enable_rtpp usage
 ...
 $ kamctl fifo nh_enable_rtpp udp:192.168.2.133:8081 0
 ...
@@ -669,23 +700,23 @@ $ kamctl fifo nh_enable_rtpp udp:192.168.2.133:8081 0
 
    No parameter.
 
-   Example 1.17.  nh_show_rtpp usage
+   Example 1.18.  nh_show_rtpp usage
 ...
 $ kamctl fifo nh_show_rtpp
 ...
 
 Chapter 2. Frequently Asked Questions
 
-   2.1. What happend with “rtpproxy_disable” parameter?
+   2.1. What happend with "rtpproxy_disable" parameter?
    2.2. Where can I find more about Kamailio?
    2.3. Where can I post a question about this module?
    2.4. How can I report a bug?
 
    2.1.
 
-       What happend with “rtpproxy_disable” parameter?
+       What happend with "rtpproxy_disable" parameter?
 
-       It was removed as it became obsolete - now “rtpproxy_sock” can take
+       It was removed as it became obsolete - now "rtpproxy_sock" can take
        empty value to disable the rtpproxy functionality.
 
    2.2.

+ 37 - 0
modules/rtpproxy/doc/rtpproxy_admin.xml

@@ -260,6 +260,24 @@ modparam("nathelper", "timeout_socket", "xmlrpc:http://127.0.0.1:8000/RPC2")
 ...
 modparam("rtpproxy", "ice_candidate_priority_avp", "$avp(ice_priority)")
 ...
+</programlisting>
+		</example>
+	</section>
+	<section>
+		<title><varname>extra_id_pv</varname> (string)</title>
+		<para>
+			The parameter sets the PV defination to use when the <quote>b</quote>
+			parameter is used on unforce_rtp_proxy(), rtpproxy_offer(),
+			rtpproxy_answer() or rtpproxy_manage() command.
+		</para><para>
+			Default is empty, the <quote>b</quote> parameter may not be used then.
+		</para>
+		<example>
+		<title>Set <varname>extra_id_pv</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("rtpproxy", "extra_id_pv", "$avp(extra_id)")
+...
 </programlisting>
 		</example>
 	</section>
@@ -335,6 +353,21 @@ rtpproxy_offer();
 				received doesn't support symmetric RTP. (automatically sets the 'r' flag)
 				</para></listitem>
 				<listitem><para>
+				<emphasis>b</emphasis> - append branch specific variable to Call-ID when sending
+				command to rtpproxy. This creates one rtpproxy session per unique variable.
+
+				Works similar to the 1, 2 and 3 parameter, but is usefull when forking to multiple
+				destinations on different address families or network segments, requiring different
+				rtpproxy parameters.
+
+				The variable value is taken from the <quote>extra_id_pv</quote>.
+
+				When used, it must be used in every call to rtpproxy_manage(), rtpproxy_offer(),
+				rtpproxy_answer() and rtpproxy_destroy() with the same contents of the PV.
+				The b parameter may not be used in conjunction with the 1, 2 or 3 parameter
+				to use the Via branch in the Call-ID.
+				</para></listitem>
+				<listitem><para>
 				<emphasis>l</emphasis> - force <quote>lookup</quote>, that is,
 				only rewrite SDP when corresponding session already exists
 				in the RTP proxy. By default is on when the session is to be
@@ -512,6 +545,10 @@ onreply_route[2]
 				command to rtpproxy. See flag '1' for its meaning.
 				</para></listitem>
 				<listitem><para>
+				<emphasis>b</emphasis> - append branch specific variable to Call-ID when sending
+				command to rtpproxy. See rtpproxy_offer() for details.
+				<listitem><para>
+				</para></listitem>
 				<emphasis>t</emphasis> - do not include To tag to <quote>delete</quote> command to rtpproxy thus causing full call to be deleted. Useful for deleting unused rtpproxy call when 200 OK is received on a branch, where rtpproxy is not needed.
 				</para></listitem>
 			</itemizedlist>

+ 54 - 2
modules/rtpproxy/rtpproxy.c

@@ -322,6 +322,7 @@ static int rtpproxy_tout = 1;
 static pid_t mypid;
 static unsigned int myseqn = 0;
 static str nortpproxy_str = str_init("a=nortpproxy:yes");
+static str extra_id_pv_param = {NULL, 0};
 
 static char ** rtpp_strings=0;
 static int rtpp_sets=0; /*used in rtpproxy_set_store()*/
@@ -352,6 +353,7 @@ static struct tm_binds tmb;
 unsigned int *natping_state=0;
 
 static str timeout_socket_str = {0, 0};
+static pv_elem_t *extra_id_pv = NULL;
 
 static cmd_export_t cmds[] = {
 	{"set_rtp_proxy_set",  (cmd_function)set_rtp_proxy_set_f,    1,
@@ -430,6 +432,7 @@ static param_export_t params[] = {
 	{"timeout_socket",    	  STR_PARAM, &timeout_socket_str.s  },
 	{"ice_candidate_priority_avp", STR_PARAM,
 	 &ice_candidate_priority_avp_param},
+	{"extra_id_pv",           STR_PARAM, &extra_id_pv_param.s },
 	{0, 0, 0}
 };
 
@@ -931,6 +934,16 @@ mod_init(void)
 	    ice_candidate_priority_avp_type = avp_flags;
 	}
 
+	if (extra_id_pv_param.s && *extra_id_pv_param.s) {
+		extra_id_pv_param.len = strlen(extra_id_pv_param.s);
+		if(pv_parse_format(&extra_id_pv_param, &extra_id_pv) < 0) {
+			LM_ERR("malformed PV string: %s\n", extra_id_pv_param.s);
+			return -1;
+		}
+	} else {
+		extra_id_pv = NULL;
+	}
+
 	if (rtpp_strings)
 		pkg_free(rtpp_strings);
 
@@ -1773,6 +1786,22 @@ found:
 	return node;
 }
 
+
+static int
+get_extra_id(struct sip_msg* msg, str *id_str) {
+	if(msg==NULL || extra_id_pv==NULL || id_str==NULL) {
+		LM_ERR("bad parameters\n");
+		return 0;
+	}
+	if (pv_printf_s(msg, extra_id_pv, id_str)<0) {
+		LM_ERR("cannot print the additional id\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+
 static int
 unforce_rtp_proxy_f(struct sip_msg* msg, char* flags, char* str2)
 {
@@ -1780,10 +1809,12 @@ unforce_rtp_proxy_f(struct sip_msg* msg, char* flags, char* str2)
 	char *cp;
 	int via = 0;
 	int to = 1;
+	int extra = 0;
+	str extra_id;
 	int ret;
 	struct rtpp_node *node;
 	struct iovec v[1 + 4 + 3 + 2] = {{NULL, 0}, {"D", 1}, {" ", 1}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {" ", 1}, {NULL, 0}, {" ", 1}, {NULL, 0}};
-						    /* 1 */   /* 2 */   /* 3 */    /* 4 */    /* 5 */    /* 6 */   /* 7 */    /* 8 */   /* 9 */
+	                                            /* 1 */   /* 2 */   /* 3 */    /* 4 */    /* 5 */    /* 6 */   /* 7 */    /* 8 */   /* 9 */
 
 	for (cp = flags; cp && *cp; cp++) {
 		switch (*cp) {
@@ -1806,6 +1837,9 @@ unforce_rtp_proxy_f(struct sip_msg* msg, char* flags, char* str2)
 		        case 'T':
 			    to = 0;
 			    break;
+			case 'b':
+				extra = 1;
+				break;
 			case 'a':
 			case 'A':
 			case 'i':
@@ -1863,6 +1897,12 @@ unforce_rtp_proxy_f(struct sip_msg* msg, char* flags, char* str2)
 		v[4].iov_base = ";";
 		v[4].iov_len = 1;
 		STR2IOVEC(viabranch, v[5]);
+	} else
+	/* Append extra id to call-id */
+	if (extra && extra_id_pv && get_extra_id(msg, &extra_id)) {
+		v[4].iov_base = ";";
+		v[4].iov_len = 1;
+		STR2IOVEC(extra_id, v[5]);
 	}
 	STR2IOVEC(callid, v[3]);
 	STR2IOVEC(from_tag, v[7]);
@@ -2140,6 +2180,8 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
 	};
 	int iovec_param_count;
 	int autobridge_ipv4v6;
+	int extra;
+	str extra_id;
 
 	char *c1p, *c2p, *bodylimit, *o1p;
 	char itoabuf_buf[20];
@@ -2161,7 +2203,7 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
 		LM_ERR("out of pkg memory\n");
 		FORCE_RTP_PROXY_RET (-1);
 	}
-	flookup = force = real = orgip = commip = via = autobridge_ipv4v6 = 0;
+	flookup = force = real = orgip = commip = via = autobridge_ipv4v6 = extra = 0;
 	for (cp = str1; cp != NULL && *cp != '\0'; cp++) {
 		switch (*cp) {
 		case '1':
@@ -2188,6 +2230,10 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
 			real = 1;
 			break;
 
+		case 'b':
+			extra = 1;
+			break;
+
 		case 'i':
 		case 'I':
 			if (append_opts(&opts, 'I') == -1) {
@@ -2308,6 +2354,12 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
 		v[6].iov_base = ";";
 		v[6].iov_len = 1;
 		STR2IOVEC(viabranch, v[7]);
+	} else
+	/* Append extra id to call-id */
+	if (extra && extra_id_pv && get_extra_id(msg, &extra_id)) {
+		v[6].iov_base = ";";
+		v[6].iov_len = 1;
+		STR2IOVEC(extra_id, v[7]);
 	}
 	if (flookup != 0) {
 		if (to_tag.len == 0) {