Browse Source

TT#14008 change local ICE ufrag/pwd after ICE restart

Implements RFC 5245 9.2.1.1

Also reset ICE role after a restart

closes #786

Change-Id: Idc7ec9f409b70598e2840fb7d0a31a12f9db3c21
pull/1430/head
Richard Fuchs 4 years ago
parent
commit
f5a148f268
4 changed files with 148 additions and 25 deletions
  1. +6
    -6
      daemon/call.c
  2. +6
    -7
      daemon/ice.c
  3. +25
    -12
      include/ice.h
  4. +111
    -0
      t/auto-daemon-tests.pl

+ 6
- 6
daemon/call.c View File

@ -1439,7 +1439,7 @@ static int __init_streams(struct call_media *A, struct call_media *B, const stru
}
static void __ice_offer(const struct sdp_ng_flags *flags, struct call_media *this,
struct call_media *other)
struct call_media *other, bool ice_restart)
{
if (!flags)
return;
@ -1531,7 +1531,7 @@ static void __ice_offer(const struct sdp_ng_flags *flags, struct call_media *thi
/* ICE_CONTROLLING is from our POV, the other ICE flags are from peer's POV */
if (MEDIA_ISSET(this, ICE_LITE_PEER) && !MEDIA_ISSET(this, ICE_LITE_SELF))
MEDIA_SET(this, ICE_CONTROLLING);
else if (!MEDIA_ISSET(this, INITIALIZED)) {
else if (!MEDIA_ISSET(this, INITIALIZED) || ice_restart) {
if (MEDIA_ISSET(this, ICE_LITE_SELF))
MEDIA_CLEAR(this, ICE_CONTROLLING);
else if (flags->opmode == OP_OFFER)
@ -1544,7 +1544,7 @@ static void __ice_offer(const struct sdp_ng_flags *flags, struct call_media *thi
/* roles are reversed for the other side */
if (MEDIA_ISSET(other, ICE_LITE_PEER) && !MEDIA_ISSET(other, ICE_LITE_SELF))
MEDIA_SET(other, ICE_CONTROLLING);
else if (!MEDIA_ISSET(other, INITIALIZED)) {
else if (!MEDIA_ISSET(other, INITIALIZED) || ice_restart) {
if (MEDIA_ISSET(other, ICE_LITE_SELF))
MEDIA_CLEAR(other, ICE_CONTROLLING);
else if (flags->opmode == OP_OFFER)
@ -2722,7 +2722,7 @@ int monologue_offer_answer(struct call_monologue *dialogue[2], GQueue *streams,
}
/* ICE stuff - must come after interface and address family selection */
__ice_offer(flags, media, other_media);
__ice_offer(flags, media, other_media, ice_is_restart(other_media->ice_agent, sp));
/* we now know what's being advertised by the other side */
@ -2912,7 +2912,7 @@ int monologue_publish(struct call_monologue *ml, GQueue *streams, struct sdp_ng_
return -1; // XXX return error code
/* ICE stuff - must come after interface and address family selection */
__ice_offer(flags, media, media);
__ice_offer(flags, media, media, ice_is_restart(media->ice_agent, sp));
MEDIA_SET(media, INITIALIZED);
@ -2982,7 +2982,7 @@ static int monologue_subscribe_request1(struct call_monologue *src_ml, struct ca
if (dst_media->logical_intf == NULL)
return -1; // XXX return error code
__ice_offer(flags, dst_media, src_media);
__ice_offer(flags, dst_media, src_media, ice_is_restart(src_media->ice_agent, sp));
struct endpoint_map *em = __get_endpoint_map(dst_media, sp->num_ports, NULL, flags, true);
if (!em)


+ 6
- 7
daemon/ice.c View File

@ -295,15 +295,19 @@ static void __ice_reset(struct ice_agent *ag) {
/* if the other side did a restart */
static void __ice_restart(struct ice_agent *ag) {
ilogs(ice, LOG_DEBUG, "ICE restart, resetting ICE agent");
ilogs(ice, LOG_DEBUG, "ICE restart detected, resetting ICE agent");
ag->ufrag[0] = STR_NULL;
ag->pwd[0] = STR_NULL;
ag->ufrag[1] = STR_NULL;
ag->pwd[1] = STR_NULL;
__ice_reset(ag);
}
/* if we're doing a restart */
void ice_restart(struct ice_agent *ag) {
ilogs(ice, LOG_DEBUG, "Restarting ICE and resetting ICE agent");
ag->ufrag[1] = STR_NULL;
ag->pwd[1] = STR_NULL;
__ice_reset(ag);
@ -331,12 +335,7 @@ void ice_update(struct ice_agent *ag, struct stream_params *sp) {
__role_change(ag, MEDIA_ISSET(media, ICE_CONTROLLING));
if (sp) {
/* check for ICE restarts */
if (ag->ufrag[0].s && sp->ice_ufrag.s && str_cmp_str(&ag->ufrag[0], &sp->ice_ufrag))
__ice_restart(ag);
else if (ag->pwd[0].s && sp->ice_pwd.s && str_cmp_str(&ag->pwd[0], &sp->ice_pwd))
__ice_restart(ag);
else if (ag->logical_intf != media->logical_intf)
if (ice_is_restart(ag, sp))
__ice_restart(ag);
/* update remote info */


+ 25
- 12
include/ice.h View File

@ -172,28 +172,41 @@ int ice_response(struct stream_fd *, const endpoint_t *src,
/* returns 0 if ICE still has work to do, 1 otherwise */
INLINE int ice_has_finished(struct call_media *media) {
INLINE bool ice_has_finished(struct call_media *media) {
if (!media)
return 1;
return true;
if (!MEDIA_ISSET(media, ICE))
return 1;
return true;
if (!media->ice_agent)
return 1;
return true;
if (AGENT_ISSET(media->ice_agent, COMPLETED))
return 1;
return 0;
return true;
return false;
}
/* returns 1 if media has connectivity */
INLINE int ice_is_usable(struct call_media *media) {
INLINE bool ice_is_usable(struct call_media *media) {
if (!media)
return 1;
return true;
if (!MEDIA_ISSET(media, ICE))
return 1;
return true;
if (!media->ice_agent)
return 1;
return true;
if (AGENT_ISSET(media->ice_agent, USABLE))
return 1;
return 0;
return true;
return false;
}
INLINE bool ice_is_restart(struct ice_agent *ag, struct stream_params *sp) {
if (!ag || !sp)
return false;
struct call_media *media = ag->media;
if (ag->ufrag[0].s && sp->ice_ufrag.s && str_cmp_str(&ag->ufrag[0], &sp->ice_ufrag))
return true;
else if (ag->pwd[0].s && sp->ice_pwd.s && str_cmp_str(&ag->pwd[0], &sp->ice_pwd))
return true;
else if (ag->logical_intf != media->logical_intf)
return true;
return false;
}
INLINE unsigned int ice_type_preference(enum ice_candidate_type type) {
if (type >= __ICT_LAST)


+ 111
- 0
t/auto-daemon-tests.pl View File

@ -40,6 +40,117 @@ my ($sock_a, $sock_b, $sock_c, $sock_d, $port_a, $port_b, $ssrc, $ssrc_b, $resp,
new_call;
offer('ICE restart',
{ ICE => 'remove' }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.101.40
s=tester
t=0 0
m=audio 16478 RTP/AVP 8
c=IN IP4 198.51.100.1
a=ice-pwd:bd5e845657ecb8d6dd8e1bc6
a=ice-ufrag:q2758e93
a=candidate:1 1 UDP 2130706303 198.51.100.4 2000 typ host
a=candidate:1 2 UDP 2130706302 198.51.100.4 2001 typ host
a=candidate:2 1 UDP 2130706301 198.51.100.8 3000 typ host
a=candidate:2 2 UDP 2130706300 198.51.100.8 3001 typ host
----------------------------------
v=0
o=- 1545997027 1 IN IP4 198.51.101.40
s=tester
t=0 0
m=audio PORT RTP/AVP 8
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
SDP
($port_a, undef, $ufrag_a) = answer('ICE restart',
{ }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.101.40
s=tester
t=0 0
m=audio 16478 RTP/AVP 8
c=IN IP4 198.51.100.1
----------------------------------
v=0
o=- 1545997027 1 IN IP4 198.51.101.40
s=tester
t=0 0
m=audio PORT RTP/AVP 8
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
a=ice-ufrag:ICEUFRAG
a=ice-pwd:ICEPWD
a=candidate:ICEBASE 1 UDP 2130706431 203.0.113.1 PORT typ host
a=candidate:ICEBASE 1 UDP 2130706175 2001:db8:4321::1 PORT typ host
a=candidate:ICEBASE 2 UDP 2130706430 203.0.113.1 PORT typ host
a=candidate:ICEBASE 2 UDP 2130706174 2001:db8:4321::1 PORT typ host
SDP
offer('ICE restart',
{ }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.101.40
s=tester
t=0 0
m=audio 16478 RTP/AVP 8
c=IN IP4 198.51.100.1
a=ice-pwd:bd5e8gssdfecb8d6dd8e1bc6
a=ice-ufrag:qdgsdfs3
a=candidate:1 1 UDP 2130706303 198.51.100.4 2000 typ host
a=candidate:1 2 UDP 2130706302 198.51.100.4 2001 typ host
a=candidate:2 1 UDP 2130706301 198.51.100.8 3000 typ host
a=candidate:2 2 UDP 2130706300 198.51.100.8 3001 typ host
----------------------------------
v=0
o=- 1545997027 1 IN IP4 198.51.101.40
s=tester
t=0 0
m=audio PORT RTP/AVP 8
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
SDP
($port_b, undef, $ufrag_b) = answer('ICE restart',
{ }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.101.40
s=tester
t=0 0
m=audio 16478 RTP/AVP 8
c=IN IP4 198.51.100.1
----------------------------------
v=0
o=- 1545997027 1 IN IP4 198.51.101.40
s=tester
t=0 0
m=audio PORT RTP/AVP 8
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
a=ice-ufrag:ICEUFRAG
a=ice-pwd:ICEPWD
a=candidate:ICEBASE 1 UDP 2130706431 203.0.113.1 PORT typ host
a=candidate:ICEBASE 1 UDP 2130706175 2001:db8:4321::1 PORT typ host
a=candidate:ICEBASE 2 UDP 2130706430 203.0.113.1 PORT typ host
a=candidate:ICEBASE 2 UDP 2130706174 2001:db8:4321::1 PORT typ host
SDP
is($port_a, $port_b, 'port match');
isnt($ufrag_a, $ufrag_b, 'ufrag mismatch');
new_call;
offer('GH 1373 offer', { codec => { strip => ['all'] } }, <<SDP);


Loading…
Cancel
Save