From 6183e99eec524b6f8bc5a2b9084c07ac8b345cbe Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 16 Mar 2015 17:34:05 +0100 Subject: [PATCH] dtls: Fix indention --- ext/dtls/gstdtlsagent.c | 306 ++++++----- ext/dtls/gstdtlscertificate.c | 383 ++++++------- ext/dtls/gstdtlsconnection.c | 1202 +++++++++++++++++++++-------------------- ext/dtls/gstdtlsdec.c | 819 +++++++++++++++------------- ext/dtls/gstdtlsenc.c | 733 +++++++++++++------------ ext/dtls/gstdtlssrtpbin.c | 323 +++++------ ext/dtls/gstdtlssrtpdec.c | 672 ++++++++++++----------- ext/dtls/gstdtlssrtpdemux.c | 157 +++--- ext/dtls/gstdtlssrtpenc.c | 624 +++++++++++---------- ext/dtls/plugin.c | 26 +- 10 files changed, 2741 insertions(+), 2504 deletions(-) diff --git a/ext/dtls/gstdtlsagent.c b/ext/dtls/gstdtlsagent.c index 67b552e..2e383b7 100644 --- a/ext/dtls/gstdtlsagent.c +++ b/ext/dtls/gstdtlsagent.c @@ -40,215 +40,235 @@ #include #if ER_DTLS_USE_GST_LOG - GST_DEBUG_CATEGORY_STATIC(er_dtls_agent_debug); +GST_DEBUG_CATEGORY_STATIC (er_dtls_agent_debug); # define GST_CAT_DEFAULT er_dtls_agent_debug - G_DEFINE_TYPE_WITH_CODE(ErDtlsAgent, er_dtls_agent, G_TYPE_OBJECT, - GST_DEBUG_CATEGORY_INIT(er_dtls_agent_debug, "gstdtlsagent", 0, "Ericsson DTLS Agent")); +G_DEFINE_TYPE_WITH_CODE (ErDtlsAgent, er_dtls_agent, G_TYPE_OBJECT, + GST_DEBUG_CATEGORY_INIT (er_dtls_agent_debug, "gstdtlsagent", 0, + "Ericsson DTLS Agent")); #else - G_DEFINE_TYPE(ErDtlsAgent, er_dtls_agent, G_TYPE_OBJECT); +G_DEFINE_TYPE (ErDtlsAgent, er_dtls_agent, G_TYPE_OBJECT); #endif #define ER_DTLS_AGENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), ER_TYPE_DTLS_AGENT, ErDtlsAgentPrivate)) -enum { - PROP_0, - PROP_CERTIFICATE, - NUM_PROPERTIES +enum +{ + PROP_0, + PROP_CERTIFICATE, + NUM_PROPERTIES }; static GParamSpec *properties[NUM_PROPERTIES]; -struct _ErDtlsAgentPrivate { - SSL_CTX *ssl_context; +struct _ErDtlsAgentPrivate +{ + SSL_CTX *ssl_context; - ErDtlsCertificate *certificate; + ErDtlsCertificate *certificate; }; -static void er_dtls_agent_finalize(GObject *gobject); -static void er_dtls_agent_set_property(GObject *, guint prop_id, const GValue *, GParamSpec *); -const gchar *er_dtls_agent_peek_id(ErDtlsAgent *); +static void er_dtls_agent_finalize (GObject * gobject); +static void er_dtls_agent_set_property (GObject *, guint prop_id, + const GValue *, GParamSpec *); +const gchar *er_dtls_agent_peek_id (ErDtlsAgent *); static GRWLock *ssl_locks; -static void ssl_locking_function(gint mode, gint lock_num, const gchar *file, gint line) +static void +ssl_locking_function (gint mode, gint lock_num, const gchar * file, gint line) { - gboolean locking; - gboolean reading; - GRWLock *lock; - - locking = mode & CRYPTO_LOCK; - reading = mode & CRYPTO_READ; - lock = &ssl_locks[lock_num]; - - LOG_LOG(NULL, "%s SSL lock for %s, thread=%p location=%s:%d", - locking ? "locking" : "unlocking", reading ? "reading" : "writing", - g_thread_self(), file, line); - - if (locking) { - if (reading) { - g_rw_lock_reader_lock(lock); - } else { - g_rw_lock_writer_lock(lock); - } + gboolean locking; + gboolean reading; + GRWLock *lock; + + locking = mode & CRYPTO_LOCK; + reading = mode & CRYPTO_READ; + lock = &ssl_locks[lock_num]; + + LOG_LOG (NULL, "%s SSL lock for %s, thread=%p location=%s:%d", + locking ? "locking" : "unlocking", reading ? "reading" : "writing", + g_thread_self (), file, line); + + if (locking) { + if (reading) { + g_rw_lock_reader_lock (lock); + } else { + g_rw_lock_writer_lock (lock); + } + } else { + if (reading) { + g_rw_lock_reader_unlock (lock); } else { - if (reading) { - g_rw_lock_reader_unlock(lock); - } else { - g_rw_lock_writer_unlock(lock); - } + g_rw_lock_writer_unlock (lock); } + } } -static gulong ssl_thread_id_function(void) +static gulong +ssl_thread_id_function (void) { - return (gulong) g_thread_self(); + return (gulong) g_thread_self (); } -void _er_dtls_init_openssl() +void +_er_dtls_init_openssl () { - static gsize is_init = 0; - gint i; - gint num_locks; - - if (g_once_init_enter(&is_init)) { - if (OPENSSL_VERSION_NUMBER < 0x1000100fL) { - LOG_WARNING(NULL, "Incorrect OpenSSL version, should be >= 1.0.1, is %s", OPENSSL_VERSION_TEXT); - g_assert_not_reached(); - } - - LOG_INFO(NULL, "initializing openssl %lx", OPENSSL_VERSION_NUMBER); - SSL_library_init(); - SSL_load_error_strings(); - ERR_load_BIO_strings(); - - num_locks = CRYPTO_num_locks(); - ssl_locks = g_new(GRWLock, num_locks); - for (i = 0; i < num_locks; ++i) { - g_rw_lock_init(&ssl_locks[i]); - } - CRYPTO_set_locking_callback(ssl_locking_function); - CRYPTO_set_id_callback(ssl_thread_id_function); - - g_once_init_leave(&is_init, 1); + static gsize is_init = 0; + gint i; + gint num_locks; + + if (g_once_init_enter (&is_init)) { + if (OPENSSL_VERSION_NUMBER < 0x1000100fL) { + LOG_WARNING (NULL, "Incorrect OpenSSL version, should be >= 1.0.1, is %s", + OPENSSL_VERSION_TEXT); + g_assert_not_reached (); + } + + LOG_INFO (NULL, "initializing openssl %lx", OPENSSL_VERSION_NUMBER); + SSL_library_init (); + SSL_load_error_strings (); + ERR_load_BIO_strings (); + + num_locks = CRYPTO_num_locks (); + ssl_locks = g_new (GRWLock, num_locks); + for (i = 0; i < num_locks; ++i) { + g_rw_lock_init (&ssl_locks[i]); } + CRYPTO_set_locking_callback (ssl_locking_function); + CRYPTO_set_id_callback (ssl_thread_id_function); + + g_once_init_leave (&is_init, 1); + } } -static void er_dtls_agent_class_init(ErDtlsAgentClass *klass) +static void +er_dtls_agent_class_init (ErDtlsAgentClass * klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - g_type_class_add_private(klass, sizeof(ErDtlsAgentPrivate)); + g_type_class_add_private (klass, sizeof (ErDtlsAgentPrivate)); - gobject_class->set_property = er_dtls_agent_set_property; - gobject_class->finalize = er_dtls_agent_finalize; + gobject_class->set_property = er_dtls_agent_set_property; + gobject_class->finalize = er_dtls_agent_finalize; - properties[PROP_CERTIFICATE] = - g_param_spec_object("certificate", - "ErDtlsCertificate", - "Sets the certificate of the agent", - ER_TYPE_DTLS_CERTIFICATE, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + properties[PROP_CERTIFICATE] = + g_param_spec_object ("certificate", + "ErDtlsCertificate", + "Sets the certificate of the agent", + ER_TYPE_DTLS_CERTIFICATE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties(gobject_class, NUM_PROPERTIES, properties); + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties); - _er_dtls_init_openssl(); + _er_dtls_init_openssl (); } -static void er_dtls_agent_init(ErDtlsAgent *self) +static void +er_dtls_agent_init (ErDtlsAgent * self) { - ErDtlsAgentPrivate *priv = ER_DTLS_AGENT_GET_PRIVATE(self); - self->priv = priv; + ErDtlsAgentPrivate *priv = ER_DTLS_AGENT_GET_PRIVATE (self); + self->priv = priv; - ERR_clear_error(); + ERR_clear_error (); - priv->ssl_context = SSL_CTX_new(DTLSv1_method()); - if (ERR_peek_error() || !priv->ssl_context) { - char buf[512]; + priv->ssl_context = SSL_CTX_new (DTLSv1_method ()); + if (ERR_peek_error () || !priv->ssl_context) { + char buf[512]; - priv->ssl_context = NULL; + priv->ssl_context = NULL; - LOG_WARNING(self, "Error creating SSL Context: %s", ERR_error_string(ERR_get_error(), buf)); + LOG_WARNING (self, "Error creating SSL Context: %s", + ERR_error_string (ERR_get_error (), buf)); - g_return_if_reached(); - } + g_return_if_reached (); + } - SSL_CTX_set_verify_depth(priv->ssl_context, 2); - SSL_CTX_set_tlsext_use_srtp(priv->ssl_context, "SRTP_AES128_CM_SHA1_80"); - SSL_CTX_set_cipher_list(priv->ssl_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); - SSL_CTX_set_read_ahead(priv->ssl_context, 1); + SSL_CTX_set_verify_depth (priv->ssl_context, 2); + SSL_CTX_set_tlsext_use_srtp (priv->ssl_context, "SRTP_AES128_CM_SHA1_80"); + SSL_CTX_set_cipher_list (priv->ssl_context, + "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + SSL_CTX_set_read_ahead (priv->ssl_context, 1); #if OPENSSL_VERSION_NUMBER >= 0x1000200fL - SSL_CTX_set_ecdh_auto(priv->ssl_context, 1); + SSL_CTX_set_ecdh_auto (priv->ssl_context, 1); #endif } -static void er_dtls_agent_finalize(GObject *gobject) +static void +er_dtls_agent_finalize (GObject * gobject) { - ErDtlsAgentPrivate *priv = ER_DTLS_AGENT(gobject)->priv; + ErDtlsAgentPrivate *priv = ER_DTLS_AGENT (gobject)->priv; - SSL_CTX_free(priv->ssl_context); - priv->ssl_context = NULL; + SSL_CTX_free (priv->ssl_context); + priv->ssl_context = NULL; - LOG_DEBUG(gobject, "finalized"); + LOG_DEBUG (gobject, "finalized"); - G_OBJECT_CLASS(er_dtls_agent_parent_class)->finalize(gobject); + G_OBJECT_CLASS (er_dtls_agent_parent_class)->finalize (gobject); } -static void er_dtls_agent_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +static void +er_dtls_agent_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) { - ErDtlsAgent *self = ER_DTLS_AGENT(object); - ErDtlsCertificate *certificate; + ErDtlsAgent *self = ER_DTLS_AGENT (object); + ErDtlsCertificate *certificate; - switch (prop_id) { + switch (prop_id) { case PROP_CERTIFICATE: - certificate = ER_DTLS_CERTIFICATE(g_value_get_object(value)); - g_return_if_fail(ER_IS_DTLS_CERTIFICATE(certificate)); - g_return_if_fail(self->priv->ssl_context); - - self->priv->certificate = certificate; - g_object_ref(certificate); - - if (!SSL_CTX_use_certificate(self->priv->ssl_context, _er_dtls_certificate_get_internal_certificate(certificate))) { - LOG_WARNING(self, "could not use certificate"); - g_return_if_reached(); - } - - if (!SSL_CTX_use_PrivateKey(self->priv->ssl_context, _er_dtls_certificate_get_internal_key(certificate))) { - LOG_WARNING(self, "could not use private key"); - g_return_if_reached(); - } - - if (!SSL_CTX_check_private_key(self->priv->ssl_context)) { - LOG_WARNING(self, "invalid private key"); - g_return_if_reached(); - } - break; + certificate = ER_DTLS_CERTIFICATE (g_value_get_object (value)); + g_return_if_fail (ER_IS_DTLS_CERTIFICATE (certificate)); + g_return_if_fail (self->priv->ssl_context); + + self->priv->certificate = certificate; + g_object_ref (certificate); + + if (!SSL_CTX_use_certificate (self->priv->ssl_context, + _er_dtls_certificate_get_internal_certificate (certificate))) { + LOG_WARNING (self, "could not use certificate"); + g_return_if_reached (); + } + + if (!SSL_CTX_use_PrivateKey (self->priv->ssl_context, + _er_dtls_certificate_get_internal_key (certificate))) { + LOG_WARNING (self, "could not use private key"); + g_return_if_reached (); + } + + if (!SSL_CTX_check_private_key (self->priv->ssl_context)) { + LOG_WARNING (self, "invalid private key"); + g_return_if_reached (); + } + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -ErDtlsCertificate *er_dtls_agent_get_certificate(ErDtlsAgent *self) +ErDtlsCertificate * +er_dtls_agent_get_certificate (ErDtlsAgent * self) { - g_return_val_if_fail(ER_IS_DTLS_AGENT(self), NULL); - if (self->priv->certificate) { - g_object_ref(self->priv->certificate); - } - return self->priv->certificate; + g_return_val_if_fail (ER_IS_DTLS_AGENT (self), NULL); + if (self->priv->certificate) { + g_object_ref (self->priv->certificate); + } + return self->priv->certificate; } -gchar *er_dtls_agent_get_certificate_pem(ErDtlsAgent *self) +gchar * +er_dtls_agent_get_certificate_pem (ErDtlsAgent * self) { - gchar *pem; - g_return_val_if_fail(ER_IS_DTLS_AGENT(self), NULL); - g_return_val_if_fail(ER_IS_DTLS_CERTIFICATE(self->priv->certificate), NULL); + gchar *pem; + g_return_val_if_fail (ER_IS_DTLS_AGENT (self), NULL); + g_return_val_if_fail (ER_IS_DTLS_CERTIFICATE (self->priv->certificate), NULL); - g_object_get(self->priv->certificate, "pem", &pem, NULL); + g_object_get (self->priv->certificate, "pem", &pem, NULL); - return pem; + return pem; } -const ErDtlsAgentContext _er_dtls_agent_peek_context(ErDtlsAgent *self) +const ErDtlsAgentContext +_er_dtls_agent_peek_context (ErDtlsAgent * self) { - g_return_val_if_fail(ER_IS_DTLS_AGENT(self), NULL); - return self->priv->ssl_context; + g_return_val_if_fail (ER_IS_DTLS_AGENT (self), NULL); + return self->priv->ssl_context; } diff --git a/ext/dtls/gstdtlscertificate.c b/ext/dtls/gstdtlscertificate.c index 1fc3760..27e1285 100644 --- a/ext/dtls/gstdtlscertificate.c +++ b/ext/dtls/gstdtlscertificate.c @@ -40,268 +40,287 @@ #include #if ER_DTLS_USE_GST_LOG - GST_DEBUG_CATEGORY_STATIC(er_dtls_certificate_debug); +GST_DEBUG_CATEGORY_STATIC (er_dtls_certificate_debug); # define GST_CAT_DEFAULT er_dtls_certificate_debug - G_DEFINE_TYPE_WITH_CODE(ErDtlsCertificate, er_dtls_certificate, G_TYPE_OBJECT, - GST_DEBUG_CATEGORY_INIT(er_dtls_certificate_debug, "gstdtlscertificate", 0, "Ericsson DTLS Certificate")); +G_DEFINE_TYPE_WITH_CODE (ErDtlsCertificate, er_dtls_certificate, G_TYPE_OBJECT, + GST_DEBUG_CATEGORY_INIT (er_dtls_certificate_debug, "gstdtlscertificate", 0, + "Ericsson DTLS Certificate")); #else - G_DEFINE_TYPE(ErDtlsCertificate, er_dtls_certificate, G_TYPE_OBJECT); +G_DEFINE_TYPE (ErDtlsCertificate, er_dtls_certificate, G_TYPE_OBJECT); #endif #define ER_DTLS_CERTIFICATE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), ER_TYPE_DTLS_CERTIFICATE, ErDtlsCertificatePrivate)) -enum { - PROP_0, - PROP_PEM, - NUM_PROPERTIES +enum +{ + PROP_0, + PROP_PEM, + NUM_PROPERTIES }; static GParamSpec *properties[NUM_PROPERTIES]; #define DEFAULT_PEM NULL -struct _ErDtlsCertificatePrivate { - X509 *x509; - EVP_PKEY *private_key; +struct _ErDtlsCertificatePrivate +{ + X509 *x509; + EVP_PKEY *private_key; - gchar *pem; + gchar *pem; }; -static void er_dtls_certificate_finalize(GObject *gobject); -static void er_dtls_certificate_set_property(GObject *, guint prop_id, const GValue *, GParamSpec *); -static void er_dtls_certificate_get_property(GObject *, guint prop_id, GValue *, GParamSpec *); +static void er_dtls_certificate_finalize (GObject * gobject); +static void er_dtls_certificate_set_property (GObject *, guint prop_id, + const GValue *, GParamSpec *); +static void er_dtls_certificate_get_property (GObject *, guint prop_id, + GValue *, GParamSpec *); -static void init_generated(ErDtlsCertificate *); -static void init_from_pem_string(ErDtlsCertificate *, const gchar *pem); +static void init_generated (ErDtlsCertificate *); +static void init_from_pem_string (ErDtlsCertificate *, const gchar * pem); -static void er_dtls_certificate_class_init(ErDtlsCertificateClass *klass) +static void +er_dtls_certificate_class_init (ErDtlsCertificateClass * klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - g_type_class_add_private(klass, sizeof(ErDtlsCertificatePrivate)); + g_type_class_add_private (klass, sizeof (ErDtlsCertificatePrivate)); - gobject_class->set_property = er_dtls_certificate_set_property; - gobject_class->get_property = er_dtls_certificate_get_property; + gobject_class->set_property = er_dtls_certificate_set_property; + gobject_class->get_property = er_dtls_certificate_get_property; - properties[PROP_PEM] = - g_param_spec_string("pem", - "Pem string", - "A string containing a X509 certificate and RSA private key in PEM format", - DEFAULT_PEM, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + properties[PROP_PEM] = + g_param_spec_string ("pem", + "Pem string", + "A string containing a X509 certificate and RSA private key in PEM format", + DEFAULT_PEM, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties(gobject_class, NUM_PROPERTIES, properties); + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties); - _er_dtls_init_openssl(); + _er_dtls_init_openssl (); - gobject_class->finalize = er_dtls_certificate_finalize; + gobject_class->finalize = er_dtls_certificate_finalize; } -static void er_dtls_certificate_init(ErDtlsCertificate *self) +static void +er_dtls_certificate_init (ErDtlsCertificate * self) { - ErDtlsCertificatePrivate *priv = ER_DTLS_CERTIFICATE_GET_PRIVATE(self); - self->priv = priv; + ErDtlsCertificatePrivate *priv = ER_DTLS_CERTIFICATE_GET_PRIVATE (self); + self->priv = priv; - priv->x509 = NULL; - priv->private_key = NULL; - priv->pem = NULL; + priv->x509 = NULL; + priv->private_key = NULL; + priv->pem = NULL; } -static void er_dtls_certificate_finalize(GObject *gobject) +static void +er_dtls_certificate_finalize (GObject * gobject) { - ErDtlsCertificatePrivate *priv = ER_DTLS_CERTIFICATE(gobject)->priv; + ErDtlsCertificatePrivate *priv = ER_DTLS_CERTIFICATE (gobject)->priv; - X509_free(priv->x509); - priv->x509 = NULL; + X509_free (priv->x509); + priv->x509 = NULL; - EVP_PKEY_free(priv->private_key); - priv->private_key = NULL; + EVP_PKEY_free (priv->private_key); + priv->private_key = NULL; - g_free(priv->pem); - priv->pem = NULL; + g_free (priv->pem); + priv->pem = NULL; - G_OBJECT_CLASS(er_dtls_certificate_parent_class)->finalize(gobject); + G_OBJECT_CLASS (er_dtls_certificate_parent_class)->finalize (gobject); } -static void er_dtls_certificate_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +static void +er_dtls_certificate_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) { - ErDtlsCertificate *self = ER_DTLS_CERTIFICATE(object); - const gchar *pem; + ErDtlsCertificate *self = ER_DTLS_CERTIFICATE (object); + const gchar *pem; - switch (prop_id) { + switch (prop_id) { case PROP_PEM: - pem = g_value_get_string(value); - if (pem) { - init_from_pem_string(self, pem); - } else { - init_generated(self); - } - break; + pem = g_value_get_string (value); + if (pem) { + init_from_pem_string (self, pem); + } else { + init_generated (self); + } + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -static void er_dtls_certificate_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +static void +er_dtls_certificate_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) { - ErDtlsCertificate *self = ER_DTLS_CERTIFICATE(object); + ErDtlsCertificate *self = ER_DTLS_CERTIFICATE (object); - switch (prop_id) { + switch (prop_id) { case PROP_PEM: - g_return_if_fail(self->priv->pem); - g_value_set_string(value, self->priv->pem); - break; + g_return_if_fail (self->priv->pem); + g_value_set_string (value, self->priv->pem); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -static void init_generated(ErDtlsCertificate *self) +static void +init_generated (ErDtlsCertificate * self) { - ErDtlsCertificatePrivate *priv = self->priv; - RSA *rsa; - X509_NAME *name = NULL; - - g_return_if_fail(!priv->x509); - g_return_if_fail(!priv->private_key); - - priv->private_key = EVP_PKEY_new(); - - if (!priv->private_key) { - LOG_WARNING(self, "failed to create private key"); - return; - } - - priv->x509 = X509_new(); - - if (!priv->x509) { - LOG_WARNING(self, "failed to create certificate"); - EVP_PKEY_free(priv->private_key); - priv->private_key = NULL; - return; - } - rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL); - - if (!rsa) { - LOG_WARNING(self, "failed to generate RSA"); - EVP_PKEY_free(priv->private_key); - priv->private_key = NULL; - X509_free(priv->x509); - priv->x509 = NULL; - return; - } - - if (!EVP_PKEY_assign_RSA(priv->private_key, rsa)) { - LOG_WARNING(self, "failed to assign RSA"); - RSA_free(rsa); - rsa = NULL; - EVP_PKEY_free(priv->private_key); - priv->private_key = NULL; - X509_free(priv->x509); - priv->x509 = NULL; - return; - } + ErDtlsCertificatePrivate *priv = self->priv; + RSA *rsa; + X509_NAME *name = NULL; + + g_return_if_fail (!priv->x509); + g_return_if_fail (!priv->private_key); + + priv->private_key = EVP_PKEY_new (); + + if (!priv->private_key) { + LOG_WARNING (self, "failed to create private key"); + return; + } + + priv->x509 = X509_new (); + + if (!priv->x509) { + LOG_WARNING (self, "failed to create certificate"); + EVP_PKEY_free (priv->private_key); + priv->private_key = NULL; + return; + } + rsa = RSA_generate_key (2048, RSA_F4, NULL, NULL); + + if (!rsa) { + LOG_WARNING (self, "failed to generate RSA"); + EVP_PKEY_free (priv->private_key); + priv->private_key = NULL; + X509_free (priv->x509); + priv->x509 = NULL; + return; + } + + if (!EVP_PKEY_assign_RSA (priv->private_key, rsa)) { + LOG_WARNING (self, "failed to assign RSA"); + RSA_free (rsa); rsa = NULL; + EVP_PKEY_free (priv->private_key); + priv->private_key = NULL; + X509_free (priv->x509); + priv->x509 = NULL; + return; + } + rsa = NULL; + + X509_set_version (priv->x509, 2); + ASN1_INTEGER_set (X509_get_serialNumber (priv->x509), 0); + X509_gmtime_adj (X509_get_notBefore (priv->x509), 0); + X509_gmtime_adj (X509_get_notAfter (priv->x509), 31536000L); /* A year */ + X509_set_pubkey (priv->x509, priv->private_key); + + name = X509_get_subject_name (priv->x509); + X509_NAME_add_entry_by_txt (name, "C", MBSTRING_ASC, (unsigned char *) "SE", + -1, -1, 0); + X509_NAME_add_entry_by_txt (name, "CN", MBSTRING_ASC, + (unsigned char *) "OpenWebRTC", -1, -1, 0); + X509_set_issuer_name (priv->x509, name); + name = NULL; + + if (!X509_sign (priv->x509, priv->private_key, EVP_sha256 ())) { + LOG_WARNING (self, "failed to sign certificate"); + EVP_PKEY_free (priv->private_key); + priv->private_key = NULL; + X509_free (priv->x509); + priv->x509 = NULL; + return; + } - X509_set_version(priv->x509, 2); - ASN1_INTEGER_set(X509_get_serialNumber(priv->x509), 0); - X509_gmtime_adj(X509_get_notBefore(priv->x509), 0); - X509_gmtime_adj(X509_get_notAfter(priv->x509), 31536000L); /* A year */ - X509_set_pubkey(priv->x509, priv->private_key); - - name = X509_get_subject_name(priv->x509); - X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char*) "SE", -1, -1, 0); - X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char*) "OpenWebRTC", -1, -1, 0); - X509_set_issuer_name(priv->x509, name); - name = NULL; - - if (!X509_sign(priv->x509, priv->private_key, EVP_sha256())) { - LOG_WARNING(self, "failed to sign certificate"); - EVP_PKEY_free(priv->private_key); - priv->private_key = NULL; - X509_free(priv->x509); - priv->x509 = NULL; - return; - } - - self->priv->pem = _er_dtls_x509_to_pem(priv->x509); + self->priv->pem = _er_dtls_x509_to_pem (priv->x509); } -static void init_from_pem_string(ErDtlsCertificate *self, const gchar *pem) +static void +init_from_pem_string (ErDtlsCertificate * self, const gchar * pem) { - ErDtlsCertificatePrivate *priv = self->priv; - BIO *bio; + ErDtlsCertificatePrivate *priv = self->priv; + BIO *bio; - g_return_if_fail(pem); - g_return_if_fail(!priv->x509); - g_return_if_fail(!priv->private_key); + g_return_if_fail (pem); + g_return_if_fail (!priv->x509); + g_return_if_fail (!priv->private_key); - bio = BIO_new_mem_buf((gpointer) pem, -1); - g_return_if_fail(bio); + bio = BIO_new_mem_buf ((gpointer) pem, -1); + g_return_if_fail (bio); - priv->x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); + priv->x509 = PEM_read_bio_X509 (bio, NULL, NULL, NULL); - if (!priv->x509) { - LOG_WARNING(self, "failed to read certificate from pem string"); - return; - } + if (!priv->x509) { + LOG_WARNING (self, "failed to read certificate from pem string"); + return; + } - (void) BIO_reset(bio); + (void) BIO_reset (bio); - priv->private_key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); + priv->private_key = PEM_read_bio_PrivateKey (bio, NULL, NULL, NULL); - BIO_free(bio); - bio = NULL; + BIO_free (bio); + bio = NULL; - if (!priv->private_key) { - LOG_WARNING(self, "failed to read private key from pem string"); - X509_free(priv->x509); - priv->x509 = NULL; - return; - } + if (!priv->private_key) { + LOG_WARNING (self, "failed to read private key from pem string"); + X509_free (priv->x509); + priv->x509 = NULL; + return; + } - self->priv->pem = g_strdup(pem); + self->priv->pem = g_strdup (pem); } -gchar *_er_dtls_x509_to_pem(gpointer x509) +gchar * +_er_dtls_x509_to_pem (gpointer x509) { #define ER_DTLS_BIO_BUFFER_SIZE 4096 - BIO *bio; - gchar buffer[ER_DTLS_BIO_BUFFER_SIZE] = {0}; - gint len; - gchar *pem = NULL; + BIO *bio; + gchar buffer[ER_DTLS_BIO_BUFFER_SIZE] = { 0 }; + gint len; + gchar *pem = NULL; - bio = BIO_new(BIO_s_mem()); - g_return_val_if_fail(bio, NULL); + bio = BIO_new (BIO_s_mem ()); + g_return_val_if_fail (bio, NULL); - if (!PEM_write_bio_X509(bio, (X509 *) x509)) { - g_warn_if_reached(); - goto beach; - } + if (!PEM_write_bio_X509 (bio, (X509 *) x509)) { + g_warn_if_reached (); + goto beach; + } - len = BIO_read(bio, buffer, ER_DTLS_BIO_BUFFER_SIZE); - if (!len) { - g_warn_if_reached(); - goto beach; - } + len = BIO_read (bio, buffer, ER_DTLS_BIO_BUFFER_SIZE); + if (!len) { + g_warn_if_reached (); + goto beach; + } - pem = g_strndup(buffer, len); + pem = g_strndup (buffer, len); beach: - BIO_free(bio); + BIO_free (bio); - return pem; + return pem; } -ErDtlsCertificateInternalCertificate _er_dtls_certificate_get_internal_certificate(ErDtlsCertificate *self) +ErDtlsCertificateInternalCertificate +_er_dtls_certificate_get_internal_certificate (ErDtlsCertificate * self) { - g_return_val_if_fail(ER_IS_DTLS_CERTIFICATE(self), NULL); - return self->priv->x509; + g_return_val_if_fail (ER_IS_DTLS_CERTIFICATE (self), NULL); + return self->priv->x509; } -ErDtlsCertificateInternalKey _er_dtls_certificate_get_internal_key(ErDtlsCertificate *self) +ErDtlsCertificateInternalKey +_er_dtls_certificate_get_internal_key (ErDtlsCertificate * self) { - g_return_val_if_fail(ER_IS_DTLS_CERTIFICATE(self), NULL); - return self->priv->private_key; + g_return_val_if_fail (ER_IS_DTLS_CERTIFICATE (self), NULL); + return self->priv->private_key; } diff --git a/ext/dtls/gstdtlsconnection.c b/ext/dtls/gstdtlsconnection.c index a2969df..f5505c2 100644 --- a/ext/dtls/gstdtlsconnection.c +++ b/ext/dtls/gstdtlsconnection.c @@ -42,12 +42,13 @@ #include #if ER_DTLS_USE_GST_LOG - GST_DEBUG_CATEGORY_STATIC(er_dtls_connection_debug); +GST_DEBUG_CATEGORY_STATIC (er_dtls_connection_debug); # define GST_CAT_DEFAULT er_dtls_connection_debug - G_DEFINE_TYPE_WITH_CODE(ErDtlsConnection, er_dtls_connection, G_TYPE_OBJECT, - GST_DEBUG_CATEGORY_INIT(er_dtls_connection_debug, "gstdtlsconnection", 0, "Ericsson DTLS Connection")); +G_DEFINE_TYPE_WITH_CODE (ErDtlsConnection, er_dtls_connection, G_TYPE_OBJECT, + GST_DEBUG_CATEGORY_INIT (er_dtls_connection_debug, "gstdtlsconnection", 0, + "Ericsson DTLS Connection")); #else - G_DEFINE_TYPE(ErDtlsConnection, er_dtls_connection, G_TYPE_OBJECT); +G_DEFINE_TYPE (ErDtlsConnection, er_dtls_connection, G_TYPE_OBJECT); #endif #define ER_DTLS_CONNECTION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), ER_TYPE_DTLS_CONNECTION, ErDtlsConnectionPrivate)) @@ -55,381 +56,401 @@ #define SRTP_KEY_LEN 16 #define SRTP_SALT_LEN 14 -enum { - SIGNAL_ON_ENCODER_KEY, - SIGNAL_ON_DECODER_KEY, - SIGNAL_ON_PEER_CERTIFICATE, - NUM_SIGNALS +enum +{ + SIGNAL_ON_ENCODER_KEY, + SIGNAL_ON_DECODER_KEY, + SIGNAL_ON_PEER_CERTIFICATE, + NUM_SIGNALS }; static guint signals[NUM_SIGNALS]; -enum { - PROP_0, - PROP_AGENT, - NUM_PROPERTIES +enum +{ + PROP_0, + PROP_AGENT, + NUM_PROPERTIES }; static GParamSpec *properties[NUM_PROPERTIES]; static int connection_ex_index; -struct _ErDtlsConnectionPrivate { - SSL *ssl; - BIO *bio; - GThread *thread; - - gboolean is_client; - gboolean is_alive; - gboolean keys_exported; - gboolean timeout_set; - - GMutex mutex; - GCond condition; - gpointer bio_buffer; - gint bio_buffer_len; - gint bio_buffer_offset; - - GClosure *send_closure; +struct _ErDtlsConnectionPrivate +{ + SSL *ssl; + BIO *bio; + GThread *thread; + + gboolean is_client; + gboolean is_alive; + gboolean keys_exported; + gboolean timeout_set; + + GMutex mutex; + GCond condition; + gpointer bio_buffer; + gint bio_buffer_len; + gint bio_buffer_offset; + + GClosure *send_closure; }; -static void er_dtls_connection_finalize(GObject *gobject); -static void er_dtls_connection_set_property(GObject *, guint prop_id, const GValue *, GParamSpec *); - -static void log_state(ErDtlsConnection *, const gchar *str); -static gpointer connection_timeout_thread_func(ErDtlsConnection *); -static void export_srtp_keys(ErDtlsConnection *); -static void openssl_poll(ErDtlsConnection *); -static int openssl_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); - -static BIO_METHOD* BIO_s_er_dtls_connection(); -static int bio_method_write(BIO *, const char *data, int size); -static int bio_method_read(BIO *, char *out_buffer, int size); -static long bio_method_ctrl(BIO *, int cmd, long arg1, void *arg2); -static int bio_method_new(BIO *); -static int bio_method_free(BIO *); - -static void er_dtls_connection_class_init(ErDtlsConnectionClass *klass) +static void er_dtls_connection_finalize (GObject * gobject); +static void er_dtls_connection_set_property (GObject *, guint prop_id, + const GValue *, GParamSpec *); + +static void log_state (ErDtlsConnection *, const gchar * str); +static gpointer connection_timeout_thread_func (ErDtlsConnection *); +static void export_srtp_keys (ErDtlsConnection *); +static void openssl_poll (ErDtlsConnection *); +static int openssl_verify_callback (int preverify_ok, + X509_STORE_CTX * x509_ctx); + +static BIO_METHOD *BIO_s_er_dtls_connection (); +static int bio_method_write (BIO *, const char *data, int size); +static int bio_method_read (BIO *, char *out_buffer, int size); +static long bio_method_ctrl (BIO *, int cmd, long arg1, void *arg2); +static int bio_method_new (BIO *); +static int bio_method_free (BIO *); + +static void +er_dtls_connection_class_init (ErDtlsConnectionClass * klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - g_type_class_add_private(klass, sizeof(ErDtlsConnectionPrivate)); + g_type_class_add_private (klass, sizeof (ErDtlsConnectionPrivate)); - gobject_class->set_property = er_dtls_connection_set_property; + gobject_class->set_property = er_dtls_connection_set_property; - connection_ex_index = SSL_get_ex_new_index(0, "gstdtlsagent connection index", NULL, NULL, NULL); + connection_ex_index = + SSL_get_ex_new_index (0, "gstdtlsagent connection index", NULL, NULL, + NULL); - signals[SIGNAL_ON_DECODER_KEY] = - g_signal_new("on-decoder-key", G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_generic, G_TYPE_NONE, 3, - G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT); + signals[SIGNAL_ON_DECODER_KEY] = + g_signal_new ("on-decoder-key", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + g_cclosure_marshal_generic, G_TYPE_NONE, 3, + G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT); - signals[SIGNAL_ON_ENCODER_KEY] = - g_signal_new("on-encoder-key", G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_generic, G_TYPE_NONE, 3, - G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT); + signals[SIGNAL_ON_ENCODER_KEY] = + g_signal_new ("on-encoder-key", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + g_cclosure_marshal_generic, G_TYPE_NONE, 3, + G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT); - signals[SIGNAL_ON_PEER_CERTIFICATE] = - g_signal_new("on-peer-certificate", G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 1, - G_TYPE_STRING); + signals[SIGNAL_ON_PEER_CERTIFICATE] = + g_signal_new ("on-peer-certificate", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 1, G_TYPE_STRING); - properties[PROP_AGENT] = - g_param_spec_object("agent", - "ERDtlsAgent", - "Agent to use in creation of the connection", - ER_TYPE_DTLS_AGENT, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + properties[PROP_AGENT] = + g_param_spec_object ("agent", + "ERDtlsAgent", + "Agent to use in creation of the connection", + ER_TYPE_DTLS_AGENT, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties(gobject_class, NUM_PROPERTIES, properties); + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties); - _er_dtls_init_openssl(); + _er_dtls_init_openssl (); - gobject_class->finalize = er_dtls_connection_finalize; + gobject_class->finalize = er_dtls_connection_finalize; } -static void er_dtls_connection_init(ErDtlsConnection *self) +static void +er_dtls_connection_init (ErDtlsConnection * self) { - ErDtlsConnectionPrivate *priv = ER_DTLS_CONNECTION_GET_PRIVATE(self); - self->priv = priv; + ErDtlsConnectionPrivate *priv = ER_DTLS_CONNECTION_GET_PRIVATE (self); + self->priv = priv; - priv->ssl = NULL; - priv->bio = NULL; - priv->thread = NULL; + priv->ssl = NULL; + priv->bio = NULL; + priv->thread = NULL; - priv->send_closure = NULL; + priv->send_closure = NULL; - priv->is_client = FALSE; - priv->is_alive = TRUE; - priv->keys_exported = FALSE; - priv->timeout_set = FALSE; + priv->is_client = FALSE; + priv->is_alive = TRUE; + priv->keys_exported = FALSE; + priv->timeout_set = FALSE; - priv->bio_buffer = NULL; - priv->bio_buffer_len = 0; - priv->bio_buffer_offset = 0; + priv->bio_buffer = NULL; + priv->bio_buffer_len = 0; + priv->bio_buffer_offset = 0; - g_mutex_init(&priv->mutex); - g_cond_init(&priv->condition); + g_mutex_init (&priv->mutex); + g_cond_init (&priv->condition); } -static void er_dtls_connection_finalize(GObject *gobject) +static void +er_dtls_connection_finalize (GObject * gobject) { - ErDtlsConnection *self = ER_DTLS_CONNECTION(gobject); - ErDtlsConnectionPrivate *priv = self->priv; + ErDtlsConnection *self = ER_DTLS_CONNECTION (gobject); + ErDtlsConnectionPrivate *priv = self->priv; - SSL_free(priv->ssl); - priv->ssl = NULL; + SSL_free (priv->ssl); + priv->ssl = NULL; - if (priv->send_closure) { - g_closure_unref(priv->send_closure); - priv->send_closure = NULL; - } + if (priv->send_closure) { + g_closure_unref (priv->send_closure); + priv->send_closure = NULL; + } - g_mutex_clear(&priv->mutex); - g_cond_clear(&priv->condition); + g_mutex_clear (&priv->mutex); + g_cond_clear (&priv->condition); - LOG_DEBUG(self, "finalized"); + LOG_DEBUG (self, "finalized"); - G_OBJECT_CLASS(er_dtls_connection_parent_class)->finalize(gobject); + G_OBJECT_CLASS (er_dtls_connection_parent_class)->finalize (gobject); } -static void er_dtls_connection_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +static void +er_dtls_connection_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) { - ErDtlsConnection *self = ER_DTLS_CONNECTION(object); - ErDtlsAgent *agent; - ErDtlsConnectionPrivate *priv = self->priv; - SSL_CTX *ssl_context; + ErDtlsConnection *self = ER_DTLS_CONNECTION (object); + ErDtlsAgent *agent; + ErDtlsConnectionPrivate *priv = self->priv; + SSL_CTX *ssl_context; - switch (prop_id) { + switch (prop_id) { case PROP_AGENT: - g_return_if_fail(!priv->ssl); - agent = ER_DTLS_AGENT(g_value_get_object(value)); - g_return_if_fail(ER_IS_DTLS_AGENT(agent)); + g_return_if_fail (!priv->ssl); + agent = ER_DTLS_AGENT (g_value_get_object (value)); + g_return_if_fail (ER_IS_DTLS_AGENT (agent)); - ssl_context = _er_dtls_agent_peek_context(agent); + ssl_context = _er_dtls_agent_peek_context (agent); - priv->ssl = SSL_new(ssl_context); - g_return_if_fail(priv->ssl); + priv->ssl = SSL_new (ssl_context); + g_return_if_fail (priv->ssl); - priv->bio = BIO_new(BIO_s_er_dtls_connection()); - g_return_if_fail(priv->bio); + priv->bio = BIO_new (BIO_s_er_dtls_connection ()); + g_return_if_fail (priv->bio); - priv->bio->ptr = self; - SSL_set_bio(priv->ssl, priv->bio, priv->bio); + priv->bio->ptr = self; + SSL_set_bio (priv->ssl, priv->bio, priv->bio); - SSL_set_verify(priv->ssl, - SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, openssl_verify_callback); - SSL_set_ex_data(priv->ssl, connection_ex_index, self); + SSL_set_verify (priv->ssl, + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + openssl_verify_callback); + SSL_set_ex_data (priv->ssl, connection_ex_index, self); - log_state(self, "connection created"); - break; + log_state (self, "connection created"); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -void er_dtls_connection_start(ErDtlsConnection *self, gboolean is_client) +void +er_dtls_connection_start (ErDtlsConnection * self, gboolean is_client) { - g_return_if_fail(ER_IS_DTLS_CONNECTION(self)); - ErDtlsConnectionPrivate *priv = self->priv; - g_return_if_fail(priv->send_closure); - g_return_if_fail(priv->ssl); - g_return_if_fail(priv->bio); - - LOG_TRACE(self, "locking @ start"); - g_mutex_lock(&priv->mutex); - LOG_TRACE(self, "locked @ start"); - - priv->is_alive = TRUE; - priv->timeout_set = FALSE; - priv->bio_buffer = NULL; - priv->bio_buffer_len = 0; - priv->bio_buffer_offset = 0; - priv->keys_exported = FALSE; - - priv->is_client = is_client; - if (priv->is_client) { - SSL_set_connect_state(priv->ssl); - } else { - SSL_set_accept_state(priv->ssl); - } - log_state(self, "initial state set"); + g_return_if_fail (ER_IS_DTLS_CONNECTION (self)); + ErDtlsConnectionPrivate *priv = self->priv; + g_return_if_fail (priv->send_closure); + g_return_if_fail (priv->ssl); + g_return_if_fail (priv->bio); + + LOG_TRACE (self, "locking @ start"); + g_mutex_lock (&priv->mutex); + LOG_TRACE (self, "locked @ start"); + + priv->is_alive = TRUE; + priv->timeout_set = FALSE; + priv->bio_buffer = NULL; + priv->bio_buffer_len = 0; + priv->bio_buffer_offset = 0; + priv->keys_exported = FALSE; + + priv->is_client = is_client; + if (priv->is_client) { + SSL_set_connect_state (priv->ssl); + } else { + SSL_set_accept_state (priv->ssl); + } + log_state (self, "initial state set"); + + openssl_poll (self); + + log_state (self, "first poll done"); + priv->thread = NULL; + + LOG_TRACE (self, "unlocking @ start"); + g_mutex_unlock (&priv->mutex); +} - openssl_poll(self); +void +er_dtls_connection_start_timeout (ErDtlsConnection * self) +{ + g_return_if_fail (ER_IS_DTLS_CONNECTION (self)); - log_state(self, "first poll done"); - priv->thread = NULL; + ErDtlsConnectionPrivate *priv = self->priv; + GError *error = NULL; + gchar *thread_name = g_strdup_printf ("connection_thread_%p", self); - LOG_TRACE(self, "unlocking @ start"); - g_mutex_unlock(&priv->mutex); -} + LOG_TRACE (self, "locking @ start_timeout"); + g_mutex_lock (&priv->mutex); + LOG_TRACE (self, "locked @ start_timeout"); -void er_dtls_connection_start_timeout(ErDtlsConnection *self) -{ - g_return_if_fail(ER_IS_DTLS_CONNECTION(self)); - - ErDtlsConnectionPrivate *priv = self->priv; - GError *error = NULL; - gchar *thread_name = g_strdup_printf("connection_thread_%p", self); - - LOG_TRACE(self, "locking @ start_timeout"); - g_mutex_lock(&priv->mutex); - LOG_TRACE(self, "locked @ start_timeout"); - - LOG_INFO(self, "starting connection timeout"); - priv->thread = g_thread_try_new(thread_name, - (GThreadFunc) connection_timeout_thread_func, self, &error); - if (error) { - LOG_WARNING(self, "error creating connection thread: %s (%d)", - error->message, error->code); - g_clear_error(&error); - } + LOG_INFO (self, "starting connection timeout"); + priv->thread = g_thread_try_new (thread_name, + (GThreadFunc) connection_timeout_thread_func, self, &error); + if (error) { + LOG_WARNING (self, "error creating connection thread: %s (%d)", + error->message, error->code); + g_clear_error (&error); + } - g_free(thread_name); + g_free (thread_name); - LOG_TRACE(self, "unlocking @ start_timeout"); - g_mutex_unlock(&priv->mutex); + LOG_TRACE (self, "unlocking @ start_timeout"); + g_mutex_unlock (&priv->mutex); } -void er_dtls_connection_stop(ErDtlsConnection *self) +void +er_dtls_connection_stop (ErDtlsConnection * self) { - g_return_if_fail(ER_IS_DTLS_CONNECTION(self)); - g_return_if_fail(self->priv->ssl); - g_return_if_fail(self->priv->bio); + g_return_if_fail (ER_IS_DTLS_CONNECTION (self)); + g_return_if_fail (self->priv->ssl); + g_return_if_fail (self->priv->bio); - LOG_DEBUG(self, "stopping connection"); + LOG_DEBUG (self, "stopping connection"); - LOG_TRACE(self, "locking @ stop"); - g_mutex_lock(&self->priv->mutex); - LOG_TRACE(self, "locked @ stop"); + LOG_TRACE (self, "locking @ stop"); + g_mutex_lock (&self->priv->mutex); + LOG_TRACE (self, "locked @ stop"); - self->priv->is_alive = FALSE; - LOG_TRACE(self, "signaling @ stop"); - g_cond_signal(&self->priv->condition); - LOG_TRACE(self, "signaled @ stop"); + self->priv->is_alive = FALSE; + LOG_TRACE (self, "signaling @ stop"); + g_cond_signal (&self->priv->condition); + LOG_TRACE (self, "signaled @ stop"); - LOG_TRACE(self, "unlocking @ stop"); - g_mutex_unlock(&self->priv->mutex); + LOG_TRACE (self, "unlocking @ stop"); + g_mutex_unlock (&self->priv->mutex); - LOG_DEBUG(self, "stopped connection"); + LOG_DEBUG (self, "stopped connection"); } -void er_dtls_connection_close(ErDtlsConnection *self) +void +er_dtls_connection_close (ErDtlsConnection * self) { - g_return_if_fail(ER_IS_DTLS_CONNECTION(self)); - g_return_if_fail(self->priv->ssl); - g_return_if_fail(self->priv->bio); + g_return_if_fail (ER_IS_DTLS_CONNECTION (self)); + g_return_if_fail (self->priv->ssl); + g_return_if_fail (self->priv->bio); - LOG_DEBUG(self, "closing connection"); + LOG_DEBUG (self, "closing connection"); - LOG_TRACE(self, "locking @ close"); - g_mutex_lock(&self->priv->mutex); - LOG_TRACE(self, "locked @ close"); + LOG_TRACE (self, "locking @ close"); + g_mutex_lock (&self->priv->mutex); + LOG_TRACE (self, "locked @ close"); - if (self->priv->is_alive) { - self->priv->is_alive = FALSE; - g_cond_signal(&self->priv->condition); - } + if (self->priv->is_alive) { + self->priv->is_alive = FALSE; + g_cond_signal (&self->priv->condition); + } - LOG_TRACE(self, "unlocking @ close"); - g_mutex_unlock(&self->priv->mutex); + LOG_TRACE (self, "unlocking @ close"); + g_mutex_unlock (&self->priv->mutex); - if (self->priv->thread) { - g_thread_join(self->priv->thread); - self->priv->thread = NULL; - } + if (self->priv->thread) { + g_thread_join (self->priv->thread); + self->priv->thread = NULL; + } - LOG_DEBUG(self, "closed connection"); + LOG_DEBUG (self, "closed connection"); } -void er_dtls_connection_set_send_callback(ErDtlsConnection *self, GClosure *closure) +void +er_dtls_connection_set_send_callback (ErDtlsConnection * self, + GClosure * closure) { - g_return_if_fail(ER_IS_DTLS_CONNECTION(self)); + g_return_if_fail (ER_IS_DTLS_CONNECTION (self)); - LOG_TRACE(self, "locking @ set_send_callback"); - g_mutex_lock(&self->priv->mutex); - LOG_TRACE(self, "locked @ set_send_callback"); + LOG_TRACE (self, "locking @ set_send_callback"); + g_mutex_lock (&self->priv->mutex); + LOG_TRACE (self, "locked @ set_send_callback"); - self->priv->send_closure = closure; + self->priv->send_closure = closure; - if (closure && G_CLOSURE_NEEDS_MARSHAL(closure)) { - g_closure_set_marshal(closure, g_cclosure_marshal_generic); - } + if (closure && G_CLOSURE_NEEDS_MARSHAL (closure)) { + g_closure_set_marshal (closure, g_cclosure_marshal_generic); + } - LOG_TRACE(self, "unlocking @ set_send_callback"); - g_mutex_unlock(&self->priv->mutex); + LOG_TRACE (self, "unlocking @ set_send_callback"); + g_mutex_unlock (&self->priv->mutex); } -gint er_dtls_connection_process(ErDtlsConnection *self, gpointer data, gint len) +gint +er_dtls_connection_process (ErDtlsConnection * self, gpointer data, gint len) { - g_return_val_if_fail(ER_IS_DTLS_CONNECTION(self), 0); - ErDtlsConnectionPrivate *priv = self->priv; - gint result; + g_return_val_if_fail (ER_IS_DTLS_CONNECTION (self), 0); + ErDtlsConnectionPrivate *priv = self->priv; + gint result; - g_return_val_if_fail(self->priv->ssl, 0); - g_return_val_if_fail(self->priv->bio, 0); + g_return_val_if_fail (self->priv->ssl, 0); + g_return_val_if_fail (self->priv->bio, 0); - LOG_TRACE(self, "locking @ process"); - g_mutex_lock(&priv->mutex); - LOG_TRACE(self, "locked @ process"); + LOG_TRACE (self, "locking @ process"); + g_mutex_lock (&priv->mutex); + LOG_TRACE (self, "locked @ process"); - g_warn_if_fail(!priv->bio_buffer); + g_warn_if_fail (!priv->bio_buffer); - priv->bio_buffer = data; - priv->bio_buffer_len = len; - priv->bio_buffer_offset = 0; + priv->bio_buffer = data; + priv->bio_buffer_len = len; + priv->bio_buffer_offset = 0; - log_state(self, "process start"); + log_state (self, "process start"); - if (SSL_want_write(priv->ssl)) { - openssl_poll(self); - log_state(self, "process want write, after poll"); - } + if (SSL_want_write (priv->ssl)) { + openssl_poll (self); + log_state (self, "process want write, after poll"); + } - result = SSL_read(priv->ssl, data, len); + result = SSL_read (priv->ssl, data, len); - log_state(self, "process after read"); + log_state (self, "process after read"); - openssl_poll(self); + openssl_poll (self); - log_state(self, "process after poll"); + log_state (self, "process after poll"); - LOG_DEBUG(self, "read result: %d", result); + LOG_DEBUG (self, "read result: %d", result); - LOG_TRACE(self, "unlocking @ process"); - g_mutex_unlock(&priv->mutex); + LOG_TRACE (self, "unlocking @ process"); + g_mutex_unlock (&priv->mutex); - return result; + return result; } -gint er_dtls_connection_send(ErDtlsConnection *self, gpointer data, gint len) +gint +er_dtls_connection_send (ErDtlsConnection * self, gpointer data, gint len) { - g_return_val_if_fail(ER_IS_DTLS_CONNECTION(self), 0); - int ret = 0; + g_return_val_if_fail (ER_IS_DTLS_CONNECTION (self), 0); + int ret = 0; - g_return_val_if_fail(self->priv->ssl, 0); - g_return_val_if_fail(self->priv->bio, 0); + g_return_val_if_fail (self->priv->ssl, 0); + g_return_val_if_fail (self->priv->bio, 0); - LOG_TRACE(self, "locking @ send"); - g_mutex_lock(&self->priv->mutex); - LOG_TRACE(self, "locked @ send"); + LOG_TRACE (self, "locking @ send"); + g_mutex_lock (&self->priv->mutex); + LOG_TRACE (self, "locked @ send"); - if (SSL_is_init_finished(self->priv->ssl)) { - ret = SSL_write(self->priv->ssl, data, len); - LOG_DEBUG(self, "data sent: input was %d B, output is %d B", len, ret); - } else { - LOG_WARNING(self, "tried to send data before handshake was complete"); - ret = 0; - } + if (SSL_is_init_finished (self->priv->ssl)) { + ret = SSL_write (self->priv->ssl, data, len); + LOG_DEBUG (self, "data sent: input was %d B, output is %d B", len, ret); + } else { + LOG_WARNING (self, "tried to send data before handshake was complete"); + ret = 0; + } - LOG_TRACE(self, "unlocking @ send"); - g_mutex_unlock(&self->priv->mutex); + LOG_TRACE (self, "unlocking @ send"); + g_mutex_unlock (&self->priv->mutex); - return ret; + return ret; } /* @@ -442,253 +463,273 @@ gint er_dtls_connection_send(ErDtlsConnection *self, gpointer data, gint len) ###### ####### ## ## */ -static void log_state(ErDtlsConnection *self, const gchar *str) +static void +log_state (ErDtlsConnection * self, const gchar * str) { - ErDtlsConnectionPrivate *priv = self->priv; - guint states = 0; - - states |= (!!SSL_is_init_finished(priv->ssl) << 0); - states |= (!!SSL_in_init(priv->ssl) << 4); - states |= (!!SSL_in_before(priv->ssl) << 8); - states |= (!!SSL_in_connect_init(priv->ssl) << 12); - states |= (!!SSL_in_accept_init(priv->ssl) << 16); - states |= (!!SSL_want_write(priv->ssl) << 20); - states |= (!!SSL_want_read(priv->ssl) << 24); - - LOG_LOG(self, "%s: role=%s buf=(%d,%p:%d/%d) %x|%x %s", - str, - priv->is_client ? "client" : "server", - pqueue_size(priv->ssl->d1->sent_messages), - priv->bio_buffer, - priv->bio_buffer_offset, - priv->bio_buffer_len, - states, SSL_get_state(priv->ssl), - SSL_state_string_long(priv->ssl)); + ErDtlsConnectionPrivate *priv = self->priv; + guint states = 0; + + states |= (! !SSL_is_init_finished (priv->ssl) << 0); + states |= (! !SSL_in_init (priv->ssl) << 4); + states |= (! !SSL_in_before (priv->ssl) << 8); + states |= (! !SSL_in_connect_init (priv->ssl) << 12); + states |= (! !SSL_in_accept_init (priv->ssl) << 16); + states |= (! !SSL_want_write (priv->ssl) << 20); + states |= (! !SSL_want_read (priv->ssl) << 24); + + LOG_LOG (self, "%s: role=%s buf=(%d,%p:%d/%d) %x|%x %s", + str, + priv->is_client ? "client" : "server", + pqueue_size (priv->ssl->d1->sent_messages), + priv->bio_buffer, + priv->bio_buffer_offset, + priv->bio_buffer_len, + states, SSL_get_state (priv->ssl), SSL_state_string_long (priv->ssl)); } -static gpointer connection_timeout_thread_func(ErDtlsConnection *self) +static gpointer +connection_timeout_thread_func (ErDtlsConnection * self) { - ErDtlsConnectionPrivate *priv = self->priv; - struct timeval timeout; - gint64 end_time, wait_time; - gint ret; - - while (priv->is_alive) { - LOG_TRACE(self, "locking @ timeout"); - g_mutex_lock(&priv->mutex); - LOG_TRACE(self, "locked @ timeout"); - - if (DTLSv1_get_timeout(priv->ssl, &timeout)) { - wait_time = timeout.tv_sec * G_USEC_PER_SEC + timeout.tv_usec; - - if (wait_time) { - LOG_DEBUG(self, "waiting for %" G_GINT64_FORMAT " usec", wait_time); - - end_time = g_get_monotonic_time() + wait_time; - - LOG_TRACE(self, "wait @ timeout"); - g_cond_wait_until(&priv->condition, &priv->mutex, end_time); - LOG_TRACE(self, "continued @ timeout"); - } - - ret = DTLSv1_handle_timeout(priv->ssl); - - LOG_DEBUG(self, "handle timeout returned %d, is_alive: %d", ret, priv->is_alive); - - if (ret < 0) { - LOG_TRACE(self, "unlocking @ timeout failed"); - g_mutex_unlock(&priv->mutex); - break; /* self failed after DTLS1_TMO_ALERT_COUNT (12) attempts */ - } - - if (ret > 0) { - log_state(self, "handling timeout before poll"); - openssl_poll(self); - log_state(self, "handling timeout after poll"); - } - } else { - LOG_DEBUG(self, "waiting indefinitely"); - - priv->timeout_set = FALSE; - - while (!priv->timeout_set && priv->is_alive) { - LOG_TRACE(self, "wait @ timeout"); - g_cond_wait(&priv->condition, &priv->mutex); - } - LOG_TRACE(self, "continued @ timeout"); - } - - LOG_TRACE(self, "unlocking @ timeout"); - g_mutex_unlock(&priv->mutex); - } + ErDtlsConnectionPrivate *priv = self->priv; + struct timeval timeout; + gint64 end_time, wait_time; + gint ret; - log_state(self, "timeout thread exiting"); + while (priv->is_alive) { + LOG_TRACE (self, "locking @ timeout"); + g_mutex_lock (&priv->mutex); + LOG_TRACE (self, "locked @ timeout"); - return NULL; -} + if (DTLSv1_get_timeout (priv->ssl, &timeout)) { + wait_time = timeout.tv_sec * G_USEC_PER_SEC + timeout.tv_usec; -static void export_srtp_keys(ErDtlsConnection *self) -{ - typedef struct { - guint8 v[SRTP_KEY_LEN]; - } Key; - - typedef struct { - guint8 v[SRTP_SALT_LEN]; - } Salt; - - struct { - Key client_key; - Key server_key; - Salt client_salt; - Salt server_salt; - } exported_keys; - - struct { - Key key; - Salt salt; - } client_key, server_key; - - SRTP_PROTECTION_PROFILE *profile; - ErDtlsSrtpCipher cipher; - ErDtlsSrtpAuth auth; - gint success; - - static gchar export_string[] = "EXTRACTOR-dtls_srtp"; - - success = SSL_export_keying_material(self->priv->ssl, - (gpointer) &exported_keys, 60, export_string, strlen(export_string), NULL, 0, 0); - - if (!success) { - LOG_WARNING(self, "failed to export srtp keys"); - return; - } + if (wait_time) { + LOG_DEBUG (self, "waiting for %" G_GINT64_FORMAT " usec", wait_time); - profile = SSL_get_selected_srtp_profile(self->priv->ssl); + end_time = g_get_monotonic_time () + wait_time; - LOG_INFO(self, "keys received, profile is %s", profile->name); + LOG_TRACE (self, "wait @ timeout"); + g_cond_wait_until (&priv->condition, &priv->mutex, end_time); + LOG_TRACE (self, "continued @ timeout"); + } - switch (profile->id) { - case SRTP_AES128_CM_SHA1_80: - cipher = ER_DTLS_SRTP_CIPHER_AES_128_ICM; - auth = ER_DTLS_SRTP_AUTH_HMAC_SHA1_80; - break; - case SRTP_AES128_CM_SHA1_32: - cipher = ER_DTLS_SRTP_CIPHER_AES_128_ICM; - auth = ER_DTLS_SRTP_AUTH_HMAC_SHA1_32; - break; - default: - LOG_WARNING(self, "invalid crypto suite set by handshake"); - goto beach; - } + ret = DTLSv1_handle_timeout (priv->ssl); + + LOG_DEBUG (self, "handle timeout returned %d, is_alive: %d", ret, + priv->is_alive); - client_key.key = exported_keys.client_key; - server_key.key = exported_keys.server_key; - client_key.salt = exported_keys.client_salt; - server_key.salt = exported_keys.server_salt; + if (ret < 0) { + LOG_TRACE (self, "unlocking @ timeout failed"); + g_mutex_unlock (&priv->mutex); + break; /* self failed after DTLS1_TMO_ALERT_COUNT (12) attempts */ + } - if (self->priv->is_client) { - g_signal_emit(self, signals[SIGNAL_ON_ENCODER_KEY], 0, &client_key, cipher, auth); - g_signal_emit(self, signals[SIGNAL_ON_DECODER_KEY], 0, &server_key, cipher, auth); + if (ret > 0) { + log_state (self, "handling timeout before poll"); + openssl_poll (self); + log_state (self, "handling timeout after poll"); + } } else { - g_signal_emit(self, signals[SIGNAL_ON_ENCODER_KEY], 0, &server_key, cipher, auth); - g_signal_emit(self, signals[SIGNAL_ON_DECODER_KEY], 0, &client_key, cipher, auth); + LOG_DEBUG (self, "waiting indefinitely"); + + priv->timeout_set = FALSE; + + while (!priv->timeout_set && priv->is_alive) { + LOG_TRACE (self, "wait @ timeout"); + g_cond_wait (&priv->condition, &priv->mutex); + } + LOG_TRACE (self, "continued @ timeout"); } + LOG_TRACE (self, "unlocking @ timeout"); + g_mutex_unlock (&priv->mutex); + } + + log_state (self, "timeout thread exiting"); + + return NULL; +} + +static void +export_srtp_keys (ErDtlsConnection * self) +{ + typedef struct + { + guint8 v[SRTP_KEY_LEN]; + } Key; + + typedef struct + { + guint8 v[SRTP_SALT_LEN]; + } Salt; + + struct + { + Key client_key; + Key server_key; + Salt client_salt; + Salt server_salt; + } exported_keys; + + struct + { + Key key; + Salt salt; + } client_key, server_key; + + SRTP_PROTECTION_PROFILE *profile; + ErDtlsSrtpCipher cipher; + ErDtlsSrtpAuth auth; + gint success; + + static gchar export_string[] = "EXTRACTOR-dtls_srtp"; + + success = SSL_export_keying_material (self->priv->ssl, + (gpointer) & exported_keys, 60, export_string, strlen (export_string), + NULL, 0, 0); + + if (!success) { + LOG_WARNING (self, "failed to export srtp keys"); + return; + } + + profile = SSL_get_selected_srtp_profile (self->priv->ssl); + + LOG_INFO (self, "keys received, profile is %s", profile->name); + + switch (profile->id) { + case SRTP_AES128_CM_SHA1_80: + cipher = ER_DTLS_SRTP_CIPHER_AES_128_ICM; + auth = ER_DTLS_SRTP_AUTH_HMAC_SHA1_80; + break; + case SRTP_AES128_CM_SHA1_32: + cipher = ER_DTLS_SRTP_CIPHER_AES_128_ICM; + auth = ER_DTLS_SRTP_AUTH_HMAC_SHA1_32; + break; + default: + LOG_WARNING (self, "invalid crypto suite set by handshake"); + goto beach; + } + + client_key.key = exported_keys.client_key; + server_key.key = exported_keys.server_key; + client_key.salt = exported_keys.client_salt; + server_key.salt = exported_keys.server_salt; + + if (self->priv->is_client) { + g_signal_emit (self, signals[SIGNAL_ON_ENCODER_KEY], 0, &client_key, cipher, + auth); + g_signal_emit (self, signals[SIGNAL_ON_DECODER_KEY], 0, &server_key, cipher, + auth); + } else { + g_signal_emit (self, signals[SIGNAL_ON_ENCODER_KEY], 0, &server_key, cipher, + auth); + g_signal_emit (self, signals[SIGNAL_ON_DECODER_KEY], 0, &client_key, cipher, + auth); + } + beach: - self->priv->keys_exported = TRUE; + self->priv->keys_exported = TRUE; } -static void openssl_poll(ErDtlsConnection *self) +static void +openssl_poll (ErDtlsConnection * self) { - int ret; - char buf[512]; - int error; + int ret; + char buf[512]; + int error; - log_state(self, "poll: before handshake"); + log_state (self, "poll: before handshake"); - ret = SSL_do_handshake(self->priv->ssl); + ret = SSL_do_handshake (self->priv->ssl); - log_state(self, "poll: after handshake"); + log_state (self, "poll: after handshake"); - if (ret == 1) { - if (!self->priv->keys_exported) { - LOG_INFO(self, "handshake just completed successfully, exporting keys"); - export_srtp_keys(self); - } else { - LOG_INFO(self, "handshake is completed"); - } - return; + if (ret == 1) { + if (!self->priv->keys_exported) { + LOG_INFO (self, "handshake just completed successfully, exporting keys"); + export_srtp_keys (self); + } else { + LOG_INFO (self, "handshake is completed"); + } + return; + } else { + if (ret == 0) { + LOG_DEBUG (self, "do_handshake encountered EOF"); + } else if (ret == -1) { + LOG_WARNING (self, "do_handshake encountered BIO error"); } else { - if (ret == 0) { - LOG_DEBUG(self, "do_handshake encountered EOF"); - } else if (ret == -1) { - LOG_WARNING(self, "do_handshake encountered BIO error"); - } else { - LOG_DEBUG(self, "do_handshake returned %d", ret); - } + LOG_DEBUG (self, "do_handshake returned %d", ret); } + } - error = SSL_get_error(self->priv->ssl, ret); + error = SSL_get_error (self->priv->ssl, ret); - switch (error) { + switch (error) { case SSL_ERROR_NONE: - LOG_WARNING(self, "no error, handshake should be done"); - break; + LOG_WARNING (self, "no error, handshake should be done"); + break; case SSL_ERROR_SSL: - LOG_LOG(self, "SSL error %d: %s", error, ERR_error_string(ERR_get_error(), buf)); - break; + LOG_LOG (self, "SSL error %d: %s", error, + ERR_error_string (ERR_get_error (), buf)); + break; case SSL_ERROR_WANT_READ: - LOG_LOG(self, "SSL wants read"); - break; + LOG_LOG (self, "SSL wants read"); + break; case SSL_ERROR_WANT_WRITE: - LOG_LOG(self, "SSL wants write"); - break; - case SSL_ERROR_SYSCALL: { - LOG_LOG(self, "SSL syscall (error) : %lu", ERR_get_error()); - break; + LOG_LOG (self, "SSL wants write"); + break; + case SSL_ERROR_SYSCALL:{ + LOG_LOG (self, "SSL syscall (error) : %lu", ERR_get_error ()); + break; } default: - LOG_WARNING(self, "Unknown SSL error: %d, ret: %d", error, ret); - } + LOG_WARNING (self, "Unknown SSL error: %d, ret: %d", error, ret); + } } -static int openssl_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) +static int +openssl_verify_callback (int preverify_ok, X509_STORE_CTX * x509_ctx) { - ErDtlsConnection *self; - SSL *ssl; - BIO *bio; - gchar *pem = NULL; - gboolean accepted = FALSE; - - ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); - self = SSL_get_ex_data(ssl, connection_ex_index); - g_return_val_if_fail(ER_IS_DTLS_CONNECTION(self), FALSE); - - pem = _er_dtls_x509_to_pem(x509_ctx->cert); - - if (!pem) { - LOG_WARNING(self, "failed to convert received certificate to pem format"); + ErDtlsConnection *self; + SSL *ssl; + BIO *bio; + gchar *pem = NULL; + gboolean accepted = FALSE; + + ssl = + X509_STORE_CTX_get_ex_data (x509_ctx, + SSL_get_ex_data_X509_STORE_CTX_idx ()); + self = SSL_get_ex_data (ssl, connection_ex_index); + g_return_val_if_fail (ER_IS_DTLS_CONNECTION (self), FALSE); + + pem = _er_dtls_x509_to_pem (x509_ctx->cert); + + if (!pem) { + LOG_WARNING (self, "failed to convert received certificate to pem format"); + } else { + bio = BIO_new (BIO_s_mem ()); + if (bio) { + gchar buffer[2048]; + gint len; + + len = + X509_NAME_print_ex (bio, X509_get_subject_name (x509_ctx->cert), 1, + XN_FLAG_MULTILINE); + BIO_read (bio, buffer, len); + buffer[len] = '\0'; + LOG_DEBUG (self, "Peer certificate received:\n%s", buffer); + BIO_free (bio); } else { - bio = BIO_new(BIO_s_mem()); - if (bio) { - gchar buffer[2048]; - gint len; - - len = X509_NAME_print_ex(bio, X509_get_subject_name(x509_ctx->cert), 1, XN_FLAG_MULTILINE); - BIO_read(bio, buffer, len); - buffer[len] = '\0'; - LOG_DEBUG(self, "Peer certificate received:\n%s", buffer); - BIO_free(bio); - } else { - LOG_DEBUG(self, "failed to create certificate print membio"); - } - - g_signal_emit(self, signals[SIGNAL_ON_PEER_CERTIFICATE], 0, pem, &accepted); - g_free(pem); + LOG_DEBUG (self, "failed to create certificate print membio"); } - return accepted; + g_signal_emit (self, signals[SIGNAL_ON_PEER_CERTIFICATE], 0, pem, + &accepted); + g_free (pem); + } + + return accepted; } /* @@ -702,151 +743,158 @@ static int openssl_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) */ static BIO_METHOD custom_bio_methods = { - BIO_TYPE_BIO, - "stream", - bio_method_write, - bio_method_read, - NULL, - NULL, - bio_method_ctrl, - bio_method_new, - bio_method_free, - NULL, + BIO_TYPE_BIO, + "stream", + bio_method_write, + bio_method_read, + NULL, + NULL, + bio_method_ctrl, + bio_method_new, + bio_method_free, + NULL, }; -static BIO_METHOD* BIO_s_er_dtls_connection() +static BIO_METHOD * +BIO_s_er_dtls_connection () { - return &custom_bio_methods; + return &custom_bio_methods; } -static int bio_method_write(BIO *bio, const char *data, int size) +static int +bio_method_write (BIO * bio, const char *data, int size) { - ErDtlsConnection *self = ER_DTLS_CONNECTION(bio->ptr); + ErDtlsConnection *self = ER_DTLS_CONNECTION (bio->ptr); - LOG_LOG(self, "BIO: writing %d", size); + LOG_LOG (self, "BIO: writing %d", size); - if (self->priv->send_closure) { - GValue values[3] = { G_VALUE_INIT }; + if (self->priv->send_closure) { + GValue values[3] = { G_VALUE_INIT }; - g_value_init(&values[0], ER_TYPE_DTLS_CONNECTION); - g_value_set_object(&values[0], self); + g_value_init (&values[0], ER_TYPE_DTLS_CONNECTION); + g_value_set_object (&values[0], self); - g_value_init(&values[1], G_TYPE_POINTER); - g_value_set_pointer(&values[1], (gpointer) data); + g_value_init (&values[1], G_TYPE_POINTER); + g_value_set_pointer (&values[1], (gpointer) data); - g_value_init(&values[2], G_TYPE_INT); - g_value_set_int(&values[2], size); + g_value_init (&values[2], G_TYPE_INT); + g_value_set_int (&values[2], size); - g_closure_invoke(self->priv->send_closure, NULL, 3, values, NULL); - } + g_closure_invoke (self->priv->send_closure, NULL, 3, values, NULL); + } - return size; + return size; } -static int bio_method_read(BIO *bio, char *out_buffer, int size) +static int +bio_method_read (BIO * bio, char *out_buffer, int size) { - ErDtlsConnection *self = ER_DTLS_CONNECTION(bio->ptr); - ErDtlsConnectionPrivate *priv = self->priv; - guint internal_size; - gint copy_size; + ErDtlsConnection *self = ER_DTLS_CONNECTION (bio->ptr); + ErDtlsConnectionPrivate *priv = self->priv; + guint internal_size; + gint copy_size; - internal_size = priv->bio_buffer_len - priv->bio_buffer_offset; + internal_size = priv->bio_buffer_len - priv->bio_buffer_offset; - if (!priv->bio_buffer) { - LOG_LOG(self, "BIO: EOF"); - return 0; - } + if (!priv->bio_buffer) { + LOG_LOG (self, "BIO: EOF"); + return 0; + } - if (!out_buffer || size <= 0) { - LOG_WARNING(self, "BIO: read got invalid arguments"); - if (internal_size) { - BIO_set_retry_read(bio); - } - return internal_size; + if (!out_buffer || size <= 0) { + LOG_WARNING (self, "BIO: read got invalid arguments"); + if (internal_size) { + BIO_set_retry_read (bio); } + return internal_size; + } - if (size > internal_size) { - copy_size = internal_size; - } else { - copy_size = size; - } + if (size > internal_size) { + copy_size = internal_size; + } else { + copy_size = size; + } - LOG_DEBUG(self, "reading %d/%d bytes %d at offset %d, output buff size is %d", - copy_size, priv->bio_buffer_len, internal_size, priv->bio_buffer_offset, size); + LOG_DEBUG (self, + "reading %d/%d bytes %d at offset %d, output buff size is %d", copy_size, + priv->bio_buffer_len, internal_size, priv->bio_buffer_offset, size); - memcpy(out_buffer, priv->bio_buffer + priv->bio_buffer_offset, copy_size); - priv->bio_buffer_offset += copy_size; + memcpy (out_buffer, priv->bio_buffer + priv->bio_buffer_offset, copy_size); + priv->bio_buffer_offset += copy_size; - if (priv->bio_buffer_len == priv->bio_buffer_offset) { - priv->bio_buffer = NULL; - } + if (priv->bio_buffer_len == priv->bio_buffer_offset) { + priv->bio_buffer = NULL; + } - return copy_size; + return copy_size; } -static long bio_method_ctrl(BIO *bio, int cmd, long arg1, void *arg2) +static long +bio_method_ctrl (BIO * bio, int cmd, long arg1, void *arg2) { - ErDtlsConnection *self = ER_DTLS_CONNECTION(bio->ptr); - ErDtlsConnectionPrivate *priv = self->priv; + ErDtlsConnection *self = ER_DTLS_CONNECTION (bio->ptr); + ErDtlsConnectionPrivate *priv = self->priv; - switch (cmd) { + switch (cmd) { case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: - LOG_LOG(self, "BIO: Timeout set"); - priv->timeout_set = TRUE; - g_cond_signal(&priv->condition); - return 1; + LOG_LOG (self, "BIO: Timeout set"); + priv->timeout_set = TRUE; + g_cond_signal (&priv->condition); + return 1; case BIO_CTRL_RESET: - priv->bio_buffer = NULL; - priv->bio_buffer_len = 0; - priv->bio_buffer_offset = 0; - LOG_LOG(self, "BIO: EOF reset"); - return 1; - case BIO_CTRL_EOF: { - gint eof = !(priv->bio_buffer_len - priv->bio_buffer_offset); - LOG_LOG(self, "BIO: EOF query returned %d", eof); - return eof; + priv->bio_buffer = NULL; + priv->bio_buffer_len = 0; + priv->bio_buffer_offset = 0; + LOG_LOG (self, "BIO: EOF reset"); + return 1; + case BIO_CTRL_EOF:{ + gint eof = !(priv->bio_buffer_len - priv->bio_buffer_offset); + LOG_LOG (self, "BIO: EOF query returned %d", eof); + return eof; } case BIO_CTRL_WPENDING: - LOG_LOG(self, "BIO: pending write"); - return 1; - case BIO_CTRL_PENDING: { - gint pending = priv->bio_buffer_len - priv->bio_buffer_offset; - LOG_LOG(self, "BIO: %d bytes pending", pending); - return pending; + LOG_LOG (self, "BIO: pending write"); + return 1; + case BIO_CTRL_PENDING:{ + gint pending = priv->bio_buffer_len - priv->bio_buffer_offset; + LOG_LOG (self, "BIO: %d bytes pending", pending); + return pending; } case BIO_CTRL_FLUSH: - LOG_LOG(self, "BIO: flushing"); - return 1; + LOG_LOG (self, "BIO: flushing"); + return 1; case BIO_CTRL_DGRAM_QUERY_MTU: - LOG_DEBUG(self, "BIO: MTU query, returning 0..."); - return 0; + LOG_DEBUG (self, "BIO: MTU query, returning 0..."); + return 0; case BIO_CTRL_DGRAM_MTU_EXCEEDED: - LOG_WARNING(self, "BIO: MTU exceeded"); - return 0; + LOG_WARNING (self, "BIO: MTU exceeded"); + return 0; default: - LOG_LOG(self, "BIO: unhandled ctrl, %d", cmd); - return 0; - } + LOG_LOG (self, "BIO: unhandled ctrl, %d", cmd); + return 0; + } } -static int bio_method_new(BIO *bio) +static int +bio_method_new (BIO * bio) { - LOG_LOG(NULL, "BIO: new"); + LOG_LOG (NULL, "BIO: new"); - bio->shutdown = 0; - bio->init = 1; + bio->shutdown = 0; + bio->init = 1; - return 1; + return 1; } -static int bio_method_free(BIO *bio) +static int +bio_method_free (BIO * bio) { - if (!bio) { - LOG_LOG(NULL, "BIO free called with null bio"); - return 0; - } - - LOG_LOG(ER_DTLS_CONNECTION(bio->ptr), "BIO free"); + if (!bio) { + LOG_LOG (NULL, "BIO free called with null bio"); return 0; + } + + LOG_LOG (ER_DTLS_CONNECTION (bio->ptr), "BIO free"); + return 0; } diff --git a/ext/dtls/gstdtlsdec.c b/ext/dtls/gstdtlsdec.c index 70865be..f4ca997 100644 --- a/ext/dtls/gstdtlsdec.c +++ b/ext/dtls/gstdtlsdec.c @@ -31,46 +31,46 @@ #include "gstdtlscertificate.h" -static GstStaticPadTemplate sink_template = - GST_STATIC_PAD_TEMPLATE("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS("application/x-dtls") +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-dtls") ); -static GstStaticPadTemplate src_template = - GST_STATIC_PAD_TEMPLATE("src", - GST_PAD_SRC, - GST_PAD_REQUEST, - GST_STATIC_CAPS_ANY - ); +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); -GST_DEBUG_CATEGORY_STATIC(er_dtls_dec_debug); +GST_DEBUG_CATEGORY_STATIC (er_dtls_dec_debug); #define GST_CAT_DEFAULT er_dtls_dec_debug #define gst_er_dtls_dec_parent_class parent_class -G_DEFINE_TYPE_WITH_CODE(GstErDtlsDec, gst_er_dtls_dec, GST_TYPE_ELEMENT, - GST_DEBUG_CATEGORY_INIT(er_dtls_dec_debug, "erdtlsdec", 0, "Ericsson DTLS Decoder")); +G_DEFINE_TYPE_WITH_CODE (GstErDtlsDec, gst_er_dtls_dec, GST_TYPE_ELEMENT, + GST_DEBUG_CATEGORY_INIT (er_dtls_dec_debug, "erdtlsdec", 0, + "Ericsson DTLS Decoder")); #define UNUSED(param) while (0) { (void)(param); } -enum { - SIGNAL_ON_KEY_RECEIVED, - NUM_SIGNALS +enum +{ + SIGNAL_ON_KEY_RECEIVED, + NUM_SIGNALS }; static guint signals[NUM_SIGNALS]; -enum { - PROP_0, - PROP_CONNECTION_ID, - PROP_PEM, - PROP_PEER_PEM, - - PROP_DECODER_KEY, - PROP_SRTP_CIPHER, - PROP_SRTP_AUTH, - NUM_PROPERTIES +enum +{ + PROP_0, + PROP_CONNECTION_ID, + PROP_PEM, + PROP_PEER_PEM, + + PROP_DECODER_KEY, + PROP_SRTP_CIPHER, + PROP_SRTP_AUTH, + NUM_PROPERTIES }; static GParamSpec *properties[NUM_PROPERTIES]; @@ -84,524 +84,565 @@ static GParamSpec *properties[NUM_PROPERTIES]; #define DEFAULT_SRTP_AUTH 0 -static void gst_er_dtls_dec_finalize(GObject *); -static void gst_er_dtls_dec_dispose(GObject *); -static void gst_er_dtls_dec_set_property(GObject *, guint prop_id, const GValue *, GParamSpec *); -static void gst_er_dtls_dec_get_property(GObject *, guint prop_id, GValue *, GParamSpec *); - -static GstStateChangeReturn gst_er_dtls_dec_change_state(GstElement *, GstStateChange); -static GstPad *gst_er_dtls_dec_request_new_pad(GstElement *, GstPadTemplate *, const gchar *name, const GstCaps *); -static void gst_er_dtls_dec_release_pad(GstElement *, GstPad *); - -static void on_key_received(ErDtlsConnection *, gpointer key, guint cipher, guint auth, GstErDtlsDec *); -static gboolean on_peer_certificate_received(ErDtlsConnection *, gchar *pem, GstErDtlsDec *); -static GstFlowReturn sink_chain(GstPad *, GstObject *parent, GstBuffer *); - -static ErDtlsAgent *get_agent_by_pem(const gchar *pem); -static void agent_weak_ref_notify(gchar *pem, ErDtlsAgent *); -static void create_connection(GstErDtlsDec *, gchar *id); -static void connection_weak_ref_notify(gchar *id, ErDtlsConnection *); - -static void gst_er_dtls_dec_class_init(GstErDtlsDecClass *klass) +static void gst_er_dtls_dec_finalize (GObject *); +static void gst_er_dtls_dec_dispose (GObject *); +static void gst_er_dtls_dec_set_property (GObject *, guint prop_id, + const GValue *, GParamSpec *); +static void gst_er_dtls_dec_get_property (GObject *, guint prop_id, GValue *, + GParamSpec *); + +static GstStateChangeReturn gst_er_dtls_dec_change_state (GstElement *, + GstStateChange); +static GstPad *gst_er_dtls_dec_request_new_pad (GstElement *, GstPadTemplate *, + const gchar * name, const GstCaps *); +static void gst_er_dtls_dec_release_pad (GstElement *, GstPad *); + +static void on_key_received (ErDtlsConnection *, gpointer key, guint cipher, + guint auth, GstErDtlsDec *); +static gboolean on_peer_certificate_received (ErDtlsConnection *, gchar * pem, + GstErDtlsDec *); +static GstFlowReturn sink_chain (GstPad *, GstObject * parent, GstBuffer *); + +static ErDtlsAgent *get_agent_by_pem (const gchar * pem); +static void agent_weak_ref_notify (gchar * pem, ErDtlsAgent *); +static void create_connection (GstErDtlsDec *, gchar * id); +static void connection_weak_ref_notify (gchar * id, ErDtlsConnection *); + +static void +gst_er_dtls_dec_class_init (GstErDtlsDecClass * klass) { - GObjectClass *gobject_class; - GstElementClass *element_class; - - gobject_class = (GObjectClass *) klass; - element_class = (GstElementClass *) klass; - - gobject_class->finalize = GST_DEBUG_FUNCPTR(gst_er_dtls_dec_finalize); - gobject_class->dispose = GST_DEBUG_FUNCPTR(gst_er_dtls_dec_dispose); - gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_er_dtls_dec_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_er_dtls_dec_get_property); - - element_class->change_state = GST_DEBUG_FUNCPTR(gst_er_dtls_dec_change_state); - element_class->request_new_pad = GST_DEBUG_FUNCPTR(gst_er_dtls_dec_request_new_pad); - element_class->release_pad = GST_DEBUG_FUNCPTR(gst_er_dtls_dec_release_pad); - - signals[SIGNAL_ON_KEY_RECEIVED] = - g_signal_new("on-key-received", G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_generic, G_TYPE_NONE, 0); - - properties[PROP_CONNECTION_ID] = - g_param_spec_string("connection-id", - "Connection id", - "Every encoder/decoder pair should have the same, unique, connection-id", - DEFAULT_CONNECTION_ID, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - properties[PROP_PEM] = - g_param_spec_string("pem", - "PEM string", - "A string containing a X509 certificate and RSA private key in PEM format", - DEFAULT_PEM, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - properties[PROP_PEER_PEM] = - g_param_spec_string("peer-pem", - "Peer PEM string", - "The X509 certificate received in the DTLS handshake, in PEM format", - DEFAULT_PEER_PEM, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - properties[PROP_DECODER_KEY] = - g_param_spec_boxed("decoder-key", - "Decoder key", - "SRTP key that should be used by the decider", - GST_TYPE_CAPS, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - properties[PROP_SRTP_CIPHER] = - g_param_spec_uint("srtp-cipher", - "SRTP cipher", - "The SRTP cipher selected in the DTLS handshake. " - "The value will be set to an ErDtlsSrtpCipher.", - 0, ER_DTLS_SRTP_CIPHER_AES_128_ICM, DEFAULT_SRTP_CIPHER, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - properties[PROP_SRTP_AUTH] = - g_param_spec_uint("srtp-auth", - "SRTP authentication", - "The SRTP authentication selected in the DTLS handshake. " - "The value will be set to an ErDtlsSrtpAuth.", - 0, ER_DTLS_SRTP_AUTH_HMAC_SHA1_80, DEFAULT_SRTP_AUTH, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobject_class, NUM_PROPERTIES, properties); - - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&src_template)); - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&sink_template)); - - gst_element_class_set_static_metadata(element_class, - "DTLS Decoder", - "Decoder/Network/DTLS", - "Decodes DTLS packets", - "Patrik Oldsberg patrik.oldsberg@ericsson.com"); + GObjectClass *gobject_class; + GstElementClass *element_class; + + gobject_class = (GObjectClass *) klass; + element_class = (GstElementClass *) klass; + + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_er_dtls_dec_finalize); + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_er_dtls_dec_dispose); + gobject_class->set_property = + GST_DEBUG_FUNCPTR (gst_er_dtls_dec_set_property); + gobject_class->get_property = + GST_DEBUG_FUNCPTR (gst_er_dtls_dec_get_property); + + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_er_dtls_dec_change_state); + element_class->request_new_pad = + GST_DEBUG_FUNCPTR (gst_er_dtls_dec_request_new_pad); + element_class->release_pad = GST_DEBUG_FUNCPTR (gst_er_dtls_dec_release_pad); + + signals[SIGNAL_ON_KEY_RECEIVED] = + g_signal_new ("on-key-received", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + g_cclosure_marshal_generic, G_TYPE_NONE, 0); + + properties[PROP_CONNECTION_ID] = + g_param_spec_string ("connection-id", + "Connection id", + "Every encoder/decoder pair should have the same, unique, connection-id", + DEFAULT_CONNECTION_ID, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_PEM] = + g_param_spec_string ("pem", + "PEM string", + "A string containing a X509 certificate and RSA private key in PEM format", + DEFAULT_PEM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_PEER_PEM] = + g_param_spec_string ("peer-pem", + "Peer PEM string", + "The X509 certificate received in the DTLS handshake, in PEM format", + DEFAULT_PEER_PEM, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + properties[PROP_DECODER_KEY] = + g_param_spec_boxed ("decoder-key", + "Decoder key", + "SRTP key that should be used by the decider", + GST_TYPE_CAPS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + properties[PROP_SRTP_CIPHER] = + g_param_spec_uint ("srtp-cipher", + "SRTP cipher", + "The SRTP cipher selected in the DTLS handshake. " + "The value will be set to an ErDtlsSrtpCipher.", + 0, ER_DTLS_SRTP_CIPHER_AES_128_ICM, DEFAULT_SRTP_CIPHER, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + properties[PROP_SRTP_AUTH] = + g_param_spec_uint ("srtp-auth", + "SRTP authentication", + "The SRTP authentication selected in the DTLS handshake. " + "The value will be set to an ErDtlsSrtpAuth.", + 0, ER_DTLS_SRTP_AUTH_HMAC_SHA1_80, DEFAULT_SRTP_AUTH, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + + gst_element_class_set_static_metadata (element_class, + "DTLS Decoder", + "Decoder/Network/DTLS", + "Decodes DTLS packets", "Patrik Oldsberg patrik.oldsberg@ericsson.com"); } -static void gst_er_dtls_dec_init(GstErDtlsDec *self) +static void +gst_er_dtls_dec_init (GstErDtlsDec * self) { - GstPad *sink; - self->agent = get_agent_by_pem(NULL); - self->connection_id = NULL; - self->connection = NULL; - self->peer_pem = NULL; + GstPad *sink; + self->agent = get_agent_by_pem (NULL); + self->connection_id = NULL; + self->connection = NULL; + self->peer_pem = NULL; - self->decoder_key = NULL; - self->srtp_cipher = DEFAULT_SRTP_CIPHER; - self->srtp_auth = DEFAULT_SRTP_AUTH; + self->decoder_key = NULL; + self->srtp_cipher = DEFAULT_SRTP_CIPHER; + self->srtp_auth = DEFAULT_SRTP_AUTH; - g_mutex_init(&self->src_mutex); + g_mutex_init (&self->src_mutex); - self->src = NULL; - sink = gst_pad_new_from_static_template(&sink_template, "sink"); - g_return_if_fail(sink); + self->src = NULL; + sink = gst_pad_new_from_static_template (&sink_template, "sink"); + g_return_if_fail (sink); - gst_pad_set_chain_function(sink, GST_DEBUG_FUNCPTR(sink_chain)); + gst_pad_set_chain_function (sink, GST_DEBUG_FUNCPTR (sink_chain)); - gst_element_add_pad(GST_ELEMENT(self), sink); + gst_element_add_pad (GST_ELEMENT (self), sink); } -static void gst_er_dtls_dec_finalize(GObject *object) +static void +gst_er_dtls_dec_finalize (GObject * object) { - GstErDtlsDec *self = GST_ER_DTLS_DEC(object); + GstErDtlsDec *self = GST_ER_DTLS_DEC (object); - if (self->decoder_key) { - gst_buffer_unref(self->decoder_key); - self->decoder_key = NULL; - } + if (self->decoder_key) { + gst_buffer_unref (self->decoder_key); + self->decoder_key = NULL; + } - g_free(self->connection_id); - self->connection_id = NULL; + g_free (self->connection_id); + self->connection_id = NULL; - g_free(self->peer_pem); - self->peer_pem = NULL; + g_free (self->peer_pem); + self->peer_pem = NULL; - g_mutex_clear(&self->src_mutex); + g_mutex_clear (&self->src_mutex); - GST_LOG_OBJECT(self, "finalized"); + GST_LOG_OBJECT (self, "finalized"); - G_OBJECT_CLASS(parent_class)->finalize(object); + G_OBJECT_CLASS (parent_class)->finalize (object); } -static void gst_er_dtls_dec_dispose(GObject *object) +static void +gst_er_dtls_dec_dispose (GObject * object) { - GstErDtlsDec *self = GST_ER_DTLS_DEC(object); + GstErDtlsDec *self = GST_ER_DTLS_DEC (object); - if (self->agent) { - g_object_unref(self->agent); - self->agent = NULL; - } + if (self->agent) { + g_object_unref (self->agent); + self->agent = NULL; + } - if (self->connection) { - g_object_unref(self->connection); - self->connection = NULL; - } + if (self->connection) { + g_object_unref (self->connection); + self->connection = NULL; + } } -static void gst_er_dtls_dec_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +static void +gst_er_dtls_dec_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) { - GstErDtlsDec *self = GST_ER_DTLS_DEC(object); + GstErDtlsDec *self = GST_ER_DTLS_DEC (object); - switch (prop_id) { + switch (prop_id) { case PROP_CONNECTION_ID: - g_free(self->connection_id); - self->connection_id = g_value_dup_string(value); - g_return_if_fail(self->agent); - create_connection(self, self->connection_id); - break; + g_free (self->connection_id); + self->connection_id = g_value_dup_string (value); + g_return_if_fail (self->agent); + create_connection (self, self->connection_id); + break; case PROP_PEM: - if (self->agent) { - g_object_unref(self->agent); - } - self->agent = get_agent_by_pem(g_value_get_string(value)); - if (self->connection_id) { - create_connection(self, self->connection_id); - } - break; + if (self->agent) { + g_object_unref (self->agent); + } + self->agent = get_agent_by_pem (g_value_get_string (value)); + if (self->connection_id) { + create_connection (self, self->connection_id); + } + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -static void gst_er_dtls_dec_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +static void +gst_er_dtls_dec_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) { - GstErDtlsDec *self = GST_ER_DTLS_DEC(object); + GstErDtlsDec *self = GST_ER_DTLS_DEC (object); - switch (prop_id) { + switch (prop_id) { case PROP_CONNECTION_ID: - g_value_set_string(value, self->connection_id); - break; + g_value_set_string (value, self->connection_id); + break; case PROP_PEM: - g_value_take_string(value, er_dtls_agent_get_certificate_pem(self->agent)); - break; + g_value_take_string (value, + er_dtls_agent_get_certificate_pem (self->agent)); + break; case PROP_PEER_PEM: - g_value_set_string(value, self->peer_pem); - break; + g_value_set_string (value, self->peer_pem); + break; case PROP_DECODER_KEY: - g_value_set_boxed(value, self->decoder_key); - break; + g_value_set_boxed (value, self->decoder_key); + break; case PROP_SRTP_CIPHER: - g_value_set_uint(value, self->srtp_cipher); - break; + g_value_set_uint (value, self->srtp_cipher); + break; case PROP_SRTP_AUTH: - g_value_set_uint(value, self->srtp_auth); - break; + g_value_set_uint (value, self->srtp_auth); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -static GstStateChangeReturn gst_er_dtls_dec_change_state(GstElement *element, GstStateChange transition) +static GstStateChangeReturn +gst_er_dtls_dec_change_state (GstElement * element, GstStateChange transition) { - GstErDtlsDec *self = GST_ER_DTLS_DEC(element); - GstStateChangeReturn ret; + GstErDtlsDec *self = GST_ER_DTLS_DEC (element); + GstStateChangeReturn ret; - switch (transition) { + switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - if (self->connection) { - g_signal_connect_object(self->connection, - "on-decoder-key", G_CALLBACK(on_key_received), self, 0); - g_signal_connect_object(self->connection, - "on-peer-certificate", G_CALLBACK(on_peer_certificate_received), self, 0); - } else { - GST_WARNING_OBJECT(self, "trying to change state to ready without connection id and pem"); - return GST_STATE_CHANGE_FAILURE; - } - break; + if (self->connection) { + g_signal_connect_object (self->connection, + "on-decoder-key", G_CALLBACK (on_key_received), self, 0); + g_signal_connect_object (self->connection, + "on-peer-certificate", G_CALLBACK (on_peer_certificate_received), + self, 0); + } else { + GST_WARNING_OBJECT (self, + "trying to change state to ready without connection id and pem"); + return GST_STATE_CHANGE_FAILURE; + } + break; default: - break; - } + break; + } - ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition); + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - return ret; + return ret; } -static GstPad *gst_er_dtls_dec_request_new_pad(GstElement *element, - GstPadTemplate *tmpl, const gchar *name, const GstCaps *caps) +static GstPad * +gst_er_dtls_dec_request_new_pad (GstElement * element, + GstPadTemplate * tmpl, const gchar * name, const GstCaps * caps) { - GstErDtlsDec *self = GST_ER_DTLS_DEC(element); + GstErDtlsDec *self = GST_ER_DTLS_DEC (element); - GST_DEBUG_OBJECT(element, "requesting pad"); + GST_DEBUG_OBJECT (element, "requesting pad"); - g_return_val_if_fail(!self->src, NULL); - g_return_val_if_fail(tmpl->direction == GST_PAD_SRC, NULL); + g_return_val_if_fail (!self->src, NULL); + g_return_val_if_fail (tmpl->direction == GST_PAD_SRC, NULL); - g_mutex_lock(&self->src_mutex); + g_mutex_lock (&self->src_mutex); - self->src = gst_pad_new_from_template(tmpl, name); - g_return_val_if_fail(self->src, NULL); + self->src = gst_pad_new_from_template (tmpl, name); + g_return_val_if_fail (self->src, NULL); - if (caps) { - g_object_set(self->src, "caps", caps, NULL); - } + if (caps) { + g_object_set (self->src, "caps", caps, NULL); + } - gst_pad_set_active(self->src, TRUE); - gst_element_add_pad(element, self->src); + gst_pad_set_active (self->src, TRUE); + gst_element_add_pad (element, self->src); - g_mutex_unlock(&self->src_mutex); + g_mutex_unlock (&self->src_mutex); - return self->src; + return self->src; } -static void gst_er_dtls_dec_release_pad(GstElement *element, GstPad *pad) +static void +gst_er_dtls_dec_release_pad (GstElement * element, GstPad * pad) { - GstErDtlsDec *self = GST_ER_DTLS_DEC(element); + GstErDtlsDec *self = GST_ER_DTLS_DEC (element); - g_mutex_lock(&self->src_mutex); + g_mutex_lock (&self->src_mutex); - g_return_if_fail(self->src == pad); - gst_element_remove_pad(element, self->src); - self->src = NULL; + g_return_if_fail (self->src == pad); + gst_element_remove_pad (element, self->src); + self->src = NULL; - GST_DEBUG_OBJECT(self, "releasing src pad"); + GST_DEBUG_OBJECT (self, "releasing src pad"); - g_mutex_unlock(&self->src_mutex); + g_mutex_unlock (&self->src_mutex); - GST_ELEMENT_GET_CLASS(element)->release_pad(element, pad); + GST_ELEMENT_GET_CLASS (element)->release_pad (element, pad); } -static void on_key_received(ErDtlsConnection *connection, gpointer key, guint cipher, guint auth, GstErDtlsDec *self) +static void +on_key_received (ErDtlsConnection * connection, gpointer key, guint cipher, + guint auth, GstErDtlsDec * self) { - gpointer key_dup; - gchar *key_str; + gpointer key_dup; + gchar *key_str; - UNUSED(connection); - g_return_if_fail(GST_IS_ER_DTLS_DEC(self)); + UNUSED (connection); + g_return_if_fail (GST_IS_ER_DTLS_DEC (self)); - self->srtp_cipher = cipher; - self->srtp_auth = auth; + self->srtp_cipher = cipher; + self->srtp_auth = auth; - key_dup = g_memdup(key, ER_DTLS_SRTP_MASTER_KEY_LENGTH); - self->decoder_key = gst_buffer_new_wrapped(key_dup, ER_DTLS_SRTP_MASTER_KEY_LENGTH); + key_dup = g_memdup (key, ER_DTLS_SRTP_MASTER_KEY_LENGTH); + self->decoder_key = + gst_buffer_new_wrapped (key_dup, ER_DTLS_SRTP_MASTER_KEY_LENGTH); - key_str = g_base64_encode(key, ER_DTLS_SRTP_MASTER_KEY_LENGTH); - GST_INFO_OBJECT(self, "received key: %s", key_str); - g_free(key_str); + key_str = g_base64_encode (key, ER_DTLS_SRTP_MASTER_KEY_LENGTH); + GST_INFO_OBJECT (self, "received key: %s", key_str); + g_free (key_str); - g_signal_emit(self, signals[SIGNAL_ON_KEY_RECEIVED], 0); + g_signal_emit (self, signals[SIGNAL_ON_KEY_RECEIVED], 0); } -static gboolean signal_peer_certificate_received(GWeakRef *ref) +static gboolean +signal_peer_certificate_received (GWeakRef * ref) { - GstErDtlsDec *self; + GstErDtlsDec *self; - self = g_weak_ref_get(ref); - g_weak_ref_clear(ref); - g_free(ref); - ref = NULL; + self = g_weak_ref_get (ref); + g_weak_ref_clear (ref); + g_free (ref); + ref = NULL; - if (self) { - g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_PEER_PEM]); - g_object_unref(self); - self = NULL; - } + if (self) { + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PEER_PEM]); + g_object_unref (self); + self = NULL; + } - return FALSE; + return FALSE; } -static gboolean on_peer_certificate_received(ErDtlsConnection *connection, gchar *pem, GstErDtlsDec *self) +static gboolean +on_peer_certificate_received (ErDtlsConnection * connection, gchar * pem, + GstErDtlsDec * self) { - GWeakRef *ref; + GWeakRef *ref; - UNUSED(connection); - g_return_val_if_fail(GST_IS_ER_DTLS_DEC(self), TRUE); + UNUSED (connection); + g_return_val_if_fail (GST_IS_ER_DTLS_DEC (self), TRUE); - GST_DEBUG_OBJECT(self, "Received peer certificate PEM: \n%s", pem); + GST_DEBUG_OBJECT (self, "Received peer certificate PEM: \n%s", pem); - self->peer_pem = g_strdup(pem); + self->peer_pem = g_strdup (pem); - ref = g_new(GWeakRef, 1); - g_weak_ref_init(ref, self); + ref = g_new (GWeakRef, 1); + g_weak_ref_init (ref, self); - g_idle_add((GSourceFunc) signal_peer_certificate_received, ref); + g_idle_add ((GSourceFunc) signal_peer_certificate_received, ref); - return TRUE; + return TRUE; } -static GstFlowReturn sink_chain(GstPad *pad, GstObject *parent, GstBuffer *buffer) +static GstFlowReturn +sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) { - GstErDtlsDec *self = GST_ER_DTLS_DEC(parent); - GstFlowReturn ret = GST_FLOW_OK; - GstMapInfo map_info = GST_MAP_INFO_INIT; - gint size; - - if (!self->agent) { - gst_buffer_unref(buffer); - return GST_FLOW_OK; - } + GstErDtlsDec *self = GST_ER_DTLS_DEC (parent); + GstFlowReturn ret = GST_FLOW_OK; + GstMapInfo map_info = GST_MAP_INFO_INIT; + gint size; - GST_DEBUG_OBJECT(self, "received buffer from %s with length %zd", - self->connection_id, gst_buffer_get_size(buffer)); + if (!self->agent) { + gst_buffer_unref (buffer); + return GST_FLOW_OK; + } - gst_buffer_map(buffer, &map_info, GST_MAP_READWRITE); + GST_DEBUG_OBJECT (self, "received buffer from %s with length %zd", + self->connection_id, gst_buffer_get_size (buffer)); - if (!map_info.size) { - gst_buffer_unmap(buffer, &map_info); - return GST_FLOW_OK; - } + gst_buffer_map (buffer, &map_info, GST_MAP_READWRITE); - size = er_dtls_connection_process(self->connection, map_info.data, map_info.size); - gst_buffer_unmap(buffer, &map_info); + if (!map_info.size) { + gst_buffer_unmap (buffer, &map_info); + return GST_FLOW_OK; + } - if (size <= 0) { - gst_buffer_unref(buffer); + size = + er_dtls_connection_process (self->connection, map_info.data, + map_info.size); + gst_buffer_unmap (buffer, &map_info); - return GST_FLOW_OK; - } + if (size <= 0) { + gst_buffer_unref (buffer); - g_mutex_lock(&self->src_mutex); + return GST_FLOW_OK; + } - if (self->src) { - gst_buffer_set_size(buffer, size); - GST_LOG_OBJECT(self, "decoded buffer with length %d, pushing", size); - ret = gst_pad_push(self->src, buffer); - } else { - GST_LOG_OBJECT(self, "dropped buffer with length %d, not linked", size); - gst_buffer_unref(buffer); - } + g_mutex_lock (&self->src_mutex); + + if (self->src) { + gst_buffer_set_size (buffer, size); + GST_LOG_OBJECT (self, "decoded buffer with length %d, pushing", size); + ret = gst_pad_push (self->src, buffer); + } else { + GST_LOG_OBJECT (self, "dropped buffer with length %d, not linked", size); + gst_buffer_unref (buffer); + } - g_mutex_unlock(&self->src_mutex); + g_mutex_unlock (&self->src_mutex); - return ret; + return ret; } static GHashTable *agent_table = NULL; -G_LOCK_DEFINE_STATIC(agent_table); +G_LOCK_DEFINE_STATIC (agent_table); static ErDtlsAgent *generated_cert_agent = NULL; -static ErDtlsAgent *get_agent_by_pem(const gchar *pem) +static ErDtlsAgent * +get_agent_by_pem (const gchar * pem) { - ErDtlsAgent *agent; + ErDtlsAgent *agent; - if (!pem) { - if (g_once_init_enter (&generated_cert_agent)) { - ErDtlsAgent *new_agent; + if (!pem) { + if (g_once_init_enter (&generated_cert_agent)) { + ErDtlsAgent *new_agent; - new_agent = g_object_new(ER_TYPE_DTLS_AGENT, "certificate", - g_object_new(ER_TYPE_DTLS_CERTIFICATE, NULL), NULL); + new_agent = g_object_new (ER_TYPE_DTLS_AGENT, "certificate", + g_object_new (ER_TYPE_DTLS_CERTIFICATE, NULL), NULL); - GST_DEBUG_OBJECT(generated_cert_agent, "no agent with generated cert found, creating new"); - g_once_init_leave (&generated_cert_agent, new_agent); - } else { - GST_DEBUG_OBJECT(generated_cert_agent, "using agent with generated cert"); - } - - agent = generated_cert_agent; - g_object_ref(agent); + GST_DEBUG_OBJECT (generated_cert_agent, + "no agent with generated cert found, creating new"); + g_once_init_leave (&generated_cert_agent, new_agent); } else { - G_LOCK(agent_table); + GST_DEBUG_OBJECT (generated_cert_agent, + "using agent with generated cert"); + } - if (!agent_table) { - agent_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); - } + agent = generated_cert_agent; + g_object_ref (agent); + } else { + G_LOCK (agent_table); - agent = ER_DTLS_AGENT(g_hash_table_lookup(agent_table, pem)); + if (!agent_table) { + agent_table = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + } - if (!agent) { - agent = g_object_new(ER_TYPE_DTLS_AGENT, - "certificate", g_object_new(ER_TYPE_DTLS_CERTIFICATE, "pem", pem, NULL), NULL); + agent = ER_DTLS_AGENT (g_hash_table_lookup (agent_table, pem)); - g_object_weak_ref(G_OBJECT(agent), (GWeakNotify) agent_weak_ref_notify, (gpointer) g_strdup(pem)); + if (!agent) { + agent = g_object_new (ER_TYPE_DTLS_AGENT, + "certificate", g_object_new (ER_TYPE_DTLS_CERTIFICATE, "pem", pem, + NULL), NULL); - g_hash_table_insert(agent_table, g_strdup(pem), agent); + g_object_weak_ref (G_OBJECT (agent), (GWeakNotify) agent_weak_ref_notify, + (gpointer) g_strdup (pem)); - GST_DEBUG_OBJECT(agent, "no agent found, created new"); - } else { - g_object_ref(agent); - GST_DEBUG_OBJECT(agent, "agent found"); - } + g_hash_table_insert (agent_table, g_strdup (pem), agent); - G_UNLOCK(agent_table); + GST_DEBUG_OBJECT (agent, "no agent found, created new"); + } else { + g_object_ref (agent); + GST_DEBUG_OBJECT (agent, "agent found"); } + G_UNLOCK (agent_table); + } + - return agent; + return agent; } -static void agent_weak_ref_notify(gchar *pem, ErDtlsAgent *agent) +static void +agent_weak_ref_notify (gchar * pem, ErDtlsAgent * agent) { - UNUSED(agent); + UNUSED (agent); - G_LOCK(agent_table); - g_hash_table_remove(agent_table, pem); - G_UNLOCK(agent_table); + G_LOCK (agent_table); + g_hash_table_remove (agent_table, pem); + G_UNLOCK (agent_table); - g_free(pem); - pem = NULL; + g_free (pem); + pem = NULL; } static GHashTable *connection_table = NULL; -G_LOCK_DEFINE_STATIC(connection_table); +G_LOCK_DEFINE_STATIC (connection_table); -ErDtlsConnection *gst_er_dtls_dec_fetch_connection(gchar *id) +ErDtlsConnection * +gst_er_dtls_dec_fetch_connection (gchar * id) { - ErDtlsConnection *connection; - g_return_val_if_fail(id, NULL); + ErDtlsConnection *connection; + g_return_val_if_fail (id, NULL); - GST_DEBUG("fetching '%s' from connection table, size is %d", - id, g_hash_table_size(connection_table)); + GST_DEBUG ("fetching '%s' from connection table, size is %d", + id, g_hash_table_size (connection_table)); - G_LOCK(connection_table); + G_LOCK (connection_table); - connection = g_hash_table_lookup(connection_table, id); + connection = g_hash_table_lookup (connection_table, id); - if (connection) { - g_object_ref(connection); - g_hash_table_remove(connection_table, id); - } else { - GST_WARNING("no connection with id '%s' found", id); - } + if (connection) { + g_object_ref (connection); + g_hash_table_remove (connection_table, id); + } else { + GST_WARNING ("no connection with id '%s' found", id); + } - G_UNLOCK(connection_table); + G_UNLOCK (connection_table); - return connection; + return connection; } -static void create_connection(GstErDtlsDec *self, gchar *id) +static void +create_connection (GstErDtlsDec * self, gchar * id) { - g_return_if_fail(GST_IS_ER_DTLS_DEC(self)); - g_return_if_fail(ER_IS_DTLS_AGENT(self->agent)); + g_return_if_fail (GST_IS_ER_DTLS_DEC (self)); + g_return_if_fail (ER_IS_DTLS_AGENT (self->agent)); - if (self->connection) { - g_object_unref(self->connection); - self->connection = NULL; - } + if (self->connection) { + g_object_unref (self->connection); + self->connection = NULL; + } - G_LOCK(connection_table); + G_LOCK (connection_table); - if (!connection_table) { - connection_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); - } + if (!connection_table) { + connection_table = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + } - if (g_hash_table_contains(connection_table, id)) { - G_UNLOCK(connection_table); + if (g_hash_table_contains (connection_table, id)) { + G_UNLOCK (connection_table); - g_return_if_reached(); - } + g_return_if_reached (); + } - self->connection = g_object_new(ER_TYPE_DTLS_CONNECTION, "agent", self->agent, NULL); + self->connection = + g_object_new (ER_TYPE_DTLS_CONNECTION, "agent", self->agent, NULL); - g_object_weak_ref(G_OBJECT(self->connection), (GWeakNotify) connection_weak_ref_notify, g_strdup(id)); + g_object_weak_ref (G_OBJECT (self->connection), + (GWeakNotify) connection_weak_ref_notify, g_strdup (id)); - g_hash_table_insert(connection_table, g_strdup(id), self->connection); + g_hash_table_insert (connection_table, g_strdup (id), self->connection); - G_UNLOCK(connection_table); + G_UNLOCK (connection_table); } -static void connection_weak_ref_notify(gchar *id, ErDtlsConnection *connection) +static void +connection_weak_ref_notify (gchar * id, ErDtlsConnection * connection) { - UNUSED(connection); + UNUSED (connection); - G_LOCK(connection_table); - g_hash_table_remove(connection_table, id); - G_UNLOCK(connection_table); + G_LOCK (connection_table); + g_hash_table_remove (connection_table, id); + G_UNLOCK (connection_table); - g_free(id); - id = NULL; + g_free (id); + id = NULL; } diff --git a/ext/dtls/gstdtlsenc.c b/ext/dtls/gstdtlsenc.c index 9dadab1..8d89066 100644 --- a/ext/dtls/gstdtlsenc.c +++ b/ext/dtls/gstdtlsenc.c @@ -31,43 +31,43 @@ #include "gstdtlsdec.h" -static GstStaticPadTemplate sink_template = - GST_STATIC_PAD_TEMPLATE("sink", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS_ANY +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-dtls") ); -static GstStaticPadTemplate src_template = - GST_STATIC_PAD_TEMPLATE("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS("application/x-dtls") - ); - -GST_DEBUG_CATEGORY_STATIC(er_dtls_enc_debug); +GST_DEBUG_CATEGORY_STATIC (er_dtls_enc_debug); #define GST_CAT_DEFAULT er_dtls_enc_debug #define gst_er_dtls_enc_parent_class parent_class -G_DEFINE_TYPE_WITH_CODE(GstErDtlsEnc, gst_er_dtls_enc, GST_TYPE_ELEMENT, - GST_DEBUG_CATEGORY_INIT(er_dtls_enc_debug, "erdtlsenc", 0, "Ericsson DTLS Encoder")); +G_DEFINE_TYPE_WITH_CODE (GstErDtlsEnc, gst_er_dtls_enc, GST_TYPE_ELEMENT, + GST_DEBUG_CATEGORY_INIT (er_dtls_enc_debug, "erdtlsenc", 0, + "Ericsson DTLS Encoder")); -enum { - SIGNAL_ON_KEY_RECEIVED, - NUM_SIGNALS +enum +{ + SIGNAL_ON_KEY_RECEIVED, + NUM_SIGNALS }; static guint signals[NUM_SIGNALS]; -enum { - PROP_0, - PROP_CONNECTION_ID, - PROP_IS_CLIENT, - - PROP_ENCODER_KEY, - PROP_SRTP_CIPHER, - PROP_SRTP_AUTH, - NUM_PROPERTIES +enum +{ + PROP_0, + PROP_CONNECTION_ID, + PROP_IS_CLIENT, + + PROP_ENCODER_KEY, + PROP_SRTP_CIPHER, + PROP_SRTP_AUTH, + NUM_PROPERTIES }; static GParamSpec *properties[NUM_PROPERTIES]; @@ -81,434 +81,471 @@ static GParamSpec *properties[NUM_PROPERTIES]; #define INITIAL_QUEUE_SIZE 64 -static void gst_er_dtls_enc_finalize(GObject *); -static void gst_er_dtls_enc_set_property(GObject *, guint prop_id, const GValue *, GParamSpec *); -static void gst_er_dtls_enc_get_property(GObject *, guint prop_id, GValue *, GParamSpec *); +static void gst_er_dtls_enc_finalize (GObject *); +static void gst_er_dtls_enc_set_property (GObject *, guint prop_id, + const GValue *, GParamSpec *); +static void gst_er_dtls_enc_get_property (GObject *, guint prop_id, GValue *, + GParamSpec *); -static GstStateChangeReturn gst_er_dtls_enc_change_state(GstElement *, GstStateChange); -static GstPad *gst_er_dtls_enc_request_new_pad(GstElement *, GstPadTemplate *, const gchar *name, const GstCaps *); +static GstStateChangeReturn gst_er_dtls_enc_change_state (GstElement *, + GstStateChange); +static GstPad *gst_er_dtls_enc_request_new_pad (GstElement *, GstPadTemplate *, + const gchar * name, const GstCaps *); -static gboolean src_activate_mode(GstPad *, GstObject *, GstPadMode, gboolean active); -static void src_task_loop(GstPad *); +static gboolean src_activate_mode (GstPad *, GstObject *, GstPadMode, + gboolean active); +static void src_task_loop (GstPad *); -static GstFlowReturn sink_chain(GstPad *, GstObject *, GstBuffer *); +static GstFlowReturn sink_chain (GstPad *, GstObject *, GstBuffer *); -static void on_key_received(ErDtlsConnection *, gpointer key, guint cipher, guint auth, GstErDtlsEnc *); -static void on_send_data(ErDtlsConnection *, gconstpointer data, gint length, GstErDtlsEnc *); +static void on_key_received (ErDtlsConnection *, gpointer key, guint cipher, + guint auth, GstErDtlsEnc *); +static void on_send_data (ErDtlsConnection *, gconstpointer data, gint length, + GstErDtlsEnc *); -static void gst_er_dtls_enc_class_init(GstErDtlsEncClass *klass) +static void +gst_er_dtls_enc_class_init (GstErDtlsEncClass * klass) { - GObjectClass *gobject_class; - GstElementClass *element_class; - - gobject_class = (GObjectClass *) klass; - element_class = (GstElementClass *) klass; - - gobject_class->finalize = GST_DEBUG_FUNCPTR(gst_er_dtls_enc_finalize); - gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_er_dtls_enc_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_er_dtls_enc_get_property); - - element_class->change_state = GST_DEBUG_FUNCPTR(gst_er_dtls_enc_change_state); - element_class->request_new_pad = GST_DEBUG_FUNCPTR(gst_er_dtls_enc_request_new_pad); - - signals[SIGNAL_ON_KEY_RECEIVED] = - g_signal_new("on-key-received", G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_generic, G_TYPE_NONE, 0); - - properties[PROP_CONNECTION_ID] = - g_param_spec_string("connection-id", - "Connection id", - "Every encoder/decoder pair should have the same, unique, connection-id", - DEFAULT_CONNECTION_ID, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - properties[PROP_IS_CLIENT] = - g_param_spec_boolean("is-client", - "Is client", - "Set to true if the decoder should act as" - "client and initiate the handshake", - DEFAULT_IS_CLIENT, - GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - properties[PROP_ENCODER_KEY] = - g_param_spec_boxed("encoder-key", - "Encoder key", - "Master key that should be used by the SRTP encoder", - GST_TYPE_BUFFER, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - properties[PROP_SRTP_CIPHER] = - g_param_spec_uint("srtp-cipher", - "SRTP cipher", - "The SRTP cipher selected in the DTLS handshake. " - "The value will be set to an ErDtlsSrtpCipher.", - 0, ER_DTLS_SRTP_CIPHER_AES_128_ICM, DEFAULT_SRTP_CIPHER, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - properties[PROP_SRTP_AUTH] = - g_param_spec_uint("srtp-auth", - "SRTP authentication", - "The SRTP authentication selected in the DTLS handshake. " - "The value will be set to an ErDtlsSrtpAuth.", - 0, ER_DTLS_SRTP_AUTH_HMAC_SHA1_80, DEFAULT_SRTP_AUTH, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobject_class, NUM_PROPERTIES, properties); - - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&src_template)); - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&sink_template)); - - gst_element_class_set_static_metadata(element_class, - "DTLS Encoder", - "Encoder/Network/DTLS", - "Encodes packets with DTLS", - "Patrik Oldsberg patrik.oldsberg@ericsson.com"); + GObjectClass *gobject_class; + GstElementClass *element_class; + + gobject_class = (GObjectClass *) klass; + element_class = (GstElementClass *) klass; + + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_er_dtls_enc_finalize); + gobject_class->set_property = + GST_DEBUG_FUNCPTR (gst_er_dtls_enc_set_property); + gobject_class->get_property = + GST_DEBUG_FUNCPTR (gst_er_dtls_enc_get_property); + + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_er_dtls_enc_change_state); + element_class->request_new_pad = + GST_DEBUG_FUNCPTR (gst_er_dtls_enc_request_new_pad); + + signals[SIGNAL_ON_KEY_RECEIVED] = + g_signal_new ("on-key-received", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + g_cclosure_marshal_generic, G_TYPE_NONE, 0); + + properties[PROP_CONNECTION_ID] = + g_param_spec_string ("connection-id", + "Connection id", + "Every encoder/decoder pair should have the same, unique, connection-id", + DEFAULT_CONNECTION_ID, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_IS_CLIENT] = + g_param_spec_boolean ("is-client", + "Is client", + "Set to true if the decoder should act as" + "client and initiate the handshake", + DEFAULT_IS_CLIENT, + GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_ENCODER_KEY] = + g_param_spec_boxed ("encoder-key", + "Encoder key", + "Master key that should be used by the SRTP encoder", + GST_TYPE_BUFFER, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + properties[PROP_SRTP_CIPHER] = + g_param_spec_uint ("srtp-cipher", + "SRTP cipher", + "The SRTP cipher selected in the DTLS handshake. " + "The value will be set to an ErDtlsSrtpCipher.", + 0, ER_DTLS_SRTP_CIPHER_AES_128_ICM, DEFAULT_SRTP_CIPHER, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + properties[PROP_SRTP_AUTH] = + g_param_spec_uint ("srtp-auth", + "SRTP authentication", + "The SRTP authentication selected in the DTLS handshake. " + "The value will be set to an ErDtlsSrtpAuth.", + 0, ER_DTLS_SRTP_AUTH_HMAC_SHA1_80, DEFAULT_SRTP_AUTH, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + + gst_element_class_set_static_metadata (element_class, + "DTLS Encoder", + "Encoder/Network/DTLS", + "Encodes packets with DTLS", + "Patrik Oldsberg patrik.oldsberg@ericsson.com"); } -static void gst_er_dtls_enc_init(GstErDtlsEnc *self) +static void +gst_er_dtls_enc_init (GstErDtlsEnc * self) { - self->connection_id = NULL; - self->connection = NULL; + self->connection_id = NULL; + self->connection = NULL; - self->is_client = DEFAULT_IS_CLIENT; + self->is_client = DEFAULT_IS_CLIENT; - self->encoder_key = NULL; - self->srtp_cipher = DEFAULT_SRTP_CIPHER; - self->srtp_auth = DEFAULT_SRTP_AUTH; + self->encoder_key = NULL; + self->srtp_cipher = DEFAULT_SRTP_CIPHER; + self->srtp_auth = DEFAULT_SRTP_AUTH; - self->queue = g_ptr_array_sized_new(INITIAL_QUEUE_SIZE); + self->queue = g_ptr_array_sized_new (INITIAL_QUEUE_SIZE); - g_mutex_init(&self->queue_lock); - g_cond_init(&self->queue_cond_add); + g_mutex_init (&self->queue_lock); + g_cond_init (&self->queue_cond_add); - self->src = gst_pad_new_from_static_template(&src_template, "src"); - g_return_if_fail(self->src); + self->src = gst_pad_new_from_static_template (&src_template, "src"); + g_return_if_fail (self->src); - gst_pad_set_activatemode_function(self->src, GST_DEBUG_FUNCPTR(src_activate_mode)); + gst_pad_set_activatemode_function (self->src, + GST_DEBUG_FUNCPTR (src_activate_mode)); - gst_element_add_pad(GST_ELEMENT(self), self->src); + gst_element_add_pad (GST_ELEMENT (self), self->src); } -static void gst_er_dtls_enc_finalize(GObject *object) +static void +gst_er_dtls_enc_finalize (GObject * object) { - GstErDtlsEnc *self = GST_ER_DTLS_ENC(object); + GstErDtlsEnc *self = GST_ER_DTLS_ENC (object); - if (self->encoder_key) { - gst_buffer_unref(self->encoder_key); - self->encoder_key = NULL; - } + if (self->encoder_key) { + gst_buffer_unref (self->encoder_key); + self->encoder_key = NULL; + } - g_mutex_lock(&self->queue_lock); + g_mutex_lock (&self->queue_lock); - g_ptr_array_set_free_func(self->queue, (GDestroyNotify) gst_buffer_unref); - g_ptr_array_unref(self->queue); - self->queue = NULL; + g_ptr_array_set_free_func (self->queue, (GDestroyNotify) gst_buffer_unref); + g_ptr_array_unref (self->queue); + self->queue = NULL; - g_mutex_unlock(&self->queue_lock); + g_mutex_unlock (&self->queue_lock); - g_mutex_clear(&self->queue_lock); - g_cond_clear(&self->queue_cond_add); + g_mutex_clear (&self->queue_lock); + g_cond_clear (&self->queue_cond_add); - GST_LOG_OBJECT(self, "finalized"); + GST_LOG_OBJECT (self, "finalized"); - G_OBJECT_CLASS(parent_class)->finalize(object); + G_OBJECT_CLASS (parent_class)->finalize (object); } -static void gst_er_dtls_enc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +static void +gst_er_dtls_enc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) { - GstErDtlsEnc *self = GST_ER_DTLS_ENC(object); + GstErDtlsEnc *self = GST_ER_DTLS_ENC (object); - switch (prop_id) { + switch (prop_id) { case PROP_CONNECTION_ID: - self->connection_id = g_value_dup_string(value); - break; + self->connection_id = g_value_dup_string (value); + break; case PROP_IS_CLIENT: - self->is_client = g_value_get_boolean(value); - break; + self->is_client = g_value_get_boolean (value); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -static void gst_er_dtls_enc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +static void +gst_er_dtls_enc_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) { - GstErDtlsEnc *self = GST_ER_DTLS_ENC(object); + GstErDtlsEnc *self = GST_ER_DTLS_ENC (object); - switch (prop_id) { + switch (prop_id) { case PROP_CONNECTION_ID: - g_value_set_string(value, self->connection_id); - break; + g_value_set_string (value, self->connection_id); + break; case PROP_IS_CLIENT: - g_value_set_boolean(value, self->is_client); - break; + g_value_set_boolean (value, self->is_client); + break; case PROP_ENCODER_KEY: - g_value_set_boxed(value, self->encoder_key); - break; + g_value_set_boxed (value, self->encoder_key); + break; case PROP_SRTP_CIPHER: - g_value_set_uint(value, self->srtp_cipher); - break; + g_value_set_uint (value, self->srtp_cipher); + break; case PROP_SRTP_AUTH: - g_value_set_uint(value, self->srtp_auth); - break; + g_value_set_uint (value, self->srtp_auth); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -static GstStateChangeReturn gst_er_dtls_enc_change_state(GstElement *element, GstStateChange transition) +static GstStateChangeReturn +gst_er_dtls_enc_change_state (GstElement * element, GstStateChange transition) { - GstErDtlsEnc *self = GST_ER_DTLS_ENC(element); - GstStateChangeReturn ret; + GstErDtlsEnc *self = GST_ER_DTLS_ENC (element); + GstStateChangeReturn ret; - switch (transition) { + switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - if (self->connection_id) { - self->connection = gst_er_dtls_dec_fetch_connection(self->connection_id); - - if (!self->connection) { - GST_WARNING_OBJECT(self, - "invalid connection id: '%s', connection not found or already in use", - self->connection_id); - return GST_STATE_CHANGE_FAILURE; - } - - g_signal_connect_object(self->connection, - "on-encoder-key", G_CALLBACK(on_key_received), self, 0); - - er_dtls_connection_set_send_callback(self->connection, - g_cclosure_new(G_CALLBACK(on_send_data), self, NULL)); - } else { - GST_WARNING_OBJECT(self, "trying to change state to ready without connection id"); - return GST_STATE_CHANGE_FAILURE; + if (self->connection_id) { + self->connection = + gst_er_dtls_dec_fetch_connection (self->connection_id); + + if (!self->connection) { + GST_WARNING_OBJECT (self, + "invalid connection id: '%s', connection not found or already in use", + self->connection_id); + return GST_STATE_CHANGE_FAILURE; } - break; + + g_signal_connect_object (self->connection, + "on-encoder-key", G_CALLBACK (on_key_received), self, 0); + + er_dtls_connection_set_send_callback (self->connection, + g_cclosure_new (G_CALLBACK (on_send_data), self, NULL)); + } else { + GST_WARNING_OBJECT (self, + "trying to change state to ready without connection id"); + return GST_STATE_CHANGE_FAILURE; + } + break; case GST_STATE_CHANGE_READY_TO_PAUSED: - GST_DEBUG_OBJECT(self, "starting connection %s", self->connection_id); - er_dtls_connection_start(self->connection, self->is_client); + GST_DEBUG_OBJECT (self, "starting connection %s", self->connection_id); + er_dtls_connection_start (self->connection, self->is_client); - gst_pad_set_active(self->src, TRUE); - break; + gst_pad_set_active (self->src, TRUE); + break; case GST_STATE_CHANGE_PAUSED_TO_READY: - GST_DEBUG_OBJECT(self, "stopping connection %s", self->connection_id); - gst_pad_set_active(self->src, FALSE); + GST_DEBUG_OBJECT (self, "stopping connection %s", self->connection_id); + gst_pad_set_active (self->src, FALSE); - er_dtls_connection_stop(self->connection); - break; + er_dtls_connection_stop (self->connection); + break; case GST_STATE_CHANGE_READY_TO_NULL: - GST_DEBUG_OBJECT(self, "closing connection %s", self->connection_id); - - if (self->connection) { - er_dtls_connection_close(self->connection); - er_dtls_connection_set_send_callback(self->connection, NULL); - g_object_unref(self->connection); - self->connection = NULL; - } - break; + GST_DEBUG_OBJECT (self, "closing connection %s", self->connection_id); + + if (self->connection) { + er_dtls_connection_close (self->connection); + er_dtls_connection_set_send_callback (self->connection, NULL); + g_object_unref (self->connection); + self->connection = NULL; + } + break; default: - break; - } + break; + } - ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition); + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - return ret; + return ret; } -static GstPad *gst_er_dtls_enc_request_new_pad(GstElement *element, - GstPadTemplate *templ, const gchar *name, const GstCaps *caps) +static GstPad * +gst_er_dtls_enc_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * name, const GstCaps * caps) { - GstPad *sink; - gboolean ret; + GstPad *sink; + gboolean ret; - GST_DEBUG_OBJECT(element, "sink pad requested"); + GST_DEBUG_OBJECT (element, "sink pad requested"); - g_return_val_if_fail(templ->direction == GST_PAD_SINK, NULL); + g_return_val_if_fail (templ->direction == GST_PAD_SINK, NULL); - sink = gst_pad_new_from_template(templ, name); - g_return_val_if_fail(sink, NULL); + sink = gst_pad_new_from_template (templ, name); + g_return_val_if_fail (sink, NULL); - if (caps) { - g_object_set(sink, "caps", caps, NULL); - } + if (caps) { + g_object_set (sink, "caps", caps, NULL); + } - gst_pad_set_chain_function(sink, GST_DEBUG_FUNCPTR(sink_chain)); + gst_pad_set_chain_function (sink, GST_DEBUG_FUNCPTR (sink_chain)); - ret = gst_pad_set_active(sink, TRUE); - g_warn_if_fail(ret); + ret = gst_pad_set_active (sink, TRUE); + g_warn_if_fail (ret); - gst_element_add_pad(element, sink); + gst_element_add_pad (element, sink); - return sink; + return sink; } -static gboolean src_activate_mode(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean active) +static gboolean +src_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode, + gboolean active) { - GstErDtlsEnc *self = GST_ER_DTLS_ENC (parent); - gboolean success = TRUE; - g_return_val_if_fail(mode == GST_PAD_MODE_PUSH, FALSE); - - if (active) { - GST_DEBUG_OBJECT(self, "src pad activating in push mode"); - - self->send_initial_events = TRUE; - success = gst_pad_start_task(pad, (GstTaskFunction) src_task_loop, self->src, NULL); - if (!success) { - GST_WARNING_OBJECT(self, "failed to activate pad task"); - } - } else { - GST_DEBUG_OBJECT(self, "deactivating src pad"); - - g_mutex_lock(&self->queue_lock); - GST_PAD_MODE(pad) = GST_PAD_MODE_NONE; - g_cond_signal(&self->queue_cond_add); - g_mutex_unlock(&self->queue_lock); - success = gst_pad_stop_task(pad); - if (!success) { - GST_WARNING_OBJECT(self, "failed to deactivate pad task"); - } + GstErDtlsEnc *self = GST_ER_DTLS_ENC (parent); + gboolean success = TRUE; + g_return_val_if_fail (mode == GST_PAD_MODE_PUSH, FALSE); + + if (active) { + GST_DEBUG_OBJECT (self, "src pad activating in push mode"); + + self->send_initial_events = TRUE; + success = + gst_pad_start_task (pad, (GstTaskFunction) src_task_loop, self->src, + NULL); + if (!success) { + GST_WARNING_OBJECT (self, "failed to activate pad task"); + } + } else { + GST_DEBUG_OBJECT (self, "deactivating src pad"); + + g_mutex_lock (&self->queue_lock); + GST_PAD_MODE (pad) = GST_PAD_MODE_NONE; + g_cond_signal (&self->queue_cond_add); + g_mutex_unlock (&self->queue_lock); + success = gst_pad_stop_task (pad); + if (!success) { + GST_WARNING_OBJECT (self, "failed to deactivate pad task"); } + } - return success; + return success; } -static void src_task_loop(GstPad *pad) +static void +src_task_loop (GstPad * pad) { - GstErDtlsEnc *self = GST_ER_DTLS_ENC(GST_PAD_PARENT(pad)); - GstFlowReturn ret; - GstPad *peer; - gboolean peer_is_active; - - GST_TRACE_OBJECT(self, "src loop: acquiring lock"); - g_mutex_lock(&self->queue_lock); - GST_TRACE_OBJECT(self, "src loop: acquired lock"); - - if (!gst_pad_is_active(pad)) { - GST_LOG_OBJECT(self, "src task loop entered on inactive pad"); - GST_TRACE_OBJECT(self, "src loop: releasing lock"); - g_mutex_unlock(&self->queue_lock); - return; + GstErDtlsEnc *self = GST_ER_DTLS_ENC (GST_PAD_PARENT (pad)); + GstFlowReturn ret; + GstPad *peer; + gboolean peer_is_active; + + GST_TRACE_OBJECT (self, "src loop: acquiring lock"); + g_mutex_lock (&self->queue_lock); + GST_TRACE_OBJECT (self, "src loop: acquired lock"); + + if (!gst_pad_is_active (pad)) { + GST_LOG_OBJECT (self, "src task loop entered on inactive pad"); + GST_TRACE_OBJECT (self, "src loop: releasing lock"); + g_mutex_unlock (&self->queue_lock); + return; + } + + while (!self->queue->len) { + GST_TRACE_OBJECT (self, "src loop: queue empty, waiting for add"); + g_cond_wait (&self->queue_cond_add, &self->queue_lock); + GST_TRACE_OBJECT (self, "src loop: add signaled"); + + if (!gst_pad_is_active (pad)) { + GST_LOG_OBJECT (self, "pad inactive, task returning"); + GST_TRACE_OBJECT (self, "src loop: releasing lock"); + g_mutex_unlock (&self->queue_lock); + return; } + } + GST_TRACE_OBJECT (self, "src loop: queue has element"); - while (!self->queue->len) { - GST_TRACE_OBJECT(self, "src loop: queue empty, waiting for add"); - g_cond_wait(&self->queue_cond_add, &self->queue_lock); - GST_TRACE_OBJECT(self, "src loop: add signaled"); + peer = gst_pad_get_peer (pad); + peer_is_active = gst_pad_is_active (peer); + gst_object_unref (peer); - if (!gst_pad_is_active(pad)) { - GST_LOG_OBJECT(self, "pad inactive, task returning"); - GST_TRACE_OBJECT(self, "src loop: releasing lock"); - g_mutex_unlock(&self->queue_lock); - return; - } + if (peer_is_active) { + GstBuffer *buffer; + gboolean start_connection_timeout = FALSE; + + if (self->send_initial_events) { + GstSegment segment; + gchar s_id[32]; + GstCaps *caps; + + g_snprintf (s_id, sizeof (s_id), "erdtlsenc-%08x", g_random_int ()); + gst_pad_push_event (self->src, gst_event_new_stream_start (s_id)); + caps = gst_caps_new_empty_simple ("application/x-dtls"); + gst_pad_push_event (self->src, gst_event_new_caps (caps)); + gst_caps_unref (caps); + gst_segment_init (&segment, GST_FORMAT_BYTES); + gst_pad_push_event (self->src, gst_event_new_segment (&segment)); + self->send_initial_events = FALSE; + start_connection_timeout = TRUE; } - GST_TRACE_OBJECT(self, "src loop: queue has element"); - - peer = gst_pad_get_peer(pad); - peer_is_active = gst_pad_is_active(peer); - gst_object_unref(peer); - - if (peer_is_active) { - GstBuffer *buffer; - gboolean start_connection_timeout = FALSE; - - if (self->send_initial_events) { - GstSegment segment; - gchar s_id[32]; - GstCaps *caps; - - g_snprintf (s_id, sizeof (s_id), "erdtlsenc-%08x", g_random_int ()); - gst_pad_push_event (self->src, gst_event_new_stream_start (s_id)); - caps = gst_caps_new_empty_simple ("application/x-dtls"); - gst_pad_push_event (self->src, gst_event_new_caps (caps)); - gst_caps_unref (caps); - gst_segment_init (&segment, GST_FORMAT_BYTES); - gst_pad_push_event (self->src, gst_event_new_segment (&segment)); - self->send_initial_events = FALSE; - start_connection_timeout = TRUE; - } - buffer = g_ptr_array_remove_index(self->queue, 0); + buffer = g_ptr_array_remove_index (self->queue, 0); - GST_TRACE_OBJECT(self, "src loop: releasing lock"); - g_mutex_unlock(&self->queue_lock); + GST_TRACE_OBJECT (self, "src loop: releasing lock"); + g_mutex_unlock (&self->queue_lock); - ret = gst_pad_push(self->src, buffer); - if (start_connection_timeout) - er_dtls_connection_start_timeout (self->connection); + ret = gst_pad_push (self->src, buffer); + if (start_connection_timeout) + er_dtls_connection_start_timeout (self->connection); - if (G_UNLIKELY(ret != GST_FLOW_OK)) { - GST_WARNING_OBJECT(self, "failed to push buffer on src pad: %s", gst_flow_get_name(ret)); - } - } else { - g_warn_if_reached(); - GST_TRACE_OBJECT(self, "src loop: releasing lock"); - g_mutex_unlock(&self->queue_lock); + if (G_UNLIKELY (ret != GST_FLOW_OK)) { + GST_WARNING_OBJECT (self, "failed to push buffer on src pad: %s", + gst_flow_get_name (ret)); } + } else { + g_warn_if_reached (); + GST_TRACE_OBJECT (self, "src loop: releasing lock"); + g_mutex_unlock (&self->queue_lock); + } } -static GstFlowReturn sink_chain(GstPad *pad, GstObject *parent, GstBuffer *buffer) +static GstFlowReturn +sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) { - GstErDtlsEnc *self = GST_ER_DTLS_ENC(parent); - GstMapInfo map_info; - gint ret; - - gst_buffer_map(buffer, &map_info, GST_MAP_READ); - - if (map_info.size) { - ret = er_dtls_connection_send(self->connection, map_info.data, map_info.size); - if (ret != map_info.size) { - GST_WARNING_OBJECT(self, "error sending data: %d B were written, expected value was %zd B", - ret, map_info.size); - } + GstErDtlsEnc *self = GST_ER_DTLS_ENC (parent); + GstMapInfo map_info; + gint ret; + + gst_buffer_map (buffer, &map_info, GST_MAP_READ); + + if (map_info.size) { + ret = + er_dtls_connection_send (self->connection, map_info.data, + map_info.size); + if (ret != map_info.size) { + GST_WARNING_OBJECT (self, + "error sending data: %d B were written, expected value was %zd B", + ret, map_info.size); } + } - gst_buffer_unmap(buffer, &map_info); + gst_buffer_unmap (buffer, &map_info); - gst_buffer_unref(buffer); + gst_buffer_unref (buffer); - return GST_FLOW_OK; + return GST_FLOW_OK; } -static void on_key_received(ErDtlsConnection *connection, gpointer key, guint cipher, guint auth, GstErDtlsEnc *self) +static void +on_key_received (ErDtlsConnection * connection, gpointer key, guint cipher, + guint auth, GstErDtlsEnc * self) { - gpointer key_dup; - gchar *key_str; + gpointer key_dup; + gchar *key_str; - g_return_if_fail(GST_IS_ER_DTLS_ENC(self)); - g_return_if_fail(ER_IS_DTLS_CONNECTION(connection)); + g_return_if_fail (GST_IS_ER_DTLS_ENC (self)); + g_return_if_fail (ER_IS_DTLS_CONNECTION (connection)); - self->srtp_cipher = cipher; - self->srtp_auth = auth; + self->srtp_cipher = cipher; + self->srtp_auth = auth; - key_dup = g_memdup(key, ER_DTLS_SRTP_MASTER_KEY_LENGTH); - self->encoder_key = gst_buffer_new_wrapped(key_dup, ER_DTLS_SRTP_MASTER_KEY_LENGTH); + key_dup = g_memdup (key, ER_DTLS_SRTP_MASTER_KEY_LENGTH); + self->encoder_key = + gst_buffer_new_wrapped (key_dup, ER_DTLS_SRTP_MASTER_KEY_LENGTH); - key_str = g_base64_encode(key, ER_DTLS_SRTP_MASTER_KEY_LENGTH); - GST_INFO_OBJECT(self, "received key: %s", key_str); - g_free(key_str); + key_str = g_base64_encode (key, ER_DTLS_SRTP_MASTER_KEY_LENGTH); + GST_INFO_OBJECT (self, "received key: %s", key_str); + g_free (key_str); - g_signal_emit(self, signals[SIGNAL_ON_KEY_RECEIVED], 0); + g_signal_emit (self, signals[SIGNAL_ON_KEY_RECEIVED], 0); } -static void on_send_data(ErDtlsConnection *connection, gconstpointer data, gint length, GstErDtlsEnc *self) +static void +on_send_data (ErDtlsConnection * connection, gconstpointer data, gint length, + GstErDtlsEnc * self) { - GstBuffer *buffer; + GstBuffer *buffer; - GST_DEBUG_OBJECT(self, "sending data from %s with length %d", self->connection_id, length); + GST_DEBUG_OBJECT (self, "sending data from %s with length %d", + self->connection_id, length); - buffer = gst_buffer_new_wrapped(g_memdup(data, length), length); + buffer = gst_buffer_new_wrapped (g_memdup (data, length), length); - GST_TRACE_OBJECT(self, "send data: acquiring lock"); - g_mutex_lock(&self->queue_lock); - GST_TRACE_OBJECT(self, "send data: acquired lock"); + GST_TRACE_OBJECT (self, "send data: acquiring lock"); + g_mutex_lock (&self->queue_lock); + GST_TRACE_OBJECT (self, "send data: acquired lock"); - g_ptr_array_add(self->queue, buffer); + g_ptr_array_add (self->queue, buffer); - GST_TRACE_OBJECT(self, "send data: signaling add"); - g_cond_signal(&self->queue_cond_add); + GST_TRACE_OBJECT (self, "send data: signaling add"); + g_cond_signal (&self->queue_cond_add); - GST_TRACE_OBJECT(self, "send data: releasing lock"); - g_mutex_unlock(&self->queue_lock); + GST_TRACE_OBJECT (self, "send data: releasing lock"); + g_mutex_unlock (&self->queue_lock); } diff --git a/ext/dtls/gstdtlssrtpbin.c b/ext/dtls/gstdtlssrtpbin.c index c477a62..ac7d18f 100644 --- a/ext/dtls/gstdtlssrtpbin.c +++ b/ext/dtls/gstdtlssrtpbin.c @@ -31,17 +31,18 @@ #include "gstdtlssrtpbin.h" #define gst_er_dtls_srtp_bin_parent_class parent_class -G_DEFINE_ABSTRACT_TYPE(GstErDtlsSrtpBin, gst_er_dtls_srtp_bin, GST_TYPE_BIN); - -enum { - PROP_0, - PROP_CONNECTION_ID, - PROP_KEY, - PROP_SRTP_AUTH, - PROP_SRTP_CIPHER, - PROP_SRTCP_AUTH, - PROP_SRTCP_CIPHER, - NUM_PROPERTIES +G_DEFINE_ABSTRACT_TYPE (GstErDtlsSrtpBin, gst_er_dtls_srtp_bin, GST_TYPE_BIN); + +enum +{ + PROP_0, + PROP_CONNECTION_ID, + PROP_KEY, + PROP_SRTP_AUTH, + PROP_SRTP_CIPHER, + PROP_SRTCP_AUTH, + PROP_SRTCP_CIPHER, + NUM_PROPERTIES }; static GParamSpec *properties[NUM_PROPERTIES]; @@ -53,179 +54,189 @@ static GParamSpec *properties[NUM_PROPERTIES]; #define DEFAULT_SRTCP_AUTH NULL #define DEFAULT_SRTCP_CIPHER NULL -static void gst_er_dtls_srtp_bin_finalize(GObject *); -static void gst_er_dtls_srtp_bin_set_property(GObject *, guint prop_id, const GValue *, GParamSpec *); -static void gst_er_dtls_srtp_bin_get_property(GObject *, guint prop_id, GValue *, GParamSpec *); +static void gst_er_dtls_srtp_bin_finalize (GObject *); +static void gst_er_dtls_srtp_bin_set_property (GObject *, guint prop_id, + const GValue *, GParamSpec *); +static void gst_er_dtls_srtp_bin_get_property (GObject *, guint prop_id, + GValue *, GParamSpec *); -static void gst_er_dtls_srtp_bin_class_init(GstErDtlsSrtpBinClass *klass) +static void +gst_er_dtls_srtp_bin_class_init (GstErDtlsSrtpBinClass * klass) { - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) klass; - - gobject_class->finalize = GST_DEBUG_FUNCPTR(gst_er_dtls_srtp_bin_finalize); - gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_er_dtls_srtp_bin_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_er_dtls_srtp_bin_get_property); - - klass->remove_dtls_element = NULL; - - properties[PROP_CONNECTION_ID] = - g_param_spec_string("connection-id", - "Connection id", - "Every encoder/decoder pair should have the same, unique, connection-id", - DEFAULT_CONNECTION_ID, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - properties[PROP_KEY] = - g_param_spec_boxed("key", - "Key", - "SRTP master key, if this property is set, DTLS will be disabled", - GST_TYPE_BUFFER, - G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS); - - properties[PROP_SRTP_CIPHER] = - g_param_spec_string("srtp-cipher", - "SRTP Cipher", - "SRTP cipher name, should be 'null' or 'aes-128-icm', " - "if this property is set, DTLS will be disabled", - DEFAULT_SRTP_CIPHER, - G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS); - - properties[PROP_SRTCP_CIPHER] = - g_param_spec_string("srtcp-cipher", - "SRTCP Cipher", - "SRTCP cipher name, should be 'null' or 'aes-128-icm', " - "if this property is set, DTLS will be disabled", - DEFAULT_SRTCP_CIPHER, - G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS); - - properties[PROP_SRTP_AUTH] = - g_param_spec_string("srtp-auth", - "SRTP Auth", - "SRTP auth name, should be 'null', 'hmac-sha1-32' or 'hmac-sha1-80', " - "if this property is set, DTLS will be disabled", - DEFAULT_SRTP_AUTH, - G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS); - - properties[PROP_SRTCP_AUTH] = - g_param_spec_string("srtcp-auth", - "SRTCP Auth", - "SRTCP auth name, should be 'null', 'hmac-sha1-32' or 'hmac-sha1-80', " - "if this property is set, DTLS will be disabled", - DEFAULT_SRTCP_AUTH, - G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobject_class, NUM_PROPERTIES, properties); + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) klass; + + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_er_dtls_srtp_bin_finalize); + gobject_class->set_property = + GST_DEBUG_FUNCPTR (gst_er_dtls_srtp_bin_set_property); + gobject_class->get_property = + GST_DEBUG_FUNCPTR (gst_er_dtls_srtp_bin_get_property); + + klass->remove_dtls_element = NULL; + + properties[PROP_CONNECTION_ID] = + g_param_spec_string ("connection-id", + "Connection id", + "Every encoder/decoder pair should have the same, unique, connection-id", + DEFAULT_CONNECTION_ID, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_KEY] = + g_param_spec_boxed ("key", + "Key", + "SRTP master key, if this property is set, DTLS will be disabled", + GST_TYPE_BUFFER, + G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS); + + properties[PROP_SRTP_CIPHER] = + g_param_spec_string ("srtp-cipher", + "SRTP Cipher", + "SRTP cipher name, should be 'null' or 'aes-128-icm', " + "if this property is set, DTLS will be disabled", + DEFAULT_SRTP_CIPHER, + G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS); + + properties[PROP_SRTCP_CIPHER] = + g_param_spec_string ("srtcp-cipher", + "SRTCP Cipher", + "SRTCP cipher name, should be 'null' or 'aes-128-icm', " + "if this property is set, DTLS will be disabled", + DEFAULT_SRTCP_CIPHER, + G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS); + + properties[PROP_SRTP_AUTH] = + g_param_spec_string ("srtp-auth", + "SRTP Auth", + "SRTP auth name, should be 'null', 'hmac-sha1-32' or 'hmac-sha1-80', " + "if this property is set, DTLS will be disabled", + DEFAULT_SRTP_AUTH, + G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS); + + properties[PROP_SRTCP_AUTH] = + g_param_spec_string ("srtcp-auth", + "SRTCP Auth", + "SRTCP auth name, should be 'null', 'hmac-sha1-32' or 'hmac-sha1-80', " + "if this property is set, DTLS will be disabled", + DEFAULT_SRTCP_AUTH, + G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties); } -static void gst_er_dtls_srtp_bin_init(GstErDtlsSrtpBin *self) +static void +gst_er_dtls_srtp_bin_init (GstErDtlsSrtpBin * self) { - self->key = NULL; - self->key_is_set = FALSE; - self->srtp_auth = NULL; - self->srtp_cipher = NULL; - self->srtcp_auth = NULL; - self->srtcp_cipher = NULL; + self->key = NULL; + self->key_is_set = FALSE; + self->srtp_auth = NULL; + self->srtp_cipher = NULL; + self->srtcp_auth = NULL; + self->srtcp_cipher = NULL; } -static void gst_er_dtls_srtp_bin_finalize(GObject *object) +static void +gst_er_dtls_srtp_bin_finalize (GObject * object) { - GstErDtlsSrtpBin *self = GST_ER_DTLS_SRTP_BIN(object); - - if (self->key) { - gst_buffer_unref(self->key); - self->key = NULL; - } - g_free(self->srtp_auth); - self->srtp_auth = NULL; - g_free(self->srtp_cipher); - self->srtp_cipher = NULL; - g_free(self->srtcp_auth); - self->srtcp_auth = NULL; - g_free(self->srtcp_cipher); - self->srtcp_cipher = NULL; - - G_OBJECT_CLASS(parent_class)->finalize(object); + GstErDtlsSrtpBin *self = GST_ER_DTLS_SRTP_BIN (object); + + if (self->key) { + gst_buffer_unref (self->key); + self->key = NULL; + } + g_free (self->srtp_auth); + self->srtp_auth = NULL; + g_free (self->srtp_cipher); + self->srtp_cipher = NULL; + g_free (self->srtcp_auth); + self->srtcp_auth = NULL; + g_free (self->srtcp_cipher); + self->srtcp_cipher = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); } -static void gst_er_dtls_srtp_bin_set_property(GObject *object, - guint prop_id, const GValue *value, GParamSpec *pspec) +static void +gst_er_dtls_srtp_bin_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) { - GstErDtlsSrtpBin *self = GST_ER_DTLS_SRTP_BIN(object); - GstErDtlsSrtpBinClass *klass = GST_ER_DTLS_SRTP_BIN_GET_CLASS(self); + GstErDtlsSrtpBin *self = GST_ER_DTLS_SRTP_BIN (object); + GstErDtlsSrtpBinClass *klass = GST_ER_DTLS_SRTP_BIN_GET_CLASS (self); - switch (prop_id) { + switch (prop_id) { case PROP_CONNECTION_ID: - if (self->dtls_element) { - g_object_set_property(G_OBJECT(self->dtls_element), "connection-id", value); - } else { - g_warning("tried to set connection-id after disabling DTLS"); - } - break; + if (self->dtls_element) { + g_object_set_property (G_OBJECT (self->dtls_element), "connection-id", + value); + } else { + g_warning ("tried to set connection-id after disabling DTLS"); + } + break; case PROP_KEY: - if (self->key) { - gst_buffer_unref(self->key); - } - self->key = g_value_dup_boxed(value); - self->key_is_set = TRUE; - klass->remove_dtls_element(self); - break; + if (self->key) { + gst_buffer_unref (self->key); + } + self->key = g_value_dup_boxed (value); + self->key_is_set = TRUE; + klass->remove_dtls_element (self); + break; case PROP_SRTP_AUTH: - g_free(self->srtp_auth); - self->srtp_auth = g_value_dup_string(value); - klass->remove_dtls_element(self); - break; + g_free (self->srtp_auth); + self->srtp_auth = g_value_dup_string (value); + klass->remove_dtls_element (self); + break; case PROP_SRTP_CIPHER: - g_free(self->srtp_cipher); - self->srtp_cipher = g_value_dup_string(value); - klass->remove_dtls_element(self); - break; + g_free (self->srtp_cipher); + self->srtp_cipher = g_value_dup_string (value); + klass->remove_dtls_element (self); + break; case PROP_SRTCP_AUTH: - g_free(self->srtcp_auth); - self->srtcp_auth = g_value_dup_string(value); - klass->remove_dtls_element(self); - break; + g_free (self->srtcp_auth); + self->srtcp_auth = g_value_dup_string (value); + klass->remove_dtls_element (self); + break; case PROP_SRTCP_CIPHER: - g_free(self->srtcp_cipher); - self->srtcp_cipher = g_value_dup_string(value); - klass->remove_dtls_element(self); - break; + g_free (self->srtcp_cipher); + self->srtcp_cipher = g_value_dup_string (value); + klass->remove_dtls_element (self); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -static void gst_er_dtls_srtp_bin_get_property(GObject *object, - guint prop_id, GValue *value, GParamSpec *pspec) +static void +gst_er_dtls_srtp_bin_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) { - GstErDtlsSrtpBin *self = GST_ER_DTLS_SRTP_BIN(object); + GstErDtlsSrtpBin *self = GST_ER_DTLS_SRTP_BIN (object); - switch (prop_id) { + switch (prop_id) { case PROP_CONNECTION_ID: - if (self->dtls_element) { - g_object_get_property(G_OBJECT(self->dtls_element), "connection-id", value); - } else { - g_warning("tried to get connection-id after disabling DTLS"); - } - break; + if (self->dtls_element) { + g_object_get_property (G_OBJECT (self->dtls_element), "connection-id", + value); + } else { + g_warning ("tried to get connection-id after disabling DTLS"); + } + break; case PROP_KEY: - if (self->key) { - g_value_set_boxed(value, self->key); - } - break; + if (self->key) { + g_value_set_boxed (value, self->key); + } + break; case PROP_SRTP_AUTH: - g_value_set_string(value, self->srtp_auth); - break; + g_value_set_string (value, self->srtp_auth); + break; case PROP_SRTP_CIPHER: - g_value_set_string(value, self->srtp_cipher); - break; + g_value_set_string (value, self->srtp_cipher); + break; case PROP_SRTCP_AUTH: - g_value_set_string(value, self->srtcp_auth); - break; + g_value_set_string (value, self->srtcp_auth); + break; case PROP_SRTCP_CIPHER: - g_value_set_string(value, self->srtcp_cipher); - break; + g_value_set_string (value, self->srtcp_cipher); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } diff --git a/ext/dtls/gstdtlssrtpdec.c b/ext/dtls/gstdtlssrtpdec.c index 7d8b341..08e124f 100644 --- a/ext/dtls/gstdtlssrtpdec.c +++ b/ext/dtls/gstdtlssrtpdec.c @@ -31,41 +31,40 @@ #include "gstdtlsconnection.h" -static GstStaticPadTemplate sink_template = - GST_STATIC_PAD_TEMPLATE("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY - ); +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); static GstStaticPadTemplate rtp_src_template = - GST_STATIC_PAD_TEMPLATE("rtp_src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS("application/x-rtp;application/x-rtcp") + GST_STATIC_PAD_TEMPLATE ("rtp_src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-rtp;application/x-rtcp") ); static GstStaticPadTemplate data_src_template = - GST_STATIC_PAD_TEMPLATE("data_src", - GST_PAD_SRC, - GST_PAD_REQUEST, - GST_STATIC_CAPS_ANY - ); +GST_STATIC_PAD_TEMPLATE ("data_src", + GST_PAD_SRC, + GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); -GST_DEBUG_CATEGORY_STATIC(er_dtls_srtp_dec_debug); +GST_DEBUG_CATEGORY_STATIC (er_dtls_srtp_dec_debug); #define GST_CAT_DEFAULT er_dtls_srtp_dec_debug #define gst_er_dtls_srtp_dec_parent_class parent_class -G_DEFINE_TYPE_WITH_CODE(GstErDtlsSrtpDec, gst_er_dtls_srtp_dec, GST_TYPE_ER_DTLS_SRTP_BIN, - GST_DEBUG_CATEGORY_INIT(er_dtls_srtp_dec_debug, "erdtlssrtpdec", 0, "Ericsson DTLS Decoder")); +G_DEFINE_TYPE_WITH_CODE (GstErDtlsSrtpDec, gst_er_dtls_srtp_dec, + GST_TYPE_ER_DTLS_SRTP_BIN, GST_DEBUG_CATEGORY_INIT (er_dtls_srtp_dec_debug, + "erdtlssrtpdec", 0, "Ericsson DTLS Decoder")); #define UNUSED(param) while (0) { (void)(param); } -enum { - PROP_0, - PROP_PEM, - PROP_PEER_PEM, - NUM_PROPERTIES +enum +{ + PROP_0, + PROP_PEM, + PROP_PEER_PEM, + NUM_PROPERTIES }; static GParamSpec *properties[NUM_PROPERTIES]; @@ -73,71 +72,82 @@ static GParamSpec *properties[NUM_PROPERTIES]; #define DEFAULT_PEM NULL #define DEFAULT_PEER_PEM NULL -static void gst_er_dtls_srtp_dec_set_property(GObject *, guint prop_id, const GValue *, GParamSpec *); -static void gst_er_dtls_srtp_dec_get_property(GObject *, guint prop_id, GValue *, GParamSpec *); +static void gst_er_dtls_srtp_dec_set_property (GObject *, guint prop_id, + const GValue *, GParamSpec *); +static void gst_er_dtls_srtp_dec_get_property (GObject *, guint prop_id, + GValue *, GParamSpec *); -static GstPad *gst_er_dtls_srtp_dec_request_new_pad(GstElement *, GstPadTemplate *, const gchar *name, const GstCaps *); -static GstCaps *on_decoder_request_key(GstElement *srtp_decoder, guint ssrc, GstErDtlsSrtpBin *); -static void on_peer_pem(GstElement *srtp_decoder, GParamSpec *pspec, GstErDtlsSrtpDec *self); +static GstPad *gst_er_dtls_srtp_dec_request_new_pad (GstElement *, + GstPadTemplate *, const gchar * name, const GstCaps *); +static GstCaps *on_decoder_request_key (GstElement * srtp_decoder, guint ssrc, + GstErDtlsSrtpBin *); +static void on_peer_pem (GstElement * srtp_decoder, GParamSpec * pspec, + GstErDtlsSrtpDec * self); -static void gst_er_dtls_srtp_dec_remove_dtls_element(GstErDtlsSrtpBin *); -static GstPadProbeReturn remove_dtls_decoder_probe_callback(GstPad *, GstPadProbeInfo *, GstElement *); +static void gst_er_dtls_srtp_dec_remove_dtls_element (GstErDtlsSrtpBin *); +static GstPadProbeReturn remove_dtls_decoder_probe_callback (GstPad *, + GstPadProbeInfo *, GstElement *); -static GstPadProbeReturn drop_funnel_rtcp_caps(GstPad *, GstPadProbeInfo *, gpointer); +static GstPadProbeReturn drop_funnel_rtcp_caps (GstPad *, GstPadProbeInfo *, + gpointer); -static void gst_er_dtls_srtp_dec_class_init(GstErDtlsSrtpDecClass *klass) +static void +gst_er_dtls_srtp_dec_class_init (GstErDtlsSrtpDecClass * klass) { - GObjectClass *gobject_class; - GstElementClass *element_class; - GstErDtlsSrtpBinClass *dtls_srtp_bin_class; - - gobject_class = (GObjectClass *) klass; - element_class = (GstElementClass *) klass; - dtls_srtp_bin_class = (GstErDtlsSrtpBinClass *) klass; - - gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_er_dtls_srtp_dec_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_er_dtls_srtp_dec_get_property); - - element_class->request_new_pad = GST_DEBUG_FUNCPTR(gst_er_dtls_srtp_dec_request_new_pad); - - dtls_srtp_bin_class->remove_dtls_element = GST_DEBUG_FUNCPTR(gst_er_dtls_srtp_dec_remove_dtls_element); - - properties[PROP_PEM] = - g_param_spec_string("pem", - "PEM string", - "A string containing a X509 certificate and RSA private key in PEM format", - DEFAULT_PEM, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - properties[PROP_PEER_PEM] = - g_param_spec_string("peer-pem", - "Peer PEM string", - "The X509 certificate received in the DTLS handshake, in PEM format", - DEFAULT_PEER_PEM, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobject_class, NUM_PROPERTIES, properties); - - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&sink_template)); - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&rtp_src_template)); - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&data_src_template)); - - gst_element_class_set_static_metadata(element_class, - "DTLS-SRTP Decoder", - "Decoder/Network/DTLS/SRTP", - "Decodes SRTP packets with a key received from DTLS", - "Patrik Oldsberg patrik.oldsberg@ericsson.com"); + GObjectClass *gobject_class; + GstElementClass *element_class; + GstErDtlsSrtpBinClass *dtls_srtp_bin_class; + + gobject_class = (GObjectClass *) klass; + element_class = (GstElementClass *) klass; + dtls_srtp_bin_class = (GstErDtlsSrtpBinClass *) klass; + + gobject_class->set_property = + GST_DEBUG_FUNCPTR (gst_er_dtls_srtp_dec_set_property); + gobject_class->get_property = + GST_DEBUG_FUNCPTR (gst_er_dtls_srtp_dec_get_property); + + element_class->request_new_pad = + GST_DEBUG_FUNCPTR (gst_er_dtls_srtp_dec_request_new_pad); + + dtls_srtp_bin_class->remove_dtls_element = + GST_DEBUG_FUNCPTR (gst_er_dtls_srtp_dec_remove_dtls_element); + + properties[PROP_PEM] = + g_param_spec_string ("pem", + "PEM string", + "A string containing a X509 certificate and RSA private key in PEM format", + DEFAULT_PEM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_PEER_PEM] = + g_param_spec_string ("peer-pem", + "Peer PEM string", + "The X509 certificate received in the DTLS handshake, in PEM format", + DEFAULT_PEER_PEM, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&rtp_src_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&data_src_template)); + + gst_element_class_set_static_metadata (element_class, + "DTLS-SRTP Decoder", + "Decoder/Network/DTLS/SRTP", + "Decodes SRTP packets with a key received from DTLS", + "Patrik Oldsberg patrik.oldsberg@ericsson.com"); } -static void gst_er_dtls_srtp_dec_init(GstErDtlsSrtpDec *self) +static void +gst_er_dtls_srtp_dec_init (GstErDtlsSrtpDec * self) { - GstElementClass *klass = GST_ELEMENT_GET_CLASS(GST_ELEMENT(self)); - GstPadTemplate *templ; - GstPad *target_pad, *ghost_pad, *pad; - gboolean ret; + GstElementClass *klass = GST_ELEMENT_GET_CLASS (GST_ELEMENT (self)); + GstPadTemplate *templ; + GstPad *target_pad, *ghost_pad, *pad; + gboolean ret; /* +--------------------+ @@ -151,303 +161,319 @@ static void gst_er_dtls_srtp_dec_init(GstErDtlsSrtpDec *self) +-----------+ +-----------+ */ - self->srtp_dec = gst_element_factory_make("srtpdec", "srtp-decoder"); - if (!self->srtp_dec) { - GST_ERROR_OBJECT(self, "failed to create srtp_dec, is the srtp plugin registered?"); - return; - } - self->dtls_srtp_demux = gst_element_factory_make("erdtlssrtpdemux", "dtls-srtp-demux"); - if (!self->dtls_srtp_demux) { - GST_ERROR_OBJECT(self, "failed to create dtls_srtp_demux"); - return; - } - self->bin.dtls_element = gst_element_factory_make("erdtlsdec", "dtls-decoder"); - if (!self->bin.dtls_element) { - GST_ERROR_OBJECT(self, "failed to create dtls_dec"); - return; - } - self->funnel = gst_element_factory_make("funnel", "funnel"); - if (!self->funnel) { - GST_ERROR_OBJECT(self, "failed to create funnel"); - return; - } - - gst_bin_add_many(GST_BIN(self), - self->dtls_srtp_demux, - self->bin.dtls_element, - self->srtp_dec, - self->funnel, - NULL); - - ret = gst_element_link_pads(self->dtls_srtp_demux, "dtls_src", self->bin.dtls_element, NULL); - g_return_if_fail(ret); - ret = gst_element_link_pads(self->dtls_srtp_demux, "rtp_src", self->srtp_dec, "rtp_sink"); - g_return_if_fail(ret); - ret = gst_element_link_pads(self->srtp_dec, "rtp_src", self->funnel, "sink_0"); - g_return_if_fail(ret); - ret = gst_element_link_pads(self->srtp_dec, "rtcp_src", self->funnel, "sink_1"); - g_return_if_fail(ret); - - pad = gst_element_get_static_pad(self->funnel, "sink_1"); - gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, drop_funnel_rtcp_caps, NULL, NULL); - gst_object_unref(pad); - - templ = gst_element_class_get_pad_template(klass, "rtp_src"); - target_pad = gst_element_get_static_pad(self->funnel, "src"); - ghost_pad = gst_ghost_pad_new_from_template("rtp_src", target_pad, templ); - gst_object_unref(target_pad); - g_return_if_fail(ghost_pad); - - ret = gst_element_add_pad(GST_ELEMENT(self), ghost_pad); - g_return_if_fail(ret); - - templ = gst_element_class_get_pad_template(klass, "sink"); - target_pad = gst_element_get_static_pad(self->dtls_srtp_demux, "sink"); - ghost_pad = gst_ghost_pad_new_from_template("sink", target_pad, templ); - gst_object_unref(target_pad); - g_return_if_fail(ghost_pad); - - ret = gst_element_add_pad(GST_ELEMENT(self), ghost_pad); - g_return_if_fail(ret); - - g_signal_connect(self->srtp_dec, "request-key", G_CALLBACK(on_decoder_request_key), self); - g_signal_connect(self->bin.dtls_element, "notify::peer-pem", G_CALLBACK(on_peer_pem), self); + self->srtp_dec = gst_element_factory_make ("srtpdec", "srtp-decoder"); + if (!self->srtp_dec) { + GST_ERROR_OBJECT (self, + "failed to create srtp_dec, is the srtp plugin registered?"); + return; + } + self->dtls_srtp_demux = + gst_element_factory_make ("erdtlssrtpdemux", "dtls-srtp-demux"); + if (!self->dtls_srtp_demux) { + GST_ERROR_OBJECT (self, "failed to create dtls_srtp_demux"); + return; + } + self->bin.dtls_element = + gst_element_factory_make ("erdtlsdec", "dtls-decoder"); + if (!self->bin.dtls_element) { + GST_ERROR_OBJECT (self, "failed to create dtls_dec"); + return; + } + self->funnel = gst_element_factory_make ("funnel", "funnel"); + if (!self->funnel) { + GST_ERROR_OBJECT (self, "failed to create funnel"); + return; + } + + gst_bin_add_many (GST_BIN (self), + self->dtls_srtp_demux, + self->bin.dtls_element, self->srtp_dec, self->funnel, NULL); + + ret = + gst_element_link_pads (self->dtls_srtp_demux, "dtls_src", + self->bin.dtls_element, NULL); + g_return_if_fail (ret); + ret = + gst_element_link_pads (self->dtls_srtp_demux, "rtp_src", self->srtp_dec, + "rtp_sink"); + g_return_if_fail (ret); + ret = + gst_element_link_pads (self->srtp_dec, "rtp_src", self->funnel, "sink_0"); + g_return_if_fail (ret); + ret = + gst_element_link_pads (self->srtp_dec, "rtcp_src", self->funnel, + "sink_1"); + g_return_if_fail (ret); + + pad = gst_element_get_static_pad (self->funnel, "sink_1"); + gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, + drop_funnel_rtcp_caps, NULL, NULL); + gst_object_unref (pad); + + templ = gst_element_class_get_pad_template (klass, "rtp_src"); + target_pad = gst_element_get_static_pad (self->funnel, "src"); + ghost_pad = gst_ghost_pad_new_from_template ("rtp_src", target_pad, templ); + gst_object_unref (target_pad); + g_return_if_fail (ghost_pad); + + ret = gst_element_add_pad (GST_ELEMENT (self), ghost_pad); + g_return_if_fail (ret); + + templ = gst_element_class_get_pad_template (klass, "sink"); + target_pad = gst_element_get_static_pad (self->dtls_srtp_demux, "sink"); + ghost_pad = gst_ghost_pad_new_from_template ("sink", target_pad, templ); + gst_object_unref (target_pad); + g_return_if_fail (ghost_pad); + + ret = gst_element_add_pad (GST_ELEMENT (self), ghost_pad); + g_return_if_fail (ret); + + g_signal_connect (self->srtp_dec, "request-key", + G_CALLBACK (on_decoder_request_key), self); + g_signal_connect (self->bin.dtls_element, "notify::peer-pem", + G_CALLBACK (on_peer_pem), self); } -static void gst_er_dtls_srtp_dec_set_property(GObject *object, - guint prop_id, const GValue *value, GParamSpec *pspec) +static void +gst_er_dtls_srtp_dec_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) { - GstErDtlsSrtpDec *self = GST_ER_DTLS_SRTP_DEC(object); + GstErDtlsSrtpDec *self = GST_ER_DTLS_SRTP_DEC (object); - switch (prop_id) { + switch (prop_id) { case PROP_PEM: - if (self->bin.dtls_element) { - g_object_set_property(G_OBJECT(self->bin.dtls_element), "pem", value); - } else { - GST_WARNING_OBJECT(self, "tried to set pem after disabling DTLS"); - } - break; + if (self->bin.dtls_element) { + g_object_set_property (G_OBJECT (self->bin.dtls_element), "pem", value); + } else { + GST_WARNING_OBJECT (self, "tried to set pem after disabling DTLS"); + } + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -static void gst_er_dtls_srtp_dec_get_property(GObject *object, - guint prop_id, GValue *value, GParamSpec *pspec) +static void +gst_er_dtls_srtp_dec_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) { - GstErDtlsSrtpDec *self = GST_ER_DTLS_SRTP_DEC(object); + GstErDtlsSrtpDec *self = GST_ER_DTLS_SRTP_DEC (object); - switch (prop_id) { + switch (prop_id) { case PROP_PEM: - if (self->bin.dtls_element) { - g_object_get_property(G_OBJECT(self->bin.dtls_element), "pem", value); - } else { - GST_WARNING_OBJECT(self, "tried to get pem after disabling DTLS"); - } - break; + if (self->bin.dtls_element) { + g_object_get_property (G_OBJECT (self->bin.dtls_element), "pem", value); + } else { + GST_WARNING_OBJECT (self, "tried to get pem after disabling DTLS"); + } + break; case PROP_PEER_PEM: - if (self->bin.dtls_element) { - g_object_get_property(G_OBJECT(self->bin.dtls_element), "peer-pem", value); - } else { - GST_WARNING_OBJECT(self, "tried to get peer-pem after disabling DTLS"); - } - break; + if (self->bin.dtls_element) { + g_object_get_property (G_OBJECT (self->bin.dtls_element), "peer-pem", + value); + } else { + GST_WARNING_OBJECT (self, "tried to get peer-pem after disabling DTLS"); + } + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -static GstPad *gst_er_dtls_srtp_dec_request_new_pad(GstElement *element, - GstPadTemplate *templ, const gchar *name, const GstCaps *caps) +static GstPad * +gst_er_dtls_srtp_dec_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * name, const GstCaps * caps) { - GstErDtlsSrtpDec *self = GST_ER_DTLS_SRTP_DEC(element); - GstElementClass *klass = GST_ELEMENT_GET_CLASS(element); - GstPad *ghost_pad = NULL; - gboolean ret; - - GST_DEBUG_OBJECT(element, "pad requested"); + GstErDtlsSrtpDec *self = GST_ER_DTLS_SRTP_DEC (element); + GstElementClass *klass = GST_ELEMENT_GET_CLASS (element); + GstPad *ghost_pad = NULL; + gboolean ret; - g_return_val_if_fail(self->bin.dtls_element, NULL); - g_return_val_if_fail(!self->bin.key_is_set, NULL); + GST_DEBUG_OBJECT (element, "pad requested"); - if (templ == gst_element_class_get_pad_template(klass, "data_src")) { - GstPad *target_pad; + g_return_val_if_fail (self->bin.dtls_element, NULL); + g_return_val_if_fail (!self->bin.key_is_set, NULL); - target_pad = gst_element_get_request_pad(self->bin.dtls_element, "src"); + if (templ == gst_element_class_get_pad_template (klass, "data_src")) { + GstPad *target_pad; - ghost_pad = gst_ghost_pad_new_from_template(name, target_pad, templ); - gst_object_unref(target_pad); - g_return_val_if_fail(ghost_pad, NULL); + target_pad = gst_element_get_request_pad (self->bin.dtls_element, "src"); - ret = gst_pad_set_active(ghost_pad, TRUE); - g_return_val_if_fail(ret, NULL); - ret = gst_element_add_pad(element, ghost_pad); - g_return_val_if_fail(ret, NULL); + ghost_pad = gst_ghost_pad_new_from_template (name, target_pad, templ); + gst_object_unref (target_pad); + g_return_val_if_fail (ghost_pad, NULL); - GST_LOG_OBJECT(self, "added data src pad"); + ret = gst_pad_set_active (ghost_pad, TRUE); + g_return_val_if_fail (ret, NULL); + ret = gst_element_add_pad (element, ghost_pad); + g_return_val_if_fail (ret, NULL); - if (caps) { - g_object_set(ghost_pad, "caps", caps, NULL); - } + GST_LOG_OBJECT (self, "added data src pad"); - return ghost_pad; + if (caps) { + g_object_set (ghost_pad, "caps", caps, NULL); } - g_return_val_if_reached(NULL); + return ghost_pad; + } + + g_return_val_if_reached (NULL); } -static GstCaps *on_decoder_request_key(GstElement *srtp_decoder, - guint ssrc, GstErDtlsSrtpBin *bin) +static GstCaps * +on_decoder_request_key (GstElement * srtp_decoder, + guint ssrc, GstErDtlsSrtpBin * bin) { - GstCaps *key_caps; - GstBuffer *key_buffer = NULL; - guint cipher; - guint auth; - - if (bin->key_is_set) { - if (bin->key) { - if (bin->srtp_cipher && bin->srtp_auth && bin->srtcp_cipher && bin->srtcp_auth) { - GST_DEBUG_OBJECT(bin, "setting srtp key"); - return gst_caps_new_simple("application/x-srtp", - "srtp-key", GST_TYPE_BUFFER, gst_buffer_copy(bin->key), - "srtp-auth", G_TYPE_STRING, bin->srtp_auth, - "srtcp-auth", G_TYPE_STRING, bin->srtcp_auth, - "srtp-cipher", G_TYPE_STRING, bin->srtp_cipher, - "srtcp-cipher", G_TYPE_STRING, bin->srtcp_cipher, - NULL); - } else { - GST_WARNING_OBJECT(bin, "srtp key is set but not all ciphers and auths"); - return NULL; - } - } - - GST_DEBUG_OBJECT(bin, "setting srtp key to null"); - return gst_caps_new_simple("application/x-srtp", - "srtp-key", GST_TYPE_BUFFER, NULL, - "srtp-auth", G_TYPE_STRING, "null", - "srtcp-auth", G_TYPE_STRING, "null", - "srtp-cipher", G_TYPE_STRING, "null", - "srtcp-cipher", G_TYPE_STRING, "null", - NULL); + GstCaps *key_caps; + GstBuffer *key_buffer = NULL; + guint cipher; + guint auth; + + if (bin->key_is_set) { + if (bin->key) { + if (bin->srtp_cipher && bin->srtp_auth && bin->srtcp_cipher + && bin->srtcp_auth) { + GST_DEBUG_OBJECT (bin, "setting srtp key"); + return gst_caps_new_simple ("application/x-srtp", + "srtp-key", GST_TYPE_BUFFER, gst_buffer_copy (bin->key), + "srtp-auth", G_TYPE_STRING, bin->srtp_auth, + "srtcp-auth", G_TYPE_STRING, bin->srtcp_auth, + "srtp-cipher", G_TYPE_STRING, bin->srtp_cipher, + "srtcp-cipher", G_TYPE_STRING, bin->srtcp_cipher, NULL); + } else { + GST_WARNING_OBJECT (bin, + "srtp key is set but not all ciphers and auths"); + return NULL; + } } - if (bin->dtls_element) { - g_object_get(bin->dtls_element, - "decoder-key", &key_buffer, - NULL); + GST_DEBUG_OBJECT (bin, "setting srtp key to null"); + return gst_caps_new_simple ("application/x-srtp", + "srtp-key", GST_TYPE_BUFFER, NULL, + "srtp-auth", G_TYPE_STRING, "null", + "srtcp-auth", G_TYPE_STRING, "null", + "srtp-cipher", G_TYPE_STRING, "null", + "srtcp-cipher", G_TYPE_STRING, "null", NULL); + } + + if (bin->dtls_element) { + g_object_get (bin->dtls_element, "decoder-key", &key_buffer, NULL); + } + + if (key_buffer) { + g_object_get (bin->dtls_element, + "srtp-cipher", &cipher, "srtp-auth", &auth, NULL); + + g_return_val_if_fail (cipher == ER_DTLS_SRTP_CIPHER_AES_128_ICM, NULL); + + key_caps = gst_caps_new_simple ("application/x-srtp", + "srtp-key", GST_TYPE_BUFFER, key_buffer, + "srtp-cipher", G_TYPE_STRING, "aes-128-icm", + "srtcp-cipher", G_TYPE_STRING, "aes-128-icm", NULL); + + switch (auth) { + case ER_DTLS_SRTP_AUTH_HMAC_SHA1_32: + gst_caps_set_simple (key_caps, + "srtp-auth", G_TYPE_STRING, "hmac-sha1-32", + "srtcp-auth", G_TYPE_STRING, "hmac-sha1-32", NULL); + break; + case ER_DTLS_SRTP_AUTH_HMAC_SHA1_80: + gst_caps_set_simple (key_caps, + "srtp-auth", G_TYPE_STRING, "hmac-sha1-80", + "srtcp-auth", G_TYPE_STRING, "hmac-sha1-80", NULL); + break; + default: + g_return_val_if_reached (NULL); + break; } - if (key_buffer) { - g_object_get(bin->dtls_element, - "srtp-cipher", &cipher, - "srtp-auth", &auth, - NULL); - - g_return_val_if_fail(cipher == ER_DTLS_SRTP_CIPHER_AES_128_ICM, NULL); - - key_caps = gst_caps_new_simple("application/x-srtp", - "srtp-key", GST_TYPE_BUFFER, key_buffer, - "srtp-cipher", G_TYPE_STRING, "aes-128-icm", - "srtcp-cipher", G_TYPE_STRING, "aes-128-icm", - NULL); - - switch (auth) { - case ER_DTLS_SRTP_AUTH_HMAC_SHA1_32: - gst_caps_set_simple(key_caps, - "srtp-auth", G_TYPE_STRING, "hmac-sha1-32", - "srtcp-auth", G_TYPE_STRING, "hmac-sha1-32", - NULL); - break; - case ER_DTLS_SRTP_AUTH_HMAC_SHA1_80: - gst_caps_set_simple(key_caps, - "srtp-auth", G_TYPE_STRING, "hmac-sha1-80", - "srtcp-auth", G_TYPE_STRING, "hmac-sha1-80", - NULL); - break; - default: - g_return_val_if_reached(NULL); - break; - } - - return key_caps; - } + return key_caps; + } - return NULL; + return NULL; } -static void on_peer_pem(GstElement *srtp_decoder, GParamSpec *pspec, GstErDtlsSrtpDec *self) +static void +on_peer_pem (GstElement * srtp_decoder, GParamSpec * pspec, + GstErDtlsSrtpDec * self) { - UNUSED(srtp_decoder); - UNUSED(pspec); - g_return_if_fail(self); - g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_PEER_PEM]); + UNUSED (srtp_decoder); + UNUSED (pspec); + g_return_if_fail (self); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PEER_PEM]); } -static void gst_er_dtls_srtp_dec_remove_dtls_element(GstErDtlsSrtpBin *bin) +static void +gst_er_dtls_srtp_dec_remove_dtls_element (GstErDtlsSrtpBin * bin) { - GstErDtlsSrtpDec *self = GST_ER_DTLS_SRTP_DEC(bin); - GstPad *demux_pad; - gulong id; + GstErDtlsSrtpDec *self = GST_ER_DTLS_SRTP_DEC (bin); + GstPad *demux_pad; + gulong id; - if (!bin->dtls_element) { - return; - } + if (!bin->dtls_element) { + return; + } - demux_pad = gst_element_get_static_pad(self->dtls_srtp_demux, "dtls_src"); + demux_pad = gst_element_get_static_pad (self->dtls_srtp_demux, "dtls_src"); - id = gst_pad_add_probe(demux_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, - (GstPadProbeCallback) remove_dtls_decoder_probe_callback, bin->dtls_element, NULL); - g_return_if_fail(id); - bin->dtls_element = NULL; + id = gst_pad_add_probe (demux_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, + (GstPadProbeCallback) remove_dtls_decoder_probe_callback, + bin->dtls_element, NULL); + g_return_if_fail (id); + bin->dtls_element = NULL; - gst_pad_push_event(demux_pad, gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, gst_structure_new_empty("dummy"))); + gst_pad_push_event (demux_pad, + gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, + gst_structure_new_empty ("dummy"))); - gst_object_unref(demux_pad); + gst_object_unref (demux_pad); } -static GstPadProbeReturn remove_dtls_decoder_probe_callback(GstPad *pad, - GstPadProbeInfo *info, GstElement *element) +static GstPadProbeReturn +remove_dtls_decoder_probe_callback (GstPad * pad, + GstPadProbeInfo * info, GstElement * element) { - gst_pad_remove_probe(pad, GST_PAD_PROBE_INFO_ID(info)); + gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info)); - gst_element_set_state(GST_ELEMENT(element), GST_STATE_NULL); - gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(element)), element); + gst_element_set_state (GST_ELEMENT (element), GST_STATE_NULL); + gst_bin_remove (GST_BIN (GST_ELEMENT_PARENT (element)), element); - return GST_PAD_PROBE_OK; + return GST_PAD_PROBE_OK; } -static GstPadProbeReturn drop_funnel_rtcp_caps(GstPad *pad, GstPadProbeInfo *info, gpointer data) +static GstPadProbeReturn +drop_funnel_rtcp_caps (GstPad * pad, GstPadProbeInfo * info, gpointer data) { - /* FIXME: This is needed for setting the proper caps until - * GStreamer supports MIXED caps or another mechanism to - * prevent renegotiation all the time when two different caps - * are going over the same pad - */ - if (GST_EVENT_TYPE (info->data) == GST_EVENT_CAPS) { - GstCaps *caps, *peercaps; - GstStructure *s; - - gst_event_parse_caps (GST_EVENT (info->data), &caps); - s = gst_caps_get_structure (caps, 0); - if (gst_structure_has_name (s, "application/x-rtcp")) { - peercaps = gst_pad_query_caps (pad, NULL); - - /* If the peer does not accept RTCP, we are linked to - * the RTP sinkpad of rtpbin. In that case we have to - * drop the RTCP caps and assume that we sent RTP caps - * before here, which is very likely but not guaranteed - * if for some reason we receive RTCP before any RTP. - * In that unlikely case we will get event misordering - * warnings later, instead of getting them always as - * happens now. - */ - if (peercaps && !gst_caps_is_subset (caps, peercaps)) { - gst_caps_unref (peercaps); - return GST_PAD_PROBE_DROP; - } - gst_caps_replace (&peercaps, NULL); + /* FIXME: This is needed for setting the proper caps until + * GStreamer supports MIXED caps or another mechanism to + * prevent renegotiation all the time when two different caps + * are going over the same pad + */ + if (GST_EVENT_TYPE (info->data) == GST_EVENT_CAPS) { + GstCaps *caps, *peercaps; + GstStructure *s; + + gst_event_parse_caps (GST_EVENT (info->data), &caps); + s = gst_caps_get_structure (caps, 0); + if (gst_structure_has_name (s, "application/x-rtcp")) { + peercaps = gst_pad_query_caps (pad, NULL); + + /* If the peer does not accept RTCP, we are linked to + * the RTP sinkpad of rtpbin. In that case we have to + * drop the RTCP caps and assume that we sent RTP caps + * before here, which is very likely but not guaranteed + * if for some reason we receive RTCP before any RTP. + * In that unlikely case we will get event misordering + * warnings later, instead of getting them always as + * happens now. + */ + if (peercaps && !gst_caps_is_subset (caps, peercaps)) { + gst_caps_unref (peercaps); + return GST_PAD_PROBE_DROP; } + gst_caps_replace (&peercaps, NULL); } + } - return GST_PAD_PROBE_OK; + return GST_PAD_PROBE_OK; } diff --git a/ext/dtls/gstdtlssrtpdemux.c b/ext/dtls/gstdtlssrtpdemux.c index b4854de..2596940 100644 --- a/ext/dtls/gstdtlssrtpdemux.c +++ b/ext/dtls/gstdtlssrtpdemux.c @@ -32,108 +32,109 @@ #define PACKET_IS_DTLS(b) (b > 0x13 && b < 0x40) #define PACKET_IS_RTP(b) (b > 0x7f && b < 0xc0) -static GstStaticPadTemplate sink_template = - GST_STATIC_PAD_TEMPLATE("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY - ); +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); static GstStaticPadTemplate rtp_src_template = - GST_STATIC_PAD_TEMPLATE("rtp_src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS( - "application/x-rtp;" - "application/x-rtcp;" - "application/x-srtp;" - "application/x-srtcp") + GST_STATIC_PAD_TEMPLATE ("rtp_src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-rtp;" + "application/x-rtcp;" "application/x-srtp;" "application/x-srtcp") ); static GstStaticPadTemplate dtls_src_template = - GST_STATIC_PAD_TEMPLATE("dtls_src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS("application/x-dtls") +GST_STATIC_PAD_TEMPLATE ("dtls_src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-dtls") ); -GST_DEBUG_CATEGORY_STATIC(er_er_dtls_srtp_demux_debug); +GST_DEBUG_CATEGORY_STATIC (er_er_dtls_srtp_demux_debug); #define GST_CAT_DEFAULT er_er_dtls_srtp_demux_debug #define gst_er_dtls_srtp_demux_parent_class parent_class -G_DEFINE_TYPE_WITH_CODE(GstErDtlsSrtpDemux, gst_er_dtls_srtp_demux, GST_TYPE_ELEMENT, - GST_DEBUG_CATEGORY_INIT(er_er_dtls_srtp_demux_debug, "erdtlssrtpdemux", 0, "Ericsson DTLS SRTP Demultiplexer")); +G_DEFINE_TYPE_WITH_CODE (GstErDtlsSrtpDemux, gst_er_dtls_srtp_demux, + GST_TYPE_ELEMENT, GST_DEBUG_CATEGORY_INIT (er_er_dtls_srtp_demux_debug, + "erdtlssrtpdemux", 0, "Ericsson DTLS SRTP Demultiplexer")); -static GstFlowReturn sink_chain(GstPad *, GstObject *self, GstBuffer *); +static GstFlowReturn sink_chain (GstPad *, GstObject * self, GstBuffer *); -static void gst_er_dtls_srtp_demux_class_init(GstErDtlsSrtpDemuxClass *klass) +static void +gst_er_dtls_srtp_demux_class_init (GstErDtlsSrtpDemuxClass * klass) { - GstElementClass *element_class; - - element_class = (GstElementClass *) klass; - - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&sink_template)); - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&rtp_src_template)); - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&dtls_src_template)); - - gst_element_class_set_static_metadata(element_class, - "DTLS SRTP Demultiplexer", - "DTLS/SRTP/Demux", - "Demultiplexes DTLS and SRTP packets", - "Patrik Oldsberg patrik.oldsberg@ericsson.com"); + GstElementClass *element_class; + + element_class = (GstElementClass *) klass; + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&rtp_src_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&dtls_src_template)); + + gst_element_class_set_static_metadata (element_class, + "DTLS SRTP Demultiplexer", + "DTLS/SRTP/Demux", + "Demultiplexes DTLS and SRTP packets", + "Patrik Oldsberg patrik.oldsberg@ericsson.com"); } -static void gst_er_dtls_srtp_demux_init(GstErDtlsSrtpDemux *self) +static void +gst_er_dtls_srtp_demux_init (GstErDtlsSrtpDemux * self) { - GstPad *sink; - - sink = gst_pad_new_from_static_template(&sink_template, "sink"); - self->rtp_src = gst_pad_new_from_static_template(&rtp_src_template, "rtp_src"); - self->dtls_src = gst_pad_new_from_static_template(&dtls_src_template, "dtls_src"); - g_return_if_fail(sink); - g_return_if_fail(self->rtp_src); - g_return_if_fail(self->dtls_src); - - gst_pad_set_chain_function(sink, GST_DEBUG_FUNCPTR(sink_chain)); - - gst_element_add_pad(GST_ELEMENT(self), sink); - gst_element_add_pad(GST_ELEMENT(self), self->rtp_src); - gst_element_add_pad(GST_ELEMENT(self), self->dtls_src); + GstPad *sink; + + sink = gst_pad_new_from_static_template (&sink_template, "sink"); + self->rtp_src = + gst_pad_new_from_static_template (&rtp_src_template, "rtp_src"); + self->dtls_src = + gst_pad_new_from_static_template (&dtls_src_template, "dtls_src"); + g_return_if_fail (sink); + g_return_if_fail (self->rtp_src); + g_return_if_fail (self->dtls_src); + + gst_pad_set_chain_function (sink, GST_DEBUG_FUNCPTR (sink_chain)); + + gst_element_add_pad (GST_ELEMENT (self), sink); + gst_element_add_pad (GST_ELEMENT (self), self->rtp_src); + gst_element_add_pad (GST_ELEMENT (self), self->dtls_src); } -static GstFlowReturn sink_chain(GstPad *pad, GstObject *parent, GstBuffer *buffer) +static GstFlowReturn +sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) { - GstErDtlsSrtpDemux *self = GST_ER_DTLS_SRTP_DEMUX(parent); - guint8 first_byte; + GstErDtlsSrtpDemux *self = GST_ER_DTLS_SRTP_DEMUX (parent); + guint8 first_byte; - if (gst_buffer_get_size(buffer) == 0) { - GST_LOG_OBJECT(self, "received buffer with size 0"); - gst_buffer_unref(buffer); - return GST_FLOW_OK; - } + if (gst_buffer_get_size (buffer) == 0) { + GST_LOG_OBJECT (self, "received buffer with size 0"); + gst_buffer_unref (buffer); + return GST_FLOW_OK; + } - if (gst_buffer_extract(buffer, 0, &first_byte, 1) != 1) { - GST_WARNING_OBJECT(self, "could not extract first byte from buffer"); - gst_buffer_unref(buffer); - return GST_FLOW_OK; - } + if (gst_buffer_extract (buffer, 0, &first_byte, 1) != 1) { + GST_WARNING_OBJECT (self, "could not extract first byte from buffer"); + gst_buffer_unref (buffer); + return GST_FLOW_OK; + } - if (PACKET_IS_DTLS(first_byte)) { - GST_LOG_OBJECT(self, "pushing dtls packet"); + if (PACKET_IS_DTLS (first_byte)) { + GST_LOG_OBJECT (self, "pushing dtls packet"); - return gst_pad_push(self->dtls_src, buffer); - } + return gst_pad_push (self->dtls_src, buffer); + } - if (PACKET_IS_RTP(first_byte)) { - GST_LOG_OBJECT(self, "pushing rtp packet"); + if (PACKET_IS_RTP (first_byte)) { + GST_LOG_OBJECT (self, "pushing rtp packet"); - return gst_pad_push(self->rtp_src, buffer); - } + return gst_pad_push (self->rtp_src, buffer); + } - GST_WARNING_OBJECT(self, "received invalid buffer: %x", first_byte); - gst_buffer_unref(buffer); - return GST_FLOW_OK; + GST_WARNING_OBJECT (self, "received invalid buffer: %x", first_byte); + gst_buffer_unref (buffer); + return GST_FLOW_OK; } diff --git a/ext/dtls/gstdtlssrtpenc.c b/ext/dtls/gstdtlssrtpenc.c index 34b45a1..7280c59 100644 --- a/ext/dtls/gstdtlssrtpenc.c +++ b/ext/dtls/gstdtlssrtpenc.c @@ -32,123 +32,135 @@ #include static GstStaticPadTemplate rtp_sink_template = - GST_STATIC_PAD_TEMPLATE("rtp_sink_%d", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS("application/x-rtp;application/x-rtcp") + GST_STATIC_PAD_TEMPLATE ("rtp_sink_%d", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS ("application/x-rtp;application/x-rtcp") ); static GstStaticPadTemplate rtcp_sink_template = - GST_STATIC_PAD_TEMPLATE("rtcp_sink_%d", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS("application/x-rtp;application/x-rtcp") + GST_STATIC_PAD_TEMPLATE ("rtcp_sink_%d", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS ("application/x-rtp;application/x-rtcp") ); static GstStaticPadTemplate data_sink_template = - GST_STATIC_PAD_TEMPLATE("data_sink", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS_ANY - ); +GST_STATIC_PAD_TEMPLATE ("data_sink", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS_ANY); -static GstStaticPadTemplate src_template = - GST_STATIC_PAD_TEMPLATE("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY - ); +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); -GST_DEBUG_CATEGORY_STATIC(er_dtls_srtp_enc_debug); +GST_DEBUG_CATEGORY_STATIC (er_dtls_srtp_enc_debug); #define GST_CAT_DEFAULT er_dtls_srtp_enc_debug #define gst_er_dtls_srtp_enc_parent_class parent_class -G_DEFINE_TYPE_WITH_CODE(GstErDtlsSrtpEnc, gst_er_dtls_srtp_enc, GST_TYPE_ER_DTLS_SRTP_BIN, - GST_DEBUG_CATEGORY_INIT(er_dtls_srtp_enc_debug, "erdtlssrtpenc", 0, "Ericsson DTLS Decoder")); +G_DEFINE_TYPE_WITH_CODE (GstErDtlsSrtpEnc, gst_er_dtls_srtp_enc, + GST_TYPE_ER_DTLS_SRTP_BIN, GST_DEBUG_CATEGORY_INIT (er_dtls_srtp_enc_debug, + "erdtlssrtpenc", 0, "Ericsson DTLS Decoder")); -enum { - SIGNAL_ON_KEY_SET, - NUM_SIGNALS +enum +{ + SIGNAL_ON_KEY_SET, + NUM_SIGNALS }; static guint signals[NUM_SIGNALS]; -enum { - PROP_0, - PROP_IS_CLIENT, - NUM_PROPERTIES +enum +{ + PROP_0, + PROP_IS_CLIENT, + NUM_PROPERTIES }; static GParamSpec *properties[NUM_PROPERTIES]; #define DEFAULT_IS_CLIENT FALSE -static gboolean transform_enum(GBinding *, const GValue *source_value, GValue *target_value, GEnumClass *); +static gboolean transform_enum (GBinding *, const GValue * source_value, + GValue * target_value, GEnumClass *); -static void gst_er_dtls_srtp_enc_set_property(GObject *, guint prop_id, const GValue *, GParamSpec *); -static void gst_er_dtls_srtp_enc_get_property(GObject *, guint prop_id, GValue *, GParamSpec *); +static void gst_er_dtls_srtp_enc_set_property (GObject *, guint prop_id, + const GValue *, GParamSpec *); +static void gst_er_dtls_srtp_enc_get_property (GObject *, guint prop_id, + GValue *, GParamSpec *); -static GstPad *add_ghost_pad(GstElement *, const gchar *name, GstPad *, GstPadTemplate *); -static GstPad *gst_er_dtls_srtp_enc_request_new_pad(GstElement *, GstPadTemplate *, const gchar *name, const GstCaps *); +static GstPad *add_ghost_pad (GstElement *, const gchar * name, GstPad *, + GstPadTemplate *); +static GstPad *gst_er_dtls_srtp_enc_request_new_pad (GstElement *, + GstPadTemplate *, const gchar * name, const GstCaps *); -static void on_key_received(GObject *encoder, GstErDtlsSrtpEnc *); +static void on_key_received (GObject * encoder, GstErDtlsSrtpEnc *); -static void gst_er_dtls_srtp_enc_remove_dtls_element(GstErDtlsSrtpBin *); -static GstPadProbeReturn remove_dtls_encoder_probe_callback(GstPad *, GstPadProbeInfo *, GstElement *); +static void gst_er_dtls_srtp_enc_remove_dtls_element (GstErDtlsSrtpBin *); +static GstPadProbeReturn remove_dtls_encoder_probe_callback (GstPad *, + GstPadProbeInfo *, GstElement *); -static void gst_er_dtls_srtp_enc_class_init(GstErDtlsSrtpEncClass *klass) +static void +gst_er_dtls_srtp_enc_class_init (GstErDtlsSrtpEncClass * klass) { - GObjectClass *gobject_class; - GstElementClass *element_class; - GstErDtlsSrtpBinClass *dtls_srtp_bin_class; - - gobject_class = (GObjectClass *) klass; - element_class = (GstElementClass *) klass; - dtls_srtp_bin_class = (GstErDtlsSrtpBinClass *) klass; - - gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_er_dtls_srtp_enc_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_er_dtls_srtp_enc_get_property); - - element_class->request_new_pad = GST_DEBUG_FUNCPTR(gst_er_dtls_srtp_enc_request_new_pad); - - dtls_srtp_bin_class->remove_dtls_element = GST_DEBUG_FUNCPTR(gst_er_dtls_srtp_enc_remove_dtls_element); - - signals[SIGNAL_ON_KEY_SET] = - g_signal_new("on-key-set", G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_generic, G_TYPE_NONE, 0); - - properties[PROP_IS_CLIENT] = - g_param_spec_boolean("is-client", - "Is client", - "Set to true if the decoder should act as " - "client and initiate the handshake", - DEFAULT_IS_CLIENT, - GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobject_class, NUM_PROPERTIES, properties); - - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&rtp_sink_template)); - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&rtcp_sink_template)); - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&data_sink_template)); - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get(&src_template)); - - gst_element_class_set_static_metadata(element_class, - "DTLS-SRTP Encoder", - "Encoder/Network/DTLS/SRTP", - "Encodes SRTP packets with a key received from DTLS", - "Patrik Oldsberg patrik.oldsberg@ericsson.com"); + GObjectClass *gobject_class; + GstElementClass *element_class; + GstErDtlsSrtpBinClass *dtls_srtp_bin_class; + + gobject_class = (GObjectClass *) klass; + element_class = (GstElementClass *) klass; + dtls_srtp_bin_class = (GstErDtlsSrtpBinClass *) klass; + + gobject_class->set_property = + GST_DEBUG_FUNCPTR (gst_er_dtls_srtp_enc_set_property); + gobject_class->get_property = + GST_DEBUG_FUNCPTR (gst_er_dtls_srtp_enc_get_property); + + element_class->request_new_pad = + GST_DEBUG_FUNCPTR (gst_er_dtls_srtp_enc_request_new_pad); + + dtls_srtp_bin_class->remove_dtls_element = + GST_DEBUG_FUNCPTR (gst_er_dtls_srtp_enc_remove_dtls_element); + + signals[SIGNAL_ON_KEY_SET] = + g_signal_new ("on-key-set", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + g_cclosure_marshal_generic, G_TYPE_NONE, 0); + + properties[PROP_IS_CLIENT] = + g_param_spec_boolean ("is-client", + "Is client", + "Set to true if the decoder should act as " + "client and initiate the handshake", + DEFAULT_IS_CLIENT, + GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&rtp_sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&rtcp_sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&data_sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); + + gst_element_class_set_static_metadata (element_class, + "DTLS-SRTP Encoder", + "Encoder/Network/DTLS/SRTP", + "Encodes SRTP packets with a key received from DTLS", + "Patrik Oldsberg patrik.oldsberg@ericsson.com"); } -static void gst_er_dtls_srtp_enc_init(GstErDtlsSrtpEnc *self) +static void +gst_er_dtls_srtp_enc_init (GstErDtlsSrtpEnc * self) { - GstElementClass *klass = GST_ELEMENT_GET_CLASS(GST_ELEMENT(self)); - static GEnumClass *cipher_enum_class, *auth_enum_class; - gboolean ret; + GstElementClass *klass = GST_ELEMENT_GET_CLASS (GST_ELEMENT (self)); + static GEnumClass *cipher_enum_class, *auth_enum_class; + gboolean ret; /* +--------------------+ +-----------------+ @@ -162,275 +174,295 @@ static void gst_er_dtls_srtp_enc_init(GstErDtlsSrtpEnc *self) +--------------------+ +-----------------+ */ - self->srtp_enc = gst_element_factory_make("srtpenc", "srtp-encoder"); - if (!self->srtp_enc) { - GST_ERROR_OBJECT(self, "failed to create srtp encoder, is the srtp plugin registered?"); - return; - } - g_return_if_fail(self->srtp_enc); - self->bin.dtls_element = gst_element_factory_make("erdtlsenc", "dtls-encoder"); - if (!self->bin.dtls_element) { - GST_ERROR_OBJECT(self, "failed to create dtls encoder"); - return; - } - self->funnel = gst_element_factory_make("funnel", "funnel"); - if (!self->funnel) { - GST_ERROR_OBJECT(self, "failed to create funnel"); - return; - } - - gst_bin_add_many(GST_BIN(self), self->bin.dtls_element, self->srtp_enc, self->funnel, NULL); - - ret = gst_element_link(self->bin.dtls_element, self->funnel); - g_return_if_fail(ret); - - add_ghost_pad(GST_ELEMENT(self), "src", - gst_element_get_static_pad(self->funnel, "src"), - gst_element_class_get_pad_template(klass, "src")); - - g_signal_connect(self->bin.dtls_element, "on-key-received", G_CALLBACK(on_key_received), self); - - if (g_once_init_enter(&cipher_enum_class)) { - GType type = g_type_from_name("GstSrtpCipherType"); - g_assert(type); - g_once_init_leave(&cipher_enum_class, g_type_class_peek(type)); - } - if (g_once_init_enter(&auth_enum_class)) { - GType type = g_type_from_name("GstSrtpAuthType"); - g_assert(type); - g_once_init_leave(&auth_enum_class, g_type_class_peek(type)); - } - - g_object_set(self->srtp_enc, "random-key", TRUE, NULL); - - g_object_bind_property(G_OBJECT(self), "key", self->srtp_enc, "key", G_BINDING_DEFAULT); - g_object_bind_property_full(G_OBJECT(self), "srtp-cipher", self->srtp_enc, "rtp-cipher", G_BINDING_DEFAULT, - (GBindingTransformFunc) transform_enum, NULL, cipher_enum_class, NULL); - g_object_bind_property_full(G_OBJECT(self), "srtcp-cipher", self->srtp_enc, "rtcp-cipher", G_BINDING_DEFAULT, - (GBindingTransformFunc) transform_enum, NULL, cipher_enum_class, NULL); - g_object_bind_property_full(G_OBJECT(self), "srtp-auth", self->srtp_enc, "rtp-auth", G_BINDING_DEFAULT, - (GBindingTransformFunc) transform_enum, NULL, auth_enum_class, NULL); - g_object_bind_property_full(G_OBJECT(self), "srtcp-auth", self->srtp_enc, "rtcp-auth", G_BINDING_DEFAULT, - (GBindingTransformFunc) transform_enum, NULL, auth_enum_class, NULL); + self->srtp_enc = gst_element_factory_make ("srtpenc", "srtp-encoder"); + if (!self->srtp_enc) { + GST_ERROR_OBJECT (self, + "failed to create srtp encoder, is the srtp plugin registered?"); + return; + } + g_return_if_fail (self->srtp_enc); + self->bin.dtls_element = + gst_element_factory_make ("erdtlsenc", "dtls-encoder"); + if (!self->bin.dtls_element) { + GST_ERROR_OBJECT (self, "failed to create dtls encoder"); + return; + } + self->funnel = gst_element_factory_make ("funnel", "funnel"); + if (!self->funnel) { + GST_ERROR_OBJECT (self, "failed to create funnel"); + return; + } + + gst_bin_add_many (GST_BIN (self), self->bin.dtls_element, self->srtp_enc, + self->funnel, NULL); + + ret = gst_element_link (self->bin.dtls_element, self->funnel); + g_return_if_fail (ret); + + add_ghost_pad (GST_ELEMENT (self), "src", + gst_element_get_static_pad (self->funnel, "src"), + gst_element_class_get_pad_template (klass, "src")); + + g_signal_connect (self->bin.dtls_element, "on-key-received", + G_CALLBACK (on_key_received), self); + + if (g_once_init_enter (&cipher_enum_class)) { + GType type = g_type_from_name ("GstSrtpCipherType"); + g_assert (type); + g_once_init_leave (&cipher_enum_class, g_type_class_peek (type)); + } + if (g_once_init_enter (&auth_enum_class)) { + GType type = g_type_from_name ("GstSrtpAuthType"); + g_assert (type); + g_once_init_leave (&auth_enum_class, g_type_class_peek (type)); + } + + g_object_set (self->srtp_enc, "random-key", TRUE, NULL); + + g_object_bind_property (G_OBJECT (self), "key", self->srtp_enc, "key", + G_BINDING_DEFAULT); + g_object_bind_property_full (G_OBJECT (self), "srtp-cipher", self->srtp_enc, + "rtp-cipher", G_BINDING_DEFAULT, (GBindingTransformFunc) transform_enum, + NULL, cipher_enum_class, NULL); + g_object_bind_property_full (G_OBJECT (self), "srtcp-cipher", self->srtp_enc, + "rtcp-cipher", G_BINDING_DEFAULT, (GBindingTransformFunc) transform_enum, + NULL, cipher_enum_class, NULL); + g_object_bind_property_full (G_OBJECT (self), "srtp-auth", self->srtp_enc, + "rtp-auth", G_BINDING_DEFAULT, (GBindingTransformFunc) transform_enum, + NULL, auth_enum_class, NULL); + g_object_bind_property_full (G_OBJECT (self), "srtcp-auth", self->srtp_enc, + "rtcp-auth", G_BINDING_DEFAULT, (GBindingTransformFunc) transform_enum, + NULL, auth_enum_class, NULL); } -static gboolean transform_enum(GBinding *binding, const GValue *source_value, GValue *target_value, GEnumClass *enum_class) +static gboolean +transform_enum (GBinding * binding, const GValue * source_value, + GValue * target_value, GEnumClass * enum_class) { - GEnumValue *enum_value; - const gchar *nick; + GEnumValue *enum_value; + const gchar *nick; - nick = g_value_get_string(source_value); - g_return_val_if_fail(nick, FALSE); + nick = g_value_get_string (source_value); + g_return_val_if_fail (nick, FALSE); - enum_value = g_enum_get_value_by_nick(enum_class, nick); - g_return_val_if_fail(enum_value, FALSE); + enum_value = g_enum_get_value_by_nick (enum_class, nick); + g_return_val_if_fail (enum_value, FALSE); - GST_DEBUG_OBJECT(g_binding_get_source(binding), - "transforming enum from %s to %d", nick, enum_value->value); + GST_DEBUG_OBJECT (g_binding_get_source (binding), + "transforming enum from %s to %d", nick, enum_value->value); - g_value_set_enum(target_value, enum_value->value); + g_value_set_enum (target_value, enum_value->value); - return TRUE; + return TRUE; } -static void gst_er_dtls_srtp_enc_set_property(GObject *object, - guint prop_id, const GValue *value, GParamSpec *pspec) +static void +gst_er_dtls_srtp_enc_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) { - GstErDtlsSrtpEnc *self = GST_ER_DTLS_SRTP_ENC(object); + GstErDtlsSrtpEnc *self = GST_ER_DTLS_SRTP_ENC (object); - switch (prop_id) { + switch (prop_id) { case PROP_IS_CLIENT: - if (self->bin.dtls_element) { - g_object_set_property(G_OBJECT(self->bin.dtls_element), "is-client", value); - } else { - GST_WARNING_OBJECT(self, "tried to set is-client after disabling DTLS"); - } - break; + if (self->bin.dtls_element) { + g_object_set_property (G_OBJECT (self->bin.dtls_element), "is-client", + value); + } else { + GST_WARNING_OBJECT (self, + "tried to set is-client after disabling DTLS"); + } + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -static void gst_er_dtls_srtp_enc_get_property(GObject *object, - guint prop_id, GValue *value, GParamSpec *pspec) +static void +gst_er_dtls_srtp_enc_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) { - GstErDtlsSrtpEnc *self = GST_ER_DTLS_SRTP_ENC(object); + GstErDtlsSrtpEnc *self = GST_ER_DTLS_SRTP_ENC (object); - switch (prop_id) { + switch (prop_id) { case PROP_IS_CLIENT: - if (self->bin.dtls_element) { - g_object_get_property(G_OBJECT(self->bin.dtls_element), "is-client", value); - } else { - GST_WARNING_OBJECT(self, "tried to get is-client after disabling DTLS"); - } - break; + if (self->bin.dtls_element) { + g_object_get_property (G_OBJECT (self->bin.dtls_element), "is-client", + value); + } else { + GST_WARNING_OBJECT (self, + "tried to get is-client after disabling DTLS"); + } + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(self, prop_id, pspec); - } + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + } } -static GstPad *add_ghost_pad(GstElement *element, - const gchar *name, GstPad *target, GstPadTemplate *templ) +static GstPad * +add_ghost_pad (GstElement * element, + const gchar * name, GstPad * target, GstPadTemplate * templ) { - GstPad *pad; - gboolean ret; + GstPad *pad; + gboolean ret; - pad = gst_ghost_pad_new_from_template(name, target, templ); - gst_object_unref(target); - target = NULL; + pad = gst_ghost_pad_new_from_template (name, target, templ); + gst_object_unref (target); + target = NULL; - ret = gst_pad_set_active(pad, TRUE); - g_warn_if_fail(ret); + ret = gst_pad_set_active (pad, TRUE); + g_warn_if_fail (ret); - ret = gst_element_add_pad(element, pad); - g_warn_if_fail(ret); + ret = gst_element_add_pad (element, pad); + g_warn_if_fail (ret); - return pad; + return pad; } -static GstPad *gst_er_dtls_srtp_enc_request_new_pad(GstElement *element, - GstPadTemplate *templ, const gchar *name, const GstCaps *caps) +static GstPad * +gst_er_dtls_srtp_enc_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * name, const GstCaps * caps) { - GstErDtlsSrtpEnc *self = GST_ER_DTLS_SRTP_ENC(element); - GstElementClass *klass = GST_ELEMENT_GET_CLASS(element); - GstPad *target_pad; - GstPad *ghost_pad = NULL; - guint pad_n; - gchar *srtp_src_name; + GstErDtlsSrtpEnc *self = GST_ER_DTLS_SRTP_ENC (element); + GstElementClass *klass = GST_ELEMENT_GET_CLASS (element); + GstPad *target_pad; + GstPad *ghost_pad = NULL; + guint pad_n; + gchar *srtp_src_name; - GST_DEBUG_OBJECT(element, "pad requested"); + GST_DEBUG_OBJECT (element, "pad requested"); - g_return_val_if_fail(templ->direction == GST_PAD_SINK, NULL); - g_return_val_if_fail(self->srtp_enc, NULL); + g_return_val_if_fail (templ->direction == GST_PAD_SINK, NULL); + g_return_val_if_fail (self->srtp_enc, NULL); - if (templ == gst_element_class_get_pad_template(klass, "rtp_sink_%d")) { - target_pad = gst_element_get_request_pad(self->srtp_enc, name); - g_return_val_if_fail(target_pad, NULL); + if (templ == gst_element_class_get_pad_template (klass, "rtp_sink_%d")) { + target_pad = gst_element_get_request_pad (self->srtp_enc, name); + g_return_val_if_fail (target_pad, NULL); - sscanf(GST_PAD_NAME(target_pad), "rtp_sink_%d", &pad_n); - srtp_src_name = g_strdup_printf("rtp_src_%d", pad_n); + sscanf (GST_PAD_NAME (target_pad), "rtp_sink_%d", &pad_n); + srtp_src_name = g_strdup_printf ("rtp_src_%d", pad_n); - gst_element_link_pads(self->srtp_enc, srtp_src_name, self->funnel, NULL); + gst_element_link_pads (self->srtp_enc, srtp_src_name, self->funnel, NULL); - g_free(srtp_src_name); + g_free (srtp_src_name); - ghost_pad = add_ghost_pad(element, name, target_pad, templ); + ghost_pad = add_ghost_pad (element, name, target_pad, templ); - GST_LOG_OBJECT(self, "added rtp sink pad"); - } else if (templ == gst_element_class_get_pad_template(klass, "rtcp_sink_%d")) { - target_pad = gst_element_get_request_pad(self->srtp_enc, name); - g_return_val_if_fail(target_pad, NULL); + GST_LOG_OBJECT (self, "added rtp sink pad"); + } else if (templ == gst_element_class_get_pad_template (klass, + "rtcp_sink_%d")) { + target_pad = gst_element_get_request_pad (self->srtp_enc, name); + g_return_val_if_fail (target_pad, NULL); - sscanf(GST_PAD_NAME(target_pad), "rtcp_sink_%d", &pad_n); - srtp_src_name = g_strdup_printf("rtcp_src_%d", pad_n); + sscanf (GST_PAD_NAME (target_pad), "rtcp_sink_%d", &pad_n); + srtp_src_name = g_strdup_printf ("rtcp_src_%d", pad_n); - gst_element_link_pads(self->srtp_enc, srtp_src_name, self->funnel, NULL); + gst_element_link_pads (self->srtp_enc, srtp_src_name, self->funnel, NULL); - g_free(srtp_src_name); + g_free (srtp_src_name); - ghost_pad = add_ghost_pad(element, name, target_pad, templ); + ghost_pad = add_ghost_pad (element, name, target_pad, templ); - GST_LOG_OBJECT(self, "added rtcp sink pad"); - } else if (templ == gst_element_class_get_pad_template(klass, "data_sink")) { - g_return_val_if_fail(self->bin.dtls_element, NULL); - target_pad = gst_element_get_request_pad(self->bin.dtls_element, "sink"); + GST_LOG_OBJECT (self, "added rtcp sink pad"); + } else if (templ == gst_element_class_get_pad_template (klass, "data_sink")) { + g_return_val_if_fail (self->bin.dtls_element, NULL); + target_pad = gst_element_get_request_pad (self->bin.dtls_element, "sink"); - ghost_pad = add_ghost_pad(element, name, target_pad, templ); + ghost_pad = add_ghost_pad (element, name, target_pad, templ); - GST_LOG_OBJECT(self, "added data sink pad"); - } else { - g_warn_if_reached(); - } + GST_LOG_OBJECT (self, "added data sink pad"); + } else { + g_warn_if_reached (); + } - if (caps && ghost_pad) { - g_object_set(ghost_pad, "caps", caps, NULL); - } + if (caps && ghost_pad) { + g_object_set (ghost_pad, "caps", caps, NULL); + } - return ghost_pad; + return ghost_pad; } -static void on_key_received(GObject *encoder, GstErDtlsSrtpEnc *self) +static void +on_key_received (GObject * encoder, GstErDtlsSrtpEnc * self) { - GstErDtlsSrtpBin *bin = GST_ER_DTLS_SRTP_BIN(self); - GstBuffer *buffer = NULL; - guint cipher, auth; - - if (!(bin->key_is_set || bin->srtp_cipher || bin->srtp_auth - || bin->srtcp_cipher || bin->srtcp_auth)) { - g_object_get(encoder, - "encoder-key", &buffer, - "srtp-cipher", &cipher, - "srtp-auth", &auth, - NULL); - - g_object_set(self->srtp_enc, - "rtp-cipher", cipher, - "rtcp-cipher", cipher, - "rtp-auth", auth, - "rtcp-auth", auth, - "key", buffer, - "random-key", FALSE, - NULL); - - g_signal_emit(self, signals[SIGNAL_ON_KEY_SET], 0); - } else { - GST_DEBUG_OBJECT(self, "ignoring keys received from DTLS handshake, key struct is set"); - } + GstErDtlsSrtpBin *bin = GST_ER_DTLS_SRTP_BIN (self); + GstBuffer *buffer = NULL; + guint cipher, auth; + + if (!(bin->key_is_set || bin->srtp_cipher || bin->srtp_auth + || bin->srtcp_cipher || bin->srtcp_auth)) { + g_object_get (encoder, + "encoder-key", &buffer, + "srtp-cipher", &cipher, "srtp-auth", &auth, NULL); + + g_object_set (self->srtp_enc, + "rtp-cipher", cipher, + "rtcp-cipher", cipher, + "rtp-auth", auth, + "rtcp-auth", auth, "key", buffer, "random-key", FALSE, NULL); + + g_signal_emit (self, signals[SIGNAL_ON_KEY_SET], 0); + } else { + GST_DEBUG_OBJECT (self, + "ignoring keys received from DTLS handshake, key struct is set"); + } } -static void gst_er_dtls_srtp_enc_remove_dtls_element(GstErDtlsSrtpBin *bin) +static void +gst_er_dtls_srtp_enc_remove_dtls_element (GstErDtlsSrtpBin * bin) { - GstErDtlsSrtpEnc *self = GST_ER_DTLS_SRTP_ENC(bin); - GstPad *dtls_sink_pad, *peer_pad; - gulong id; - guint rtp_cipher = 1, rtcp_cipher = 1, rtp_auth = 1, rtcp_auth = 1; - - if (!bin->dtls_element) { - return; - } - - g_object_get(self->srtp_enc, - "rtp-cipher", &rtp_cipher, - "rtcp-cipher", &rtcp_cipher, - "rtp-auth", &rtp_auth, - "rtcp-auth", &rtcp_auth, - NULL); - - if (!rtp_cipher && !rtcp_cipher && !rtp_auth && !rtcp_auth) { - g_object_set(self->srtp_enc, "random-key", FALSE, NULL); - } - - dtls_sink_pad = gst_element_get_static_pad(bin->dtls_element, "sink"); - - if (!dtls_sink_pad) { - gst_element_set_state(GST_ELEMENT(bin->dtls_element), GST_STATE_NULL); - gst_bin_remove(GST_BIN(self), bin->dtls_element); - bin->dtls_element = NULL; - return; - } - - peer_pad = gst_pad_get_peer(dtls_sink_pad); - g_return_if_fail(peer_pad); - gst_object_unref(dtls_sink_pad); - dtls_sink_pad = NULL; - - id = gst_pad_add_probe(peer_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, - (GstPadProbeCallback) remove_dtls_encoder_probe_callback, bin->dtls_element, NULL); - g_return_if_fail(id); + GstErDtlsSrtpEnc *self = GST_ER_DTLS_SRTP_ENC (bin); + GstPad *dtls_sink_pad, *peer_pad; + gulong id; + guint rtp_cipher = 1, rtcp_cipher = 1, rtp_auth = 1, rtcp_auth = 1; + + if (!bin->dtls_element) { + return; + } + + g_object_get (self->srtp_enc, + "rtp-cipher", &rtp_cipher, + "rtcp-cipher", &rtcp_cipher, + "rtp-auth", &rtp_auth, "rtcp-auth", &rtcp_auth, NULL); + + if (!rtp_cipher && !rtcp_cipher && !rtp_auth && !rtcp_auth) { + g_object_set (self->srtp_enc, "random-key", FALSE, NULL); + } + + dtls_sink_pad = gst_element_get_static_pad (bin->dtls_element, "sink"); + + if (!dtls_sink_pad) { + gst_element_set_state (GST_ELEMENT (bin->dtls_element), GST_STATE_NULL); + gst_bin_remove (GST_BIN (self), bin->dtls_element); bin->dtls_element = NULL; + return; + } + + peer_pad = gst_pad_get_peer (dtls_sink_pad); + g_return_if_fail (peer_pad); + gst_object_unref (dtls_sink_pad); + dtls_sink_pad = NULL; + + id = gst_pad_add_probe (peer_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, + (GstPadProbeCallback) remove_dtls_encoder_probe_callback, + bin->dtls_element, NULL); + g_return_if_fail (id); + bin->dtls_element = NULL; - gst_pad_push_event(peer_pad, gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, gst_structure_new_empty("dummy"))); + gst_pad_push_event (peer_pad, + gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, + gst_structure_new_empty ("dummy"))); - gst_object_unref(peer_pad); + gst_object_unref (peer_pad); } -static GstPadProbeReturn remove_dtls_encoder_probe_callback(GstPad *pad, - GstPadProbeInfo *info, GstElement *element) +static GstPadProbeReturn +remove_dtls_encoder_probe_callback (GstPad * pad, + GstPadProbeInfo * info, GstElement * element) { - gst_pad_remove_probe(pad, GST_PAD_PROBE_INFO_ID(info)); + gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info)); - gst_element_set_state(GST_ELEMENT(element), GST_STATE_NULL); - gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(element)), element); + gst_element_set_state (GST_ELEMENT (element), GST_STATE_NULL); + gst_bin_remove (GST_BIN (GST_ELEMENT_PARENT (element)), element); - return GST_PAD_PROBE_OK; + return GST_PAD_PROBE_OK; } diff --git a/ext/dtls/plugin.c b/ext/dtls/plugin.c index 0aa811d..2750177 100644 --- a/ext/dtls/plugin.c +++ b/ext/dtls/plugin.c @@ -35,13 +35,19 @@ #include -static gboolean plugin_init(GstPlugin *plugin) +static gboolean +plugin_init (GstPlugin * plugin) { - return gst_element_register(plugin, "erdtlsenc", GST_RANK_NONE, GST_TYPE_ER_DTLS_ENC) - && gst_element_register(plugin, "erdtlsdec", GST_RANK_NONE, GST_TYPE_ER_DTLS_DEC) - && gst_element_register(plugin, "erdtlssrtpdec", GST_RANK_NONE, GST_TYPE_ER_DTLS_SRTP_DEC) - && gst_element_register(plugin, "erdtlssrtpenc", GST_RANK_NONE, GST_TYPE_ER_DTLS_SRTP_ENC) - && gst_element_register(plugin, "erdtlssrtpdemux", GST_RANK_NONE, GST_TYPE_ER_DTLS_SRTP_DEMUX); + return gst_element_register (plugin, "erdtlsenc", GST_RANK_NONE, + GST_TYPE_ER_DTLS_ENC) + && gst_element_register (plugin, "erdtlsdec", GST_RANK_NONE, + GST_TYPE_ER_DTLS_DEC) + && gst_element_register (plugin, "erdtlssrtpdec", GST_RANK_NONE, + GST_TYPE_ER_DTLS_SRTP_DEC) + && gst_element_register (plugin, "erdtlssrtpenc", GST_RANK_NONE, + GST_TYPE_ER_DTLS_SRTP_ENC) + && gst_element_register (plugin, "erdtlssrtpdemux", GST_RANK_NONE, + GST_TYPE_ER_DTLS_SRTP_DEMUX); } /* PACKAGE: this is usually set by autotools depending on some _INIT macro @@ -55,14 +61,10 @@ static gboolean plugin_init(GstPlugin *plugin) /* gstreamer looks for this structure to register plugins */ -GST_PLUGIN_DEFINE( - GST_VERSION_MAJOR, +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, erdtls, "Ericsson DTLS decoder and encoder plugins", plugin_init, PACKAGE_VERSION, - "BSD", - "OpenWebRTC GStreamer plugins", - "http://www.openwebrtc.io/" -) + "BSD", "OpenWebRTC GStreamer plugins", "http://www.openwebrtc.io/") -- 2.7.4