diff --git a/ext/srt/gstsrt.c b/ext/srt/gstsrt.c index 4afe16920f..9983c48901 100644 --- a/ext/srt/gstsrt.c +++ b/ext/srt/gstsrt.c @@ -33,10 +33,11 @@ GST_DEBUG_CATEGORY (GST_CAT_DEFAULT); SRTSOCKET -gst_srt_client_connect (GstElement * elem, int sender, +gst_srt_client_connect_full (GstElement * elem, int sender, const gchar * host, guint16 port, int rendez_vous, const gchar * bind_address, guint16 bind_port, int latency, - GSocketAddress ** socket_address, gint * poll_id) + GSocketAddress ** socket_address, gint * poll_id, gchar * passphrase, + int key_length) { SRTSOCKET sock; GError *error = NULL; @@ -78,6 +79,11 @@ gst_srt_client_connect (GstElement * elem, int sender, srt_setsockopt (sock, 0, SRTO_RENDEZVOUS, &rendez_vous, sizeof (int)); + if (passphrase != NULL && passphrase[0] != '\0') { + srt_setsockopt (sock, 0, SRTO_PASSPHRASE, passphrase, strlen (passphrase)); + srt_setsockopt (sock, 0, SRTO_PBKEYLEN, &key_length, sizeof (int)); + } + if (bind_address || bind_port || rendez_vous) { gpointer bsa; size_t bsa_len; @@ -153,6 +159,17 @@ failed: return SRT_INVALID_SOCK; } +SRTSOCKET +gst_srt_client_connect (GstElement * elem, int sender, + const gchar * host, guint16 port, int rendez_vous, + const gchar * bind_address, guint16 bind_port, int latency, + GSocketAddress ** socket_address, gint * poll_id) +{ + return gst_srt_client_connect_full (elem, sender, host, port, + rendez_vous, bind_address, bind_port, latency, socket_address, poll_id, + NULL, 0); +} + static gboolean plugin_init (GstPlugin * plugin) { diff --git a/ext/srt/gstsrt.h b/ext/srt/gstsrt.h index 7a7fec779c..2777cae2dd 100644 --- a/ext/srt/gstsrt.h +++ b/ext/srt/gstsrt.h @@ -31,6 +31,7 @@ #define SRT_DEFAULT_HOST "127.0.0.1" #define SRT_DEFAULT_URI SRT_URI_SCHEME"://"SRT_DEFAULT_HOST":"G_STRINGIFY(SRT_DEFAULT_PORT) #define SRT_DEFAULT_LATENCY 125 +#define SRT_DEFAULT_KEY_LENGTH 16 G_BEGIN_DECLS @@ -40,6 +41,13 @@ gst_srt_client_connect (GstElement * elem, int sender, const gchar * bind_address, guint16 bind_port, int latency, GSocketAddress ** socket_address, gint * poll_id); +SRTSOCKET +gst_srt_client_connect_full (GstElement * elem, int sender, + const gchar * host, guint16 port, int rendez_vous, + const gchar * bind_address, guint16 bind_port, int latency, + GSocketAddress ** socket_address, gint * poll_id, + gchar * passphrase, int key_length); + G_END_DECLS diff --git a/ext/srt/gstsrtbasesink.c b/ext/srt/gstsrtbasesink.c index a9fdc96c46..3f60020bbf 100644 --- a/ext/srt/gstsrtbasesink.c +++ b/ext/srt/gstsrtbasesink.c @@ -37,6 +37,9 @@ enum { PROP_URI = 1, PROP_LATENCY, + PROP_PASSPHRASE, + PROP_KEY_LENGTH, + /*< private > */ PROP_LAST }; @@ -73,6 +76,12 @@ gst_srt_base_sink_get_property (GObject * object, case PROP_LATENCY: g_value_set_int (value, self->latency); break; + case PROP_PASSPHRASE: + g_value_set_string (value, self->passphrase); + break; + case PROP_KEY_LENGTH: + g_value_set_int (value, self->key_length); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -93,6 +102,18 @@ gst_srt_base_sink_set_property (GObject * object, case PROP_LATENCY: self->latency = g_value_get_int (value); break; + case PROP_PASSPHRASE: + g_free (self->passphrase); + self->passphrase = g_value_dup_string (value); + break; + case PROP_KEY_LENGTH: + { + gint key_length = g_value_get_int (value); + g_return_if_fail (key_length == 16 || key_length == 24 + || key_length == 32); + self->key_length = key_length; + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -105,6 +126,7 @@ gst_srt_base_sink_finalize (GObject * object) GstSRTBaseSink *self = GST_SRT_BASE_SINK (object); g_clear_pointer (&self->uri, gst_uri_unref); + g_clear_pointer (&self->passphrase, g_free); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -166,6 +188,15 @@ gst_srt_base_sink_class_init (GstSRTBaseSinkClass * klass) G_MAXINT32, SRT_DEFAULT_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + properties[PROP_PASSPHRASE] = g_param_spec_string ("passphrase", "Passphrase", + "The password for the encrypted transmission", NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_KEY_LENGTH] = + g_param_spec_int ("key-length", "key length", + "Crypto key length in bytes{16,24,32}", 16, + 32, SRT_DEFAULT_KEY_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (gobject_class, PROP_LAST, properties); gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_srt_base_sink_render); @@ -177,6 +208,8 @@ gst_srt_base_sink_init (GstSRTBaseSink * self) self->uri = gst_uri_from_string (SRT_DEFAULT_URI); self->queued_buffers = NULL; self->latency = SRT_DEFAULT_LATENCY; + self->passphrase = NULL; + self->key_length = SRT_DEFAULT_KEY_LENGTH; } static GstURIType diff --git a/ext/srt/gstsrtbasesink.h b/ext/srt/gstsrtbasesink.h index 6e0b918353..45c5bcf073 100644 --- a/ext/srt/gstsrtbasesink.h +++ b/ext/srt/gstsrtbasesink.h @@ -47,6 +47,8 @@ struct _GstSRTBaseSink { GstUri *uri; GList *queued_buffers; gint latency; + gchar *passphrase; + gint key_length; /*< private >*/ gpointer _gst_reserved[GST_PADDING]; diff --git a/ext/srt/gstsrtbasesrc.c b/ext/srt/gstsrtbasesrc.c index a34ae38520..5558cd145d 100644 --- a/ext/srt/gstsrtbasesrc.c +++ b/ext/srt/gstsrtbasesrc.c @@ -37,6 +37,8 @@ enum PROP_URI = 1, PROP_CAPS, PROP_LATENCY, + PROP_PASSPHRASE, + PROP_KEY_LENGTH, /*< private > */ PROP_LAST @@ -78,6 +80,12 @@ gst_srt_base_src_get_property (GObject * object, case PROP_LATENCY: g_value_set_int (value, self->latency); break; + case PROP_PASSPHRASE: + g_value_set_string (value, self->passphrase); + break; + case PROP_KEY_LENGTH: + g_value_set_int (value, self->key_length); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -104,6 +112,18 @@ gst_srt_base_src_set_property (GObject * object, case PROP_LATENCY: self->latency = g_value_get_int (value); break; + case PROP_PASSPHRASE: + g_free (self->passphrase); + self->passphrase = g_value_dup_string (value); + break; + case PROP_KEY_LENGTH: + { + gint key_length = g_value_get_int (value); + g_return_if_fail (key_length == 16 || key_length == 24 + || key_length == 32); + self->key_length = key_length; + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -117,6 +137,7 @@ gst_srt_base_src_finalize (GObject * object) g_clear_pointer (&self->uri, gst_uri_unref); g_clear_pointer (&self->caps, gst_caps_unref); + g_clear_pointer (&self->passphrase, g_free); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -182,6 +203,15 @@ gst_srt_base_src_class_init (GstSRTBaseSrcClass * klass) G_MAXINT32, SRT_DEFAULT_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + properties[PROP_PASSPHRASE] = g_param_spec_string ("passphrase", "Passphrase", + "The password for the encrypted transmission", NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_KEY_LENGTH] = + g_param_spec_int ("key-length", "key length", + "Crypto key length in bytes{16,24,32}", 16, + 32, SRT_DEFAULT_KEY_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (gobject_class, PROP_LAST, properties); gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_srt_base_src_get_caps); @@ -194,6 +224,7 @@ gst_srt_base_src_init (GstSRTBaseSrc * self) gst_base_src_set_format (GST_BASE_SRC (self), GST_FORMAT_TIME); gst_base_src_set_live (GST_BASE_SRC (self), TRUE); self->latency = SRT_DEFAULT_LATENCY; + self->key_length = SRT_DEFAULT_KEY_LENGTH; } static GstURIType diff --git a/ext/srt/gstsrtbasesrc.h b/ext/srt/gstsrtbasesrc.h index bf7414ee8b..b55a05eead 100644 --- a/ext/srt/gstsrtbasesrc.h +++ b/ext/srt/gstsrtbasesrc.h @@ -44,6 +44,8 @@ struct _GstSRTBaseSrc { GstUri *uri; GstCaps *caps; gint latency; + gchar *passphrase; + gint key_length; /*< private >*/ gpointer _gst_reserved[GST_PADDING]; diff --git a/ext/srt/gstsrtclientsink.c b/ext/srt/gstsrtclientsink.c index 7371e08f09..40e49ae44c 100644 --- a/ext/srt/gstsrtclientsink.c +++ b/ext/srt/gstsrtclientsink.c @@ -157,10 +157,10 @@ gst_srt_client_sink_start (GstBaseSink * sink) GstSRTBaseSink *base = GST_SRT_BASE_SINK (sink); GstUri *uri = gst_uri_ref (GST_SRT_BASE_SINK (self)->uri); - priv->sock = gst_srt_client_connect (GST_ELEMENT (sink), FALSE, + priv->sock = gst_srt_client_connect_full (GST_ELEMENT (sink), FALSE, gst_uri_get_host (uri), gst_uri_get_port (uri), priv->rendez_vous, priv->bind_address, priv->bind_port, base->latency, - &priv->sockaddr, &priv->poll_id); + &priv->sockaddr, &priv->poll_id, base->passphrase, base->key_length); g_clear_pointer (&uri, gst_uri_unref); diff --git a/ext/srt/gstsrtclientsrc.c b/ext/srt/gstsrtclientsrc.c index 2ad35b98ee..a57b4faebe 100644 --- a/ext/srt/gstsrtclientsrc.c +++ b/ext/srt/gstsrtclientsrc.c @@ -240,10 +240,10 @@ gst_srt_client_src_start (GstBaseSrc * src) GstUri *uri = gst_uri_ref (base->uri); GSocketAddress *socket_address = NULL; - priv->sock = gst_srt_client_connect (GST_ELEMENT (src), FALSE, + priv->sock = gst_srt_client_connect_full (GST_ELEMENT (src), FALSE, gst_uri_get_host (uri), gst_uri_get_port (uri), priv->rendez_vous, priv->bind_address, priv->bind_port, base->latency, - &socket_address, &priv->poll_id); + &socket_address, &priv->poll_id, base->passphrase, base->key_length); g_clear_object (&socket_address); g_clear_pointer (&uri, gst_uri_unref); diff --git a/ext/srt/gstsrtserversink.c b/ext/srt/gstsrtserversink.c index a4095a016f..78b170fad4 100644 --- a/ext/srt/gstsrtserversink.c +++ b/ext/srt/gstsrtserversink.c @@ -321,6 +321,13 @@ gst_srt_server_sink_start (GstBaseSink * sink) srt_setsockopt (priv->sock, 0, SRTO_TSBPDDELAY, &lat, sizeof (int)); + if (base->passphrase != NULL && base->passphrase[0] != '\0') { + srt_setsockopt (priv->sock, 0, SRTO_PASSPHRASE, + base->passphrase, strlen (base->passphrase)); + srt_setsockopt (priv->sock, 0, SRTO_PBKEYLEN, + &base->key_length, sizeof (int)); + } + priv->poll_id = srt_epoll_create (); if (priv->poll_id == -1) { GST_WARNING_OBJECT (self, diff --git a/ext/srt/gstsrtserversrc.c b/ext/srt/gstsrtserversrc.c index 9b0f586991..271f4eb0b4 100644 --- a/ext/srt/gstsrtserversrc.c +++ b/ext/srt/gstsrtserversrc.c @@ -320,6 +320,13 @@ gst_srt_server_src_start (GstBaseSrc * src) srt_setsockopt (priv->sock, 0, SRTO_TSBPDDELAY, &lat, sizeof (int)); + if (base->passphrase != NULL && base->passphrase[0] != '\0') { + srt_setsockopt (priv->sock, 0, SRTO_PASSPHRASE, + base->passphrase, strlen (base->passphrase)); + srt_setsockopt (priv->sock, 0, SRTO_PBKEYLEN, + &base->key_length, sizeof (int)); + } + priv->poll_id = srt_epoll_create (); if (priv->poll_id == -1) { GST_ELEMENT_ERROR (self, LIBRARY, INIT, (NULL),