rtmp2: Improve handling incoming set chunk/window size

Reject out-of-spec sizes and warn about suspiciously small sizes.
This commit is contained in:
Jan Alexander Steffens (heftig) 2020-02-14 12:28:43 +01:00 committed by GStreamer Merge Bot
parent 14fd7e0884
commit 286a3829b6
5 changed files with 58 additions and 7 deletions

View file

@ -111,6 +111,7 @@ chunk_stream_next_size (GstRtmpChunkStream * cstream, guint32 chunk_size)
size = cstream->meta->size;
offset = cstream->offset;
g_return_val_if_fail (chunk_size, 0);
g_return_val_if_fail (offset <= size, 0);
return MIN (size - offset, chunk_size);
}

View file

@ -25,7 +25,6 @@
G_BEGIN_DECLS
#define GST_RTMP_DEFAULT_CHUNK_SIZE 128
#define GST_RTMP_CHUNK_STREAM_PROTOCOL 2
typedef struct _GstRtmpChunkStream GstRtmpChunkStream;

View file

@ -1011,7 +1011,8 @@ send_create_stream (GTask * task)
"FCPublish", command_object, stream_name, NULL);
} else {
/* Matches librtmp */
gst_rtmp_connection_request_window_size (connection, 2500000);
gst_rtmp_connection_request_window_size (connection,
GST_RTMP_DEFAULT_WINDOW_ACK_SIZE);
send_set_buffer_length (connection, 0, 300);
}

View file

@ -111,6 +111,10 @@ static void gst_rtmp_connection_handle_user_control (GstRtmpConnection * sc,
GstBuffer * buffer);
static void gst_rtmp_connection_handle_message (GstRtmpConnection * sc,
GstBuffer * buffer);
static void gst_rtmp_connection_handle_set_chunk_size (GstRtmpConnection * self,
guint32 in_chunk_size);
static void gst_rtmp_connection_handle_window_ack_size (GstRtmpConnection *
self, guint32 in_chunk_size);
static void gst_rtmp_connection_send_ack (GstRtmpConnection * connection);
static void
@ -658,9 +662,9 @@ gst_rtmp_connection_handle_protocol_control (GstRtmpConnection * connection,
switch (pc.type) {
case GST_RTMP_MESSAGE_TYPE_SET_CHUNK_SIZE:
GST_INFO_OBJECT (connection, "new chunk size %" G_GUINT32_FORMAT,
GST_INFO_OBJECT (connection, "incoming chunk size %" G_GUINT32_FORMAT,
pc.param);
connection->in_chunk_size = pc.param;
gst_rtmp_connection_handle_set_chunk_size (connection, pc.param);
break;
case GST_RTMP_MESSAGE_TYPE_ABORT_MESSAGE:
@ -675,9 +679,9 @@ gst_rtmp_connection_handle_protocol_control (GstRtmpConnection * connection,
break;
case GST_RTMP_MESSAGE_TYPE_WINDOW_ACK_SIZE:
GST_INFO_OBJECT (connection, "window ack size: %" G_GUINT32_FORMAT,
pc.param);
connection->in_window_ack_size = pc.param;
GST_INFO_OBJECT (connection,
"incoming window ack size: %" G_GUINT32_FORMAT, pc.param);
gst_rtmp_connection_handle_window_ack_size (connection, pc.param);
break;
case GST_RTMP_MESSAGE_TYPE_SET_PEER_BANDWIDTH:
@ -752,6 +756,45 @@ gst_rtmp_connection_handle_user_control (GstRtmpConnection * connection,
}
}
static void
gst_rtmp_connection_handle_set_chunk_size (GstRtmpConnection * self,
guint32 chunk_size)
{
if (chunk_size < GST_RTMP_MINIMUM_CHUNK_SIZE) {
GST_ERROR_OBJECT (self,
"peer requested chunk size %" G_GUINT32_FORMAT "; too small",
chunk_size);
return;
}
if (chunk_size > GST_RTMP_MAXIMUM_CHUNK_SIZE) {
GST_ERROR_OBJECT (self,
"peer requested chunk size %" G_GUINT32_FORMAT "; too large",
chunk_size);
return;
}
if (chunk_size < GST_RTMP_DEFAULT_CHUNK_SIZE) {
GST_WARNING_OBJECT (self,
"peer requested small chunk size %" G_GUINT32_FORMAT, chunk_size);
}
self->in_chunk_size = chunk_size;
}
static void
gst_rtmp_connection_handle_window_ack_size (GstRtmpConnection * self,
guint32 window_ack_size)
{
if (window_ack_size < GST_RTMP_DEFAULT_WINDOW_ACK_SIZE) {
GST_WARNING_OBJECT (self,
"peer requested small window ack size %" G_GUINT32_FORMAT,
window_ack_size);
}
self->in_window_ack_size = window_ack_size;
}
static gboolean
is_command_response (const gchar * command_name)
{

View file

@ -32,6 +32,13 @@ G_BEGIN_DECLS
#define GST_RTMP_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTMP_CONNECTION,GstRtmpConnection))
#define GST_IS_RTMP_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTMP_CONNECTION))
#define GST_RTMP_DEFAULT_CHUNK_SIZE 128
#define GST_RTMP_MINIMUM_CHUNK_SIZE 1
#define GST_RTMP_MAXIMUM_CHUNK_SIZE 0x7FFFFFFF
/* Matches librtmp */
#define GST_RTMP_DEFAULT_WINDOW_ACK_SIZE 2500000
typedef struct _GstRtmpConnection GstRtmpConnection;
typedef void (*GstRtmpConnectionFunc)