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/gtask.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>
43 * SECTION:gsocketlistener
44 * @title: GSocketListener
45 * @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.
66 static GQuark source_quark
= 0;
68 struct _GSocketListenerPrivate
71 GMainContext
*main_context
;
76 G_DEFINE_TYPE_WITH_PRIVATE (GSocketListener
, g_socket_listener
, G_TYPE_OBJECT
)
79 g_socket_listener_finalize (GObject
*object
)
81 GSocketListener
*listener
= G_SOCKET_LISTENER (object
);
83 if (listener
->priv
->main_context
)
84 g_main_context_unref (listener
->priv
->main_context
);
86 if (!listener
->priv
->closed
)
87 g_socket_listener_close (listener
);
89 g_ptr_array_free (listener
->priv
->sockets
, TRUE
);
91 G_OBJECT_CLASS (g_socket_listener_parent_class
)
96 g_socket_listener_get_property (GObject
*object
,
101 GSocketListener
*listener
= G_SOCKET_LISTENER (object
);
105 case PROP_LISTEN_BACKLOG
:
106 g_value_set_int (value
, listener
->priv
->listen_backlog
);
110 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
115 g_socket_listener_set_property (GObject
*object
,
120 GSocketListener
*listener
= G_SOCKET_LISTENER (object
);
124 case PROP_LISTEN_BACKLOG
:
125 g_socket_listener_set_backlog (listener
, g_value_get_int (value
));
129 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
135 g_socket_listener_class_init (GSocketListenerClass
*klass
)
137 GObjectClass
*gobject_class G_GNUC_UNUSED
= G_OBJECT_CLASS (klass
);
139 gobject_class
->finalize
= g_socket_listener_finalize
;
140 gobject_class
->set_property
= g_socket_listener_set_property
;
141 gobject_class
->get_property
= g_socket_listener_get_property
;
142 g_object_class_install_property (gobject_class
, PROP_LISTEN_BACKLOG
,
143 g_param_spec_int ("listen-backlog",
144 P_("Listen backlog"),
145 P_("outstanding connections in the listen queue"),
149 G_PARAM_CONSTRUCT
| G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
));
151 source_quark
= g_quark_from_static_string ("g-socket-listener-source");
155 g_socket_listener_init (GSocketListener
*listener
)
157 listener
->priv
= g_socket_listener_get_instance_private (listener
);
158 listener
->priv
->sockets
=
159 g_ptr_array_new_with_free_func ((GDestroyNotify
) g_object_unref
);
160 listener
->priv
->listen_backlog
= 10;
164 * g_socket_listener_new:
166 * Creates a new #GSocketListener with no sockets to listen for.
167 * New listeners can be added with e.g. g_socket_listener_add_address()
168 * or g_socket_listener_add_inet_port().
170 * Returns: a new #GSocketListener.
175 g_socket_listener_new (void)
177 return g_object_new (G_TYPE_SOCKET_LISTENER
, NULL
);
181 check_listener (GSocketListener
*listener
,
184 if (listener
->priv
->closed
)
186 g_set_error_literal (error
, G_IO_ERROR
, G_IO_ERROR_CLOSED
,
187 _("Listener is already closed"));
195 * g_socket_listener_add_socket:
196 * @listener: a #GSocketListener
197 * @socket: a listening #GSocket
198 * @source_object: (allow-none): Optional #GObject identifying this source
199 * @error: #GError for error reporting, or %NULL to ignore.
201 * Adds @socket to the set of sockets that we try to accept
202 * new clients from. The socket must be bound to a local
203 * address and listened to.
205 * @source_object will be passed out in the various calls
206 * to accept to identify this particular source, which is
207 * useful if you're listening on multiple addresses and do
208 * different things depending on what address is connected to.
210 * Returns: %TRUE on success, %FALSE on error.
215 g_socket_listener_add_socket (GSocketListener
*listener
,
217 GObject
*source_object
,
220 if (!check_listener (listener
, error
))
223 /* TODO: Check that socket it is bound & not closed? */
225 if (g_socket_is_closed (socket
))
227 g_set_error_literal (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
228 _("Added socket is closed"));
232 g_object_ref (socket
);
233 g_ptr_array_add (listener
->priv
->sockets
, socket
);
236 g_object_set_qdata_full (G_OBJECT (socket
), source_quark
,
237 g_object_ref (source_object
), g_object_unref
);
240 if (G_SOCKET_LISTENER_GET_CLASS (listener
)->changed
)
241 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed (listener
);
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: (allow-none): Optional #GObject identifying this source
253 * @effective_address: (out) (allow-none): location to store the address that was bound to, or %NULL.
254 * @error: #GError for error reporting, or %NULL to ignore.
256 * Creates a socket of type @type and protocol @protocol, binds
257 * it to @address and adds it to the set of sockets we're accepting
260 * Note that adding an IPv6 address, depending on the platform,
261 * may or may not result in a listener that also accepts IPv4
262 * connections. For more deterministic behavior, see
263 * g_socket_listener_add_inet_port().
265 * @source_object will be passed out in the various calls
266 * to accept to identify this particular source, which is
267 * useful if you're listening on multiple addresses and do
268 * different things depending on what address is connected to.
270 * If successful and @effective_address is non-%NULL then it will
271 * be set to the address that the binding actually occurred at. This
272 * is helpful for determining the port number that was used for when
273 * requesting a binding to port 0 (ie: "any port"). This address, if
274 * requested, belongs to the caller and must be freed.
276 * Returns: %TRUE on success, %FALSE on error.
281 g_socket_listener_add_address (GSocketListener
*listener
,
282 GSocketAddress
*address
,
284 GSocketProtocol protocol
,
285 GObject
*source_object
,
286 GSocketAddress
**effective_address
,
289 GSocketAddress
*local_address
;
290 GSocketFamily family
;
293 if (!check_listener (listener
, error
))
296 family
= g_socket_address_get_family (address
);
297 socket
= g_socket_new (family
, type
, protocol
, error
);
301 g_socket_set_listen_backlog (socket
, listener
->priv
->listen_backlog
);
303 if (!g_socket_bind (socket
, address
, TRUE
, error
) ||
304 !g_socket_listen (socket
, error
))
306 g_object_unref (socket
);
310 local_address
= NULL
;
311 if (effective_address
)
313 local_address
= g_socket_get_local_address (socket
, error
);
314 if (local_address
== NULL
)
316 g_object_unref (socket
);
321 if (!g_socket_listener_add_socket (listener
, socket
,
326 g_object_unref (local_address
);
327 g_object_unref (socket
);
331 if (effective_address
)
332 *effective_address
= local_address
;
334 g_object_unref (socket
); /* add_socket refs this */
340 * g_socket_listener_add_inet_port:
341 * @listener: a #GSocketListener
342 * @port: an IP port number (non-zero)
343 * @source_object: (allow-none): Optional #GObject identifying this source
344 * @error: #GError for error reporting, or %NULL to ignore.
346 * Helper function for g_socket_listener_add_address() that
347 * creates a TCP/IP socket listening on IPv4 and IPv6 (if
348 * supported) on the specified port on all interfaces.
350 * @source_object will be passed out in the various calls
351 * to accept to identify this particular source, which is
352 * useful if you're listening on multiple addresses and do
353 * different things depending on what address is connected to.
355 * Returns: %TRUE on success, %FALSE on error.
360 g_socket_listener_add_inet_port (GSocketListener
*listener
,
362 GObject
*source_object
,
365 gboolean need_ipv4_socket
= TRUE
;
366 GSocket
*socket4
= NULL
;
369 g_return_val_if_fail (listener
!= NULL
, FALSE
);
370 g_return_val_if_fail (port
!= 0, FALSE
);
372 if (!check_listener (listener
, error
))
375 /* first try to create an IPv6 socket */
376 socket6
= g_socket_new (G_SOCKET_FAMILY_IPV6
,
377 G_SOCKET_TYPE_STREAM
,
378 G_SOCKET_PROTOCOL_DEFAULT
,
382 /* IPv6 is supported on this platform, so if we fail now it is
383 * a result of being unable to bind to our port. Don't fail
384 * silently as a result of this!
387 GInetAddress
*inet_address
;
388 GSocketAddress
*address
;
391 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV6
);
392 address
= g_inet_socket_address_new (inet_address
, port
);
393 g_object_unref (inet_address
);
395 g_socket_set_listen_backlog (socket6
, listener
->priv
->listen_backlog
);
397 result
= g_socket_bind (socket6
, address
, TRUE
, error
) &&
398 g_socket_listen (socket6
, error
);
400 g_object_unref (address
);
404 g_object_unref (socket6
);
410 g_object_set_qdata_full (G_OBJECT (socket6
), source_quark
,
411 g_object_ref (source_object
),
414 /* If this socket already speaks IPv4 then we are done. */
415 if (g_socket_speaks_ipv4 (socket6
))
416 need_ipv4_socket
= FALSE
;
419 if (need_ipv4_socket
)
420 /* We are here for exactly one of the following reasons:
422 * - our platform doesn't support IPv6
423 * - we successfully created an IPv6 socket but it's V6ONLY
425 * In either case, we need to go ahead and create an IPv4 socket
426 * and fail the call if we can't bind to it.
429 socket4
= g_socket_new (G_SOCKET_FAMILY_IPV4
,
430 G_SOCKET_TYPE_STREAM
,
431 G_SOCKET_PROTOCOL_DEFAULT
,
435 /* IPv4 is supported on this platform, so if we fail now it is
436 * a result of being unable to bind to our port. Don't fail
437 * silently as a result of this!
440 GInetAddress
*inet_address
;
441 GSocketAddress
*address
;
444 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV4
);
445 address
= g_inet_socket_address_new (inet_address
, port
);
446 g_object_unref (inet_address
);
448 g_socket_set_listen_backlog (socket4
,
449 listener
->priv
->listen_backlog
);
451 result
= g_socket_bind (socket4
, address
, TRUE
, error
) &&
452 g_socket_listen (socket4
, error
);
454 g_object_unref (address
);
458 g_object_unref (socket4
);
461 g_object_unref (socket6
);
467 g_object_set_qdata_full (G_OBJECT (socket4
), source_quark
,
468 g_object_ref (source_object
),
472 /* Ok. So IPv4 is not supported on this platform. If we
473 * succeeded at creating an IPv6 socket then that's OK, but
474 * otherwise we need to tell the user we failed.
478 g_clear_error (error
);
484 g_assert (socket6
!= NULL
|| socket4
!= NULL
);
487 g_ptr_array_add (listener
->priv
->sockets
, socket6
);
490 g_ptr_array_add (listener
->priv
->sockets
, socket4
);
492 if (G_SOCKET_LISTENER_GET_CLASS (listener
)->changed
)
493 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed (listener
);
499 add_sources (GSocketListener
*listener
,
500 GSocketSourceFunc callback
,
501 gpointer callback_data
,
502 GCancellable
*cancellable
,
503 GMainContext
*context
)
511 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
513 socket
= listener
->priv
->sockets
->pdata
[i
];
515 source
= g_socket_create_source (socket
, G_IO_IN
, cancellable
);
516 g_source_set_callback (source
,
517 (GSourceFunc
) callback
,
518 callback_data
, NULL
);
519 g_source_attach (source
, context
);
521 sources
= g_list_prepend (sources
, source
);
528 free_sources (GList
*sources
)
531 while (sources
!= NULL
)
533 source
= sources
->data
;
534 sources
= g_list_delete_link (sources
, sources
);
535 g_source_destroy (source
);
536 g_source_unref (source
);
546 accept_callback (GSocket
*socket
,
547 GIOCondition condition
,
550 struct AcceptData
*data
= user_data
;
552 data
->socket
= socket
;
553 g_main_loop_quit (data
->loop
);
559 * g_socket_listener_accept_socket:
560 * @listener: a #GSocketListener
561 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL.
562 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
563 * @error: #GError for error reporting, or %NULL to ignore.
565 * Blocks waiting for a client to connect to any of the sockets added
566 * to the listener. Returns the #GSocket that was accepted.
568 * If you want to accept the high-level #GSocketConnection, not a #GSocket,
569 * which is often the case, then you should use g_socket_listener_accept()
572 * If @source_object is not %NULL it will be filled out with the source
573 * object specified when the corresponding socket or address was added
576 * If @cancellable is not %NULL, then the operation can be cancelled by
577 * triggering the cancellable object from another thread. If the operation
578 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
580 * Returns: (transfer full): a #GSocket on success, %NULL on error.
585 g_socket_listener_accept_socket (GSocketListener
*listener
,
586 GObject
**source_object
,
587 GCancellable
*cancellable
,
590 GSocket
*accept_socket
, *socket
;
592 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener
), NULL
);
594 if (!check_listener (listener
, error
))
597 if (listener
->priv
->sockets
->len
== 1)
599 accept_socket
= listener
->priv
->sockets
->pdata
[0];
600 if (!g_socket_condition_wait (accept_socket
, G_IO_IN
,
607 struct AcceptData data
;
610 if (listener
->priv
->main_context
== NULL
)
611 listener
->priv
->main_context
= g_main_context_new ();
613 loop
= g_main_loop_new (listener
->priv
->main_context
, FALSE
);
615 sources
= add_sources (listener
,
619 listener
->priv
->main_context
);
620 g_main_loop_run (loop
);
621 accept_socket
= data
.socket
;
622 free_sources (sources
);
623 g_main_loop_unref (loop
);
626 if (!(socket
= g_socket_accept (accept_socket
, cancellable
, error
)))
630 *source_object
= g_object_get_qdata (G_OBJECT (accept_socket
), source_quark
);
636 * g_socket_listener_accept:
637 * @listener: a #GSocketListener
638 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL
639 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
640 * @error: #GError for error reporting, or %NULL to ignore.
642 * Blocks waiting for a client to connect to any of the sockets added
643 * to the listener. Returns a #GSocketConnection for the socket that was
646 * If @source_object is not %NULL it will be filled out with the source
647 * object specified when the corresponding socket or address was added
650 * If @cancellable is not %NULL, then the operation can be cancelled by
651 * triggering the cancellable object from another thread. If the operation
652 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
654 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
659 g_socket_listener_accept (GSocketListener
*listener
,
660 GObject
**source_object
,
661 GCancellable
*cancellable
,
664 GSocketConnection
*connection
;
667 socket
= g_socket_listener_accept_socket (listener
,
674 connection
= g_socket_connection_factory_create_connection (socket
);
675 g_object_unref (socket
);
681 accept_ready (GSocket
*accept_socket
,
682 GIOCondition condition
,
685 GTask
*task
= user_data
;
686 GError
*error
= NULL
;
688 GObject
*source_object
;
690 socket
= g_socket_accept (accept_socket
, g_task_get_cancellable (task
), &error
);
693 source_object
= g_object_get_qdata (G_OBJECT (accept_socket
), source_quark
);
695 g_object_set_qdata_full (G_OBJECT (task
),
697 g_object_ref (source_object
), g_object_unref
);
698 g_task_return_pointer (task
, socket
, g_object_unref
);
702 g_task_return_error (task
, error
);
705 g_object_unref (task
);
710 * g_socket_listener_accept_socket_async:
711 * @listener: a #GSocketListener
712 * @cancellable: (allow-none): a #GCancellable, or %NULL
713 * @callback: (scope async): a #GAsyncReadyCallback
714 * @user_data: (closure): user data for the callback
716 * This is the asynchronous version of g_socket_listener_accept_socket().
718 * When the operation is finished @callback will be
719 * called. You can then call g_socket_listener_accept_socket_finish()
720 * to get the result of the operation.
725 g_socket_listener_accept_socket_async (GSocketListener
*listener
,
726 GCancellable
*cancellable
,
727 GAsyncReadyCallback callback
,
732 GError
*error
= NULL
;
734 task
= g_task_new (listener
, cancellable
, callback
, user_data
);
736 if (!check_listener (listener
, &error
))
738 g_task_return_error (task
, error
);
739 g_object_unref (task
);
743 sources
= add_sources (listener
,
747 g_main_context_get_thread_default ());
748 g_task_set_task_data (task
, sources
, (GDestroyNotify
) free_sources
);
752 * g_socket_listener_accept_socket_finish:
753 * @listener: a #GSocketListener
754 * @result: a #GAsyncResult.
755 * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
756 * @error: a #GError location to store the error occurring, or %NULL to
759 * Finishes an async accept operation. See g_socket_listener_accept_socket_async()
761 * Returns: (transfer full): a #GSocket on success, %NULL on error.
766 g_socket_listener_accept_socket_finish (GSocketListener
*listener
,
767 GAsyncResult
*result
,
768 GObject
**source_object
,
771 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener
), NULL
);
772 g_return_val_if_fail (g_task_is_valid (result
, listener
), NULL
);
775 *source_object
= g_object_get_qdata (G_OBJECT (result
), source_quark
);
777 return g_task_propagate_pointer (G_TASK (result
), error
);
781 * g_socket_listener_accept_async:
782 * @listener: a #GSocketListener
783 * @cancellable: (allow-none): a #GCancellable, or %NULL
784 * @callback: (scope async): a #GAsyncReadyCallback
785 * @user_data: (closure): user data for the callback
787 * This is the asynchronous version of g_socket_listener_accept().
789 * When the operation is finished @callback will be
790 * called. You can then call g_socket_listener_accept_socket()
791 * to get the result of the operation.
796 g_socket_listener_accept_async (GSocketListener
*listener
,
797 GCancellable
*cancellable
,
798 GAsyncReadyCallback callback
,
801 g_socket_listener_accept_socket_async (listener
,
808 * g_socket_listener_accept_finish:
809 * @listener: a #GSocketListener
810 * @result: a #GAsyncResult.
811 * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
812 * @error: a #GError location to store the error occurring, or %NULL to
815 * Finishes an async accept operation. See g_socket_listener_accept_async()
817 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
822 g_socket_listener_accept_finish (GSocketListener
*listener
,
823 GAsyncResult
*result
,
824 GObject
**source_object
,
828 GSocketConnection
*connection
;
830 socket
= g_socket_listener_accept_socket_finish (listener
,
837 connection
= g_socket_connection_factory_create_connection (socket
);
838 g_object_unref (socket
);
843 * g_socket_listener_set_backlog:
844 * @listener: a #GSocketListener
845 * @listen_backlog: an integer
847 * Sets the listen backlog on the sockets in the listener.
849 * See g_socket_set_listen_backlog() for details
854 g_socket_listener_set_backlog (GSocketListener
*listener
,
860 if (listener
->priv
->closed
)
863 listener
->priv
->listen_backlog
= listen_backlog
;
865 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
867 socket
= listener
->priv
->sockets
->pdata
[i
];
868 g_socket_set_listen_backlog (socket
, listen_backlog
);
873 * g_socket_listener_close:
874 * @listener: a #GSocketListener
876 * Closes all the sockets in the listener.
881 g_socket_listener_close (GSocketListener
*listener
)
886 g_return_if_fail (G_IS_SOCKET_LISTENER (listener
));
888 if (listener
->priv
->closed
)
891 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
893 socket
= listener
->priv
->sockets
->pdata
[i
];
894 g_socket_close (socket
, NULL
);
896 listener
->priv
->closed
= TRUE
;
900 * g_socket_listener_add_any_inet_port:
901 * @listener: a #GSocketListener
902 * @source_object: (allow-none): Optional #GObject identifying this source
903 * @error: a #GError location to store the error occurring, or %NULL to
906 * Listens for TCP connections on any available port number for both
907 * IPv6 and IPv4 (if each is available).
909 * This is useful if you need to have a socket for incoming connections
910 * but don't care about the specific port number.
912 * @source_object will be passed out in the various calls
913 * to accept to identify this particular source, which is
914 * useful if you're listening on multiple addresses and do
915 * different things depending on what address is connected to.
917 * Returns: the port number, or 0 in case of failure.
922 g_socket_listener_add_any_inet_port (GSocketListener
*listener
,
923 GObject
*source_object
,
926 GSList
*sockets_to_close
= NULL
;
927 guint16 candidate_port
= 0;
928 GSocket
*socket6
= NULL
;
929 GSocket
*socket4
= NULL
;
933 * multi-step process:
934 * - first, create an IPv6 socket.
935 * - if that fails, create an IPv4 socket and bind it to port 0 and
936 * that's it. no retries if that fails (why would it?).
937 * - if our IPv6 socket also speaks IPv4 then we are done.
938 * - if not, then we need to create a IPv4 socket with the same port
939 * number. this might fail, of course. so we try this a bunch of
940 * times -- leaving the old IPv6 sockets open so that we get a
941 * different port number to try each time.
942 * - if all that fails then just give up.
947 GInetAddress
*inet_address
;
948 GSocketAddress
*address
;
951 g_assert (socket6
== NULL
);
952 socket6
= g_socket_new (G_SOCKET_FAMILY_IPV6
,
953 G_SOCKET_TYPE_STREAM
,
954 G_SOCKET_PROTOCOL_DEFAULT
,
959 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV6
);
960 address
= g_inet_socket_address_new (inet_address
, 0);
961 g_object_unref (inet_address
);
962 result
= g_socket_bind (socket6
, address
, TRUE
, error
);
963 g_object_unref (address
);
966 !(address
= g_socket_get_local_address (socket6
, error
)))
968 g_object_unref (socket6
);
973 g_assert (G_IS_INET_SOCKET_ADDRESS (address
));
975 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address
));
976 g_assert (candidate_port
!= 0);
977 g_object_unref (address
);
979 if (g_socket_speaks_ipv4 (socket6
))
983 g_assert (socket4
== NULL
);
984 socket4
= g_socket_new (G_SOCKET_FAMILY_IPV4
,
985 G_SOCKET_TYPE_STREAM
,
986 G_SOCKET_PROTOCOL_DEFAULT
,
987 socket6
? NULL
: error
);
990 /* IPv4 not supported.
991 * if IPv6 is supported then candidate_port will be non-zero
992 * (and the error parameter above will have been NULL)
993 * if IPv6 is unsupported then candidate_port will be zero
994 * (and error will have been set by the above call)
998 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV4
);
999 address
= g_inet_socket_address_new (inet_address
, candidate_port
);
1000 g_object_unref (inet_address
);
1001 /* a note on the 'error' clause below:
1003 * if candidate_port is 0 then we report the error right away
1004 * since it is strange that this binding would fail at all.
1005 * otherwise, we ignore the error message (ie: NULL).
1007 * the exception to this rule is the last time through the loop
1008 * (ie: attempts == 0) in which case we want to set the error
1009 * because failure here means that the entire call will fail and
1010 * we need something to show to the user.
1012 * an english summary of the situation: "if we gave a candidate
1013 * port number AND we have more attempts to try, then ignore the
1016 result
= g_socket_bind (socket4
, address
, TRUE
,
1017 (candidate_port
&& attempts
) ? NULL
: error
);
1018 g_object_unref (address
);
1022 g_assert (socket6
!= NULL
);
1025 /* got our candidate port successfully */
1029 /* we failed to bind to the specified port. try again. */
1031 g_object_unref (socket4
);
1034 /* keep this open so we get a different port number */
1035 sockets_to_close
= g_slist_prepend (sockets_to_close
,
1042 /* we didn't tell it a port. this means two things.
1043 * - if we failed, then something really bad happened.
1044 * - if we succeeded, then we need to find out the port number.
1047 g_assert (socket6
== NULL
);
1050 !(address
= g_socket_get_local_address (socket4
, error
)))
1052 g_object_unref (socket4
);
1057 g_assert (G_IS_INET_SOCKET_ADDRESS (address
));
1059 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address
));
1060 g_assert (candidate_port
!= 0);
1061 g_object_unref (address
);
1066 /* should only be non-zero if we have a socket */
1067 g_assert ((candidate_port
!= 0) == (socket4
|| socket6
));
1069 while (sockets_to_close
)
1071 g_object_unref (sockets_to_close
->data
);
1072 sockets_to_close
= g_slist_delete_link (sockets_to_close
,
1076 /* now we actually listen() the sockets and add them to the listener */
1077 if (socket6
!= NULL
)
1079 g_socket_set_listen_backlog (socket6
, listener
->priv
->listen_backlog
);
1080 if (!g_socket_listen (socket6
, error
))
1082 g_object_unref (socket6
);
1084 g_object_unref (socket4
);
1090 g_object_set_qdata_full (G_OBJECT (socket6
), source_quark
,
1091 g_object_ref (source_object
),
1094 g_ptr_array_add (listener
->priv
->sockets
, socket6
);
1097 if (socket4
!= NULL
)
1099 g_socket_set_listen_backlog (socket4
, listener
->priv
->listen_backlog
);
1100 if (!g_socket_listen (socket4
, error
))
1102 g_object_unref (socket4
);
1104 g_object_unref (socket6
);
1110 g_object_set_qdata_full (G_OBJECT (socket4
), source_quark
,
1111 g_object_ref (source_object
),
1114 g_ptr_array_add (listener
->priv
->sockets
, socket4
);
1117 if ((socket4
!= NULL
|| socket6
!= NULL
) &&
1118 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed
)
1119 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed (listener
);
1121 return candidate_port
;