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>
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.
59 G_DEFINE_TYPE (GSocketListener
, g_socket_listener
, G_TYPE_OBJECT
);
68 static GQuark source_quark
= 0;
70 struct _GSocketListenerPrivate
73 GMainContext
*main_context
;
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 g_type_class_add_private (klass
, sizeof (GSocketListenerPrivate
));
141 gobject_class
->finalize
= g_socket_listener_finalize
;
142 gobject_class
->set_property
= g_socket_listener_set_property
;
143 gobject_class
->get_property
= g_socket_listener_get_property
;
144 g_object_class_install_property (gobject_class
, PROP_LISTEN_BACKLOG
,
145 g_param_spec_int ("listen-backlog",
146 P_("Listen backlog"),
147 P_("outstanding connections in the listen queue"),
151 G_PARAM_CONSTRUCT
| G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
));
153 source_quark
= g_quark_from_static_string ("g-socket-listener-source");
157 g_socket_listener_init (GSocketListener
*listener
)
159 listener
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (listener
,
160 G_TYPE_SOCKET_LISTENER
,
161 GSocketListenerPrivate
);
162 listener
->priv
->sockets
=
163 g_ptr_array_new_with_free_func ((GDestroyNotify
) g_object_unref
);
164 listener
->priv
->listen_backlog
= 10;
168 * g_socket_listener_new:
170 * Creates a new #GSocketListener with no sockets to listen for.
171 * New listeners can be added with e.g. g_socket_listener_add_address()
172 * or g_socket_listener_add_inet_port().
174 * Returns: a new #GSocketListener.
179 g_socket_listener_new (void)
181 return g_object_new (G_TYPE_SOCKET_LISTENER
, NULL
);
185 check_listener (GSocketListener
*listener
,
188 if (listener
->priv
->closed
)
190 g_set_error_literal (error
, G_IO_ERROR
, G_IO_ERROR_CLOSED
,
191 _("Listener is already closed"));
199 * g_socket_listener_add_socket:
200 * @listener: a #GSocketListener
201 * @socket: a listening #GSocket
202 * @source_object: (allow-none): Optional #GObject identifying this source
203 * @error: #GError for error reporting, or %NULL to ignore.
205 * Adds @socket to the set of sockets that we try to accept
206 * new clients from. The socket must be bound to a local
207 * address and listened to.
209 * @source_object will be passed out in the various calls
210 * to accept to identify this particular source, which is
211 * useful if you're listening on multiple addresses and do
212 * different things depending on what address is connected to.
214 * Returns: %TRUE on success, %FALSE on error.
219 g_socket_listener_add_socket (GSocketListener
*listener
,
221 GObject
*source_object
,
224 if (!check_listener (listener
, error
))
227 /* TODO: Check that socket it is bound & not closed? */
229 if (g_socket_is_closed (socket
))
231 g_set_error_literal (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
232 _("Added socket is closed"));
236 g_object_ref (socket
);
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
);
244 if (G_SOCKET_LISTENER_GET_CLASS (listener
)->changed
)
245 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed (listener
);
251 * g_socket_listener_add_address:
252 * @listener: a #GSocketListener
253 * @address: a #GSocketAddress
254 * @type: a #GSocketType
255 * @protocol: a #GSocketProtocol
256 * @source_object: (allow-none): Optional #GObject identifying this source
257 * @effective_address: (out) (allow-none): location to store the address that was bound to, or %NULL.
258 * @error: #GError for error reporting, or %NULL to ignore.
260 * Creates a socket of type @type and protocol @protocol, binds
261 * it to @address and adds it to the set of sockets we're accepting
264 * Note that adding an IPv6 address, depending on the platform,
265 * may or may not result in a listener that also accepts IPv4
266 * connections. For more deterministic behavior, see
267 * g_socket_listener_add_inet_port().
269 * @source_object will be passed out in the various calls
270 * to accept to identify this particular source, which is
271 * useful if you're listening on multiple addresses and do
272 * different things depending on what address is connected to.
274 * If successful and @effective_address is non-%NULL then it will
275 * be set to the address that the binding actually occurred at. This
276 * is helpful for determining the port number that was used for when
277 * requesting a binding to port 0 (ie: "any port"). This address, if
278 * requested, belongs to the caller and must be freed.
280 * Returns: %TRUE on success, %FALSE on error.
285 g_socket_listener_add_address (GSocketListener
*listener
,
286 GSocketAddress
*address
,
288 GSocketProtocol protocol
,
289 GObject
*source_object
,
290 GSocketAddress
**effective_address
,
293 GSocketAddress
*local_address
;
294 GSocketFamily family
;
297 if (!check_listener (listener
, error
))
300 family
= g_socket_address_get_family (address
);
301 socket
= g_socket_new (family
, type
, protocol
, error
);
305 g_socket_set_listen_backlog (socket
, listener
->priv
->listen_backlog
);
307 if (!g_socket_bind (socket
, address
, TRUE
, error
) ||
308 !g_socket_listen (socket
, error
))
310 g_object_unref (socket
);
314 local_address
= NULL
;
315 if (effective_address
)
317 local_address
= g_socket_get_local_address (socket
, error
);
318 if (local_address
== NULL
)
320 g_object_unref (socket
);
325 if (!g_socket_listener_add_socket (listener
, socket
,
330 g_object_unref (local_address
);
331 g_object_unref (socket
);
335 if (effective_address
)
336 *effective_address
= local_address
;
338 g_object_unref (socket
); /* add_socket refs this */
344 * g_socket_listener_add_inet_port:
345 * @listener: a #GSocketListener
346 * @port: an IP port number (non-zero)
347 * @source_object: (allow-none): Optional #GObject identifying this source
348 * @error: #GError for error reporting, or %NULL to ignore.
350 * Helper function for g_socket_listener_add_address() that
351 * creates a TCP/IP socket listening on IPv4 and IPv6 (if
352 * supported) on the specified port on all interfaces.
354 * @source_object will be passed out in the various calls
355 * to accept to identify this particular source, which is
356 * useful if you're listening on multiple addresses and do
357 * different things depending on what address is connected to.
359 * Returns: %TRUE on success, %FALSE on error.
364 g_socket_listener_add_inet_port (GSocketListener
*listener
,
366 GObject
*source_object
,
369 gboolean need_ipv4_socket
= TRUE
;
370 GSocket
*socket4
= NULL
;
373 g_return_val_if_fail (listener
!= NULL
, FALSE
);
374 g_return_val_if_fail (port
!= 0, FALSE
);
376 if (!check_listener (listener
, error
))
379 /* first try to create an IPv6 socket */
380 socket6
= g_socket_new (G_SOCKET_FAMILY_IPV6
,
381 G_SOCKET_TYPE_STREAM
,
382 G_SOCKET_PROTOCOL_DEFAULT
,
386 /* IPv6 is supported on this platform, so if we fail now it is
387 * a result of being unable to bind to our port. Don't fail
388 * silently as a result of this!
391 GInetAddress
*inet_address
;
392 GSocketAddress
*address
;
395 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV6
);
396 address
= g_inet_socket_address_new (inet_address
, port
);
397 g_object_unref (inet_address
);
399 g_socket_set_listen_backlog (socket6
, listener
->priv
->listen_backlog
);
401 result
= g_socket_bind (socket6
, address
, TRUE
, error
) &&
402 g_socket_listen (socket6
, error
);
404 g_object_unref (address
);
408 g_object_unref (socket6
);
414 g_object_set_qdata_full (G_OBJECT (socket6
), source_quark
,
415 g_object_ref (source_object
),
418 /* If this socket already speaks IPv4 then we are done. */
419 if (g_socket_speaks_ipv4 (socket6
))
420 need_ipv4_socket
= FALSE
;
423 if (need_ipv4_socket
)
424 /* We are here for exactly one of the following reasons:
426 * - our platform doesn't support IPv6
427 * - we successfully created an IPv6 socket but it's V6ONLY
429 * In either case, we need to go ahead and create an IPv4 socket
430 * and fail the call if we can't bind to it.
433 socket4
= g_socket_new (G_SOCKET_FAMILY_IPV4
,
434 G_SOCKET_TYPE_STREAM
,
435 G_SOCKET_PROTOCOL_DEFAULT
,
439 /* IPv4 is supported on this platform, so if we fail now it is
440 * a result of being unable to bind to our port. Don't fail
441 * silently as a result of this!
444 GInetAddress
*inet_address
;
445 GSocketAddress
*address
;
448 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV4
);
449 address
= g_inet_socket_address_new (inet_address
, port
);
450 g_object_unref (inet_address
);
452 g_socket_set_listen_backlog (socket4
,
453 listener
->priv
->listen_backlog
);
455 result
= g_socket_bind (socket4
, address
, TRUE
, error
) &&
456 g_socket_listen (socket4
, error
);
458 g_object_unref (address
);
462 g_object_unref (socket4
);
465 g_object_unref (socket6
);
471 g_object_set_qdata_full (G_OBJECT (socket4
), source_quark
,
472 g_object_ref (source_object
),
476 /* Ok. So IPv4 is not supported on this platform. If we
477 * succeeded at creating an IPv6 socket then that's OK, but
478 * otherwise we need to tell the user we failed.
482 g_clear_error (error
);
488 g_assert (socket6
!= NULL
|| socket4
!= NULL
);
491 g_ptr_array_add (listener
->priv
->sockets
, socket6
);
494 g_ptr_array_add (listener
->priv
->sockets
, socket4
);
496 if (G_SOCKET_LISTENER_GET_CLASS (listener
)->changed
)
497 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed (listener
);
503 add_sources (GSocketListener
*listener
,
504 GSocketSourceFunc callback
,
505 gpointer callback_data
,
506 GCancellable
*cancellable
,
507 GMainContext
*context
)
515 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
517 socket
= listener
->priv
->sockets
->pdata
[i
];
519 source
= g_socket_create_source (socket
, G_IO_IN
, cancellable
);
520 g_source_set_callback (source
,
521 (GSourceFunc
) callback
,
522 callback_data
, NULL
);
523 g_source_attach (source
, context
);
525 sources
= g_list_prepend (sources
, source
);
532 free_sources (GList
*sources
)
535 while (sources
!= NULL
)
537 source
= sources
->data
;
538 sources
= g_list_delete_link (sources
, sources
);
539 g_source_destroy (source
);
540 g_source_unref (source
);
550 accept_callback (GSocket
*socket
,
551 GIOCondition condition
,
554 struct AcceptData
*data
= user_data
;
556 data
->socket
= socket
;
557 g_main_loop_quit (data
->loop
);
563 * g_socket_listener_accept_socket:
564 * @listener: a #GSocketListener
565 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL.
566 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
567 * @error: #GError for error reporting, or %NULL to ignore.
569 * Blocks waiting for a client to connect to any of the sockets added
570 * to the listener. Returns the #GSocket that was accepted.
572 * If you want to accept the high-level #GSocketConnection, not a #GSocket,
573 * which is often the case, then you should use g_socket_listener_accept()
576 * If @source_object is not %NULL it will be filled out with the source
577 * object specified when the corresponding socket or address was added
580 * If @cancellable is not %NULL, then the operation can be cancelled by
581 * triggering the cancellable object from another thread. If the operation
582 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
584 * Returns: (transfer full): a #GSocket on success, %NULL on error.
589 g_socket_listener_accept_socket (GSocketListener
*listener
,
590 GObject
**source_object
,
591 GCancellable
*cancellable
,
594 GSocket
*accept_socket
, *socket
;
596 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener
), NULL
);
598 if (!check_listener (listener
, error
))
601 if (listener
->priv
->sockets
->len
== 1)
603 accept_socket
= listener
->priv
->sockets
->pdata
[0];
604 if (!g_socket_condition_wait (accept_socket
, G_IO_IN
,
611 struct AcceptData data
;
614 if (listener
->priv
->main_context
== NULL
)
615 listener
->priv
->main_context
= g_main_context_new ();
617 loop
= g_main_loop_new (listener
->priv
->main_context
, FALSE
);
619 sources
= add_sources (listener
,
623 listener
->priv
->main_context
);
624 g_main_loop_run (loop
);
625 accept_socket
= data
.socket
;
626 free_sources (sources
);
627 g_main_loop_unref (loop
);
630 if (!(socket
= g_socket_accept (accept_socket
, cancellable
, error
)))
634 *source_object
= g_object_get_qdata (G_OBJECT (accept_socket
), source_quark
);
640 * g_socket_listener_accept:
641 * @listener: a #GSocketListener
642 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL
643 * @cancellable: (allow-none): 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 a #GSocketConnection for the socket that was
650 * If @source_object is not %NULL it will be filled out with the source
651 * object specified when the corresponding socket or address was added
654 * If @cancellable is not %NULL, then the operation can be cancelled by
655 * triggering the cancellable object from another thread. If the operation
656 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
658 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
663 g_socket_listener_accept (GSocketListener
*listener
,
664 GObject
**source_object
,
665 GCancellable
*cancellable
,
668 GSocketConnection
*connection
;
671 socket
= g_socket_listener_accept_socket (listener
,
678 connection
= g_socket_connection_factory_create_connection (socket
);
679 g_object_unref (socket
);
684 struct AcceptAsyncData
{
685 GSimpleAsyncResult
*simple
;
686 GCancellable
*cancellable
;
691 accept_ready (GSocket
*accept_socket
,
692 GIOCondition condition
,
695 struct AcceptAsyncData
*data
= _data
;
696 GError
*error
= NULL
;
698 GObject
*source_object
;
700 socket
= g_socket_accept (accept_socket
, data
->cancellable
, &error
);
703 g_simple_async_result_set_op_res_gpointer (data
->simple
, socket
,
705 source_object
= g_object_get_qdata (G_OBJECT (accept_socket
), source_quark
);
707 g_object_set_qdata_full (G_OBJECT (data
->simple
),
709 g_object_ref (source_object
), g_object_unref
);
713 g_simple_async_result_take_error (data
->simple
, error
);
716 g_simple_async_result_complete_in_idle (data
->simple
);
717 g_object_unref (data
->simple
);
718 free_sources (data
->sources
);
725 * g_socket_listener_accept_socket_async:
726 * @listener: a #GSocketListener
727 * @cancellable: (allow-none): a #GCancellable, or %NULL
728 * @callback: (scope async): a #GAsyncReadyCallback
729 * @user_data: (closure): user data for the callback
731 * This is the asynchronous version of g_socket_listener_accept_socket().
733 * When the operation is finished @callback will be
734 * called. You can then call g_socket_listener_accept_socket_finish()
735 * to get the result of the operation.
740 g_socket_listener_accept_socket_async (GSocketListener
*listener
,
741 GCancellable
*cancellable
,
742 GAsyncReadyCallback callback
,
745 struct AcceptAsyncData
*data
;
746 GError
*error
= NULL
;
748 if (!check_listener (listener
, &error
))
750 g_simple_async_report_take_gerror_in_idle (G_OBJECT (listener
),
756 data
= g_new0 (struct AcceptAsyncData
, 1);
757 data
->simple
= g_simple_async_result_new (G_OBJECT (listener
),
759 g_socket_listener_accept_socket_async
);
760 data
->cancellable
= cancellable
;
761 data
->sources
= add_sources (listener
,
765 g_main_context_get_thread_default ());
769 * g_socket_listener_accept_socket_finish:
770 * @listener: a #GSocketListener
771 * @result: a #GAsyncResult.
772 * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
773 * @error: a #GError location to store the error occurring, or %NULL to
776 * Finishes an async accept operation. See g_socket_listener_accept_socket_async()
778 * Returns: (transfer full): a #GSocket on success, %NULL on error.
783 g_socket_listener_accept_socket_finish (GSocketListener
*listener
,
784 GAsyncResult
*result
,
785 GObject
**source_object
,
789 GSimpleAsyncResult
*simple
;
791 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener
), NULL
);
793 simple
= G_SIMPLE_ASYNC_RESULT (result
);
795 if (g_simple_async_result_propagate_error (simple
, error
))
798 g_warn_if_fail (g_simple_async_result_get_source_tag (simple
) == g_socket_listener_accept_socket_async
);
800 socket
= g_simple_async_result_get_op_res_gpointer (simple
);
803 *source_object
= g_object_get_qdata (G_OBJECT (result
), source_quark
);
805 return g_object_ref (socket
);
809 * g_socket_listener_accept_async:
810 * @listener: a #GSocketListener
811 * @cancellable: (allow-none): a #GCancellable, or %NULL
812 * @callback: (scope async): a #GAsyncReadyCallback
813 * @user_data: (closure): user data for the callback
815 * This is the asynchronous version of g_socket_listener_accept().
817 * When the operation is finished @callback will be
818 * called. You can then call g_socket_listener_accept_socket()
819 * to get the result of the operation.
824 g_socket_listener_accept_async (GSocketListener
*listener
,
825 GCancellable
*cancellable
,
826 GAsyncReadyCallback callback
,
829 g_socket_listener_accept_socket_async (listener
,
836 * g_socket_listener_accept_finish:
837 * @listener: a #GSocketListener
838 * @result: a #GAsyncResult.
839 * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
840 * @error: a #GError location to store the error occurring, or %NULL to
843 * Finishes an async accept operation. See g_socket_listener_accept_async()
845 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
850 g_socket_listener_accept_finish (GSocketListener
*listener
,
851 GAsyncResult
*result
,
852 GObject
**source_object
,
856 GSocketConnection
*connection
;
858 socket
= g_socket_listener_accept_socket_finish (listener
,
865 connection
= g_socket_connection_factory_create_connection (socket
);
866 g_object_unref (socket
);
871 * g_socket_listener_set_backlog:
872 * @listener: a #GSocketListener
873 * @listen_backlog: an integer
875 * Sets the listen backlog on the sockets in the listener.
877 * See g_socket_set_listen_backlog() for details
882 g_socket_listener_set_backlog (GSocketListener
*listener
,
888 if (listener
->priv
->closed
)
891 listener
->priv
->listen_backlog
= listen_backlog
;
893 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
895 socket
= listener
->priv
->sockets
->pdata
[i
];
896 g_socket_set_listen_backlog (socket
, listen_backlog
);
901 * g_socket_listener_close:
902 * @listener: a #GSocketListener
904 * Closes all the sockets in the listener.
909 g_socket_listener_close (GSocketListener
*listener
)
914 g_return_if_fail (G_IS_SOCKET_LISTENER (listener
));
916 if (listener
->priv
->closed
)
919 for (i
= 0; i
< listener
->priv
->sockets
->len
; i
++)
921 socket
= listener
->priv
->sockets
->pdata
[i
];
922 g_socket_close (socket
, NULL
);
924 listener
->priv
->closed
= TRUE
;
928 * g_socket_listener_add_any_inet_port:
929 * @listener: a #GSocketListener
930 * @source_object: (allow-none): Optional #GObject identifying this source
931 * @error: a #GError location to store the error occurring, or %NULL to
934 * Listens for TCP connections on any available port number for both
935 * IPv6 and IPv4 (if each is available).
937 * This is useful if you need to have a socket for incoming connections
938 * but don't care about the specific port number.
940 * @source_object will be passed out in the various calls
941 * to accept to identify this particular source, which is
942 * useful if you're listening on multiple addresses and do
943 * different things depending on what address is connected to.
945 * Returns: the port number, or 0 in case of failure.
950 g_socket_listener_add_any_inet_port (GSocketListener
*listener
,
951 GObject
*source_object
,
954 GSList
*sockets_to_close
= NULL
;
955 guint16 candidate_port
= 0;
956 GSocket
*socket6
= NULL
;
957 GSocket
*socket4
= NULL
;
961 * multi-step process:
962 * - first, create an IPv6 socket.
963 * - if that fails, create an IPv4 socket and bind it to port 0 and
964 * that's it. no retries if that fails (why would it?).
965 * - if our IPv6 socket also speaks IPv4 then we are done.
966 * - if not, then we need to create a IPv4 socket with the same port
967 * number. this might fail, of course. so we try this a bunch of
968 * times -- leaving the old IPv6 sockets open so that we get a
969 * different port number to try each time.
970 * - if all that fails then just give up.
975 GInetAddress
*inet_address
;
976 GSocketAddress
*address
;
979 g_assert (socket6
== NULL
);
980 socket6
= g_socket_new (G_SOCKET_FAMILY_IPV6
,
981 G_SOCKET_TYPE_STREAM
,
982 G_SOCKET_PROTOCOL_DEFAULT
,
987 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV6
);
988 address
= g_inet_socket_address_new (inet_address
, 0);
989 g_object_unref (inet_address
);
990 result
= g_socket_bind (socket6
, address
, TRUE
, error
);
991 g_object_unref (address
);
994 !(address
= g_socket_get_local_address (socket6
, error
)))
996 g_object_unref (socket6
);
1001 g_assert (G_IS_INET_SOCKET_ADDRESS (address
));
1003 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address
));
1004 g_assert (candidate_port
!= 0);
1005 g_object_unref (address
);
1007 if (g_socket_speaks_ipv4 (socket6
))
1011 g_assert (socket4
== NULL
);
1012 socket4
= g_socket_new (G_SOCKET_FAMILY_IPV4
,
1013 G_SOCKET_TYPE_STREAM
,
1014 G_SOCKET_PROTOCOL_DEFAULT
,
1015 socket6
? NULL
: error
);
1017 if (socket4
== NULL
)
1018 /* IPv4 not supported.
1019 * if IPv6 is supported then candidate_port will be non-zero
1020 * (and the error parameter above will have been NULL)
1021 * if IPv6 is unsupported then candidate_port will be zero
1022 * (and error will have been set by the above call)
1026 inet_address
= g_inet_address_new_any (G_SOCKET_FAMILY_IPV4
);
1027 address
= g_inet_socket_address_new (inet_address
, candidate_port
);
1028 g_object_unref (inet_address
);
1029 /* a note on the 'error' clause below:
1031 * if candidate_port is 0 then we report the error right away
1032 * since it is strange that this binding would fail at all.
1033 * otherwise, we ignore the error message (ie: NULL).
1035 * the exception to this rule is the last time through the loop
1036 * (ie: attempts == 0) in which case we want to set the error
1037 * because failure here means that the entire call will fail and
1038 * we need something to show to the user.
1040 * an english summary of the situation: "if we gave a candidate
1041 * port number AND we have more attempts to try, then ignore the
1044 result
= g_socket_bind (socket4
, address
, TRUE
,
1045 (candidate_port
&& attempts
) ? NULL
: error
);
1046 g_object_unref (address
);
1050 g_assert (socket6
!= NULL
);
1053 /* got our candidate port successfully */
1057 /* we failed to bind to the specified port. try again. */
1059 g_object_unref (socket4
);
1062 /* keep this open so we get a different port number */
1063 sockets_to_close
= g_slist_prepend (sockets_to_close
,
1070 /* we didn't tell it a port. this means two things.
1071 * - if we failed, then something really bad happened.
1072 * - if we succeeded, then we need to find out the port number.
1075 g_assert (socket6
== NULL
);
1078 !(address
= g_socket_get_local_address (socket4
, error
)))
1080 g_object_unref (socket4
);
1085 g_assert (G_IS_INET_SOCKET_ADDRESS (address
));
1087 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address
));
1088 g_assert (candidate_port
!= 0);
1089 g_object_unref (address
);
1094 /* should only be non-zero if we have a socket */
1095 g_assert ((candidate_port
!= 0) == (socket4
|| socket6
));
1097 while (sockets_to_close
)
1099 g_object_unref (sockets_to_close
->data
);
1100 sockets_to_close
= g_slist_delete_link (sockets_to_close
,
1104 /* now we actually listen() the sockets and add them to the listener */
1105 if (socket6
!= NULL
)
1107 g_socket_set_listen_backlog (socket6
, listener
->priv
->listen_backlog
);
1108 if (!g_socket_listen (socket6
, error
))
1110 g_object_unref (socket6
);
1112 g_object_unref (socket4
);
1118 g_object_set_qdata_full (G_OBJECT (socket6
), source_quark
,
1119 g_object_ref (source_object
),
1122 g_ptr_array_add (listener
->priv
->sockets
, socket6
);
1125 if (socket4
!= NULL
)
1127 g_socket_set_listen_backlog (socket4
, listener
->priv
->listen_backlog
);
1128 if (!g_socket_listen (socket4
, error
))
1130 g_object_unref (socket4
);
1132 g_object_unref (socket6
);
1138 g_object_set_qdata_full (G_OBJECT (socket4
), source_quark
,
1139 g_object_ref (source_object
),
1142 g_ptr_array_add (listener
->priv
->sockets
, socket4
);
1145 if ((socket4
!= NULL
|| socket6
!= NULL
) &&
1146 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed
)
1147 G_SOCKET_LISTENER_GET_CLASS (listener
)->changed (listener
);
1149 return candidate_port
;