From ce9b41f5d4443cdf4825ec3e23794471ce4d6ba6 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Fri, 1 May 2020 00:47:53 +1000 Subject: [PATCH] webrtcbin: fix bundle none case with remote offer bundling If the remote is bundling, but we are not and remote is offering. we cannot put the remote media sections into a bundled transport as that is not how we are going to respond. This specific failure case was that the remote ICE credentials were never set on the ice stream and so ice connectivity would fail. Technically, this whole bunde-policy=none handling should be removed eventually when we implement bundle-policy=balanced. Until such time, we have this workaround. Part-of: --- ext/webrtc/gstwebrtcbin.c | 29 ++++++++++++++++------------- ext/webrtc/webrtcsdp.c | 16 ++++++++++++++++ ext/webrtc/webrtcsdp.h | 3 +++ 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/ext/webrtc/gstwebrtcbin.c b/ext/webrtc/gstwebrtcbin.c index 986cfb7c1d..10a961c289 100644 --- a/ext/webrtc/gstwebrtcbin.c +++ b/ext/webrtc/gstwebrtcbin.c @@ -4105,8 +4105,9 @@ _update_transceivers_from_sdp (GstWebRTCBin * webrtc, SDPSource source, /* FIXME: With some peers, it's possible we could have * multiple bundles to deal with, although I've never seen one yet */ - if (!_parse_bundle (sdp->sdp, &bundled)) - goto done; + if (webrtc->bundle_policy != GST_WEBRTC_BUNDLE_POLICY_NONE) + if (!_parse_bundle (sdp->sdp, &bundled)) + goto done; if (bundled) { @@ -4255,8 +4256,9 @@ _set_description_task (GstWebRTCBin * webrtc, struct set_description *sd) goto out; } - if (!_parse_bundle (sd->sdp->sdp, &bundled)) - goto out; + if (webrtc->bundle_policy != GST_WEBRTC_BUNDLE_POLICY_NONE) + if (!_parse_bundle (sd->sdp->sdp, &bundled)) + goto out; if (bundled) { if (!_get_bundle_index (sd->sdp->sdp, bundled, &bundle_idx)) { @@ -4412,6 +4414,7 @@ _set_description_task (GstWebRTCBin * webrtc, struct set_description *sd) } for (i = 0; i < gst_sdp_message_medias_len (sd->sdp->sdp); i++) { + const GstSDPMedia *media = gst_sdp_message_get_media (sd->sdp->sdp, i); gchar *ufrag, *pwd; TransportStream *item; @@ -4420,7 +4423,6 @@ _set_description_task (GstWebRTCBin * webrtc, struct set_description *sd) _message_media_is_datachannel (sd->sdp->sdp, bundled ? bundle_idx : i)); if (sd->source == SDP_REMOTE) { - const GstSDPMedia *media = gst_sdp_message_get_media (sd->sdp->sdp, i); guint j; for (j = 0; j < gst_sdp_media_attributes_len (media); j++) { @@ -4443,20 +4445,21 @@ _set_description_task (GstWebRTCBin * webrtc, struct set_description *sd) } } - if (bundled && bundle_idx != i) - continue; + if (sd->source == SDP_LOCAL && (!bundled || bundle_idx == i)) { + _get_ice_credentials_from_sdp_media (sd->sdp->sdp, i, &ufrag, &pwd); - _get_ice_credentials_from_sdp_media (sd->sdp->sdp, i, &ufrag, &pwd); - - if (sd->source == SDP_LOCAL) { gst_webrtc_ice_set_local_credentials (webrtc->priv->ice, item->stream, ufrag, pwd); - } else { + g_free (ufrag); + g_free (pwd); + } else if (sd->source == SDP_REMOTE && !_media_is_bundle_only (media)) { + _get_ice_credentials_from_sdp_media (sd->sdp->sdp, i, &ufrag, &pwd); + gst_webrtc_ice_set_remote_credentials (webrtc->priv->ice, item->stream, ufrag, pwd); + g_free (ufrag); + g_free (pwd); } - g_free (ufrag); - g_free (pwd); } if (sd->source == SDP_LOCAL) { diff --git a/ext/webrtc/webrtcsdp.c b/ext/webrtc/webrtcsdp.c index c6cdf04141..a93a1068ea 100644 --- a/ext/webrtc/webrtcsdp.c +++ b/ext/webrtc/webrtcsdp.c @@ -919,3 +919,19 @@ _get_bundle_index (GstSDPMessage * sdp, GStrv bundled, guint * idx) return ret; } + +gboolean +_media_is_bundle_only (const GstSDPMedia * media) +{ + int i; + + for (i = 0; i < gst_sdp_media_attributes_len (media); i++) { + const GstSDPAttribute *attr = gst_sdp_media_get_attribute (media, i); + + if (g_strcmp0 (attr->key, "bundle-only") == 0) { + return TRUE; + } + } + + return FALSE; +} diff --git a/ext/webrtc/webrtcsdp.h b/ext/webrtc/webrtcsdp.h index 7620091fa6..c116df5d28 100644 --- a/ext/webrtc/webrtcsdp.h +++ b/ext/webrtc/webrtcsdp.h @@ -107,4 +107,7 @@ G_GNUC_INTERNAL const gchar * _media_get_ice_ufrag (const GstSDPMessage * msg, guint media_idx); +G_GNUC_INTERNAL +gboolean _media_is_bundle_only (const GstSDPMedia * sdp); + #endif /* __WEBRTC_UTILS_H__ */