소스 검색

modules/rtpproxy: rtpproxy_manage can now add ice relay candidates

- The feature is activated by defining ice_candidate_priority_avp module
  parameter.
Juha Heinanen 12 년 전
부모
커밋
75fde552f1
3개의 변경된 파일250개의 추가작업 그리고 66개의 파일을 삭제
  1. 85 64
      modules/rtpproxy/README
  2. 28 0
      modules/rtpproxy/doc/rtpproxy_admin.xml
  3. 137 2
      modules/rtpproxy/rtpproxy.c

+ 85 - 64
modules/rtpproxy/README

@@ -30,13 +30,13 @@ Carsten Bock
 
    ng-voice GmbH
 
-   Copyright © 2003-2008 Sippy Software, Inc.
+   Copyright © 2003-2008 Sippy Software, Inc.
 
-   Copyright © 2005 Voice Sistem SRL
+   Copyright © 2005 Voice Sistem SRL
 
-   Copyright © 2009-2012 TuTPro Inc.
+   Copyright © 2009-2012 TuTPro Inc.
 
-   Copyright © 2010 VoIPEmbedded Inc.
+   Copyright © 2010 VoIPEmbedded Inc.
      __________________________________________________________________
 
    Table of Contents
@@ -58,6 +58,7 @@ Carsten Bock
               4.4. rtpproxy_retr (integer)
               4.5. nortpproxy_str (string)
               4.6. timeout_socket (string)
+              4.7. ice_candidate_priority_avp (string)
 
         5. Functions
 
@@ -92,16 +93,17 @@ Carsten Bock
    1.4. Set rtpproxy_retr parameter
    1.5. Set nortpproxy_str parameter
    1.6. Set timeout_socket parameter
-   1.7. set_rtp_proxy_set usage
-   1.8. rtpproxy_offer usage
-   1.9. rtpproxy_answer usage
-   1.10. rtpproxy_destroy usage
-   1.11. rtpproxy_manage usage
-   1.12. rtpproxy_stream2xxx usage
-   1.13. start_recording usage
-   1.14. $rtpstat-Usage
-   1.15. nh_enable_rtpp usage
-   1.16. nh_show_rtpp usage
+   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
 
 Chapter 1. Admin Guide
 
@@ -122,6 +124,7 @@ Chapter 1. Admin Guide
         4.4. rtpproxy_retr (integer)
         4.5. nortpproxy_str (string)
         4.6. timeout_socket (string)
+        4.7. ice_candidate_priority_avp (string)
 
    5. Functions
 
@@ -163,7 +166,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
@@ -205,13 +208,14 @@ Chapter 1. Admin Guide
    4.4. rtpproxy_retr (integer)
    4.5. nortpproxy_str (string)
    4.6. timeout_socket (string)
+   4.7. ice_candidate_priority_avp (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
 ...
@@ -233,7 +237,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
 ...
@@ -244,7 +248,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
 ...
@@ -256,7 +260,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
 ...
@@ -275,7 +279,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
 ...
@@ -291,13 +295,30 @@ 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
 ...
 modparam("nathelper", "timeout_socket", "xmlrpc:http://127.0.0.1:8000/RPC2")
 ...
 
+4.7. ice_candidate_priority_avp (string)
+
+   If specified and if value of the avp value is not 0, rtpproxy_manage
+   function adds ICE relay candidate attributes to sdp stream(s)
+   containing ICE candidate attributes.
+
+   If value of the avp is 1, added candidates have high priority. If value
+   of the avp is 2 (default), added candidates have low priority.
+
+   There is no default value meaning that no ICE relay candidates are
+   added in any circumstance.
+
+   Example 1.7. Set ice_candidate_priority_avp parameter
+...
+modparam("rtpproxy", "ice_candidate_priority_avp", "$avp(ice_priority)")
+...
+
 5. Functions
 
    5.1. set_rtp_proxy_set(setid)
@@ -322,7 +343,7 @@ modparam("nathelper", "timeout_socket", "xmlrpc:http://127.0.0.1:8000/RPC2")
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
    BRANCH_ROUTE.
 
-   Example 1.7. set_rtp_proxy_set usage
+   Example 1.8. set_rtp_proxy_set usage
 ...
 set_rtp_proxy_set("2");
 rtpproxy_offer();
@@ -338,16 +359,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.
@@ -355,7 +376,7 @@ 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
+          + 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.
@@ -416,7 +437,7 @@ rtpproxy_offer();
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.8. rtpproxy_offer usage
+   Example 1.9. rtpproxy_offer usage
 route {
 ...
     if (is_method("INVITE")) {
@@ -460,7 +481,7 @@ onreply_route[2]
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
    FAILURE_ROUTE, BRANCH_ROUTE.
 
-   Example 1.9. rtpproxy_answer usage
+   Example 1.10. rtpproxy_answer usage
 
    See rtpproxy_offer() function example above for example.
 
@@ -474,25 +495,25 @@ 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
+          + 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.10. rtpproxy_destroy usage
+   Example 1.11. rtpproxy_destroy usage
 ...
 rtpproxy_destroy();
 ...
@@ -524,7 +545,7 @@ rtpproxy_destroy();
 
    This function can be used from ANY_ROUTE.
 
-   Example 1.11. rtpproxy_manage usage
+   Example 1.12. rtpproxy_manage usage
 ...
 rtpproxy_manage();
 ...
@@ -560,7 +581,7 @@ rtpproxy_manage();
        -1 means that it will be streaming in a loop indefinitely, until
        the appropriate rtpproxy_stop_stream2xxx is issued.
 
-   Example 1.12. rtpproxy_stream2xxx usage
+   Example 1.13. rtpproxy_stream2xxx usage
 ...
     if (is_method("INVITE")) {
         rtpproxy_offer();
@@ -593,7 +614,7 @@ rtpproxy_manage();
 
    This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE.
 
-   Example 1.13. start_recording usage
+   Example 1.14. start_recording usage
 ...
 start_recording();
 ...
@@ -613,7 +634,7 @@ start_recording();
    packet-counters. The statistics must be retrieved before the session is
    deleted (before unforce_rtpproxy()).
 
-   Example 1.14. $rtpstat-Usage
+   Example 1.15. $rtpstat-Usage
 ...
     append_hf("X-RTP-Statistics: $rtpstat\r\n");
 ...
@@ -636,7 +657,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.15.  nh_enable_rtpp usage
+   Example 1.16.  nh_enable_rtpp usage
 ...
 $ kamctl fifo nh_enable_rtpp udp:192.168.2.133:8081 0
 ...
@@ -648,52 +669,52 @@ $ kamctl fifo nh_enable_rtpp udp:192.168.2.133:8081 0
 
    No parameter.
 
-   Example 1.16.  nh_show_rtpp usage
+   Example 1.17.  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
-   empty value to disable the rtpproxy functionality.
+       It was removed as it became obsolete - now “rtpproxy_sock� can take
+       empty value to disable the rtpproxy functionality.
 
    2.2.
 
-   Where can I find more about Kamailio?
+       Where can I find more about Kamailio?
 
-   Take a look at http://www.kamailio.org/.
+       Take a look at http://www.kamailio.org/.
 
    2.3.
 
-   Where can I post a question about this module?
+       Where can I post a question about this module?
 
-   First at all check if your question was already answered on one of our
-   mailing lists:
-     * User Mailing List -
-       http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users
-     * Developer Mailing List -
-       http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
+       First at all check if your question was already answered on one of our
+       mailing lists:
+         * User Mailing List -
+           http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users
+         * Developer Mailing List -
+           http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
 
-   E-mails regarding any stable Kamailio release should be sent to
-   <[email protected]> and e-mails regarding development
-   versions should be sent to <[email protected]>.
+       E-mails regarding any stable Kamailio release should be sent to
+       <[email protected]> and e-mails regarding development
+       versions should be sent to <[email protected]>.
 
-   If you want to keep the mail private, send it to
-   <[email protected]>.
+       If you want to keep the mail private, send it to
+       <[email protected]>.
 
    2.4.
 
-   How can I report a bug?
+       How can I report a bug?
 
-   Please follow the guidelines provided at:
-   http://sip-router.org/tracker.
+       Please follow the guidelines provided at:
+       http://sip-router.org/tracker.

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

@@ -232,6 +232,34 @@ modparam("rtpproxy", "nortpproxy_str", "a=sdpmangled:yes\r\n")
 ...
 modparam("nathelper", "timeout_socket", "xmlrpc:http://127.0.0.1:8000/RPC2")
 ...
+</programlisting>
+		</example>
+	</section>
+	<section>
+		<title><varname>ice_candidate_priority_avp</varname> (string)</title>
+		<para>
+		If specified and if value of the avp value is not 0,
+		<function>rtpproxy_manage</function> function adds
+		ICE relay candidate attributes
+		to sdp stream(s) containing ICE candidate attributes.
+		</para>
+		<para>
+		If value of the avp is 1, added candidates
+		have high priority.  If value of the avp is 2 (default),
+		added candidates have low priority.
+		</para>
+		<para>
+		<emphasis>
+		There is no default value meaning that no ICE relay
+		candidates are added in any circumstance.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>ice_candidate_priority_avp</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("rtpproxy", "ice_candidate_priority_avp", "$avp(ice_priority)")
+...
 </programlisting>
 		</example>
 	</section>

+ 137 - 2
modules/rtpproxy/rtpproxy.c

@@ -331,6 +331,9 @@ static unsigned int current_msg_id = (unsigned int)-1;
 struct rtpp_set_head * rtpp_set_list =0;
 struct rtpp_set * selected_rtpp_set =0;
 struct rtpp_set * default_rtpp_set=0;
+static char *ice_candidate_priority_avp_param = NULL;
+static int ice_candidate_priority_avp_type;
+static int_str ice_candidate_priority_avp;
 
 /* array with the sockets used by rtpporxy (per process)*/
 static unsigned int rtpp_no = 0;
@@ -425,6 +428,8 @@ static param_export_t params[] = {
 	{"rtpproxy_retr",         INT_PARAM, &rtpproxy_retr         },
 	{"rtpproxy_tout",         INT_PARAM, &rtpproxy_tout         },
 	{"timeout_socket",    	  STR_PARAM, &timeout_socket_str.s  },
+	{"ice_candidate_priority_avp", STR_PARAM,
+	 &ice_candidate_priority_avp_param},
 	{0, 0, 0}
 };
 
@@ -868,6 +873,9 @@ static int
 mod_init(void)
 {
 	int i;
+	pv_spec_t avp_spec;
+	str s;
+	unsigned short avp_flags;
 
 	if(register_mi_mod(exports.name, mi_cmds)!=0)
 	{
@@ -910,6 +918,19 @@ mod_init(void)
 		timeout_socket_str.len = strlen(timeout_socket_str.s);
 	}
 
+	if (ice_candidate_priority_avp_param) {
+	    s.s = ice_candidate_priority_avp_param; s.len = strlen(s.s);
+	    if (pv_parse_spec(&s, &avp_spec) == 0 || avp_spec.type != PVT_AVP) {
+		LM_ERR("malformed or non AVP definition <%s>\n", ice_candidate_priority_avp_param);
+		return -1;
+	    }
+	    if (pv_get_avp_name(0, &(avp_spec.pvp), &ice_candidate_priority_avp, &avp_flags) != 0) {
+		LM_ERR("invalid AVP definition <%s>\n", ice_candidate_priority_avp_param);
+		return -1;
+	    }
+	    ice_candidate_priority_avp_type = avp_flags;
+	}
+
 	if (rtpp_strings)
 		pkg_free(rtpp_strings);
 
@@ -1379,6 +1400,88 @@ alter_rtcp(struct sip_msg *msg, str *body, str *oldport, str *newport)
 	return 0;
 }
 
+
+static char *
+append_filtered_ip(char *at, str *ip)
+{
+    int i;
+    for (i = 0; i < ip->len; i++) {
+	if (isdigit(ip->s[i])) {
+	    append_chr(at, ip->s[i]);
+	}
+    }
+    return at;
+}
+
+		
+static int
+insert_candidates(struct sip_msg *msg, char *where, str *ip, unsigned int port,
+		  str *rtcp_port, int priority)
+{
+    char *buf, *at;
+    struct lump* anchor;
+    str rtp_port;
+
+    if (rtcp_port->len) {
+	buf = pkg_malloc(24 + 78 + 14 + 24 + 2*ip->len + 2 + 2*rtcp_port->len +
+			 24);
+    } else {
+	buf = pkg_malloc(12 + 39 + 12 + 12 + ip->len + 1 + rtcp_port->len + 12);
+    }	
+    if (buf == NULL) {
+	LM_ERR("insert_candidates: out of memory\n");
+	return -1;
+    }
+
+    at = buf;
+
+    if (rtcp_port->len) {
+	append_str(at, "a=candidate:", 12);
+	at = append_filtered_ip(at, ip);
+	append_str(at, " 2 UDP ", 7);
+	if (priority == 2) {
+	    append_str(at, "16777214 ", 9);
+	} else {
+	    append_str(at, "2197815294 ", 11);
+	}
+	append_str(at, ip->s, ip->len);
+	append_chr(at, ' ');
+	append_str(at, rtcp_port->s, rtcp_port->len);
+	append_str(at, " typ relay\r\n", 12);
+    }
+
+    rtp_port.s = int2str(port, &rtp_port.len);
+    append_str(at, "a=candidate:", 12);
+    at = append_filtered_ip(at, ip);
+    append_str(at, " 1 UDP ", 7);
+    if (priority == 2) {
+	append_str(at, "16777215 ", 9);
+    } else {
+	append_str(at, "2197815295 ", 11);
+    }
+    append_str(at, ip->s, ip->len);
+    append_chr(at, ' ');
+    append_str(at, rtp_port.s, rtp_port.len);
+    append_str(at, " typ relay\r\n", 12);
+
+    LM_DBG("inserting '%.*s'\n", at - buf, buf);
+
+    anchor = anchor_lump(msg, where - msg->buf, 0, 0);
+    if (anchor == 0) {
+	LOG(L_ERR, "insert_candidates: can't get anchor\n");
+	pkg_free(buf);
+	return -1;
+    }
+    if (insert_new_lump_before(anchor, buf, at - buf, 0) == 0) {
+	LM_ERR("insert_candidates: insert_new_lump_before failed\n");
+	pkg_free(buf);
+	return -1;
+    }
+
+    return 0;
+}
+    
+
 static char * gencookie(void)
 {
 	static char cook[34];
@@ -2002,7 +2105,8 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
 {
 	str body, body1, oldport, oldip, newport, newip;
 	str callid, from_tag, to_tag, tmp, payload_types;
-	str newrtcp, viabranch;
+	str newrtcp = {0, 0};
+	str viabranch;
 	int create, port, len, flookup, argc, proxied, real, via, ret;
 	int orgip, commip;
 	int pf, pf1, force;
@@ -2049,6 +2153,8 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
 	sdp_session_cell_t* sdp_session;
 	sdp_stream_cell_t* sdp_stream;
 
+	int_str ice_candidate_priority_val;
+
 	memset(&opts, '\0', sizeof(opts));
 	memset(&rep_opts, '\0', sizeof(rep_opts));
 	memset(&pt_opts, '\0', sizeof(pt_opts));
@@ -2268,6 +2374,22 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
 	STR2IOVEC(from_tag, v[13]);
 	STR2IOVEC(to_tag, v[17]);
 
+	if (ice_candidate_priority_avp_param) {
+	    if (search_first_avp(ice_candidate_priority_avp_type,
+				 ice_candidate_priority_avp,
+				 &ice_candidate_priority_val, 0)
+		== NULL) {
+		ice_candidate_priority_val.n = 2;
+	    } else if ((ice_candidate_priority_val.n < 1) ||
+		       (ice_candidate_priority_val.n > 2)) {
+		LM_ERR("invalid ice candidate priority value %d\n",
+		       ice_candidate_priority_val.n);
+		FORCE_RTP_PROXY_RET (-1);
+	    }
+	} else {
+	    ice_candidate_priority_val.n = 0;
+	}
+
 	/* check if this is a single or a multi stream SDP offer/answer */
 	sdp_stream_num = get_sdp_stream_num(msg);
 	switch (sdp_stream_num) {
@@ -2294,7 +2416,8 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
 		o1p = sdp_session->o_ip_addr.s;
 		for(;;) {
 			sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
-			if(!sdp_stream) break;
+			if (!sdp_stream ||
+			    (ice_candidate_priority_val.n && sdp_stream->remote_candidates.len)) break;
 
 			if (sdp_stream->ip_addr.s && sdp_stream->ip_addr.len>0) {
 				oldip = sdp_stream->ip_addr;
@@ -2509,6 +2632,7 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
 			 * See RFC 3605 for definition of RTCP attribute.
 			 * ported from ser
 			 */
+
 			if (sdp_stream->rtcp_port.s && sdp_stream->rtcp_port.len) {
 				newrtcp.s = int2str(port+1, &newrtcp.len); /* beware static buffer */
 				/* Alter port. */
@@ -2522,6 +2646,17 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
 				}
 			}
 
+			/* Add ice relay candidates */
+			if (ice_candidate_priority_val.n && sdp_stream->ice_attrs_num > 0) {
+			    body1.s = sdp_stream->ice_attr->foundation.s - 12;
+			    body1.len = bodylimit - body1.s;
+			    if (insert_candidates(msg, sdp_stream->ice_attr->foundation.s - 12,
+						  &newip, port, &newrtcp,
+						  ice_candidate_priority_val.n) == -1) {
+				FORCE_RTP_PROXY_RET (-1);
+			    }
+			}
+
 			c1p = sdp_session->ip_addr.s;
 			c2p = sdp_stream->ip_addr.s;
 			/*