From e6c6b5ea29228c385d6afa29e72c40bf9cde71ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 30 Jan 2020 17:29:40 +0200 Subject: [PATCH] sctpenc: Report errors when sending out data and the association is in error or disconnected state --- ext/sctp/gstsctpenc.c | 16 +++++++++------- ext/sctp/sctpassociation.c | 29 ++++++++++++++++++++++------- ext/sctp/sctpassociation.h | 5 +++-- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/ext/sctp/gstsctpenc.c b/ext/sctp/gstsctpenc.c index 1ae3bdfef7..ec0767d1ea 100644 --- a/ext/sctp/gstsctpenc.c +++ b/ext/sctp/gstsctpenc.c @@ -625,19 +625,21 @@ gst_sctp_enc_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) g_mutex_lock (&sctpenc_pad->lock); while (!sctpenc_pad->flushing) { - gint32 bytes_sent; + guint32 bytes_sent; g_mutex_unlock (&sctpenc_pad->lock); - bytes_sent = + flow_ret = gst_sctp_association_send_data (self->sctp_association, data, - length, sctpenc_pad->stream_id, ppid, ordered, pr, pr_param); + length, sctpenc_pad->stream_id, ppid, ordered, pr, pr_param, + &bytes_sent); g_mutex_lock (&sctpenc_pad->lock); - if (bytes_sent < 0) { - GST_ELEMENT_ERROR (self, RESOURCE, WRITE, (NULL), - ("Failed to send data")); - flow_ret = GST_FLOW_ERROR; + if (flow_ret != GST_FLOW_OK) { + if (flow_ret != GST_FLOW_EOS) { + GST_ELEMENT_ERROR (self, RESOURCE, WRITE, (NULL), + ("Failed to send data")); + } goto out; } else if (bytes_sent < length && !sctpenc_pad->flushing) { gint64 end_time = g_get_monotonic_time () + BUFFER_FULL_SLEEP_TIME; diff --git a/ext/sctp/sctpassociation.c b/ext/sctp/sctpassociation.c index 4331457bfa..ce685fd539 100644 --- a/ext/sctp/sctpassociation.c +++ b/ext/sctp/sctpassociation.c @@ -432,19 +432,29 @@ gst_sctp_association_incoming_packet (GstSctpAssociation * self, usrsctp_conninput ((void *) self, (const void *) buf, (size_t) length, 0); } -gint32 +GstFlowReturn gst_sctp_association_send_data (GstSctpAssociation * self, const guint8 * buf, guint32 length, guint16 stream_id, guint32 ppid, gboolean ordered, - GstSctpAssociationPartialReliability pr, guint32 reliability_param) + GstSctpAssociationPartialReliability pr, guint32 reliability_param, + guint32 * bytes_sent_) { + GstFlowReturn flow_ret; struct sctp_sendv_spa spa; - gint32 bytes_sent = -1; + gint32 bytes_sent = 0; struct sockaddr_conn remote_addr; g_rec_mutex_lock (&self->association_mutex); if (self->state != GST_SCTP_ASSOCIATION_STATE_CONNECTED) { - GST_ERROR_OBJECT (self, "Association not connected yet"); - goto end; + if (self->state == GST_SCTP_ASSOCIATION_STATE_DISCONNECTED || + self->state == GST_SCTP_ASSOCIATION_STATE_DISCONNECTING) { + GST_ERROR_OBJECT (self, "Disconnected"); + flow_ret = GST_FLOW_EOS; + goto end; + } else { + GST_ERROR_OBJECT (self, "Association not connected yet"); + flow_ret = GST_FLOW_ERROR; + goto end; + } } memset (&spa, 0, sizeof (spa)); @@ -475,19 +485,24 @@ gst_sctp_association_send_data (GstSctpAssociation * self, const guint8 * buf, if (errno == EAGAIN || errno == EWOULDBLOCK) { bytes_sent = 0; /* Resending this buffer is taken care of by the gstsctpenc */ + flow_ret = GST_FLOW_OK; goto end; } else { GST_ERROR_OBJECT (self, "Error sending data on stream %u: (%u) %s", stream_id, errno, g_strerror (errno)); + flow_ret = GST_FLOW_ERROR; goto end; } } + flow_ret = GST_FLOW_OK; end: g_rec_mutex_unlock (&self->association_mutex); - return bytes_sent; -} + if (bytes_sent_) + *bytes_sent_ = bytes_sent; + return flow_ret; +} void gst_sctp_association_reset_stream (GstSctpAssociation * self, guint16 stream_id) diff --git a/ext/sctp/sctpassociation.h b/ext/sctp/sctpassociation.h index f520994ee1..81234a6fbd 100644 --- a/ext/sctp/sctpassociation.h +++ b/ext/sctp/sctpassociation.h @@ -27,6 +27,7 @@ #define __GST_SCTP_ASSOCIATION_H__ #include +#include #define INET #define INET6 #include @@ -112,10 +113,10 @@ void gst_sctp_association_set_on_packet_received (GstSctpAssociation * self, GstSctpAssociationPacketReceivedCb packet_received_cb, gpointer user_data, GDestroyNotify destroy_notify); void gst_sctp_association_incoming_packet (GstSctpAssociation * self, const guint8 * buf, guint32 length); -gint32 gst_sctp_association_send_data (GstSctpAssociation * self, +GstFlowReturn gst_sctp_association_send_data (GstSctpAssociation * self, const guint8 * buf, guint32 length, guint16 stream_id, guint32 ppid, gboolean ordered, GstSctpAssociationPartialReliability pr, - guint32 reliability_param); + guint32 reliability_param, guint32 *bytes_sent); void gst_sctp_association_reset_stream (GstSctpAssociation * self, guint16 stream_id); void gst_sctp_association_force_close (GstSctpAssociation * self);