gst/udp/: Avoid leaking internally allocated file descriptors when setting custom...
authorPeter Kjellerstedt <pkj@axis.com>
Wed, 20 Aug 2008 11:51:38 +0000 (11:51 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 20 Aug 2008 11:51:38 +0000 (11:51 +0000)
Original commit message from CVS:
Patch by: Peter Kjellerstedt <pkj at axis com>
* gst/udp/gstdynudpsink.c: (gst_dynudpsink_init),
(gst_dynudpsink_finalize), (gst_dynudpsink_set_property),
(gst_dynudpsink_init_send), (gst_dynudpsink_close):
* gst/udp/gstmultiudpsink.c: (gst_multiudpsink_init),
(gst_multiudpsink_finalize), (gst_multiudpsink_set_property):
* gst/udp/gstudpsrc.c: (gst_udpsrc_finalize),
(gst_udpsrc_set_property):
Avoid leaking internally allocated file descriptors when setting
custom file descriptors. Fixes #543101.

ChangeLog
gst/udp/gstdynudpsink.c
gst/udp/gstmultiudpsink.c
gst/udp/gstudpsrc.c

index 7b1cc15..c309f77 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2008-08-20  Wim Taymans  <wim.taymans@collabora.co.uk>
 
+       Patch by: Peter Kjellerstedt <pkj at axis com>
+
+       * gst/udp/gstdynudpsink.c: (gst_dynudpsink_init),
+       (gst_dynudpsink_finalize), (gst_dynudpsink_set_property),
+       (gst_dynudpsink_init_send), (gst_dynudpsink_close):
+       * gst/udp/gstmultiudpsink.c: (gst_multiudpsink_init),
+       (gst_multiudpsink_finalize), (gst_multiudpsink_set_property):
+       * gst/udp/gstudpsrc.c: (gst_udpsrc_finalize),
+       (gst_udpsrc_set_property):
+       Avoid leaking internally allocated file descriptors when setting
+       custom file descriptors. Fixes #543101.
+
+2008-08-20  Wim Taymans  <wim.taymans@collabora.co.uk>
+
        * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_stream_configure_udp_sink):
        Don't try to configure RTCP back to the server when the server did not
        give us a valid port number.
index 02d52b2..f9b3eb8 100644 (file)
 GST_DEBUG_CATEGORY_STATIC (dynudpsink_debug);
 #define GST_CAT_DEFAULT (dynudpsink_debug)
 
-#define CLOSE_IF_REQUESTED(udpctx)                                      \
-  if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) \
-    CLOSE_SOCKET(udpctx->sock);                                         \
-  udpctx->sock = -1;
-
 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
@@ -80,6 +75,16 @@ enum
   PROP_CLOSEFD
 };
 
+#define CLOSE_IF_REQUESTED(udpctx)                                        \
+G_STMT_START {                                                            \
+  if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) { \
+    CLOSE_SOCKET(udpctx->sock);                                           \
+    if (udpctx->sock == udpctx->sockfd)                                   \
+      udpctx->sockfd = UDP_DEFAULT_SOCKFD;                                \
+  }                                                                       \
+  udpctx->sock = -1;                                                      \
+} G_STMT_END
+
 static void gst_dynudpsink_base_init (gpointer g_class);
 static void gst_dynudpsink_class_init (GstDynUDPSink * klass);
 static void gst_dynudpsink_init (GstDynUDPSink * udpsink);
@@ -179,12 +184,8 @@ gst_dynudpsink_class_init (GstDynUDPSink * klass)
 static void
 gst_dynudpsink_init (GstDynUDPSink * sink)
 {
-  GstDynUDPSink *udpsink;
-
   WSA_STARTUP (sink);
 
-  udpsink = GST_DYNUDPSINK (sink);
-
   sink->sockfd = UDP_DEFAULT_SOCKFD;
   sink->closefd = UDP_DEFAULT_CLOSEFD;
   sink->externalfd = FALSE;
@@ -195,6 +196,13 @@ gst_dynudpsink_init (GstDynUDPSink * sink)
 static void
 gst_dynudpsink_finalize (GObject * object)
 {
+  GstDynUDPSink *udpsink;
+
+  udpsink = GST_DYNUDPSINK (object);
+
+  if (udpsink->sockfd >= 0 && udpsink->closefd)
+    CLOSE_SOCKET (udpsink->sockfd);
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 
   WSA_CLEANUP (object);
@@ -265,6 +273,9 @@ gst_dynudpsink_set_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case PROP_SOCKFD:
+      if (udpsink->sockfd >= 0 && udpsink->sockfd != udpsink->sock &&
+          udpsink->closefd)
+        CLOSE_SOCKET (udpsink->sockfd);
       udpsink->sockfd = g_value_get_int (value);
       GST_DEBUG ("setting SOCKFD to %d", udpsink->sockfd);
       break;
@@ -309,7 +320,7 @@ gst_dynudpsink_init_send (GstDynUDPSink * sink)
 
   if (sink->sockfd == -1) {
     /* create sender socket if none available */
-    if ((sink->sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
+    if ((sink->sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
       goto no_socket;
 
     bc_val = 1;
@@ -348,8 +359,7 @@ gst_dynudpsink_get_stats (GstDynUDPSink * sink, const gchar * host, gint port)
 static void
 gst_dynudpsink_close (GstDynUDPSink * sink)
 {
-  if (sink->sock != -1)
-    CLOSE_IF_REQUESTED (sink);
+  CLOSE_IF_REQUESTED (sink);
 }
 
 static GstStateChangeReturn
index 1188b31..e08613e 100644 (file)
@@ -105,9 +105,14 @@ enum
 };
 
 #define CLOSE_IF_REQUESTED(udpctx)                                        \
-  if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd))   \
+G_STMT_START {                                                            \
+  if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) { \
     CLOSE_SOCKET(udpctx->sock);                                           \
-  udpctx->sock = -1;
+    if (udpctx->sock == udpctx->sockfd)                                   \
+      udpctx->sockfd = DEFAULT_SOCKFD;                                    \
+  }                                                                       \
+  udpctx->sock = DEFAULT_SOCK;                                            \
+} G_STMT_END
 
 static void gst_multiudpsink_base_init (gpointer g_class);
 static void gst_multiudpsink_class_init (GstMultiUDPSinkClass * klass);
@@ -332,7 +337,7 @@ gst_multiudpsink_init (GstMultiUDPSink * sink)
   WSA_STARTUP (sink);
 
   sink->client_lock = g_mutex_new ();
-  sink->sock = -1;
+  sink->sock = DEFAULT_SOCK;
   sink->sockfd = DEFAULT_SOCKFD;
   sink->closefd = DEFAULT_CLOSEFD;
   sink->externalfd = (sink->sockfd != -1);
@@ -352,6 +357,9 @@ gst_multiudpsink_finalize (GObject * object)
   g_list_foreach (sink->clients, (GFunc) free_client, NULL);
   g_list_free (sink->clients);
 
+  if (sink->sockfd >= 0 && sink->closefd)
+    CLOSE_SOCKET (sink->sockfd);
+
   g_mutex_free (sink->client_lock);
 
   WSA_CLEANUP (object);
@@ -517,6 +525,9 @@ gst_multiudpsink_set_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case PROP_SOCKFD:
+      if (udpsink->sockfd >= 0 && udpsink->sockfd != udpsink->sock &&
+          udpsink->closefd)
+        CLOSE_SOCKET (udpsink->sockfd);
       udpsink->sockfd = g_value_get_int (value);
       GST_DEBUG_OBJECT (udpsink, "setting SOCKFD to %d", udpsink->sockfd);
       break;
index 586f1d8..ed0dbc0 100644 (file)
@@ -141,13 +141,6 @@ typedef int socklen_t;
 GST_DEBUG_CATEGORY_STATIC (udpsrc_debug);
 #define GST_CAT_DEFAULT (udpsrc_debug)
 
-#define CLOSE_IF_REQUESTED(udpctx)                                        \
-G_STMT_START {                                                            \
-  if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd))   \
-    CLOSE_SOCKET(udpctx->sock.fd);                                        \
-  udpctx->sock.fd = -1;                                                   \
-} G_STMT_END
-
 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
@@ -191,6 +184,16 @@ enum
   PROP_LAST
 };
 
+#define CLOSE_IF_REQUESTED(udpctx)                                        \
+G_STMT_START {                                                            \
+  if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) { \
+    CLOSE_SOCKET(udpctx->sock.fd);                                        \
+    if (udpctx->sock.fd == udpctx->sockfd)                                \
+      udpctx->sockfd = UDP_DEFAULT_SOCKFD;                                \
+  }                                                                       \
+  udpctx->sock.fd = UDP_DEFAULT_SOCK;                                     \
+} G_STMT_END
+
 static void gst_udpsrc_uri_handler_init (gpointer g_iface, gpointer iface_data);
 
 static GstCaps *gst_udpsrc_getcaps (GstBaseSrc * src);
@@ -348,7 +351,10 @@ gst_udpsrc_finalize (GObject * object)
   g_free (udpsrc->multi_group);
   g_free (udpsrc->uri);
 
-  WSA_CLEANUP (src);
+  if (udpsrc->sockfd >= 0 && udpsrc->closefd)
+    CLOSE_SOCKET (udpsrc->sockfd);
+
+  WSA_CLEANUP (object);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -671,6 +677,9 @@ gst_udpsrc_set_property (GObject * object, guint prop_id, const GValue * value,
       break;
     }
     case PROP_SOCKFD:
+      if (udpsrc->sockfd >= 0 && udpsrc->sockfd != udpsrc->sock.fd &&
+          udpsrc->closefd)
+        CLOSE_SOCKET (udpsrc->sockfd);
       udpsrc->sockfd = g_value_get_int (value);
       GST_DEBUG ("setting SOCKFD to %d", udpsrc->sockfd);
       break;