media: disconnect from signal handlers in unprepare()
[platform/upstream/gstreamer.git] / gst / rtsp-server / rtsp-server.c
1 /* GStreamer
2  * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include "rtsp-server.h"
24 #include "rtsp-client.h"
25
26 #define GST_RTSP_SERVER_GET_PRIVATE(obj)  \
27        (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_SERVER, GstRTSPServerPrivate))
28
29 #define GST_RTSP_SERVER_GET_LOCK(server)  (&(GST_RTSP_SERVER_CAST(server)->priv->lock))
30 #define GST_RTSP_SERVER_LOCK(server)      (g_mutex_lock(GST_RTSP_SERVER_GET_LOCK(server)))
31 #define GST_RTSP_SERVER_UNLOCK(server)    (g_mutex_unlock(GST_RTSP_SERVER_GET_LOCK(server)))
32
33 struct _GstRTSPServerPrivate
34 {
35   GMutex lock;                  /* protects everything in this struct */
36
37   /* server information */
38   gchar *address;
39   gchar *service;
40   gint backlog;
41   gint max_threads;
42
43   GSocket *socket;
44
45   /* sessions on this server */
46   GstRTSPSessionPool *session_pool;
47
48   /* mount points for this server */
49   GstRTSPMountPoints *mount_points;
50
51   /* authentication manager */
52   GstRTSPAuth *auth;
53
54   /* the clients that are connected */
55   GList *clients;
56   GQueue loops;                 /* the main loops used in the threads */
57 };
58
59 #define DEFAULT_ADDRESS         "0.0.0.0"
60 #define DEFAULT_BOUND_PORT      -1
61 /* #define DEFAULT_ADDRESS         "::0" */
62 #define DEFAULT_SERVICE         "8554"
63 #define DEFAULT_BACKLOG         5
64 #define DEFAULT_MAX_THREADS     0
65
66 /* Define to use the SO_LINGER option so that the server sockets can be resused
67  * sooner. Disabled for now because it is not very well implemented by various
68  * OSes and it causes clients to fail to read the TEARDOWN response. */
69 #undef USE_SOLINGER
70
71 enum
72 {
73   PROP_0,
74   PROP_ADDRESS,
75   PROP_SERVICE,
76   PROP_BOUND_PORT,
77   PROP_BACKLOG,
78
79   PROP_SESSION_POOL,
80   PROP_MOUNT_POINTS,
81   PROP_MAX_THREADS,
82   PROP_LAST
83 };
84
85 enum
86 {
87   SIGNAL_CLIENT_CONNECTED,
88   SIGNAL_LAST
89 };
90
91 G_DEFINE_TYPE (GstRTSPServer, gst_rtsp_server, G_TYPE_OBJECT);
92
93 GST_DEBUG_CATEGORY_STATIC (rtsp_server_debug);
94 #define GST_CAT_DEFAULT rtsp_server_debug
95
96 typedef struct _ClientContext ClientContext;
97 typedef struct _Loop Loop;
98
99 static guint gst_rtsp_server_signals[SIGNAL_LAST] = { 0 };
100
101 static void gst_rtsp_server_get_property (GObject * object, guint propid,
102     GValue * value, GParamSpec * pspec);
103 static void gst_rtsp_server_set_property (GObject * object, guint propid,
104     const GValue * value, GParamSpec * pspec);
105 static void gst_rtsp_server_finalize (GObject * object);
106
107 static gpointer do_loop (Loop * loop);
108 static GstRTSPClient *default_create_client (GstRTSPServer * server);
109 static gboolean default_accept_client (GstRTSPServer * server,
110     GstRTSPClient * client, GSocket * socket, GError ** error);
111
112 static void
113 gst_rtsp_server_class_init (GstRTSPServerClass * klass)
114 {
115   GObjectClass *gobject_class;
116
117   g_type_class_add_private (klass, sizeof (GstRTSPServerPrivate));
118
119   gobject_class = G_OBJECT_CLASS (klass);
120
121   gobject_class->get_property = gst_rtsp_server_get_property;
122   gobject_class->set_property = gst_rtsp_server_set_property;
123   gobject_class->finalize = gst_rtsp_server_finalize;
124
125   /**
126    * GstRTSPServer::address:
127    *
128    * The address of the server. This is the address where the server will
129    * listen on.
130    */
131   g_object_class_install_property (gobject_class, PROP_ADDRESS,
132       g_param_spec_string ("address", "Address",
133           "The address the server uses to listen on", DEFAULT_ADDRESS,
134           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
135   /**
136    * GstRTSPServer::service:
137    *
138    * The service of the server. This is either a string with the service name or
139    * a port number (as a string) the server will listen on.
140    */
141   g_object_class_install_property (gobject_class, PROP_SERVICE,
142       g_param_spec_string ("service", "Service",
143           "The service or port number the server uses to listen on",
144           DEFAULT_SERVICE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
145   /**
146    * GstRTSPServer::bound-port:
147    *
148    * The actual port the server is listening on. Can be used to retrieve the
149    * port number when the server is started on port 0, which means bind to a
150    * random port. Set to -1 if the server has not been bound yet.
151    */
152   g_object_class_install_property (gobject_class, PROP_BOUND_PORT,
153       g_param_spec_int ("bound-port", "Bound port",
154           "The port number the server is listening on",
155           -1, G_MAXUINT16, DEFAULT_BOUND_PORT,
156           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
157   /**
158    * GstRTSPServer::backlog:
159    *
160    * The backlog argument defines the maximum length to which the queue of
161    * pending connections for the server may grow. If a connection request arrives
162    * when the queue is full, the client may receive an error with an indication of
163    * ECONNREFUSED or, if the underlying protocol supports retransmission, the
164    * request may be ignored so that a later reattempt at  connection succeeds.
165    */
166   g_object_class_install_property (gobject_class, PROP_BACKLOG,
167       g_param_spec_int ("backlog", "Backlog",
168           "The maximum length to which the queue "
169           "of pending connections may grow", 0, G_MAXINT, DEFAULT_BACKLOG,
170           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
171   /**
172    * GstRTSPServer::session-pool:
173    *
174    * The session pool of the server. By default each server has a separate
175    * session pool but sessions can be shared between servers by setting the same
176    * session pool on multiple servers.
177    */
178   g_object_class_install_property (gobject_class, PROP_SESSION_POOL,
179       g_param_spec_object ("session-pool", "Session Pool",
180           "The session pool to use for client session",
181           GST_TYPE_RTSP_SESSION_POOL,
182           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
183   /**
184    * GstRTSPServer::mount-points:
185    *
186    * The mount points to use for this server. By default the server has no
187    * mount points and thus cannot map urls to media streams.
188    */
189   g_object_class_install_property (gobject_class, PROP_MOUNT_POINTS,
190       g_param_spec_object ("mount-points", "Mount Points",
191           "The mount points to use for client session",
192           GST_TYPE_RTSP_MOUNT_POINTS,
193           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
194   /**
195    * GstRTSPServer::max-threads:
196    *
197    * The maximum amount of threads to use for client connections. A value of
198    * 0 means to use only the mainloop, -1 means an unlimited amount of
199    * threads.
200    */
201   g_object_class_install_property (gobject_class, PROP_MAX_THREADS,
202       g_param_spec_int ("max-threads", "Max Threads",
203           "The maximum amount of threads to use for client connections "
204           "(0 = only mainloop, -1 = unlimited)", -1, G_MAXINT,
205           DEFAULT_MAX_THREADS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
206
207   gst_rtsp_server_signals[SIGNAL_CLIENT_CONNECTED] =
208       g_signal_new ("client-connected", G_TYPE_FROM_CLASS (gobject_class),
209       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPServerClass, client_connected),
210       NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
211       gst_rtsp_client_get_type ());
212
213   klass->create_client = default_create_client;
214   klass->accept_client = default_accept_client;
215
216   klass->pool = g_thread_pool_new ((GFunc) do_loop, klass, -1, FALSE, NULL);
217
218   GST_DEBUG_CATEGORY_INIT (rtsp_server_debug, "rtspserver", 0, "GstRTSPServer");
219 }
220
221 static void
222 gst_rtsp_server_init (GstRTSPServer * server)
223 {
224   GstRTSPServerPrivate *priv = GST_RTSP_SERVER_GET_PRIVATE (server);
225
226   server->priv = priv;
227
228   g_mutex_init (&priv->lock);
229   priv->address = g_strdup (DEFAULT_ADDRESS);
230   priv->service = g_strdup (DEFAULT_SERVICE);
231   priv->socket = NULL;
232   priv->backlog = DEFAULT_BACKLOG;
233   priv->session_pool = gst_rtsp_session_pool_new ();
234   priv->mount_points = gst_rtsp_mount_points_new ();
235   priv->max_threads = DEFAULT_MAX_THREADS;
236   g_queue_init (&priv->loops);
237 }
238
239 static void
240 gst_rtsp_server_finalize (GObject * object)
241 {
242   GstRTSPServer *server = GST_RTSP_SERVER (object);
243   GstRTSPServerPrivate *priv = server->priv;
244
245   GST_DEBUG_OBJECT (server, "finalize server");
246
247   g_free (priv->address);
248   g_free (priv->service);
249
250   if (priv->socket)
251     g_object_unref (priv->socket);
252
253   g_object_unref (priv->session_pool);
254   g_object_unref (priv->mount_points);
255
256   if (priv->auth)
257     g_object_unref (priv->auth);
258
259   g_mutex_clear (&priv->lock);
260
261   G_OBJECT_CLASS (gst_rtsp_server_parent_class)->finalize (object);
262 }
263
264 /**
265  * gst_rtsp_server_new:
266  *
267  * Create a new #GstRTSPServer instance.
268  */
269 GstRTSPServer *
270 gst_rtsp_server_new (void)
271 {
272   GstRTSPServer *result;
273
274   result = g_object_new (GST_TYPE_RTSP_SERVER, NULL);
275
276   return result;
277 }
278
279 /**
280  * gst_rtsp_server_set_address:
281  * @server: a #GstRTSPServer
282  * @address: the address
283  *
284  * Configure @server to accept connections on the given address.
285  *
286  * This function must be called before the server is bound.
287  */
288 void
289 gst_rtsp_server_set_address (GstRTSPServer * server, const gchar * address)
290 {
291   GstRTSPServerPrivate *priv;
292
293   g_return_if_fail (GST_IS_RTSP_SERVER (server));
294   g_return_if_fail (address != NULL);
295
296   priv = server->priv;
297
298   GST_RTSP_SERVER_LOCK (server);
299   g_free (priv->address);
300   priv->address = g_strdup (address);
301   GST_RTSP_SERVER_UNLOCK (server);
302 }
303
304 /**
305  * gst_rtsp_server_get_address:
306  * @server: a #GstRTSPServer
307  *
308  * Get the address on which the server will accept connections.
309  *
310  * Returns: the server address. g_free() after usage.
311  */
312 gchar *
313 gst_rtsp_server_get_address (GstRTSPServer * server)
314 {
315   GstRTSPServerPrivate *priv;
316   gchar *result;
317
318   g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
319
320   priv = server->priv;
321
322   GST_RTSP_SERVER_LOCK (server);
323   result = g_strdup (priv->address);
324   GST_RTSP_SERVER_UNLOCK (server);
325
326   return result;
327 }
328
329 /**
330  * gst_rtsp_server_get_bound_port:
331  * @server: a #GstRTSPServer
332  *
333  * Get the port number where the server was bound to.
334  *
335  * Returns: the port number
336  */
337 int
338 gst_rtsp_server_get_bound_port (GstRTSPServer * server)
339 {
340   GstRTSPServerPrivate *priv;
341   GSocketAddress *address;
342   int result = -1;
343
344   g_return_val_if_fail (GST_IS_RTSP_SERVER (server), result);
345
346   priv = server->priv;
347
348   GST_RTSP_SERVER_LOCK (server);
349   if (priv->socket == NULL)
350     goto out;
351
352   address = g_socket_get_local_address (priv->socket, NULL);
353   result = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
354   g_object_unref (address);
355
356 out:
357   GST_RTSP_SERVER_UNLOCK (server);
358
359   return result;
360 }
361
362 /**
363  * gst_rtsp_server_set_service:
364  * @server: a #GstRTSPServer
365  * @service: the service
366  *
367  * Configure @server to accept connections on the given service.
368  * @service should be a string containing the service name (see services(5)) or
369  * a string containing a port number between 1 and 65535.
370  *
371  * This function must be called before the server is bound.
372  */
373 void
374 gst_rtsp_server_set_service (GstRTSPServer * server, const gchar * service)
375 {
376   GstRTSPServerPrivate *priv;
377
378   g_return_if_fail (GST_IS_RTSP_SERVER (server));
379   g_return_if_fail (service != NULL);
380
381   priv = server->priv;
382
383   GST_RTSP_SERVER_LOCK (server);
384   g_free (priv->service);
385   priv->service = g_strdup (service);
386   GST_RTSP_SERVER_UNLOCK (server);
387 }
388
389 /**
390  * gst_rtsp_server_get_service:
391  * @server: a #GstRTSPServer
392  *
393  * Get the service on which the server will accept connections.
394  *
395  * Returns: the service. use g_free() after usage.
396  */
397 gchar *
398 gst_rtsp_server_get_service (GstRTSPServer * server)
399 {
400   GstRTSPServerPrivate *priv;
401   gchar *result;
402
403   g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
404
405   priv = server->priv;
406
407   GST_RTSP_SERVER_LOCK (server);
408   result = g_strdup (priv->service);
409   GST_RTSP_SERVER_UNLOCK (server);
410
411   return result;
412 }
413
414 /**
415  * gst_rtsp_server_set_backlog:
416  * @server: a #GstRTSPServer
417  * @backlog: the backlog
418  *
419  * configure the maximum amount of requests that may be queued for the
420  * server.
421  *
422  * This function must be called before the server is bound.
423  */
424 void
425 gst_rtsp_server_set_backlog (GstRTSPServer * server, gint backlog)
426 {
427   GstRTSPServerPrivate *priv;
428
429   g_return_if_fail (GST_IS_RTSP_SERVER (server));
430
431   priv = server->priv;
432
433   GST_RTSP_SERVER_LOCK (server);
434   priv->backlog = backlog;
435   GST_RTSP_SERVER_UNLOCK (server);
436 }
437
438 /**
439  * gst_rtsp_server_get_backlog:
440  * @server: a #GstRTSPServer
441  *
442  * The maximum amount of queued requests for the server.
443  *
444  * Returns: the server backlog.
445  */
446 gint
447 gst_rtsp_server_get_backlog (GstRTSPServer * server)
448 {
449   GstRTSPServerPrivate *priv;
450   gint result;
451
452   g_return_val_if_fail (GST_IS_RTSP_SERVER (server), -1);
453
454   priv = server->priv;
455
456   GST_RTSP_SERVER_LOCK (server);
457   result = priv->backlog;
458   GST_RTSP_SERVER_UNLOCK (server);
459
460   return result;
461 }
462
463 /**
464  * gst_rtsp_server_set_session_pool:
465  * @server: a #GstRTSPServer
466  * @pool: a #GstRTSPSessionPool
467  *
468  * configure @pool to be used as the session pool of @server.
469  */
470 void
471 gst_rtsp_server_set_session_pool (GstRTSPServer * server,
472     GstRTSPSessionPool * pool)
473 {
474   GstRTSPServerPrivate *priv;
475   GstRTSPSessionPool *old;
476
477   g_return_if_fail (GST_IS_RTSP_SERVER (server));
478
479   priv = server->priv;
480
481   if (pool)
482     g_object_ref (pool);
483
484   GST_RTSP_SERVER_LOCK (server);
485   old = priv->session_pool;
486   priv->session_pool = pool;
487   GST_RTSP_SERVER_UNLOCK (server);
488
489   if (old)
490     g_object_unref (old);
491 }
492
493 /**
494  * gst_rtsp_server_get_session_pool:
495  * @server: a #GstRTSPServer
496  *
497  * Get the #GstRTSPSessionPool used as the session pool of @server.
498  *
499  * Returns: (transfer full): the #GstRTSPSessionPool used for sessions. g_object_unref() after
500  * usage.
501  */
502 GstRTSPSessionPool *
503 gst_rtsp_server_get_session_pool (GstRTSPServer * server)
504 {
505   GstRTSPServerPrivate *priv;
506   GstRTSPSessionPool *result;
507
508   g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
509
510   priv = server->priv;
511
512   GST_RTSP_SERVER_LOCK (server);
513   if ((result = priv->session_pool))
514     g_object_ref (result);
515   GST_RTSP_SERVER_UNLOCK (server);
516
517   return result;
518 }
519
520 /**
521  * gst_rtsp_server_set_mount_points:
522  * @server: a #GstRTSPServer
523  * @mounts: a #GstRTSPMountPoints
524  *
525  * configure @mounts to be used as the mount points of @server.
526  */
527 void
528 gst_rtsp_server_set_mount_points (GstRTSPServer * server,
529     GstRTSPMountPoints * mounts)
530 {
531   GstRTSPServerPrivate *priv;
532   GstRTSPMountPoints *old;
533
534   g_return_if_fail (GST_IS_RTSP_SERVER (server));
535
536   priv = server->priv;
537
538   if (mounts)
539     g_object_ref (mounts);
540
541   GST_RTSP_SERVER_LOCK (server);
542   old = priv->mount_points;
543   priv->mount_points = mounts;
544   GST_RTSP_SERVER_UNLOCK (server);
545
546   if (old)
547     g_object_unref (old);
548 }
549
550
551 /**
552  * gst_rtsp_server_get_mount_points:
553  * @server: a #GstRTSPServer
554  *
555  * Get the #GstRTSPMountPoints used as the mount points of @server.
556  *
557  * Returns: (transfer full): the #GstRTSPMountPoints of @server. g_object_unref() after
558  * usage.
559  */
560 GstRTSPMountPoints *
561 gst_rtsp_server_get_mount_points (GstRTSPServer * server)
562 {
563   GstRTSPServerPrivate *priv;
564   GstRTSPMountPoints *result;
565
566   g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
567
568   priv = server->priv;
569
570   GST_RTSP_SERVER_LOCK (server);
571   if ((result = priv->mount_points))
572     g_object_ref (result);
573   GST_RTSP_SERVER_UNLOCK (server);
574
575   return result;
576 }
577
578 /**
579  * gst_rtsp_server_set_auth:
580  * @server: a #GstRTSPServer
581  * @auth: a #GstRTSPAuth
582  *
583  * configure @auth to be used as the authentication manager of @server.
584  */
585 void
586 gst_rtsp_server_set_auth (GstRTSPServer * server, GstRTSPAuth * auth)
587 {
588   GstRTSPServerPrivate *priv;
589   GstRTSPAuth *old;
590
591   g_return_if_fail (GST_IS_RTSP_SERVER (server));
592
593   priv = server->priv;
594
595   if (auth)
596     g_object_ref (auth);
597
598   GST_RTSP_SERVER_LOCK (server);
599   old = priv->auth;
600   priv->auth = auth;
601   GST_RTSP_SERVER_UNLOCK (server);
602
603   if (old)
604     g_object_unref (old);
605 }
606
607
608 /**
609  * gst_rtsp_server_get_auth:
610  * @server: a #GstRTSPServer
611  *
612  * Get the #GstRTSPAuth used as the authentication manager of @server.
613  *
614  * Returns: (transfer full): the #GstRTSPAuth of @server. g_object_unref() after
615  * usage.
616  */
617 GstRTSPAuth *
618 gst_rtsp_server_get_auth (GstRTSPServer * server)
619 {
620   GstRTSPServerPrivate *priv;
621   GstRTSPAuth *result;
622
623   g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
624
625   priv = server->priv;
626
627   GST_RTSP_SERVER_LOCK (server);
628   if ((result = priv->auth))
629     g_object_ref (result);
630   GST_RTSP_SERVER_UNLOCK (server);
631
632   return result;
633 }
634
635 /**
636  * gst_rtsp_server_set_max_threads:
637  * @server: a #GstRTSPServer
638  * @max_threads: maximum threads
639  *
640  * Set the maximum threads used by the server to handle client requests.
641  * A value of 0 will use the server mainloop, a value of -1 will use an
642  * unlimited number of threads.
643  */
644 void
645 gst_rtsp_server_set_max_threads (GstRTSPServer * server, gint max_threads)
646 {
647   GstRTSPServerPrivate *priv;
648
649   g_return_if_fail (GST_IS_RTSP_SERVER (server));
650
651   priv = server->priv;
652
653   GST_RTSP_SERVER_LOCK (server);
654   priv->max_threads = max_threads;
655   GST_RTSP_SERVER_UNLOCK (server);
656 }
657
658 /**
659  * gst_rtsp_server_get_max_threads:
660  * @server: a #GstRTSPServer
661  *
662  * Get the maximum number of threads used for client connections.
663  * See gst_rtsp_server_set_max_threads().
664  *
665  * Returns: the maximum number of threads.
666  */
667 gint
668 gst_rtsp_server_get_max_threads (GstRTSPServer * server)
669 {
670   GstRTSPServerPrivate *priv;
671   gint res;
672
673   g_return_val_if_fail (GST_IS_RTSP_SERVER (server), -1);
674
675   priv = server->priv;
676
677   GST_RTSP_SERVER_LOCK (server);
678   res = priv->max_threads;
679   GST_RTSP_SERVER_UNLOCK (server);
680
681   return res;
682 }
683
684
685 static void
686 gst_rtsp_server_get_property (GObject * object, guint propid,
687     GValue * value, GParamSpec * pspec)
688 {
689   GstRTSPServer *server = GST_RTSP_SERVER (object);
690
691   switch (propid) {
692     case PROP_ADDRESS:
693       g_value_take_string (value, gst_rtsp_server_get_address (server));
694       break;
695     case PROP_SERVICE:
696       g_value_take_string (value, gst_rtsp_server_get_service (server));
697       break;
698     case PROP_BOUND_PORT:
699       g_value_set_int (value, gst_rtsp_server_get_bound_port (server));
700       break;
701     case PROP_BACKLOG:
702       g_value_set_int (value, gst_rtsp_server_get_backlog (server));
703       break;
704     case PROP_SESSION_POOL:
705       g_value_take_object (value, gst_rtsp_server_get_session_pool (server));
706       break;
707     case PROP_MOUNT_POINTS:
708       g_value_take_object (value, gst_rtsp_server_get_mount_points (server));
709       break;
710     case PROP_MAX_THREADS:
711       g_value_set_int (value, gst_rtsp_server_get_max_threads (server));
712       break;
713     default:
714       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
715   }
716 }
717
718 static void
719 gst_rtsp_server_set_property (GObject * object, guint propid,
720     const GValue * value, GParamSpec * pspec)
721 {
722   GstRTSPServer *server = GST_RTSP_SERVER (object);
723
724   switch (propid) {
725     case PROP_ADDRESS:
726       gst_rtsp_server_set_address (server, g_value_get_string (value));
727       break;
728     case PROP_SERVICE:
729       gst_rtsp_server_set_service (server, g_value_get_string (value));
730       break;
731     case PROP_BACKLOG:
732       gst_rtsp_server_set_backlog (server, g_value_get_int (value));
733       break;
734     case PROP_SESSION_POOL:
735       gst_rtsp_server_set_session_pool (server, g_value_get_object (value));
736       break;
737     case PROP_MOUNT_POINTS:
738       gst_rtsp_server_set_mount_points (server, g_value_get_object (value));
739       break;
740     case PROP_MAX_THREADS:
741       gst_rtsp_server_set_max_threads (server, g_value_get_int (value));
742       break;
743     default:
744       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
745   }
746 }
747
748 /**
749  * gst_rtsp_server_create_socket:
750  * @server: a #GstRTSPServer
751  * @cancellable: a #GCancellable
752  * @error: a #GError
753  *
754  * Create a #GSocket for @server. The socket will listen on the
755  * configured service.
756  *
757  * Returns: (transfer full): the #GSocket for @server or NULL when an error occured.
758  */
759 GSocket *
760 gst_rtsp_server_create_socket (GstRTSPServer * server,
761     GCancellable * cancellable, GError ** error)
762 {
763   GstRTSPServerPrivate *priv;
764   GSocketConnectable *conn;
765   GSocketAddressEnumerator *enumerator;
766   GSocket *socket = NULL;
767 #ifdef USE_SOLINGER
768   struct linger linger;
769 #endif
770   GError *sock_error = NULL;
771   GError *bind_error = NULL;
772   guint16 port;
773
774   g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
775
776   priv = server->priv;
777
778   GST_RTSP_SERVER_LOCK (server);
779   GST_DEBUG_OBJECT (server, "getting address info of %s/%s", priv->address,
780       priv->service);
781
782   /* resolve the server IP address */
783   port = atoi (priv->service);
784   if (port != 0 || !strcmp (priv->service, "0"))
785     conn = g_network_address_new (priv->address, port);
786   else
787     conn = g_network_service_new (priv->service, "tcp", priv->address);
788
789   enumerator = g_socket_connectable_enumerate (conn);
790   g_object_unref (conn);
791
792   /* create server socket, we loop through all the addresses until we manage to
793    * create a socket and bind. */
794   while (TRUE) {
795     GSocketAddress *sockaddr;
796
797     sockaddr =
798         g_socket_address_enumerator_next (enumerator, cancellable, error);
799     if (!sockaddr) {
800       if (!*error)
801         GST_DEBUG_OBJECT (server, "no more addresses %s",
802             *error ? (*error)->message : "");
803       else
804         GST_DEBUG_OBJECT (server, "failed to retrieve next address %s",
805             (*error)->message);
806       break;
807     }
808
809     /* only keep the first error */
810     socket = g_socket_new (g_socket_address_get_family (sockaddr),
811         G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP,
812         sock_error ? NULL : &sock_error);
813
814     if (socket == NULL) {
815       GST_DEBUG_OBJECT (server, "failed to make socket (%s), try next",
816           sock_error->message);
817       g_object_unref (sockaddr);
818       continue;
819     }
820
821     if (g_socket_bind (socket, sockaddr, TRUE, bind_error ? NULL : &bind_error)) {
822       g_object_unref (sockaddr);
823       break;
824     }
825
826     GST_DEBUG_OBJECT (server, "failed to bind socket (%s), try next",
827         bind_error->message);
828     g_object_unref (sockaddr);
829     g_object_unref (socket);
830     socket = NULL;
831   }
832   g_object_unref (enumerator);
833
834   if (socket == NULL)
835     goto no_socket;
836
837   g_clear_error (&sock_error);
838   g_clear_error (&bind_error);
839
840   GST_DEBUG_OBJECT (server, "opened sending server socket");
841
842   /* keep connection alive; avoids SIGPIPE during write */
843   g_socket_set_keepalive (socket, TRUE);
844
845 #if 0
846 #ifdef USE_SOLINGER
847   /* make sure socket is reset 5 seconds after close. This ensure that we can
848    * reuse the socket quickly while still having a chance to send data to the
849    * client. */
850   linger.l_onoff = 1;
851   linger.l_linger = 5;
852   if (setsockopt (sockfd, SOL_SOCKET, SO_LINGER,
853           (void *) &linger, sizeof (linger)) < 0)
854     goto linger_failed;
855 #endif
856 #endif
857
858   /* set the server socket to nonblocking */
859   g_socket_set_blocking (socket, FALSE);
860
861   /* set listen backlog */
862   g_socket_set_listen_backlog (socket, priv->backlog);
863
864   if (!g_socket_listen (socket, error))
865     goto listen_failed;
866
867   GST_DEBUG_OBJECT (server, "listening on server socket %p with queue of %d",
868       socket, priv->backlog);
869
870   GST_RTSP_SERVER_UNLOCK (server);
871
872   return socket;
873
874   /* ERRORS */
875 no_socket:
876   {
877     GST_ERROR_OBJECT (server, "failed to create socket");
878     goto close_error;
879   }
880 #if 0
881 #ifdef USE_SOLINGER
882 linger_failed:
883   {
884     GST_ERROR_OBJECT (server, "failed to no linger socket: %s",
885         g_strerror (errno));
886     goto close_error;
887   }
888 #endif
889 #endif
890 listen_failed:
891   {
892     GST_ERROR_OBJECT (server, "failed to listen on socket: %s",
893         (*error)->message);
894     goto close_error;
895   }
896 close_error:
897   {
898     if (socket)
899       g_object_unref (socket);
900
901     if (sock_error) {
902       if (error == NULL)
903         g_propagate_error (error, sock_error);
904       else
905         g_error_free (sock_error);
906     }
907     if (bind_error) {
908       if ((error == NULL) || (*error == NULL))
909         g_propagate_error (error, bind_error);
910       else
911         g_error_free (bind_error);
912     }
913     GST_RTSP_SERVER_UNLOCK (server);
914     return NULL;
915   }
916 }
917
918 struct _Loop
919 {
920   gint refcnt;
921
922   GstRTSPServer *server;
923   GMainLoop *mainloop;
924   GMainContext *mainctx;
925 };
926
927 /* must be called with the lock held */
928 static void
929 loop_unref (Loop * loop)
930 {
931   GstRTSPServer *server = loop->server;
932   GstRTSPServerPrivate *priv = server->priv;
933
934   loop->refcnt--;
935
936   if (loop->refcnt <= 0) {
937     g_queue_remove (&priv->loops, loop);
938     g_main_loop_quit (loop->mainloop);
939   }
940 }
941
942 struct _ClientContext
943 {
944   GstRTSPServer *server;
945   Loop *loop;
946   GstRTSPClient *client;
947 };
948
949 static gboolean
950 free_client_context (ClientContext * ctx)
951 {
952   GST_RTSP_SERVER_LOCK (ctx->server);
953   if (ctx->loop)
954     loop_unref (ctx->loop);
955   GST_RTSP_SERVER_UNLOCK (ctx->server);
956
957   g_object_unref (ctx->client);
958   g_slice_free (ClientContext, ctx);
959
960   return G_SOURCE_REMOVE;
961 }
962
963 static gpointer
964 do_loop (Loop * loop)
965 {
966   GST_INFO ("enter mainloop");
967   g_main_loop_run (loop->mainloop);
968   GST_INFO ("exit mainloop");
969
970   g_main_context_unref (loop->mainctx);
971   g_main_loop_unref (loop->mainloop);
972   g_object_unref (loop->server);
973   g_slice_free (Loop, loop);
974
975   return NULL;
976 }
977
978 /* Must be called with lock held */
979
980 static Loop *
981 gst_rtsp_server_get_main_loop (GstRTSPServer * server)
982 {
983   GstRTSPServerPrivate *priv = server->priv;
984   Loop *loop;
985
986   if (priv->max_threads > 0 &&
987       g_queue_get_length (&priv->loops) >= priv->max_threads) {
988     loop = g_queue_pop_head (&priv->loops);
989     loop->refcnt++;
990   } else {
991     GstRTSPServerClass *klass = GST_RTSP_SERVER_GET_CLASS (server);
992
993     loop = g_slice_new0 (Loop);
994     loop->refcnt = 1;
995     loop->server = g_object_ref (server);
996     loop->mainctx = g_main_context_new ();
997     loop->mainloop = g_main_loop_new (loop->mainctx, FALSE);
998
999     g_thread_pool_push (klass->pool, loop, NULL);
1000   }
1001
1002   g_queue_push_tail (&priv->loops, loop);
1003
1004   return loop;
1005 }
1006
1007 static void
1008 unmanage_client (GstRTSPClient * client, ClientContext * ctx)
1009 {
1010   GstRTSPServer *server = ctx->server;
1011   GstRTSPServerPrivate *priv = server->priv;
1012
1013   GST_DEBUG_OBJECT (server, "unmanage client %p", client);
1014
1015   g_object_ref (server);
1016
1017   GST_RTSP_SERVER_LOCK (server);
1018   priv->clients = g_list_remove (priv->clients, ctx);
1019   GST_RTSP_SERVER_UNLOCK (server);
1020
1021   if (ctx->loop) {
1022     GSource *src;
1023
1024     src = g_idle_source_new ();
1025     g_source_set_callback (src, (GSourceFunc) free_client_context, ctx, NULL);
1026     g_source_attach (src, ctx->loop->mainctx);
1027     g_source_unref (src);
1028   } else {
1029     free_client_context (ctx);
1030   }
1031
1032   g_object_unref (server);
1033 }
1034
1035 /* add the client context to the active list of clients, takes ownership
1036  * of client */
1037 static void
1038 manage_client (GstRTSPServer * server, GstRTSPClient * client)
1039 {
1040   ClientContext *ctx;
1041   GstRTSPServerPrivate *priv = server->priv;
1042   GMainContext *mainctx;
1043
1044   GST_DEBUG_OBJECT (server, "manage client %p", client);
1045
1046   ctx = g_slice_new0 (ClientContext);
1047   ctx->server = server;
1048   ctx->client = client;
1049
1050   GST_RTSP_SERVER_LOCK (server);
1051   if (priv->max_threads == 0) {
1052     GSource *source;
1053
1054     /* find the context to add the watch */
1055     if ((source = g_main_current_source ()))
1056       mainctx = g_source_get_context (source);
1057     else
1058       mainctx = NULL;
1059   } else {
1060     ctx->loop = gst_rtsp_server_get_main_loop (server);
1061     mainctx = ctx->loop->mainctx;
1062   }
1063
1064   g_signal_connect (client, "closed", (GCallback) unmanage_client, ctx);
1065   priv->clients = g_list_prepend (priv->clients, ctx);
1066
1067   gst_rtsp_client_attach (client, mainctx);
1068
1069   GST_RTSP_SERVER_UNLOCK (server);
1070 }
1071
1072 static GstRTSPClient *
1073 default_create_client (GstRTSPServer * server)
1074 {
1075   GstRTSPClient *client;
1076   GstRTSPServerPrivate *priv = server->priv;
1077
1078   /* a new client connected, create a session to handle the client. */
1079   client = gst_rtsp_client_new ();
1080
1081   /* set the session pool that this client should use */
1082   GST_RTSP_SERVER_LOCK (server);
1083   gst_rtsp_client_set_session_pool (client, priv->session_pool);
1084   /* set the mount points that this client should use */
1085   gst_rtsp_client_set_mount_points (client, priv->mount_points);
1086   /* set authentication manager */
1087   gst_rtsp_client_set_auth (client, priv->auth);
1088   GST_RTSP_SERVER_UNLOCK (server);
1089
1090   return client;
1091 }
1092
1093 /* default method for creating a new client object in the server to accept and
1094  * handle a client connection on this server */
1095 static gboolean
1096 default_accept_client (GstRTSPServer * server, GstRTSPClient * client,
1097     GSocket * socket, GError ** error)
1098 {
1099   /* accept connections for that client, this function returns after accepting
1100    * the connection and will run the remainder of the communication with the
1101    * client asyncronously. */
1102   if (!gst_rtsp_client_accept (client, socket, NULL, error))
1103     goto accept_failed;
1104
1105   return TRUE;
1106
1107   /* ERRORS */
1108 accept_failed:
1109   {
1110     GST_ERROR_OBJECT (server,
1111         "Could not accept client on server : %s", (*error)->message);
1112     return FALSE;
1113   }
1114 }
1115
1116 /**
1117  * gst_rtsp_server_transfer_connection:
1118  * @server: a #GstRTSPServer
1119  * @socket: a network socket
1120  * @ip: the IP address of the remote client
1121  * @port: the port used by the other end
1122  * @initial_buffer: any initial data that was already read from the socket
1123  *
1124  * Take an existing network socket and use it for an RTSP connection. This
1125  * is used when transferring a socket from an HTTP server which should be used
1126  * as an RTSP over HTTP tunnel. The @initial_buffer contains any remaining data
1127  * that the HTTP server read from the socket while parsing the HTTP header.
1128  *
1129  * Returns: TRUE if all was ok, FALSE if an error occured.
1130  */
1131 gboolean
1132 gst_rtsp_server_transfer_connection (GstRTSPServer * server, GSocket * socket,
1133     const gchar * ip, gint port, const gchar * initial_buffer)
1134 {
1135   GstRTSPClient *client = NULL;
1136   GstRTSPServerClass *klass;
1137   GError *error = NULL;
1138
1139   klass = GST_RTSP_SERVER_GET_CLASS (server);
1140
1141   if (klass->create_client)
1142     client = klass->create_client (server);
1143   if (client == NULL)
1144     goto client_failed;
1145
1146   /* a new client connected, create a client object to handle the client. */
1147   if (!gst_rtsp_client_use_socket (client, socket, ip,
1148           port, initial_buffer, &error)) {
1149     goto transfer_failed;
1150   }
1151
1152   /* manage the client connection */
1153   manage_client (server, client);
1154
1155   g_signal_emit (server, gst_rtsp_server_signals[SIGNAL_CLIENT_CONNECTED], 0,
1156       client);
1157
1158   return TRUE;
1159
1160   /* ERRORS */
1161 client_failed:
1162   {
1163     GST_ERROR_OBJECT (server, "failed to create a client");
1164     return FALSE;
1165   }
1166 transfer_failed:
1167   {
1168     GST_ERROR_OBJECT (server, "failed to accept client: %s", error->message);
1169     g_error_free (error);
1170     g_object_unref (client);
1171     return FALSE;
1172   }
1173 }
1174
1175 /**
1176  * gst_rtsp_server_io_func:
1177  * @socket: a #GSocket
1178  * @condition: the condition on @source
1179  * @server: a #GstRTSPServer
1180  *
1181  * A default #GSocketSourceFunc that creates a new #GstRTSPClient to accept and handle a
1182  * new connection on @socket or @server.
1183  *
1184  * Returns: TRUE if the source could be connected, FALSE if an error occured.
1185  */
1186 gboolean
1187 gst_rtsp_server_io_func (GSocket * socket, GIOCondition condition,
1188     GstRTSPServer * server)
1189 {
1190   gboolean result = TRUE;
1191   GstRTSPClient *client = NULL;
1192   GstRTSPServerClass *klass;
1193   GError *error = NULL;
1194
1195   if (condition & G_IO_IN) {
1196     klass = GST_RTSP_SERVER_GET_CLASS (server);
1197
1198     if (klass->create_client)
1199       client = klass->create_client (server);
1200     if (client == NULL)
1201       goto client_failed;
1202
1203     /* a new client connected, create a client object to handle the client. */
1204     if (klass->accept_client)
1205       result = klass->accept_client (server, client, socket, &error);
1206     if (!result)
1207       goto accept_failed;
1208
1209     /* manage the client connection */
1210     manage_client (server, client);
1211
1212     g_signal_emit (server, gst_rtsp_server_signals[SIGNAL_CLIENT_CONNECTED], 0,
1213         client);
1214   } else {
1215     GST_WARNING_OBJECT (server, "received unknown event %08x", condition);
1216   }
1217   return TRUE;
1218
1219   /* ERRORS */
1220 client_failed:
1221   {
1222     GST_ERROR_OBJECT (server, "failed to create a client");
1223     return FALSE;
1224   }
1225 accept_failed:
1226   {
1227     GST_ERROR_OBJECT (server, "failed to accept client: %s", error->message);
1228     g_error_free (error);
1229     g_object_unref (client);
1230     return FALSE;
1231   }
1232 }
1233
1234 static void
1235 watch_destroyed (GstRTSPServer * server)
1236 {
1237   GstRTSPServerPrivate *priv = server->priv;
1238
1239   GST_DEBUG_OBJECT (server, "source destroyed");
1240
1241   g_object_unref (priv->socket);
1242   priv->socket = NULL;
1243   g_object_unref (server);
1244 }
1245
1246 /**
1247  * gst_rtsp_server_create_source:
1248  * @server: a #GstRTSPServer
1249  * @cancellable: a #GCancellable or %NULL.
1250  * @error: a #GError
1251  *
1252  * Create a #GSource for @server. The new source will have a default
1253  * #GSocketSourceFunc of gst_rtsp_server_io_func().
1254  *
1255  * @cancellable if not NULL can be used to cancel the source, which will cause
1256  * the source to trigger, reporting the current condition (which is likely 0
1257  * unless cancellation happened at the same time as a condition change). You can
1258  * check for this in the callback using g_cancellable_is_cancelled().
1259  *
1260  * Returns: the #GSource for @server or NULL when an error occured. Free with
1261  * g_source_unref ()
1262  */
1263 GSource *
1264 gst_rtsp_server_create_source (GstRTSPServer * server,
1265     GCancellable * cancellable, GError ** error)
1266 {
1267   GstRTSPServerPrivate *priv;
1268   GSocket *socket, *old;
1269   GSource *source;
1270
1271   g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL);
1272
1273   priv = server->priv;
1274
1275   socket = gst_rtsp_server_create_socket (server, NULL, error);
1276   if (socket == NULL)
1277     goto no_socket;
1278
1279   GST_RTSP_SERVER_LOCK (server);
1280   old = priv->socket;
1281   priv->socket = g_object_ref (socket);
1282   GST_RTSP_SERVER_UNLOCK (server);
1283
1284   if (old)
1285     g_object_unref (old);
1286
1287   /* create a watch for reads (new connections) and possible errors */
1288   source = g_socket_create_source (socket, G_IO_IN |
1289       G_IO_ERR | G_IO_HUP | G_IO_NVAL, cancellable);
1290   g_object_unref (socket);
1291
1292   /* configure the callback */
1293   g_source_set_callback (source,
1294       (GSourceFunc) gst_rtsp_server_io_func, g_object_ref (server),
1295       (GDestroyNotify) watch_destroyed);
1296
1297   return source;
1298
1299 no_socket:
1300   {
1301     GST_ERROR_OBJECT (server, "failed to create socket");
1302     return NULL;
1303   }
1304 }
1305
1306 /**
1307  * gst_rtsp_server_attach:
1308  * @server: a #GstRTSPServer
1309  * @context: (allow-none): a #GMainContext
1310  *
1311  * Attaches @server to @context. When the mainloop for @context is run, the
1312  * server will be dispatched. When @context is NULL, the default context will be
1313  * used).
1314  *
1315  * This function should be called when the server properties and urls are fully
1316  * configured and the server is ready to start.
1317  *
1318  * Returns: the ID (greater than 0) for the source within the GMainContext.
1319  */
1320 guint
1321 gst_rtsp_server_attach (GstRTSPServer * server, GMainContext * context)
1322 {
1323   guint res;
1324   GSource *source;
1325   GError *error = NULL;
1326
1327   g_return_val_if_fail (GST_IS_RTSP_SERVER (server), 0);
1328
1329   source = gst_rtsp_server_create_source (server, NULL, &error);
1330   if (source == NULL)
1331     goto no_source;
1332
1333   res = g_source_attach (source, context);
1334   g_source_unref (source);
1335
1336   return res;
1337
1338   /* ERRORS */
1339 no_source:
1340   {
1341     GST_ERROR_OBJECT (server, "failed to create watch: %s", error->message);
1342     g_error_free (error);
1343     return 0;
1344   }
1345 }