1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima
4 * Copyright © 2009 codethink
5 * Copyright © 2009 Red Hat, Inc
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 * Boston, MA 02111-1307, USA.
22 * Authors: Christian Kellner <gicmo@gnome.org>
23 * Samuel Cormier-Iijima <sciyoshi@gmail.com>
24 * Ryan Lortie <desrt@desrt.ca>
25 * Alexander Larsson <alexl@redhat.com>
29 #include "gsocketlistener.h"
31 #include <gio/gsimpleasyncresult.h>
32 #include <gio/gcancellable.h>
33 #include <gio/gsocketaddress.h>
34 #include <gio/ginetaddress.h>
35 #include <gio/gioerror.h>
36 #include <gio/gsocket.h>
37 #include <gio/gsocketconnection.h>
38 #include <gio/ginetsocketaddress.h>
44 * SECTION: gsocketlistener
45 * @title: GSocketListener
46 * @short_description: Helper for accepting network client connections
47 * @see_also: #GThreadedSocketService, #GSocketService.
49 * A #GSocketListener is an object that keeps track of a set
50 * of server sockets and helps you accept sockets from any of the
51 * socket, either sync or async.
53 * If you want to implement a network server, also look at #GSocketService
54 * and #GThreadedSocketService which are subclass of #GSocketListener
55 * that makes this even easier.
60 G_DEFINE_TYPE (GSocketListener, g_socket_listener, G_TYPE_OBJECT);
69 static GQuark source_quark = 0;
71 struct _GSocketListenerPrivate
74 GMainContext *main_context;
80 g_socket_listener_finalize (GObject *object)
82 GSocketListener *listener = G_SOCKET_LISTENER (object);
84 if (listener->priv->main_context)
85 g_main_context_unref (listener->priv->main_context);
87 if (!listener->priv->closed)
88 g_socket_listener_close (listener);
90 g_ptr_array_free (listener->priv->sockets, TRUE);
92 G_OBJECT_CLASS (g_socket_listener_parent_class)
97 g_socket_listener_get_property (GObject *object,
102 GSocketListener *listener = G_SOCKET_LISTENER (object);
106 case PROP_LISTEN_BACKLOG:
107 g_value_set_int (value, listener->priv->listen_backlog);
111 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
116 g_socket_listener_set_property (GObject *object,
121 GSocketListener *listener = G_SOCKET_LISTENER (object);
125 case PROP_LISTEN_BACKLOG:
126 g_socket_listener_set_backlog (listener, g_value_get_int (value));
130 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
136 g_socket_listener_class_init (GSocketListenerClass *klass)
138 GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
140 g_type_class_add_private (klass, sizeof (GSocketListenerPrivate));
142 gobject_class->finalize = g_socket_listener_finalize;
143 gobject_class->set_property = g_socket_listener_set_property;
144 gobject_class->get_property = g_socket_listener_get_property;
145 g_object_class_install_property (gobject_class, PROP_LISTEN_BACKLOG,
146 g_param_spec_int ("listen-backlog",
147 P_("Listen backlog"),
148 P_("outstanding connections in the listen queue"),
152 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
154 source_quark = g_quark_from_static_string ("g-socket-listener-source");
158 g_socket_listener_init (GSocketListener *listener)
160 listener->priv = G_TYPE_INSTANCE_GET_PRIVATE (listener,
161 G_TYPE_SOCKET_LISTENER,
162 GSocketListenerPrivate);
163 listener->priv->sockets =
164 g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
165 listener->priv->listen_backlog = 10;
169 * g_socket_listener_new:
171 * Creates a new #GSocketListener with no sockets to listen for.
172 * New listeners can be added with e.g. g_socket_listener_add_address()
173 * or g_socket_listener_add_inet_port().
175 * Returns: a new #GSocketListener.
180 g_socket_listener_new (void)
182 return g_object_new (G_TYPE_SOCKET_LISTENER, NULL);
186 check_listener (GSocketListener *listener,
189 if (listener->priv->closed)
191 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
192 _("Listener is already closed"));
200 * g_socket_listener_add_socket:
201 * @listener: a #GSocketListener
202 * @socket: a listening #GSocket
203 * @source_object: Optional #GObject identifying this source
204 * @error: #GError for error reporting, or %NULL to ignore.
206 * Adds @socket to the set of sockets that we try to accept
207 * new clients from. The socket must be bound to a local
208 * address and listened to.
210 * @source_object will be passed out in the various calls
211 * to accept to identify this particular source, which is
212 * useful if you're listening on multiple addresses and do
213 * different things depending on what address is connected to.
215 * Returns: %TRUE on success, %FALSE on error.
220 g_socket_listener_add_socket (GSocketListener *listener,
222 GObject *source_object,
225 if (!check_listener (listener, error))
228 /* TODO: Check that socket it is bound & not closed? */
230 if (g_socket_is_closed (socket))
232 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
233 _("Added socket is closed"));
237 g_ptr_array_add (listener->priv->sockets, socket);
240 g_object_set_qdata_full (G_OBJECT (socket), source_quark,
241 g_object_ref (source_object), g_object_unref);
247 * g_socket_listener_add_address:
248 * @listener: a #GSocketListener
249 * @address: a #GSocketAddress
250 * @type: a #GSocketType
251 * @protocol: a #GSocketProtocol
252 * @source_object: Optional #GObject identifying this source
253 * @error: #GError for error reporting, or %NULL to ignore.
255 * Creates a socket of type @type and protocol @protocol, binds
256 * it to @address and adds it to the set of sockets we're accepting
259 * Note that adding an IPv6 address, depending on the platform,
260 * may or may not result in a listener that also accepts IPv4
261 * connections. For more determinstic behaviour, see
262 * g_socket_listener_add_inet_port().
264 * @source_object will be passed out in the various calls
265 * to accept to identify this particular source, which is
266 * useful if you're listening on multiple addresses and do
267 * different things depending on what address is connected to.
269 * Returns: %TRUE on success, %FALSE on error.
274 g_socket_listener_add_address (GSocketListener *listener,
275 GSocketAddress *address,
277 GSocketProtocol protocol,
278 GObject *source_object,
281 GSocketFamily family;
284 if (!check_listener (listener, error))
287 family = g_socket_address_get_family (address);
288 socket = g_socket_new (family, type, protocol, error);
292 g_socket_set_listen_backlog (socket, listener->priv->listen_backlog);
294 if (!g_socket_bind (socket, address, TRUE, error) ||
295 !g_socket_listen (socket, error) ||
296 !g_socket_listener_add_socket (listener, socket,
300 g_object_unref (socket);
304 if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
305 G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
311 * g_socket_listener_add_inet_port:
312 * @listener: a #GSocketListener
313 * @port: an IP port number (non-zero)
314 * @source_object: Optional #GObject identifying this source
315 * @error: #GError for error reporting, or %NULL to ignore.
317 * Helper function for g_socket_listener_add_address() that
318 * creates a TCP/IP socket listening on IPv4 and IPv6 (if
319 * supported) on the specified port on all interfaces.
321 * @source_object will be passed out in the various calls
322 * to accept to identify this particular source, which is
323 * useful if you're listening on multiple addresses and do
324 * different things depending on what address is connected to.
326 * Returns: %TRUE on success, %FALSE on error.
331 g_socket_listener_add_inet_port (GSocketListener *listener,
333 GObject *source_object,
336 gboolean need_ipv4_socket = TRUE;
337 GSocket *socket4 = NULL;
340 g_return_val_if_fail (listener != NULL, FALSE);
341 g_return_val_if_fail (port != 0, FALSE);
343 if (!check_listener (listener, error))
346 /* first try to create an IPv6 socket */
347 socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6,
348 G_SOCKET_TYPE_STREAM,
349 G_SOCKET_PROTOCOL_DEFAULT,
353 /* IPv6 is supported on this platform, so if we fail now it is
354 * a result of being unable to bind to our port. Don't fail
355 * silently as a result of this!
358 GInetAddress *inet_address;
359 GSocketAddress *address;
362 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
363 address = g_inet_socket_address_new (inet_address, port);
364 g_object_unref (inet_address);
366 g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog);
368 result = g_socket_bind (socket6, address, TRUE, error) &&
369 g_socket_listen (socket6, error);
371 g_object_unref (address);
375 g_object_unref (socket6);
381 g_object_set_qdata_full (G_OBJECT (socket6), source_quark,
382 g_object_ref (source_object),
385 /* If this socket already speaks IPv4 then we are done. */
386 if (g_socket_speaks_ipv4 (socket6))
387 need_ipv4_socket = FALSE;
390 if (need_ipv4_socket)
391 /* We are here for exactly one of the following reasons:
393 * - our platform doesn't support IPv6
394 * - we successfully created an IPv6 socket but it's V6ONLY
396 * In either case, we need to go ahead and create an IPv4 socket
397 * and fail the call if we can't bind to it.
400 socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4,
401 G_SOCKET_TYPE_STREAM,
402 G_SOCKET_PROTOCOL_DEFAULT,
406 /* IPv4 is supported on this platform, so if we fail now it is
407 * a result of being unable to bind to our port. Don't fail
408 * silently as a result of this!
411 GInetAddress *inet_address;
412 GSocketAddress *address;
415 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
416 address = g_inet_socket_address_new (inet_address, port);
417 g_object_unref (inet_address);
419 g_socket_set_listen_backlog (socket4,
420 listener->priv->listen_backlog);
422 result = g_socket_bind (socket4, address, TRUE, error) &&
423 g_socket_listen (socket4, error);
425 g_object_unref (address);
429 g_object_unref (socket4);
432 g_object_unref (socket6);
438 g_object_set_qdata_full (G_OBJECT (socket4), source_quark,
439 g_object_ref (source_object),
443 /* Ok. So IPv4 is not supported on this platform. If we
444 * succeeded at creating an IPv6 socket then that's OK, but
445 * otherwise we need to tell the user we failed.
449 g_clear_error (error);
455 g_assert (socket6 != NULL || socket4 != NULL);
458 g_ptr_array_add (listener->priv->sockets, socket6);
461 g_ptr_array_add (listener->priv->sockets, socket4);
463 if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
464 G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
470 add_sources (GSocketListener *listener,
471 GSocketSourceFunc callback,
472 gpointer callback_data,
473 GCancellable *cancellable,
474 GMainContext *context)
482 for (i = 0; i < listener->priv->sockets->len; i++)
484 socket = listener->priv->sockets->pdata[i];
486 source = g_socket_create_source (socket, G_IO_IN, cancellable);
487 g_source_set_callback (source,
488 (GSourceFunc) callback,
489 callback_data, NULL);
490 g_source_attach (source, context);
492 sources = g_list_prepend (sources, source);
499 free_sources (GList *sources)
502 while (sources != NULL)
504 source = sources->data;
505 sources = g_list_delete_link (sources, sources);
506 g_source_destroy (source);
507 g_source_unref (source);
517 accept_callback (GSocket *socket,
518 GIOCondition condition,
521 struct AcceptData *data = user_data;
523 data->socket = socket;
524 g_main_loop_quit (data->loop);
530 * g_socket_listener_accept_socket:
531 * @listener: a #GSocketListener
532 * @source_object: location where #GObject pointer will be stored, or %NULL
533 * @cancellable: optional #GCancellable object, %NULL to ignore.
534 * @error: #GError for error reporting, or %NULL to ignore.
536 * Blocks waiting for a client to connect to any of the sockets added
537 * to the listener. Returns the #GSocket that was accepted.
539 * If you want to accept the high-level #GSocketConnection, not a #GSocket,
540 * which is often the case, then you should use g_socket_listener_accept()
543 * If @source_object is not %NULL it will be filled out with the source
544 * object specified when the corresponding socket or address was added
547 * If @cancellable is not %NULL, then the operation can be cancelled by
548 * triggering the cancellable object from another thread. If the operation
549 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
551 * Returns: a #GSocket on success, %NULL on error.
556 g_socket_listener_accept_socket (GSocketListener *listener,
557 GObject **source_object,
558 GCancellable *cancellable,
561 GSocket *accept_socket, *socket;
563 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
565 if (!check_listener (listener, error))
568 if (listener->priv->sockets->len == 1)
570 accept_socket = listener->priv->sockets->pdata[0];
571 if (!g_socket_condition_wait (accept_socket, G_IO_IN,
578 struct AcceptData data;
581 if (listener->priv->main_context == NULL)
582 listener->priv->main_context = g_main_context_new ();
584 loop = g_main_loop_new (listener->priv->main_context, FALSE);
586 sources = add_sources (listener,
590 listener->priv->main_context);
591 g_main_loop_run (loop);
592 accept_socket = data.socket;
593 free_sources (sources);
594 g_main_loop_unref (loop);
597 if (!(socket = g_socket_accept (accept_socket, error)))
601 *source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
607 * g_socket_listener_accept:
608 * @listener: a #GSocketListener
609 * @source_object: location where #GObject pointer will be stored, or %NULL
610 * @cancellable: optional #GCancellable object, %NULL to ignore.
611 * @error: #GError for error reporting, or %NULL to ignore.
613 * Blocks waiting for a client to connect to any of the sockets added
614 * to the listener. Returns a #GSocketConnection for the socket that was
617 * If @source_object is not %NULL it will be filled out with the source
618 * object specified when the corresponding socket or address was added
621 * If @cancellable is not %NULL, then the operation can be cancelled by
622 * triggering the cancellable object from another thread. If the operation
623 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
625 * Returns: a #GSocketConnection on success, %NULL on error.
630 g_socket_listener_accept (GSocketListener *listener,
631 GObject **source_object,
632 GCancellable *cancellable,
635 GSocketConnection *connection;
638 socket = g_socket_listener_accept_socket (listener,
645 connection = g_socket_connection_factory_create_connection (socket);
646 g_object_unref (socket);
651 struct AcceptAsyncData {
652 GSimpleAsyncResult *simple;
653 GCancellable *cancellable;
658 accept_ready (GSocket *accept_socket,
659 GIOCondition condition,
662 struct AcceptAsyncData *data = _data;
663 GError *error = NULL;
665 if (!g_cancellable_set_error_if_cancelled (data->cancellable,
669 GObject *source_object;
671 socket = g_socket_accept (accept_socket, &error);
674 g_simple_async_result_set_op_res_gpointer (data->simple, socket,
676 source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
678 g_object_set_qdata_full (G_OBJECT (data->simple),
680 g_object_ref (source_object), g_object_unref);
686 g_simple_async_result_set_from_error (data->simple, error);
687 g_error_free (error);
690 g_simple_async_result_complete_in_idle (data->simple);
691 g_object_unref (data->simple);
692 free_sources (data->sources);
699 * g_socket_listener_accept_socket_async:
700 * @listener: a #GSocketListener
701 * @cancellable: a #GCancellable, or %NULL
702 * @callback: a #GAsyncReadyCallback
703 * @user_data: user data for the callback
705 * This is the asynchronous version of g_socket_listener_accept_socket().
707 * When the operation is finished @callback will be
708 * called. You can then call g_socket_listener_accept_socket_finish()
709 * to get the result of the operation.
714 g_socket_listener_accept_socket_async (GSocketListener *listener,
715 GCancellable *cancellable,
716 GAsyncReadyCallback callback,
719 struct AcceptAsyncData *data;
720 GError *error = NULL;
722 if (!check_listener (listener, &error))
724 g_simple_async_report_gerror_in_idle (G_OBJECT (listener),
727 g_error_free (error);
731 data = g_new0 (struct AcceptAsyncData, 1);
732 data->simple = g_simple_async_result_new (G_OBJECT (listener),
734 g_socket_listener_accept_socket_async);
735 data->cancellable = cancellable;
736 data->sources = add_sources (listener,
744 * g_socket_listener_accept_socket_finish:
745 * @listener: a #GSocketListener
746 * @result: a #GAsyncResult.
747 * @source_object: Optional #GObject identifying this source
748 * @error: a #GError location to store the error occuring, or %NULL to
751 * Finishes an async accept operation. See g_socket_listener_accept_socket_async()
753 * Returns: a #GSocket on success, %NULL on error.
758 g_socket_listener_accept_socket_finish (GSocketListener *listener,
759 GAsyncResult *result,
760 GObject **source_object,
764 GSimpleAsyncResult *simple;
766 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), FALSE);
768 simple = G_SIMPLE_ASYNC_RESULT (result);
770 if (g_simple_async_result_propagate_error (simple, error))
773 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_socket_listener_accept_socket_async);
775 socket = g_simple_async_result_get_op_res_gpointer (simple);
778 *source_object = g_object_get_qdata (G_OBJECT (result), source_quark);
780 return g_object_ref (socket);
784 * g_socket_listener_accept_async:
785 * @listener: a #GSocketListener
786 * @cancellable: a #GCancellable, or %NULL
787 * @callback: a #GAsyncReadyCallback
788 * @user_data: user data for the callback
790 * This is the asynchronous version of g_socket_listener_accept().
792 * When the operation is finished @callback will be
793 * called. You can then call g_socket_listener_accept_socket()
794 * to get the result of the operation.
799 g_socket_listener_accept_async (GSocketListener *listener,
800 GCancellable *cancellable,
801 GAsyncReadyCallback callback,
804 g_socket_listener_accept_socket_async (listener,
811 * g_socket_listener_accept_finish:
812 * @listener: a #GSocketListener
813 * @result: a #GAsyncResult.
814 * @source_object: Optional #GObject identifying this source
815 * @error: a #GError location to store the error occuring, or %NULL to
818 * Finishes an async accept operation. See g_socket_listener_accept_async()
820 * Returns: a #GSocketConnection on success, %NULL on error.
825 g_socket_listener_accept_finish (GSocketListener *listener,
826 GAsyncResult *result,
827 GObject **source_object,
831 GSocketConnection *connection;
833 socket = g_socket_listener_accept_socket_finish (listener,
840 connection = g_socket_connection_factory_create_connection (socket);
841 g_object_unref (socket);
846 * g_socket_listener_set_backlog:
847 * @listener: a #GSocketListener
848 * @listen_backlog: an integer
850 * Sets the listen backlog on the sockets in the listener.
852 * See g_socket_set_listen_backlog() for details
857 g_socket_listener_set_backlog (GSocketListener *listener,
863 if (listener->priv->closed)
866 listener->priv->listen_backlog = listen_backlog;
868 for (i = 0; i < listener->priv->sockets->len; i++)
870 socket = listener->priv->sockets->pdata[i];
871 g_socket_set_listen_backlog (socket, listen_backlog);
876 * g_socket_listener_close:
877 * @listener: a #GSocketListener
879 * Closes all the sockets in the listener.
884 g_socket_listener_close (GSocketListener *listener)
889 g_return_if_fail (G_IS_SOCKET_LISTENER (listener));
891 if (listener->priv->closed)
894 for (i = 0; i < listener->priv->sockets->len; i++)
896 socket = listener->priv->sockets->pdata[i];
897 g_socket_close (socket, NULL);
899 listener->priv->closed = TRUE;
902 #define __G_SOCKET_LISTENER_C__
903 #include "gioaliasdef.c"