rtcpbuffer: Update package validation to support reduced size rtcp packets

According to this section of the rfc.
https://tools.ietf.org/html/rfc5506#section-3.4.2
The validation should be updated to accept more types of RTCP
packages, with this mask change feedback packages will be also
accepted.

Change-Id: If5ead59e03c7c60bbe45a9b09f3ff680e7fa4868
This commit is contained in:
Jose Antonio Santos Cadenas 2015-06-03 11:20:35 +02:00 committed by Sebastian Dröge
parent 2ad27e4c13
commit 9931bef8ca
3 changed files with 119 additions and 17 deletions

View file

@ -87,20 +87,9 @@ gst_rtcp_buffer_new_copy_data (gpointer data, guint len)
return gst_rtcp_buffer_new_take_data (g_memdup (data, len), len);
}
/**
* gst_rtcp_buffer_validate_data:
* @data: (array length=len): the data to validate
* @len: the length of @data to validate
*
* Check if the @data and @size point to the data of a valid RTCP (compound)
* packet.
* Use this function to validate a packet before using the other functions in
* this module.
*
* Returns: TRUE if the data points to a valid RTCP packet.
*/
gboolean
gst_rtcp_buffer_validate_data (guint8 * data, guint len)
static gboolean
gst_rtcp_buffer_validate_data_internal (guint8 * data, guint len,
guint16 valid_mask)
{
guint16 header_mask;
guint header_len;
@ -116,7 +105,7 @@ gst_rtcp_buffer_validate_data (guint8 * data, guint len)
goto wrong_length;
/* first packet must be RR or SR and version must be 2 */
header_mask = ((data[0] << 8) | data[1]) & GST_RTCP_VALID_MASK;
header_mask = ((data[0] << 8) | data[1]) & valid_mask;
if (G_UNLIKELY (header_mask != GST_RTCP_VALID_VALUE))
goto wrong_mask;
@ -169,8 +158,7 @@ wrong_length:
}
wrong_mask:
{
GST_DEBUG ("mask check failed (%04x != %04x)", header_mask,
GST_RTCP_VALID_VALUE);
GST_DEBUG ("mask check failed (%04x != %04x)", header_mask, valid_mask);
return FALSE;
}
wrong_version:
@ -185,6 +173,72 @@ wrong_padding:
}
}
/**
* gst_rtcp_buffer_validate_data_reduced:
* @data: (array length=len): the data to validate
* @len: the length of @data to validate
*
* Check if the @data and @size point to the data of a valid RTCP
* packet.
* Use this function to validate a packet before using the other functions in
* this module.
*
* This function is updated to support reduced size rtcp packets according to
* RFC 5506
*
* Returns: TRUE if the data points to a valid RTCP packet.
*/
gboolean
gst_rtcp_buffer_validate_data_reduced (guint8 * data, guint len)
{
return gst_rtcp_buffer_validate_data_internal (data, len,
GST_RTCP_REDUCED_SIZE_VALID_MASK);
}
/**
* gst_rtcp_buffer_validate_data:
* @data: (array length=len): the data to validate
* @len: the length of @data to validate
*
* Check if the @data and @size point to the data of a valid RTCP (compound)
* packet.
* Use this function to validate a packet before using the other functions in
* this module.
*
*
* Returns: TRUE if the data points to a valid RTCP packet.
*/
gboolean
gst_rtcp_buffer_validate_data (guint8 * data, guint len)
{
return gst_rtcp_buffer_validate_data_internal (data, len,
GST_RTCP_VALID_MASK);
}
/**
* gst_rtcp_buffer_validate_reduced:
* @buffer: the buffer to validate
*
* Check if the data pointed to by @buffer is a valid RTCP packet using
* gst_rtcp_buffer_validate_reduced().
*
* Returns: TRUE if @buffer is a valid RTCP packet.
*/
gboolean
gst_rtcp_buffer_validate_reduced (GstBuffer * buffer)
{
gboolean res;
GstMapInfo map;
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
gst_buffer_map (buffer, &map, GST_MAP_READ);
res = gst_rtcp_buffer_validate_data_reduced (map.data, map.size);
gst_buffer_unmap (buffer, &map);
return res;
}
/**
* gst_rtcp_buffer_validate:
* @buffer: the buffer to validate

View file

@ -168,6 +168,15 @@ typedef enum
* Mask for version, padding bit and packet type pair
*/
#define GST_RTCP_VALID_MASK (0xc000 | 0x2000 | 0xfe)
/**
* GST_RTCP_REDUCED_SIZE_VALID_MASK:
*
* Mask for version, padding bit and packet type pair allowing reduced size
* packets, basically it accepts other types than RR and SR
*/
#define GST_RTCP_REDUCED_SIZE_VALID_MASK (0xc000 | 0x2000 | 0xf8)
/**
* GST_RTCP_VALID_VALUE:
*
@ -218,6 +227,10 @@ GstBuffer* gst_rtcp_buffer_new_copy_data (gpointer data, guint len);
gboolean gst_rtcp_buffer_validate_data (guint8 *data, guint len);
gboolean gst_rtcp_buffer_validate (GstBuffer *buffer);
gboolean gst_rtcp_buffer_validate_data_reduced (guint8 *data, guint len);
gboolean gst_rtcp_buffer_validate_reduced (GstBuffer *buffer);
GstBuffer* gst_rtcp_buffer_new (guint mtu);
gboolean gst_rtcp_buffer_map (GstBuffer *buffer, GstMapFlags flags, GstRTCPBuffer *rtcp);

View file

@ -757,6 +757,40 @@ GST_START_TEST (test_rtcp_buffer)
/* close and validate */
gst_rtcp_buffer_unmap (&rtcp);
fail_unless (gst_rtcp_buffer_validate (buf) == TRUE);
fail_unless (gst_rtcp_buffer_validate_reduced (buf) == TRUE);
gst_buffer_unref (buf);
}
GST_END_TEST;
GST_START_TEST (test_rtcp_reduced_buffer)
{
GstBuffer *buf;
GstRTCPPacket packet;
GstRTCPBuffer rtcp = { NULL, };
gsize offset;
gsize maxsize;
buf = gst_rtcp_buffer_new (1400);
fail_unless (buf != NULL);
fail_unless_equals_int (gst_buffer_get_sizes (buf, &offset, &maxsize), 0);
fail_unless_equals_int (offset, 0);
fail_unless_equals_int (maxsize, 1400);
gst_rtcp_buffer_map (buf, GST_MAP_READWRITE, &rtcp);
fail_unless (gst_rtcp_buffer_validate (buf) == FALSE);
fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &packet) == FALSE);
fail_unless (gst_rtcp_buffer_get_packet_count (&rtcp) == 0);
/* add an SR packet */
fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_PSFB,
&packet) == TRUE);
/* close and validate */
gst_rtcp_buffer_unmap (&rtcp);
fail_unless (gst_rtcp_buffer_validate (buf) == FALSE);
fail_unless (gst_rtcp_buffer_validate_reduced (buf) == TRUE);
gst_buffer_unref (buf);
}
@ -992,6 +1026,7 @@ rtp_suite (void)
tcase_add_test (tc_chain, test_rtp_seqnum_compare);
tcase_add_test (tc_chain, test_rtcp_buffer);
tcase_add_test (tc_chain, test_rtcp_reduced_buffer);
tcase_add_test (tc_chain, test_rtp_ntp64_extension);
tcase_add_test (tc_chain, test_rtp_ntp56_extension);