summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleix Conchillo FlaquƩ <aconchillo@gmail.com>2016-04-14 22:56:11 -0700
committerJosep Torra <n770galaxy@gmail.com>2016-05-30 18:02:04 +0200
commit88906252cb706cafd5007e8d3c274f148fe83549 (patch)
tree13ce7a798ec25d6904c41e000d75a71f71bf4e79
parent7de0d6580a15c18e337278fc8cc8a126919731a7 (diff)
sdp: add rollover counters for all sender SSRCsrtp
We add different crypto sessions in MIKEY, one for each sender SSRC. Currently, all of them will have the same security policy, 0. The rollover counters are obtained from the srtpenc element using the "stats" property. https://bugzilla.gnome.org/show_bug.cgi?id=730539
-rw-r--r--gst/rtsp-server/rtsp-sdp.c90
-rw-r--r--gst/rtsp-server/rtsp-stream.c26
-rw-r--r--gst/rtsp-server/rtsp-stream.h2
3 files changed, 114 insertions, 4 deletions
diff --git a/gst/rtsp-server/rtsp-sdp.c b/gst/rtsp-server/rtsp-sdp.c
index 348cab3..b5a789b 100644
--- a/gst/rtsp-server/rtsp-sdp.c
+++ b/gst/rtsp-server/rtsp-sdp.c
@@ -16,6 +16,9 @@
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
/**
* SECTION:rtsp-sdp
* @short_description: Make SDP messages
@@ -73,6 +76,87 @@ update_sdp_from_tags (GstRTSPStream * stream, GstSDPMedia * stream_media)
gst_object_unref (src_pad);
}
+static guint
+get_roc_from_stats (GstStructure * stats, guint ssrc)
+{
+ const GValue *va, *v;
+ guint i, len, roc = 0;
+
+ va = gst_structure_get_value (stats, "streams");
+ if (!va || !G_VALUE_HOLDS (va, GST_TYPE_ARRAY)) {
+ GST_WARNING ("stats doesn't have a valid 'streams' field");
+ return 0;
+ }
+
+ len = gst_value_array_get_size (va);
+
+ /* Look if there's any SSRC that matches. */
+ for (i = 0; i < len; i++) {
+ GstStructure *stream;
+ v = gst_value_array_get_value (va, i);
+ if (v && (stream = g_value_get_boxed (v))) {
+ guint stream_ssrc;
+ gst_structure_get_uint (stream, "ssrc", &stream_ssrc);
+ if (stream_ssrc == ssrc) {
+ gst_structure_get_uint (stream, "roc", &roc);
+ break;
+ }
+ }
+ }
+
+ return roc;
+}
+
+static void
+mikey_add_crypto_sessions (GstRTSPStream * stream, GstMIKEYMessage * msg)
+{
+ guint i;
+ GObject *session;
+ GstElement *encoder;
+ GValueArray *sources;
+
+ session = gst_rtsp_stream_get_rtpsession (stream);
+ if (session == NULL)
+ return;
+
+ encoder = gst_rtsp_stream_get_srtp_encoder (stream);
+ if (encoder == NULL) {
+ g_object_unref (session);
+ return;
+ }
+
+ g_object_get (session, "sources", &sources, NULL);
+ for (i = 0; i < sources->n_values; i++) {
+ GValue *val;
+ GObject *source;
+ guint32 ssrc;
+ gboolean is_sender;
+
+ val = g_value_array_get_nth (sources, i);
+ source = (GObject *) g_value_get_object (val);
+
+ g_object_get (source, "ssrc", &ssrc, "is-sender", &is_sender, NULL);
+
+ if (is_sender) {
+ guint32 roc = 0;
+ GstStructure *stats;
+
+ g_object_get (encoder, "stats", &stats, NULL);
+
+ if (stats) {
+ roc = get_roc_from_stats (stats, ssrc);
+ gst_structure_free (stats);
+ }
+
+ gst_mikey_message_add_cs_srtp (msg, 0, ssrc, roc);
+ }
+ }
+ g_value_array_free (sources);
+
+ gst_object_unref (encoder);
+ g_object_unref (session);
+}
+
static void
make_media (GstSDPMessage * sdp, GstSDPInfo * info,
GstRTSPStream * stream, GstCaps * caps, GstRTSPProfile profile)
@@ -86,7 +170,6 @@ make_media (GstSDPMessage * sdp, GstSDPInfo * info,
guint ttl;
GstClockTime rtx_time;
gchar *base64;
- guint32 ssrc;
GstMIKEYMessage *mikey_msg;
gst_sdp_media_new (&smedia);
@@ -155,9 +238,8 @@ make_media (GstSDPMessage * sdp, GstSDPInfo * info,
/* check for srtp */
mikey_msg = gst_mikey_message_new_from_caps (caps);
if (mikey_msg) {
- gst_rtsp_stream_get_ssrc (stream, &ssrc);
- /* add policy '0' for our SSRC */
- gst_mikey_message_add_cs_srtp (mikey_msg, 0, ssrc, 0);
+ /* add policy '0' for all sending SSRC */
+ mikey_add_crypto_sessions (stream, mikey_msg);
base64 = gst_mikey_message_base64_encode (mikey_msg);
if (base64) {
diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c
index 27ad5ac..5389456 100644
--- a/gst/rtsp-server/rtsp-stream.c
+++ b/gst/rtsp-server/rtsp-stream.c
@@ -1672,6 +1672,32 @@ gst_rtsp_stream_get_rtpsession (GstRTSPStream * stream)
}
/**
+ * gst_rtsp_stream_get_encoder:
+ * @stream: a #GstRTSPStream
+ *
+ * Get the SRTP encoder for this stream.
+ *
+ * Returns: (transfer full): The SRTP encoder for this stream. Unref after usage.
+ */
+GstElement *
+gst_rtsp_stream_get_srtp_encoder (GstRTSPStream * stream)
+{
+ GstRTSPStreamPrivate *priv;
+ GstElement *encoder;
+
+ g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
+
+ priv = stream->priv;
+
+ g_mutex_lock (&priv->lock);
+ if ((encoder = priv->srtpenc))
+ g_object_ref (encoder);
+ g_mutex_unlock (&priv->lock);
+
+ return encoder;
+}
+
+/**
* gst_rtsp_stream_get_ssrc:
* @stream: a #GstRTSPStream
* @ssrc: (out): result ssrc
diff --git a/gst/rtsp-server/rtsp-stream.h b/gst/rtsp-server/rtsp-stream.h
index a6ab1ff..9ef887a 100644
--- a/gst/rtsp-server/rtsp-stream.h
+++ b/gst/rtsp-server/rtsp-stream.h
@@ -129,6 +129,8 @@ GstRTSPAddress * gst_rtsp_stream_get_multicast_address (GstRTSPStream *stream,
GObject * gst_rtsp_stream_get_rtpsession (GstRTSPStream *stream);
+GstElement * gst_rtsp_stream_get_srtp_encoder (GstRTSPStream *stream);
+
void gst_rtsp_stream_get_ssrc (GstRTSPStream *stream,
guint *ssrc);