rtmp2: Improve handling incoming set chunk/window size
authorJan Alexander Steffens (heftig) <jsteffens@make.tv>
Fri, 14 Feb 2020 11:28:43 +0000 (12:28 +0100)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 21 Feb 2020 15:20:41 +0000 (15:20 +0000)
Reject out-of-spec sizes and warn about suspiciously small sizes.

gst/rtmp2/rtmp/rtmpchunkstream.c
gst/rtmp2/rtmp/rtmpchunkstream.h
gst/rtmp2/rtmp/rtmpclient.c
gst/rtmp2/rtmp/rtmpconnection.c
gst/rtmp2/rtmp/rtmpconnection.h

index 1ea1064..b0aa1fa 100644 (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);
 }
index bcc9b7d..6466f3b 100644 (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;
index 657482c..f95994f 100644 (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);
   }
 
index b438658..c27bdfe 100644 (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)
 {
index 5175144..f4c4b96 100644 (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)