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_object_ref (socket
);
238 g_ptr_array_add (listener
->priv
->sockets
, socket
);
241 g_object_set_qdata_full (G_OBJECT (socket
), source_quark
,
242 g_object_ref (source_object
), g_object_unref
);
245 if (G_SOCKET_LISTENER_GET_CLASS (listener
)->changed
)
246 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed (listener
);
252 * g_socket_listener_add_address:
253 * @listener: a #GSocketListener
254 * @address: a #GSocketAddress
255 * @type: a #GSocketType
256 * @protocol: a #GSocketProtocol
257 * @source_object: Optional #GObject identifying this source
258 * @effective_address: location to store the address that was bound to, or %NULL.
259 * @error: #GError for error reporting, or %NULL to ignore.
261 * Creates a socket of type @type and protocol @protocol, binds
262 * it to @address and adds it to the set of sockets we're accepting
265 * Note that adding an IPv6 address, depending on the platform,
266 * may or may not result in a listener that also accepts IPv4
267 * connections. For more determinstic behaviour, see
268 * g_socket_listener_add_inet_port().
270 * @source_object will be passed out in the various calls
271 * to accept to identify this particular source, which is
272 * useful if you're listening on multiple addresses and do
273 * different things depending on what address is connected to.
275 * If successful and @effective_address is non-%NULL then it will
276 * be set to the address that the binding actually occured at. This
277 * is helpful for determining the port number that was used for when
278 * requesting a binding to port 0 (ie: "any port"). This address, if
279 * requested, belongs to the caller and must be freed.
281 * Returns: %TRUE on success, %FALSE on error.
286 g_socket_listener_add_address (GSocketListener
*listener
,
287 GSocketAddress
*address
,
289 GSocketProtocol protocol
,
290 GObject
*source_object
,
291 GSocketAddress
**effective_address
,
294 GSocketAddress
*local_address
;
295 GSocketFamily family
;
298 if (!check_listener (listener
, error
))
301 family
= g_socket_address_get_family (address
);
302 socket
= g_socket_new (family
, type
, protocol
, error
);
306 g_socket_set_listen_backlog (socket
, listener
->priv
->listen_backlog
);
308 if (!g_socket_bind (socket
, address
, TRUE
, error
) ||
309 !g_socket_listen (socket
, error
))
311 g_object_unref (socket
);
315 local_address
= NULL
;
316 if (effective_address
)
318 local_address
= g_socket_get_local_address (socket
, error
);
319 if (local_address
== NULL
)
321 g_object_unref (socket
);
326 if (!g_socket_listener_add_socket (listener
, socket
,
331 g_object_unref (local_address
);
332 g_object_unref (socket
);
336 if (effective_address
)
337 *effective_address
= local_address
;
339 g_object_unref (socket
); /* add_socket refs this */
345 * g_socket_listener_add_inet_port:
346 * @listener: a #GSocketListener
347 * @port: an IP port number (non-zero)
348 * @source_object: Optional #GObject identifying this source
349 * @error: #GError for error reporting, or %NULL to ignore.
351 * Helper function for g_socket_listener_add_address() that
352 * creates a TCP/IP socket listening on IPv4 and IPv6 (if
353 * supported) on the specified port on all interfaces.
355 * @source_object will be passed out in the various calls
356 * to accept to identify this particular source, which is
357 * useful if you're listening on multiple addresses and do
358 * different things depending on what address is connected to.
360 * Returns: %TRUE on success, %FALSE on error.
365 g_socket_listener_add_inet_port (GSocketListener
*listener
,
367 GObject
*source_object
,
370 gboolean need_ipv4_socket
= TRUE
;
371 GSocket
*socket4
= NULL
;
374 g_return_val_if_fail (listener
!= NULL
, FALSE
);
375 g_return_val_if_fail (port
!= 0, FALSE
);
377 if (!check_listener (listener
, error
))
380 /* first try to create an IPv6 socket */
381 socket6
= g_socket_new (G_SOCKET_FAMILY_IPV6
,
382 G_SOCKET_TYPE_STREAM
,
383 G_SOCKET_PROTOCOL_DEFAULT
,
387 /* IPv6 is supported on this platform, so if we fail now it is
388 * a result of being unable to bind to our port. Don't fail
389 * silently as a result of this!
392 GInetAddress
*inet_address
;
393 GSocketAddress
*address
;
396 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV6
);
397 address
= g_inet_socket_address_new (inet_address
, port
);
398 g_object_unref (inet_address
);
400 g_socket_set_listen_backlog (socket6
, listener
->priv
->listen_backlog
);
402 result
= g_socket_bind (socket6
, address
, TRUE
, error
) &&
403 g_socket_listen (socket6
, error
);
405 g_object_unref (address
);
409 g_object_unref (socket6
);
415 g_object_set_qdata_full (G_OBJECT (socket6
), source_quark
,
416 g_object_ref (source_object
),
419 /* If this socket already speaks IPv4 then we are done. */
420 if (g_socket_speaks_ipv4 (socket6
))
421 need_ipv4_socket
= FALSE
;
424 if (need_ipv4_socket
)
425 /* We are here for exactly one of the following reasons:
427 * - our platform doesn't support IPv6
428 * - we successfully created an IPv6 socket but it's V6ONLY
430 * In either case, we need to go ahead and create an IPv4 socket
431 * and fail the call if we can't bind to it.
434 socket4
= g_socket_new (G_SOCKET_FAMILY_IPV4
,
435 G_SOCKET_TYPE_STREAM
,
436 G_SOCKET_PROTOCOL_DEFAULT
,
440 /* IPv4 is supported on this platform, so if we fail now it is
441 * a result of being unable to bind to our port. Don't fail
442 * silently as a result of this!
445 GInetAddress
*inet_address
;
446 GSocketAddress
*address
;
449 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV4
);
450 address
= g_inet_socket_address_new (inet_address
, port
);
451 g_object_unref (inet_address
);
453 g_socket_set_listen_backlog (socket4
,
454 listener
->priv
->listen_backlog
);
456 result
= g_socket_bind (socket4
, address
, TRUE
, error
) &&
457 g_socket_listen (socket4
, error
);
459 g_object_unref (address
);
463 g_object_unref (socket4
);
466 g_object_unref (socket6
);
472 g_object_set_qdata_full (G_OBJECT (socket4
), source_quark
,
473 g_object_ref (source_object
),
477 /* Ok. So IPv4 is not supported on this platform. If we
478 * succeeded at creating an IPv6 socket then that's OK, but
479 * otherwise we need to tell the user we failed.
483 g_clear_error (error
);
489 g_assert (socket6
!= NULL
|| socket4
!= NULL
);
492 g_ptr_array_add (listener
->priv
->sockets
, socket6
);
495 g_ptr_array_add (listener
->priv
->sockets
, socket4
);
497 if (G_SOCKET_LISTENER_GET_CLASS (listener
)->changed
)
498 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed (listener
);
504 add_sources (GSocketListener
*listener
,
505 GSocketSourceFunc callback
,
506 gpointer callback_data
,
507 GCancellable
*cancellable
,
508 GMainContext
*context
)
516 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
518 socket
= listener
->priv
->sockets
->pdata
[i
];
520 source
= g_socket_create_source (socket
, G_IO_IN
, cancellable
);
521 g_source_set_callback (source
,
522 (GSourceFunc
) callback
,
523 callback_data
, NULL
);
524 g_source_attach (source
, context
);
526 sources
= g_list_prepend (sources
, source
);
533 free_sources (GList
*sources
)
536 while (sources
!= NULL
)
538 source
= sources
->data
;
539 sources
= g_list_delete_link (sources
, sources
);
540 g_source_destroy (source
);
541 g_source_unref (source
);
551 accept_callback (GSocket
*socket
,
552 GIOCondition condition
,
555 struct AcceptData
*data
= user_data
;
557 data
->socket
= socket
;
558 g_main_loop_quit (data
->loop
);
564 * g_socket_listener_accept_socket:
565 * @listener: a #GSocketListener
566 * @source_object: location where #GObject pointer will be stored, or %NULL
567 * @cancellable: optional #GCancellable object, %NULL to ignore.
568 * @error: #GError for error reporting, or %NULL to ignore.
570 * Blocks waiting for a client to connect to any of the sockets added
571 * to the listener. Returns the #GSocket that was accepted.
573 * If you want to accept the high-level #GSocketConnection, not a #GSocket,
574 * which is often the case, then you should use g_socket_listener_accept()
577 * If @source_object is not %NULL it will be filled out with the source
578 * object specified when the corresponding socket or address was added
581 * If @cancellable is not %NULL, then the operation can be cancelled by
582 * triggering the cancellable object from another thread. If the operation
583 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
585 * Returns: a #GSocket on success, %NULL on error.
590 g_socket_listener_accept_socket (GSocketListener
*listener
,
591 GObject
**source_object
,
592 GCancellable
*cancellable
,
595 GSocket
*accept_socket
, *socket
;
597 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener
), NULL
);
599 if (!check_listener (listener
, error
))
602 if (listener
->priv
->sockets
->len
== 1)
604 accept_socket
= listener
->priv
->sockets
->pdata
[0];
605 if (!g_socket_condition_wait (accept_socket
, G_IO_IN
,
612 struct AcceptData data
;
615 if (listener
->priv
->main_context
== NULL
)
616 listener
->priv
->main_context
= g_main_context_new ();
618 loop
= g_main_loop_new (listener
->priv
->main_context
, FALSE
);
620 sources
= add_sources (listener
,
624 listener
->priv
->main_context
);
625 g_main_loop_run (loop
);
626 accept_socket
= data
.socket
;
627 free_sources (sources
);
628 g_main_loop_unref (loop
);
631 if (!(socket
= g_socket_accept (accept_socket
, cancellable
, error
)))
635 *source_object
= g_object_get_qdata (G_OBJECT (accept_socket
), source_quark
);
641 * g_socket_listener_accept:
642 * @listener: a #GSocketListener
643 * @source_object: location where #GObject pointer will be stored, or %NULL
644 * @cancellable: optional #GCancellable object, %NULL to ignore.
645 * @error: #GError for error reporting, or %NULL to ignore.
647 * Blocks waiting for a client to connect to any of the sockets added
648 * to the listener. Returns a #GSocketConnection for the socket that was
651 * If @source_object is not %NULL it will be filled out with the source
652 * object specified when the corresponding socket or address was added
655 * If @cancellable is not %NULL, then the operation can be cancelled by
656 * triggering the cancellable object from another thread. If the operation
657 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
659 * Returns: a #GSocketConnection on success, %NULL on error.
664 g_socket_listener_accept (GSocketListener
*listener
,
665 GObject
**source_object
,
666 GCancellable
*cancellable
,
669 GSocketConnection
*connection
;
672 socket
= g_socket_listener_accept_socket (listener
,
679 connection
= g_socket_connection_factory_create_connection (socket
);
680 g_object_unref (socket
);
685 struct AcceptAsyncData
{
686 GSimpleAsyncResult
*simple
;
687 GCancellable
*cancellable
;
692 accept_ready (GSocket
*accept_socket
,
693 GIOCondition condition
,
696 struct AcceptAsyncData
*data
= _data
;
697 GError
*error
= NULL
;
699 GObject
*source_object
;
701 socket
= g_socket_accept (accept_socket
, data
->cancellable
, &error
);
704 g_simple_async_result_set_op_res_gpointer (data
->simple
, socket
,
706 source_object
= g_object_get_qdata (G_OBJECT (accept_socket
), source_quark
);
708 g_object_set_qdata_full (G_OBJECT (data
->simple
),
710 g_object_ref (source_object
), g_object_unref
);
714 g_simple_async_result_set_from_error (data
->simple
, error
);
715 g_error_free (error
);
718 g_simple_async_result_complete_in_idle (data
->simple
);
719 g_object_unref (data
->simple
);
720 free_sources (data
->sources
);
727 * g_socket_listener_accept_socket_async:
728 * @listener: a #GSocketListener
729 * @cancellable: a #GCancellable, or %NULL
730 * @callback: a #GAsyncReadyCallback
731 * @user_data: user data for the callback
733 * This is the asynchronous version of g_socket_listener_accept_socket().
735 * When the operation is finished @callback will be
736 * called. You can then call g_socket_listener_accept_socket_finish()
737 * to get the result of the operation.
742 g_socket_listener_accept_socket_async (GSocketListener
*listener
,
743 GCancellable
*cancellable
,
744 GAsyncReadyCallback callback
,
747 struct AcceptAsyncData
*data
;
748 GError
*error
= NULL
;
750 if (!check_listener (listener
, &error
))
752 g_simple_async_report_gerror_in_idle (G_OBJECT (listener
),
755 g_error_free (error
);
759 data
= g_new0 (struct AcceptAsyncData
, 1);
760 data
->simple
= g_simple_async_result_new (G_OBJECT (listener
),
762 g_socket_listener_accept_socket_async
);
763 data
->cancellable
= cancellable
;
764 data
->sources
= add_sources (listener
,
768 g_main_context_get_thread_default ());
772 * g_socket_listener_accept_socket_finish:
773 * @listener: a #GSocketListener
774 * @result: a #GAsyncResult.
775 * @source_object: Optional #GObject identifying this source
776 * @error: a #GError location to store the error occuring, or %NULL to
779 * Finishes an async accept operation. See g_socket_listener_accept_socket_async()
781 * Returns: a #GSocket on success, %NULL on error.
786 g_socket_listener_accept_socket_finish (GSocketListener
*listener
,
787 GAsyncResult
*result
,
788 GObject
**source_object
,
792 GSimpleAsyncResult
*simple
;
794 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener
), FALSE
);
796 simple
= G_SIMPLE_ASYNC_RESULT (result
);
798 if (g_simple_async_result_propagate_error (simple
, error
))
801 g_warn_if_fail (g_simple_async_result_get_source_tag (simple
) == g_socket_listener_accept_socket_async
);
803 socket
= g_simple_async_result_get_op_res_gpointer (simple
);
806 *source_object
= g_object_get_qdata (G_OBJECT (result
), source_quark
);
808 return g_object_ref (socket
);
812 * g_socket_listener_accept_async:
813 * @listener: a #GSocketListener
814 * @cancellable: a #GCancellable, or %NULL
815 * @callback: a #GAsyncReadyCallback
816 * @user_data: user data for the callback
818 * This is the asynchronous version of g_socket_listener_accept().
820 * When the operation is finished @callback will be
821 * called. You can then call g_socket_listener_accept_socket()
822 * to get the result of the operation.
827 g_socket_listener_accept_async (GSocketListener
*listener
,
828 GCancellable
*cancellable
,
829 GAsyncReadyCallback callback
,
832 g_socket_listener_accept_socket_async (listener
,
839 * g_socket_listener_accept_finish:
840 * @listener: a #GSocketListener
841 * @result: a #GAsyncResult.
842 * @source_object: Optional #GObject identifying this source
843 * @error: a #GError location to store the error occuring, or %NULL to
846 * Finishes an async accept operation. See g_socket_listener_accept_async()
848 * Returns: a #GSocketConnection on success, %NULL on error.
853 g_socket_listener_accept_finish (GSocketListener
*listener
,
854 GAsyncResult
*result
,
855 GObject
**source_object
,
859 GSocketConnection
*connection
;
861 socket
= g_socket_listener_accept_socket_finish (listener
,
868 connection
= g_socket_connection_factory_create_connection (socket
);
869 g_object_unref (socket
);
874 * g_socket_listener_set_backlog:
875 * @listener: a #GSocketListener
876 * @listen_backlog: an integer
878 * Sets the listen backlog on the sockets in the listener.
880 * See g_socket_set_listen_backlog() for details
885 g_socket_listener_set_backlog (GSocketListener
*listener
,
891 if (listener
->priv
->closed
)
894 listener
->priv
->listen_backlog
= listen_backlog
;
896 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
898 socket
= listener
->priv
->sockets
->pdata
[i
];
899 g_socket_set_listen_backlog (socket
, listen_backlog
);
904 * g_socket_listener_close:
905 * @listener: a #GSocketListener
907 * Closes all the sockets in the listener.
912 g_socket_listener_close (GSocketListener
*listener
)
917 g_return_if_fail (G_IS_SOCKET_LISTENER (listener
));
919 if (listener
->priv
->closed
)
922 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
924 socket
= listener
->priv
->sockets
->pdata
[i
];
925 g_socket_close (socket
, NULL
);
927 listener
->priv
->closed
= TRUE
;
930 #define __G_SOCKET_LISTENER_C__
931 #include "gioaliasdef.c"