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, see <http://www.gnu.org/licenses/>.
20 * Authors: Christian Kellner <gicmo@gnome.org>
21 * Samuel Cormier-Iijima <sciyoshi@gmail.com>
22 * Ryan Lortie <desrt@desrt.ca>
23 * Alexander Larsson <alexl@redhat.com>
27 #include "gsocketlistener.h"
29 #include <gio/gioenumtypes.h>
30 #include <gio/gtask.h>
31 #include <gio/gcancellable.h>
32 #include <gio/gsocketaddress.h>
33 #include <gio/ginetaddress.h>
34 #include <gio/gioerror.h>
35 #include <gio/gsocket.h>
36 #include <gio/gsocketconnection.h>
37 #include <gio/ginetsocketaddress.h>
42 * SECTION:gsocketlistener
43 * @title: GSocketListener
44 * @short_description: Helper for accepting network client connections
46 * @see_also: #GThreadedSocketService, #GSocketService.
48 * A #GSocketListener is an object that keeps track of a set
49 * of server sockets and helps you accept sockets from any of the
50 * socket, either sync or async.
52 * If you want to implement a network server, also look at #GSocketService
53 * and #GThreadedSocketService which are subclass of #GSocketListener
54 * that makes this even easier.
71 static guint signals
[LAST_SIGNAL
] = { 0 };
73 static GQuark source_quark
= 0;
75 struct _GSocketListenerPrivate
78 GMainContext
*main_context
;
83 G_DEFINE_TYPE_WITH_PRIVATE (GSocketListener
, g_socket_listener
, G_TYPE_OBJECT
)
86 g_socket_listener_finalize (GObject
*object
)
88 GSocketListener
*listener
= G_SOCKET_LISTENER (object
);
90 if (listener
->priv
->main_context
)
91 g_main_context_unref (listener
->priv
->main_context
);
93 /* Do not explicitly close the sockets. Instead, let them close themselves if
94 * their final reference is dropped, but keep them open if a reference is
95 * held externally to the GSocketListener (which is possible if
96 * g_socket_listener_add_socket() was used).
98 g_ptr_array_free (listener
->priv
->sockets
, TRUE
);
100 G_OBJECT_CLASS (g_socket_listener_parent_class
)
105 g_socket_listener_get_property (GObject
*object
,
110 GSocketListener
*listener
= G_SOCKET_LISTENER (object
);
114 case PROP_LISTEN_BACKLOG
:
115 g_value_set_int (value
, listener
->priv
->listen_backlog
);
119 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
124 g_socket_listener_set_property (GObject
*object
,
129 GSocketListener
*listener
= G_SOCKET_LISTENER (object
);
133 case PROP_LISTEN_BACKLOG
:
134 g_socket_listener_set_backlog (listener
, g_value_get_int (value
));
138 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
143 g_socket_listener_class_init (GSocketListenerClass
*klass
)
145 GObjectClass
*gobject_class G_GNUC_UNUSED
= G_OBJECT_CLASS (klass
);
147 gobject_class
->finalize
= g_socket_listener_finalize
;
148 gobject_class
->set_property
= g_socket_listener_set_property
;
149 gobject_class
->get_property
= g_socket_listener_get_property
;
150 g_object_class_install_property (gobject_class
, PROP_LISTEN_BACKLOG
,
151 g_param_spec_int ("listen-backlog",
152 P_("Listen backlog"),
153 P_("outstanding connections in the listen queue"),
157 G_PARAM_CONSTRUCT
| G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
));
160 * GSocketListener::event:
161 * @listener: the #GSocketListener
162 * @event: the event that is occurring
163 * @socket: the #GSocket the event is occurring on
165 * Emitted when @listener's activity on @socket changes state.
166 * Note that when @listener is used to listen on both IPv4 and
167 * IPv6, a separate set of signals will be emitted for each, and
168 * the order they happen in is undefined.
173 g_signal_new (I_("event"),
174 G_TYPE_FROM_CLASS (gobject_class
),
176 G_STRUCT_OFFSET (GSocketListenerClass
, event
),
179 G_TYPE_SOCKET_LISTENER_EVENT
,
182 source_quark
= g_quark_from_static_string ("g-socket-listener-source");
186 g_socket_listener_init (GSocketListener
*listener
)
188 listener
->priv
= g_socket_listener_get_instance_private (listener
);
189 listener
->priv
->sockets
=
190 g_ptr_array_new_with_free_func ((GDestroyNotify
) g_object_unref
);
191 listener
->priv
->listen_backlog
= 10;
195 * g_socket_listener_new:
197 * Creates a new #GSocketListener with no sockets to listen for.
198 * New listeners can be added with e.g. g_socket_listener_add_address()
199 * or g_socket_listener_add_inet_port().
201 * Returns: a new #GSocketListener.
206 g_socket_listener_new (void)
208 return g_object_new (G_TYPE_SOCKET_LISTENER
, NULL
);
212 check_listener (GSocketListener
*listener
,
215 if (listener
->priv
->closed
)
217 g_set_error_literal (error
, G_IO_ERROR
, G_IO_ERROR_CLOSED
,
218 _("Listener is already closed"));
226 * g_socket_listener_add_socket:
227 * @listener: a #GSocketListener
228 * @socket: a listening #GSocket
229 * @source_object: (nullable): Optional #GObject identifying this source
230 * @error: #GError for error reporting, or %NULL to ignore.
232 * Adds @socket to the set of sockets that we try to accept
233 * new clients from. The socket must be bound to a local
234 * address and listened to.
236 * @source_object will be passed out in the various calls
237 * to accept to identify this particular source, which is
238 * useful if you're listening on multiple addresses and do
239 * different things depending on what address is connected to.
241 * The @socket will not be automatically closed when the @listener is finalized
242 * unless the listener held the final reference to the socket. Before GLib 2.42,
243 * the @socket was automatically closed on finalization of the @listener, even
244 * if references to it were held elsewhere.
246 * Returns: %TRUE on success, %FALSE on error.
251 g_socket_listener_add_socket (GSocketListener
*listener
,
253 GObject
*source_object
,
256 if (!check_listener (listener
, error
))
259 /* TODO: Check that socket it is bound & not closed? */
261 if (g_socket_is_closed (socket
))
263 g_set_error_literal (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
264 _("Added socket is closed"));
268 g_object_ref (socket
);
269 g_ptr_array_add (listener
->priv
->sockets
, socket
);
272 g_object_set_qdata_full (G_OBJECT (socket
), source_quark
,
273 g_object_ref (source_object
), g_object_unref
);
276 if (G_SOCKET_LISTENER_GET_CLASS (listener
)->changed
)
277 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed (listener
);
283 * g_socket_listener_add_address:
284 * @listener: a #GSocketListener
285 * @address: a #GSocketAddress
286 * @type: a #GSocketType
287 * @protocol: a #GSocketProtocol
288 * @source_object: (nullable): Optional #GObject identifying this source
289 * @effective_address: (out) (optional): location to store the address that was bound to, or %NULL.
290 * @error: #GError for error reporting, or %NULL to ignore.
292 * Creates a socket of type @type and protocol @protocol, binds
293 * it to @address and adds it to the set of sockets we're accepting
296 * Note that adding an IPv6 address, depending on the platform,
297 * may or may not result in a listener that also accepts IPv4
298 * connections. For more deterministic behavior, see
299 * g_socket_listener_add_inet_port().
301 * @source_object will be passed out in the various calls
302 * to accept to identify this particular source, which is
303 * useful if you're listening on multiple addresses and do
304 * different things depending on what address is connected to.
306 * If successful and @effective_address is non-%NULL then it will
307 * be set to the address that the binding actually occurred at. This
308 * is helpful for determining the port number that was used for when
309 * requesting a binding to port 0 (ie: "any port"). This address, if
310 * requested, belongs to the caller and must be freed.
312 * Returns: %TRUE on success, %FALSE on error.
317 g_socket_listener_add_address (GSocketListener
*listener
,
318 GSocketAddress
*address
,
320 GSocketProtocol protocol
,
321 GObject
*source_object
,
322 GSocketAddress
**effective_address
,
325 GSocketAddress
*local_address
;
326 GSocketFamily family
;
329 if (!check_listener (listener
, error
))
332 family
= g_socket_address_get_family (address
);
333 socket
= g_socket_new (family
, type
, protocol
, error
);
337 g_socket_set_listen_backlog (socket
, listener
->priv
->listen_backlog
);
339 g_signal_emit (listener
, signals
[EVENT
], 0,
340 G_SOCKET_LISTENER_BINDING
, socket
);
342 if (!g_socket_bind (socket
, address
, TRUE
, error
))
344 g_object_unref (socket
);
348 g_signal_emit (listener
, signals
[EVENT
], 0,
349 G_SOCKET_LISTENER_BOUND
, socket
);
350 g_signal_emit (listener
, signals
[EVENT
], 0,
351 G_SOCKET_LISTENER_LISTENING
, socket
);
353 if (!g_socket_listen (socket
, error
))
355 g_object_unref (socket
);
359 g_signal_emit (listener
, signals
[EVENT
], 0,
360 G_SOCKET_LISTENER_LISTENED
, socket
);
362 local_address
= NULL
;
363 if (effective_address
)
365 local_address
= g_socket_get_local_address (socket
, error
);
366 if (local_address
== NULL
)
368 g_object_unref (socket
);
373 if (!g_socket_listener_add_socket (listener
, socket
,
378 g_object_unref (local_address
);
379 g_object_unref (socket
);
383 if (effective_address
)
384 *effective_address
= local_address
;
386 g_object_unref (socket
); /* add_socket refs this */
392 * g_socket_listener_add_inet_port:
393 * @listener: a #GSocketListener
394 * @port: an IP port number (non-zero)
395 * @source_object: (nullable): Optional #GObject identifying this source
396 * @error: #GError for error reporting, or %NULL to ignore.
398 * Helper function for g_socket_listener_add_address() that
399 * creates a TCP/IP socket listening on IPv4 and IPv6 (if
400 * supported) on the specified port on all interfaces.
402 * @source_object will be passed out in the various calls
403 * to accept to identify this particular source, which is
404 * useful if you're listening on multiple addresses and do
405 * different things depending on what address is connected to.
407 * Returns: %TRUE on success, %FALSE on error.
412 g_socket_listener_add_inet_port (GSocketListener
*listener
,
414 GObject
*source_object
,
417 gboolean need_ipv4_socket
= TRUE
;
418 GSocket
*socket4
= NULL
;
421 g_return_val_if_fail (listener
!= NULL
, FALSE
);
422 g_return_val_if_fail (port
!= 0, FALSE
);
424 if (!check_listener (listener
, error
))
427 /* first try to create an IPv6 socket */
428 socket6
= g_socket_new (G_SOCKET_FAMILY_IPV6
,
429 G_SOCKET_TYPE_STREAM
,
430 G_SOCKET_PROTOCOL_DEFAULT
,
434 /* IPv6 is supported on this platform, so if we fail now it is
435 * a result of being unable to bind to our port. Don't fail
436 * silently as a result of this!
439 GInetAddress
*inet_address
;
440 GSocketAddress
*address
;
442 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV6
);
443 address
= g_inet_socket_address_new (inet_address
, port
);
444 g_object_unref (inet_address
);
446 g_socket_set_listen_backlog (socket6
, listener
->priv
->listen_backlog
);
448 g_signal_emit (listener
, signals
[EVENT
], 0,
449 G_SOCKET_LISTENER_BINDING
, socket6
);
451 if (!g_socket_bind (socket6
, address
, TRUE
, error
))
453 g_object_unref (address
);
454 g_object_unref (socket6
);
458 g_object_unref (address
);
460 g_signal_emit (listener
, signals
[EVENT
], 0,
461 G_SOCKET_LISTENER_BOUND
, socket6
);
462 g_signal_emit (listener
, signals
[EVENT
], 0,
463 G_SOCKET_LISTENER_LISTENING
, socket6
);
465 if (!g_socket_listen (socket6
, error
))
467 g_object_unref (socket6
);
471 g_signal_emit (listener
, signals
[EVENT
], 0,
472 G_SOCKET_LISTENER_LISTENED
, socket6
);
475 g_object_set_qdata_full (G_OBJECT (socket6
), source_quark
,
476 g_object_ref (source_object
),
479 /* If this socket already speaks IPv4 then we are done. */
480 if (g_socket_speaks_ipv4 (socket6
))
481 need_ipv4_socket
= FALSE
;
484 if (need_ipv4_socket
)
485 /* We are here for exactly one of the following reasons:
487 * - our platform doesn't support IPv6
488 * - we successfully created an IPv6 socket but it's V6ONLY
490 * In either case, we need to go ahead and create an IPv4 socket
491 * and fail the call if we can't bind to it.
494 socket4
= g_socket_new (G_SOCKET_FAMILY_IPV4
,
495 G_SOCKET_TYPE_STREAM
,
496 G_SOCKET_PROTOCOL_DEFAULT
,
500 /* IPv4 is supported on this platform, so if we fail now it is
501 * a result of being unable to bind to our port. Don't fail
502 * silently as a result of this!
505 GInetAddress
*inet_address
;
506 GSocketAddress
*address
;
508 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV4
);
509 address
= g_inet_socket_address_new (inet_address
, port
);
510 g_object_unref (inet_address
);
512 g_socket_set_listen_backlog (socket4
,
513 listener
->priv
->listen_backlog
);
515 g_signal_emit (listener
, signals
[EVENT
], 0,
516 G_SOCKET_LISTENER_BINDING
, socket4
);
518 if (!g_socket_bind (socket4
, address
, TRUE
, error
))
520 g_object_unref (address
);
521 g_object_unref (socket4
);
523 g_object_unref (socket6
);
528 g_object_unref (address
);
530 g_signal_emit (listener
, signals
[EVENT
], 0,
531 G_SOCKET_LISTENER_BOUND
, socket4
);
532 g_signal_emit (listener
, signals
[EVENT
], 0,
533 G_SOCKET_LISTENER_LISTENING
, socket4
);
535 if (!g_socket_listen (socket4
, error
))
537 g_object_unref (socket4
);
539 g_object_unref (socket6
);
544 g_signal_emit (listener
, signals
[EVENT
], 0,
545 G_SOCKET_LISTENER_LISTENED
, socket4
);
548 g_object_set_qdata_full (G_OBJECT (socket4
), source_quark
,
549 g_object_ref (source_object
),
553 /* Ok. So IPv4 is not supported on this platform. If we
554 * succeeded at creating an IPv6 socket then that's OK, but
555 * otherwise we need to tell the user we failed.
559 g_clear_error (error
);
565 g_assert (socket6
!= NULL
|| socket4
!= NULL
);
568 g_ptr_array_add (listener
->priv
->sockets
, socket6
);
571 g_ptr_array_add (listener
->priv
->sockets
, socket4
);
573 if (G_SOCKET_LISTENER_GET_CLASS (listener
)->changed
)
574 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed (listener
);
580 add_sources (GSocketListener
*listener
,
581 GSocketSourceFunc callback
,
582 gpointer callback_data
,
583 GCancellable
*cancellable
,
584 GMainContext
*context
)
592 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
594 socket
= listener
->priv
->sockets
->pdata
[i
];
596 source
= g_socket_create_source (socket
, G_IO_IN
, cancellable
);
597 g_source_set_callback (source
,
598 (GSourceFunc
) callback
,
599 callback_data
, NULL
);
600 g_source_attach (source
, context
);
602 sources
= g_list_prepend (sources
, source
);
609 free_sources (GList
*sources
)
612 while (sources
!= NULL
)
614 source
= sources
->data
;
615 sources
= g_list_delete_link (sources
, sources
);
616 g_source_destroy (source
);
617 g_source_unref (source
);
627 accept_callback (GSocket
*socket
,
628 GIOCondition condition
,
631 struct AcceptData
*data
= user_data
;
633 data
->socket
= socket
;
634 g_main_loop_quit (data
->loop
);
640 * g_socket_listener_accept_socket:
641 * @listener: a #GSocketListener
642 * @source_object: (out) (transfer none) (optional): location where #GObject pointer will be stored, or %NULL.
643 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
644 * @error: #GError for error reporting, or %NULL to ignore.
646 * Blocks waiting for a client to connect to any of the sockets added
647 * to the listener. Returns the #GSocket that was accepted.
649 * If you want to accept the high-level #GSocketConnection, not a #GSocket,
650 * which is often the case, then you should use g_socket_listener_accept()
653 * If @source_object is not %NULL it will be filled out with the source
654 * object specified when the corresponding socket or address was added
657 * If @cancellable is not %NULL, then the operation can be cancelled by
658 * triggering the cancellable object from another thread. If the operation
659 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
661 * Returns: (transfer full): a #GSocket on success, %NULL on error.
666 g_socket_listener_accept_socket (GSocketListener
*listener
,
667 GObject
**source_object
,
668 GCancellable
*cancellable
,
671 GSocket
*accept_socket
, *socket
;
673 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener
), NULL
);
675 if (!check_listener (listener
, error
))
678 if (listener
->priv
->sockets
->len
== 1)
680 accept_socket
= listener
->priv
->sockets
->pdata
[0];
681 if (!g_socket_condition_wait (accept_socket
, G_IO_IN
,
688 struct AcceptData data
;
691 if (listener
->priv
->main_context
== NULL
)
692 listener
->priv
->main_context
= g_main_context_new ();
694 loop
= g_main_loop_new (listener
->priv
->main_context
, FALSE
);
696 sources
= add_sources (listener
,
700 listener
->priv
->main_context
);
701 g_main_loop_run (loop
);
702 accept_socket
= data
.socket
;
703 free_sources (sources
);
704 g_main_loop_unref (loop
);
707 if (!(socket
= g_socket_accept (accept_socket
, cancellable
, error
)))
711 *source_object
= g_object_get_qdata (G_OBJECT (accept_socket
), source_quark
);
717 * g_socket_listener_accept:
718 * @listener: a #GSocketListener
719 * @source_object: (out) (transfer none) (optional): location where #GObject pointer will be stored, or %NULL
720 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
721 * @error: #GError for error reporting, or %NULL to ignore.
723 * Blocks waiting for a client to connect to any of the sockets added
724 * to the listener. Returns a #GSocketConnection for the socket that was
727 * If @source_object is not %NULL it will be filled out with the source
728 * object specified when the corresponding socket or address was added
731 * If @cancellable is not %NULL, then the operation can be cancelled by
732 * triggering the cancellable object from another thread. If the operation
733 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
735 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
740 g_socket_listener_accept (GSocketListener
*listener
,
741 GObject
**source_object
,
742 GCancellable
*cancellable
,
745 GSocketConnection
*connection
;
748 socket
= g_socket_listener_accept_socket (listener
,
755 connection
= g_socket_connection_factory_create_connection (socket
);
756 g_object_unref (socket
);
762 accept_ready (GSocket
*accept_socket
,
763 GIOCondition condition
,
766 GTask
*task
= user_data
;
767 GError
*error
= NULL
;
769 GObject
*source_object
;
771 socket
= g_socket_accept (accept_socket
, g_task_get_cancellable (task
), &error
);
774 source_object
= g_object_get_qdata (G_OBJECT (accept_socket
), source_quark
);
776 g_object_set_qdata_full (G_OBJECT (task
),
778 g_object_ref (source_object
), g_object_unref
);
779 g_task_return_pointer (task
, socket
, g_object_unref
);
783 g_task_return_error (task
, error
);
786 g_object_unref (task
);
791 * g_socket_listener_accept_socket_async:
792 * @listener: a #GSocketListener
793 * @cancellable: (nullable): a #GCancellable, or %NULL
794 * @callback: (scope async): a #GAsyncReadyCallback
795 * @user_data: (closure): user data for the callback
797 * This is the asynchronous version of g_socket_listener_accept_socket().
799 * When the operation is finished @callback will be
800 * called. You can then call g_socket_listener_accept_socket_finish()
801 * to get the result of the operation.
806 g_socket_listener_accept_socket_async (GSocketListener
*listener
,
807 GCancellable
*cancellable
,
808 GAsyncReadyCallback callback
,
813 GError
*error
= NULL
;
815 task
= g_task_new (listener
, cancellable
, callback
, user_data
);
816 g_task_set_source_tag (task
, g_socket_listener_accept_socket_async
);
818 if (!check_listener (listener
, &error
))
820 g_task_return_error (task
, error
);
821 g_object_unref (task
);
825 sources
= add_sources (listener
,
829 g_main_context_get_thread_default ());
830 g_task_set_task_data (task
, sources
, (GDestroyNotify
) free_sources
);
834 * g_socket_listener_accept_socket_finish:
835 * @listener: a #GSocketListener
836 * @result: a #GAsyncResult.
837 * @source_object: (out) (transfer none) (optional): Optional #GObject identifying this source
838 * @error: a #GError location to store the error occurring, or %NULL to
841 * Finishes an async accept operation. See g_socket_listener_accept_socket_async()
843 * Returns: (transfer full): a #GSocket on success, %NULL on error.
848 g_socket_listener_accept_socket_finish (GSocketListener
*listener
,
849 GAsyncResult
*result
,
850 GObject
**source_object
,
853 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener
), NULL
);
854 g_return_val_if_fail (g_task_is_valid (result
, listener
), NULL
);
857 *source_object
= g_object_get_qdata (G_OBJECT (result
), source_quark
);
859 return g_task_propagate_pointer (G_TASK (result
), error
);
863 * g_socket_listener_accept_async:
864 * @listener: a #GSocketListener
865 * @cancellable: (nullable): a #GCancellable, or %NULL
866 * @callback: (scope async): a #GAsyncReadyCallback
867 * @user_data: (closure): user data for the callback
869 * This is the asynchronous version of g_socket_listener_accept().
871 * When the operation is finished @callback will be
872 * called. You can then call g_socket_listener_accept_socket()
873 * to get the result of the operation.
878 g_socket_listener_accept_async (GSocketListener
*listener
,
879 GCancellable
*cancellable
,
880 GAsyncReadyCallback callback
,
883 g_socket_listener_accept_socket_async (listener
,
890 * g_socket_listener_accept_finish:
891 * @listener: a #GSocketListener
892 * @result: a #GAsyncResult.
893 * @source_object: (out) (transfer none) (optional): Optional #GObject identifying this source
894 * @error: a #GError location to store the error occurring, or %NULL to
897 * Finishes an async accept operation. See g_socket_listener_accept_async()
899 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
904 g_socket_listener_accept_finish (GSocketListener
*listener
,
905 GAsyncResult
*result
,
906 GObject
**source_object
,
910 GSocketConnection
*connection
;
912 socket
= g_socket_listener_accept_socket_finish (listener
,
919 connection
= g_socket_connection_factory_create_connection (socket
);
920 g_object_unref (socket
);
925 * g_socket_listener_set_backlog:
926 * @listener: a #GSocketListener
927 * @listen_backlog: an integer
929 * Sets the listen backlog on the sockets in the listener.
931 * See g_socket_set_listen_backlog() for details
936 g_socket_listener_set_backlog (GSocketListener
*listener
,
942 if (listener
->priv
->closed
)
945 listener
->priv
->listen_backlog
= listen_backlog
;
947 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
949 socket
= listener
->priv
->sockets
->pdata
[i
];
950 g_socket_set_listen_backlog (socket
, listen_backlog
);
955 * g_socket_listener_close:
956 * @listener: a #GSocketListener
958 * Closes all the sockets in the listener.
963 g_socket_listener_close (GSocketListener
*listener
)
968 g_return_if_fail (G_IS_SOCKET_LISTENER (listener
));
970 if (listener
->priv
->closed
)
973 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
975 socket
= listener
->priv
->sockets
->pdata
[i
];
976 g_socket_close (socket
, NULL
);
978 listener
->priv
->closed
= TRUE
;
982 * g_socket_listener_add_any_inet_port:
983 * @listener: a #GSocketListener
984 * @source_object: (nullable): Optional #GObject identifying this source
985 * @error: a #GError location to store the error occurring, or %NULL to
988 * Listens for TCP connections on any available port number for both
989 * IPv6 and IPv4 (if each is available).
991 * This is useful if you need to have a socket for incoming connections
992 * but don't care about the specific port number.
994 * @source_object will be passed out in the various calls
995 * to accept to identify this particular source, which is
996 * useful if you're listening on multiple addresses and do
997 * different things depending on what address is connected to.
999 * Returns: the port number, or 0 in case of failure.
1004 g_socket_listener_add_any_inet_port (GSocketListener
*listener
,
1005 GObject
*source_object
,
1008 GSList
*sockets_to_close
= NULL
;
1009 guint16 candidate_port
= 0;
1010 GSocket
*socket6
= NULL
;
1011 GSocket
*socket4
= NULL
;
1015 * multi-step process:
1016 * - first, create an IPv6 socket.
1017 * - if that fails, create an IPv4 socket and bind it to port 0 and
1018 * that's it. no retries if that fails (why would it?).
1019 * - if our IPv6 socket also speaks IPv4 then we are done.
1020 * - if not, then we need to create a IPv4 socket with the same port
1021 * number. this might fail, of course. so we try this a bunch of
1022 * times -- leaving the old IPv6 sockets open so that we get a
1023 * different port number to try each time.
1024 * - if all that fails then just give up.
1029 GInetAddress
*inet_address
;
1030 GSocketAddress
*address
;
1033 g_assert (socket6
== NULL
);
1034 socket6
= g_socket_new (G_SOCKET_FAMILY_IPV6
,
1035 G_SOCKET_TYPE_STREAM
,
1036 G_SOCKET_PROTOCOL_DEFAULT
,
1039 if (socket6
!= NULL
)
1041 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV6
);
1042 address
= g_inet_socket_address_new (inet_address
, 0);
1043 g_object_unref (inet_address
);
1045 g_signal_emit (listener
, signals
[EVENT
], 0,
1046 G_SOCKET_LISTENER_BINDING
, socket6
);
1048 result
= g_socket_bind (socket6
, address
, TRUE
, error
);
1049 g_object_unref (address
);
1052 !(address
= g_socket_get_local_address (socket6
, error
)))
1054 g_object_unref (socket6
);
1059 g_signal_emit (listener
, signals
[EVENT
], 0,
1060 G_SOCKET_LISTENER_BOUND
, socket6
);
1062 g_assert (G_IS_INET_SOCKET_ADDRESS (address
));
1064 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address
));
1065 g_assert (candidate_port
!= 0);
1066 g_object_unref (address
);
1068 if (g_socket_speaks_ipv4 (socket6
))
1072 g_assert (socket4
== NULL
);
1073 socket4
= g_socket_new (G_SOCKET_FAMILY_IPV4
,
1074 G_SOCKET_TYPE_STREAM
,
1075 G_SOCKET_PROTOCOL_DEFAULT
,
1076 socket6
? NULL
: error
);
1078 if (socket4
== NULL
)
1079 /* IPv4 not supported.
1080 * if IPv6 is supported then candidate_port will be non-zero
1081 * (and the error parameter above will have been NULL)
1082 * if IPv6 is unsupported then candidate_port will be zero
1083 * (and error will have been set by the above call)
1087 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV4
);
1088 address
= g_inet_socket_address_new (inet_address
, candidate_port
);
1089 g_object_unref (inet_address
);
1091 g_signal_emit (listener
, signals
[EVENT
], 0,
1092 G_SOCKET_LISTENER_BINDING
, socket4
);
1094 /* a note on the 'error' clause below:
1096 * if candidate_port is 0 then we report the error right away
1097 * since it is strange that this binding would fail at all.
1098 * otherwise, we ignore the error message (ie: NULL).
1100 * the exception to this rule is the last time through the loop
1101 * (ie: attempts == 0) in which case we want to set the error
1102 * because failure here means that the entire call will fail and
1103 * we need something to show to the user.
1105 * an english summary of the situation: "if we gave a candidate
1106 * port number AND we have more attempts to try, then ignore the
1109 result
= g_socket_bind (socket4
, address
, TRUE
,
1110 (candidate_port
&& attempts
) ? NULL
: error
);
1111 g_object_unref (address
);
1115 g_assert (socket6
!= NULL
);
1118 /* got our candidate port successfully */
1120 g_signal_emit (listener
, signals
[EVENT
], 0,
1121 G_SOCKET_LISTENER_BOUND
, socket4
);
1125 /* we failed to bind to the specified port. try again. */
1127 g_object_unref (socket4
);
1130 /* keep this open so we get a different port number */
1131 sockets_to_close
= g_slist_prepend (sockets_to_close
,
1138 /* we didn't tell it a port. this means two things.
1139 * - if we failed, then something really bad happened.
1140 * - if we succeeded, then we need to find out the port number.
1143 g_assert (socket6
== NULL
);
1146 !(address
= g_socket_get_local_address (socket4
, error
)))
1148 g_object_unref (socket4
);
1153 g_signal_emit (listener
, signals
[EVENT
], 0,
1154 G_SOCKET_LISTENER_BOUND
, socket4
);
1156 g_assert (G_IS_INET_SOCKET_ADDRESS (address
));
1158 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address
));
1159 g_assert (candidate_port
!= 0);
1160 g_object_unref (address
);
1165 /* should only be non-zero if we have a socket */
1166 g_assert ((candidate_port
!= 0) == (socket4
|| socket6
));
1168 while (sockets_to_close
)
1170 g_object_unref (sockets_to_close
->data
);
1171 sockets_to_close
= g_slist_delete_link (sockets_to_close
,
1175 /* now we actually listen() the sockets and add them to the listener */
1176 if (socket6
!= NULL
)
1178 g_socket_set_listen_backlog (socket6
, listener
->priv
->listen_backlog
);
1180 g_signal_emit (listener
, signals
[EVENT
], 0,
1181 G_SOCKET_LISTENER_LISTENING
, socket6
);
1183 if (!g_socket_listen (socket6
, error
))
1185 g_object_unref (socket6
);
1187 g_object_unref (socket4
);
1192 g_signal_emit (listener
, signals
[EVENT
], 0,
1193 G_SOCKET_LISTENER_LISTENED
, socket6
);
1196 g_object_set_qdata_full (G_OBJECT (socket6
), source_quark
,
1197 g_object_ref (source_object
),
1200 g_ptr_array_add (listener
->priv
->sockets
, socket6
);
1203 if (socket4
!= NULL
)
1205 g_socket_set_listen_backlog (socket4
, listener
->priv
->listen_backlog
);
1207 g_signal_emit (listener
, signals
[EVENT
], 0,
1208 G_SOCKET_LISTENER_LISTENING
, socket4
);
1210 if (!g_socket_listen (socket4
, error
))
1212 g_object_unref (socket4
);
1214 g_object_unref (socket6
);
1219 g_signal_emit (listener
, signals
[EVENT
], 0,
1220 G_SOCKET_LISTENER_LISTENED
, socket4
);
1223 g_object_set_qdata_full (G_OBJECT (socket4
), source_quark
,
1224 g_object_ref (source_object
),
1227 g_ptr_array_add (listener
->priv
->sockets
, socket4
);
1230 if ((socket4
!= NULL
|| socket6
!= NULL
) &&
1231 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed
)
1232 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed (listener
);
1234 return candidate_port
;