i have played with idea of adding new ICE flag value 'force_relay' to
rtpengine. if differs from ICE=force in that only existing ICE
candidates of typ relay are replaced using rtpengine relay candidates.
i would appreciate if owners of rtpengine module and rtpengine itself
could review the patches below and if ok, commit the changes. if
committed, i can update rtpengine module README.
-- juha
diff -c /usr/src/orig/sip-router/modules/rtpengine/rtpengine.c ./rtpengine.c
*** /usr/src/orig/sip-router/modules/rtpengine/rtpengine.c Wed Apr 9 08:55:16 2014
--- ./rtpengine.c Tue Apr 22 19:09:03 2014
***************
*** 1160,1166 ****
if (!val.s)
goto error;
err = "invalid value";
! if (str_eq(&val, "force") || str_eq(&val, "remove"))
bencode_dictionary_add_str(ng_flags->dict, "ICE", &val);
else
goto error;
--- 1160,1166 ----
if (!val.s)
goto error;
err = "invalid value";
! if (str_eq(&val, "force") || str_eq(&val,
"force_relay")|| str_eq(&val, "remove"))
bencode_dictionary_add_str(ng_flags->dict, "ICE", &val);
else
goto error;
diff -c /usr/src/orig/rtpengine/daemon/call_interfaces.c ./call_interfaces.c
*** /usr/src/orig/rtpengine/daemon/call_interfaces.c Mon Apr 7 09:38:28 2014
--- ./call_interfaces.c Tue Apr 22 21:31:59 2014
***************
*** 462,467 ****
--- 462,469 ----
out->ice_remove = 1;
else if (!str_cmp(&s, "force"))
out->ice_force = 1;
+ else if (!str_cmp(&s, "force_relay"))
+ out->ice_force_relay = 1;
}
if ((list = bencode_dictionary_get_expect(input, "rtcp-mux", BENCODE_LIST)))
{
diff -c /usr/src/orig/rtpengine/daemon/sdp.c ./sdp.c
*** /usr/src/orig/rtpengine/daemon/sdp.c Mon Apr 7 21:34:48 2014
--- ./sdp.c Tue Apr 22 21:33:47 2014
***************
*** 78,84 ****
str component_str;
str transport;
str priority_str;
! /* incomplete */
unsigned long component;
unsigned long priority;
--- 78,87 ----
str component_str;
str transport;
str priority_str;
! str ip_str;
! str port_str;
! str typ_str;
! str type_str;
unsigned long component;
unsigned long priority;
***************
*** 554,559 ****
--- 557,566 ----
EXTRACT_TOKEN(u.candidate.component_str);
EXTRACT_TOKEN(u.candidate.transport);
EXTRACT_TOKEN(u.candidate.priority_str);
+ EXTRACT_TOKEN(u.candidate.ip_str);
+ EXTRACT_TOKEN(u.candidate.port_str);
+ EXTRACT_TOKEN(u.candidate.typ_str);
+ EXTRACT_TOKEN(u.candidate.type_str);
output->u.candidate.component = strtoul(output->u.candidate.component_str.s,
&ep, 10);
if (ep == output->u.candidate.component_str.s)
***************
*** 1311,1317 ****
--- 1319,1336 ----
switch (attr->attr) {
case ATTR_ICE:
case ATTR_ICE_UFRAG:
+ if (!flags->ice_remove && !flags->ice_force)
+ break;
+ goto strip;
+
case ATTR_CANDIDATE:
+ if (flags->ice_force_relay) {
+ if ((attr->u.candidate.type_str.len == 5) &&
+ (strncasecmp(attr->u.candidate.type_str.s, "relay", 5) == 0))
+ goto strip;
+ else
+ break;
+ }
if (!flags->ice_remove && !flags->ice_force)
break;
goto strip;
***************
*** 1359,1367 ****
--- 1378,1399 ----
switch (attr->attr) {
case ATTR_ICE:
case ATTR_ICE_UFRAG:
+ if (MEDIA_ISSET(media, PASSTHRU))
+ break;
+ if (!flags->ice_remove && !flags->ice_force)
+ break;
+ goto strip;
+
case ATTR_CANDIDATE:
if (MEDIA_ISSET(media, PASSTHRU))
break;
+ if (flags->ice_force_relay) {
+ if ((attr->u.candidate.type_str.len == 5) &&
+ (strncasecmp(attr->u.candidate.type_str.s, "relay", 5) == 0))
+ goto strip;
+ else
+ break;
+ }
if (!flags->ice_remove && !flags->ice_force)
break;
goto strip;
***************
*** 1442,1454 ****
}
static void insert_candidates(struct sdp_chopper *chop, struct packet_stream *rtp,
struct packet_stream *rtcp,
! unsigned long priority, struct sdp_media *media)
{
chopper_append_c(chop, "a=candidate:");
chopper_append_str(chop, &ice_foundation_str);
chopper_append_printf(chop, " 1 UDP %lu ", priority);
insert_ice_address(chop, rtp);
! chopper_append_c(chop, " typ host\r\n");
if (rtcp) {
/* rtcp-mux only possible in answer */
--- 1474,1490 ----
}
static void insert_candidates(struct sdp_chopper *chop, struct packet_stream *rtp,
struct packet_stream *rtcp,
! unsigned long priority, struct sdp_media *media,
! unsigned int relay)
{
chopper_append_c(chop, "a=candidate:");
chopper_append_str(chop, &ice_foundation_str);
chopper_append_printf(chop, " 1 UDP %lu ", priority);
insert_ice_address(chop, rtp);
! if (relay == 1)
! chopper_append_c(chop, " typ relay\r\n");
! else
! chopper_append_c(chop, " typ host\r\n");
if (rtcp) {
/* rtcp-mux only possible in answer */
***************
*** 1456,1481 ****
chopper_append_str(chop, &ice_foundation_str);
chopper_append_printf(chop, " 2 UDP %lu ", priority - 1);
insert_ice_address(chop, rtcp);
! chopper_append_c(chop, " typ host\r\n");
}
}
static void insert_candidates_alt(struct sdp_chopper *chop, struct packet_stream *rtp,
struct packet_stream *rtcp,
! unsigned long priority, struct sdp_media *media)
{
chopper_append_c(chop, "a=candidate:");
chopper_append_str(chop, &ice_foundation_str_alt);
chopper_append_printf(chop, " 1 UDP %lu ", priority);
insert_ice_address_alt(chop, rtp);
! chopper_append_c(chop, " typ host\r\n");
if (rtcp) {
chopper_append_c(chop, "a=candidate:");
chopper_append_str(chop, &ice_foundation_str_alt);
chopper_append_printf(chop, " 2 UDP %lu ", priority - 1);
insert_ice_address_alt(chop, rtcp);
! chopper_append_c(chop, " typ host\r\n");
}
}
--- 1492,1527 ----
chopper_append_str(chop, &ice_foundation_str);
chopper_append_printf(chop, " 2 UDP %lu ", priority - 1);
insert_ice_address(chop, rtcp);
! if (relay)
! chopper_append_c(chop, " typ relay\r\n");
! else
! chopper_append_c(chop, " typ host\r\n");
}
}
static void insert_candidates_alt(struct sdp_chopper *chop, struct packet_stream *rtp,
struct packet_stream *rtcp,
! unsigned long priority, struct sdp_media *media,
! unsigned int relay)
{
chopper_append_c(chop, "a=candidate:");
chopper_append_str(chop, &ice_foundation_str_alt);
chopper_append_printf(chop, " 1 UDP %lu ", priority);
insert_ice_address_alt(chop, rtp);
! if (relay == 1)
! chopper_append_c(chop, " typ relay\r\n");
! else
! chopper_append_c(chop, " typ host\r\n");
if (rtcp) {
chopper_append_c(chop, "a=candidate:");
chopper_append_str(chop, &ice_foundation_str_alt);
chopper_append_printf(chop, " 2 UDP %lu ", priority - 1);
insert_ice_address_alt(chop, rtcp);
! if (relay)
! chopper_append_c(chop, " typ relay\r\n");
! else
! chopper_append_c(chop, " typ host\r\n");
}
}
***************
*** 1591,1597 ****
struct call *call;
m = monologue->medias.head;
! do_ice = (flags->ice_force || (!has_ice(sessions) && !flags->ice_remove))
? 1 : 0;
call = monologue->call;
for (l = sessions->head; l; l = l->next) {
--- 1637,1644 ----
struct call *call;
m = monologue->medias.head;
! do_ice = (flags->ice_force || flags->ice_force_relay ||
! (!has_ice(sessions) && !flags->ice_remove)) ? 1 : 0;
call = monologue->call;
for (l = sessions->head; l; l = l->next) {
***************
*** 1730,1741 ****
priority = new_priority(flags->ice_force ? NULL : sdp_media);
insert_candidates(chop, ps, ps_rtcp,
! priority, sdp_media);
if (callmaster_has_ipv6(call->callmaster)) {
priority -= 256;
insert_candidates_alt(chop, ps, ps_rtcp,
! priority, sdp_media);
}
}
--- 1777,1789 ----
priority = new_priority(flags->ice_force ? NULL : sdp_media);
insert_candidates(chop, ps, ps_rtcp,
! priority, sdp_media, flags->ice_force_relay);
if (callmaster_has_ipv6(call->callmaster)) {
priority -= 256;
insert_candidates_alt(chop, ps, ps_rtcp,
! priority, sdp_media,
! flags->ice_force_relay);
}
}
diff -c /usr/src/orig/rtpengine/daemon/sdp.h ./sdp.h
*** /usr/src/orig/rtpengine/daemon/sdp.h Mon Apr 7 09:38:28 2014
--- ./sdp.h Tue Apr 22 17:35:58 2014
***************
*** 25,30 ****
--- 25,31 ----
replace_sess_conn:1,
ice_remove:1,
ice_force:1,
+ ice_force_relay:1,
rtcp_mux_offer:1,
rtcp_mux_demux:1,
rtcp_mux_accept:1,