webrtcbin: Support data channel SDP offers from Chrome

When negotiating a data channel, Chrome as recent as 75 still uses SDP
based on version 05 of the SCTP SDP draft, for example:

 m=application 9 DTLS/SCTP 5000
 a=sctpmap:5000 webrtc-datachannel 1024

Implement support for parsing SCTP port out of SDP message with sctpmap
attribute. Fixes data channel negotiation with Chrome browser.
This commit is contained in:
Jakub Adam 2019-06-12 15:00:38 +02:00 committed by Matthew Waters
parent 2c1244331f
commit 831b124976
2 changed files with 45 additions and 17 deletions

View file

@ -2794,13 +2794,6 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options)
"for webrtc-datachannel");
goto rejected;
}
if (g_strcmp0 (gst_sdp_media_get_format (offer_media, 0),
"webrtc-datachannel") != 0) {
GST_WARNING_OBJECT (webrtc,
"format field of data channel m= line "
"is not \'webrtc-datachannel\'");
goto rejected;
}
sctp_port = _get_sctp_port_from_media (offer_media);
if (sctp_port == -1) {
GST_WARNING_OBJECT (webrtc, "media does not contain a sctp port");

View file

@ -712,21 +712,56 @@ _generate_ice_credentials (gchar ** ufrag, gchar ** password)
int
_get_sctp_port_from_media (const GstSDPMedia * media)
{
int sctpmap = -1, i;
int i;
const gchar *format;
gchar *endptr;
for (i = 0; i < gst_sdp_media_attributes_len (media); i++) {
const GstSDPAttribute *attr = gst_sdp_media_get_attribute (media, i);
if (gst_sdp_media_formats_len (media) != 1) {
/* only exactly one format is supported */
return -1;
}
if (g_strcmp0 (attr->key, "sctp-port") == 0) {
return atoi (attr->value);
} else if (g_strcmp0 (attr->key, "sctpmap") == 0) {
sctpmap = atoi (attr->value);
format = gst_sdp_media_get_format (media, 0);
if (g_strcmp0 (format, "webrtc-datachannel") == 0) {
/* draft-ietf-mmusic-sctp-sdp-21, e.g. Firefox 63 and later */
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, "sctp-port") == 0) {
gint64 port = g_ascii_strtoll (attr->value, &endptr, 10);
if (endptr == attr->value) {
/* conversion error */
return -1;
}
return port;
}
}
} else {
/* draft-ietf-mmusic-sctp-sdp-05, e.g. Chrome as recent as 75 */
gint64 port = g_ascii_strtoll (format, &endptr, 10);
if (endptr == format) {
/* conversion error */
return -1;
}
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, "sctpmap") == 0 && atoi (attr->value) == port) {
/* a=sctpmap:5000 webrtc-datachannel 256 */
gchar **parts = g_strsplit (attr->value, " ", 3);
if (!parts[1] || g_strcmp0 (parts[1], "webrtc-datachannel") != 0) {
port = -1;
}
g_strfreev (parts);
return port;
}
}
}
if (sctpmap >= 0)
GST_LOG ("no sctp-port attribute in media");
return sctpmap;
return -1;
}
guint64