MT#55283 improve setup=actpass logic

Using the FILLED flag to decide how to resolve actpass is not reliable,
as during a reinvite FILLED would be set for both stream directions.

Instead, immediately clear the ACTIVE flag during the offer phase
(dtls_logic) and assume a strict passive role. Then if the answer
indicates that the connection needs to be active instead, a reset occurs
via dtls_connection_init.

Closes #2156

Change-Id: I0ded94620bcaa481eea920ae0c412c7bb86bff1f
pull/2157/head
Richard Fuchs 4 weeks ago
parent 8e92987697
commit 91d0669499

@ -1196,11 +1196,12 @@ bool __init_stream(struct packet_stream *ps) {
if (MEDIA_ISSET(media, DTLS) && !PS_ISSET(ps, FALLBACK_RTCP)) {
// we try to retain our role if possible, but must handle a role switch
if ((dtls_active && !MEDIA_ISSET(media, SETUP_ACTIVE))
|| (!dtls_active && !MEDIA_ISSET(media, SETUP_PASSIVE)))
dtls_active = -1;
if (dtls_active == -1)
dtls_active = (PS_ISSET(ps, FILLED) && MEDIA_ISSET(media, SETUP_ACTIVE));
dtls_active = !MEDIA_ISSET(media, SETUP_PASSIVE);
else if (dtls_active == 0 && !MEDIA_ISSET(media, SETUP_PASSIVE))
dtls_active = 1;
else if (dtls_active == 1 && !MEDIA_ISSET(media, SETUP_ACTIVE))
dtls_active = 0;
dtls_connection_init(&ps->ice_dtls, ps, dtls_active, call->dtls_cert);
for (__auto_type l = ps->sfds.head; l; l = l->next) {
stream_fd *sfd = l->data;
@ -2206,17 +2207,21 @@ static void __dtls_logic(const sdp_ng_flags *flags,
MEDIA_CLEAR(other_media, SETUP_PASSIVE);
}
/* Special case: if this is an offer and actpass is being offered (as it should),
* we would normally choose to be active. However, if this is a reinvite and we
* were passive previously, we should retain this role. */
// resolve setup=actpass for offers
if ((flags->opmode == OP_OFFER || flags->opmode == OP_PUBLISH)
&& MEDIA_ARESET2(other_media, SETUP_ACTIVE, SETUP_PASSIVE)
&& (tmp & (MEDIA_FLAG_SETUP_ACTIVE | MEDIA_FLAG_SETUP_PASSIVE))
&& MEDIA_ARESET2(other_media, SETUP_ACTIVE, SETUP_PASSIVE))
{
// if passive mode is requested, honour it
if (flags->dtls_reverse_passive)
MEDIA_CLEAR(other_media, SETUP_ACTIVE);
// if we were previously passive, retain that role
else if ((tmp & (MEDIA_FLAG_SETUP_ACTIVE | MEDIA_FLAG_SETUP_PASSIVE))
== MEDIA_FLAG_SETUP_PASSIVE)
MEDIA_CLEAR(other_media, SETUP_ACTIVE);
/* if passive mode is requested, honour it if we can */
if (flags->dtls_reverse_passive && MEDIA_ISSET(other_media, SETUP_PASSIVE))
MEDIA_CLEAR(other_media, SETUP_ACTIVE);
MEDIA_CLEAR(other_media, SETUP_ACTIVE);
// in all other cases: we are active
else
MEDIA_CLEAR(other_media, SETUP_PASSIVE);
}
// restart DTLS?
if (memcmp(&other_media->fingerprint, &sp->fingerprint, sizeof(sp->fingerprint))) {

Loading…
Cancel
Save