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); return gst_rtcp_buffer_new_take_data (g_memdup (data, len), len);
} }
/** static gboolean
* gst_rtcp_buffer_validate_data: gst_rtcp_buffer_validate_data_internal (guint8 * data, guint len,
* @data: (array length=len): the data to validate guint16 valid_mask)
* @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)
{ {
guint16 header_mask; guint16 header_mask;
guint header_len; guint header_len;
@ -116,7 +105,7 @@ gst_rtcp_buffer_validate_data (guint8 * data, guint len)
goto wrong_length; goto wrong_length;
/* first packet must be RR or SR and version must be 2 */ /* 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)) if (G_UNLIKELY (header_mask != GST_RTCP_VALID_VALUE))
goto wrong_mask; goto wrong_mask;
@ -169,8 +158,7 @@ wrong_length:
} }
wrong_mask: wrong_mask:
{ {
GST_DEBUG ("mask check failed (%04x != %04x)", header_mask, GST_DEBUG ("mask check failed (%04x != %04x)", header_mask, valid_mask);
GST_RTCP_VALID_VALUE);
return FALSE; return FALSE;
} }
wrong_version: 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: * gst_rtcp_buffer_validate:
* @buffer: the buffer to validate * @buffer: the buffer to validate

View file

@ -168,6 +168,15 @@ typedef enum
* Mask for version, padding bit and packet type pair * Mask for version, padding bit and packet type pair
*/ */
#define GST_RTCP_VALID_MASK (0xc000 | 0x2000 | 0xfe) #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: * 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_data (guint8 *data, guint len);
gboolean gst_rtcp_buffer_validate (GstBuffer *buffer); 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); GstBuffer* gst_rtcp_buffer_new (guint mtu);
gboolean gst_rtcp_buffer_map (GstBuffer *buffer, GstMapFlags flags, GstRTCPBuffer *rtcp); 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 */ /* close and validate */
gst_rtcp_buffer_unmap (&rtcp); gst_rtcp_buffer_unmap (&rtcp);
fail_unless (gst_rtcp_buffer_validate (buf) == TRUE); 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); 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_rtp_seqnum_compare);
tcase_add_test (tc_chain, test_rtcp_buffer); 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_ntp64_extension);
tcase_add_test (tc_chain, test_rtp_ntp56_extension); tcase_add_test (tc_chain, test_rtp_ntp56_extension);