Branch data Line data Source code
1 : : /* GIO - GLib Input, Output and Streaming Library
2 : : *
3 : : * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima
4 : : * Copyright © 2009 codethink
5 : : * Copyright © 2009 Red Hat, Inc
6 : : *
7 : : * SPDX-License-Identifier: LGPL-2.1-or-later
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2.1 of the License, or (at your option) any later version.
13 : : *
14 : : * This library is distributed in the hope that it will be useful,
15 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : * Lesser General Public License for more details.
18 : : *
19 : : * You should have received a copy of the GNU Lesser General
20 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 : : *
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>
26 : : */
27 : :
28 : : #include "config.h"
29 : : #include "gsocketlistener.h"
30 : :
31 : : #include <gio/gioenumtypes.h>
32 : : #include <gio/gtask.h>
33 : : #include <gio/gcancellable.h>
34 : : #include <gio/gsocketaddress.h>
35 : : #include <gio/ginetaddress.h>
36 : : #include <gio/gioerror.h>
37 : : #include <gio/gsocket.h>
38 : : #include <gio/gsocketconnection.h>
39 : : #include <gio/ginetsocketaddress.h>
40 : : #include "glibintl.h"
41 : : #include "gmarshal-internal.h"
42 : :
43 : :
44 : : /**
45 : : * GSocketListener:
46 : : *
47 : : * A `GSocketListener` is an object that keeps track of a set
48 : : * of server sockets and helps you accept sockets from any of the
49 : : * socket, either sync or async.
50 : : *
51 : : * Add addresses and ports to listen on using
52 : : * [method@Gio.SocketListener.add_address] and
53 : : * [method@Gio.SocketListener.add_inet_port]. These will be listened on until
54 : : * [method@Gio.SocketListener.close] is called. Dropping your final reference to
55 : : * the `GSocketListener` will not cause [method@Gio.SocketListener.close] to be
56 : : * called implicitly, as some references to the `GSocketListener` may be held
57 : : * internally.
58 : : *
59 : : * If you want to implement a network server, also look at
60 : : * [class@Gio.SocketService] and [class@Gio.ThreadedSocketService] which are
61 : : * subclasses of `GSocketListener` that make this even easier.
62 : : *
63 : : * Since: 2.22
64 : : */
65 : :
66 : : enum
67 : : {
68 : : PROP_0,
69 : : PROP_LISTEN_BACKLOG
70 : : };
71 : :
72 : : enum
73 : : {
74 : : EVENT,
75 : : LAST_SIGNAL
76 : : };
77 : :
78 : : static guint signals[LAST_SIGNAL] = { 0 };
79 : :
80 : : static GQuark source_quark = 0;
81 : :
82 : : struct _GSocketListenerPrivate
83 : : {
84 : : GPtrArray *sockets;
85 : : GMainContext *main_context;
86 : : int listen_backlog;
87 : : guint closed : 1;
88 : : };
89 : :
90 : 1082 : G_DEFINE_TYPE_WITH_PRIVATE (GSocketListener, g_socket_listener, G_TYPE_OBJECT)
91 : :
92 : : static void
93 : 36 : g_socket_listener_finalize (GObject *object)
94 : : {
95 : 36 : GSocketListener *listener = G_SOCKET_LISTENER (object);
96 : :
97 : 36 : if (listener->priv->main_context)
98 : 0 : g_main_context_unref (listener->priv->main_context);
99 : :
100 : : /* Do not explicitly close the sockets. Instead, let them close themselves if
101 : : * their final reference is dropped, but keep them open if a reference is
102 : : * held externally to the GSocketListener (which is possible if
103 : : * g_socket_listener_add_socket() was used).
104 : : */
105 : 36 : g_ptr_array_free (listener->priv->sockets, TRUE);
106 : :
107 : 36 : G_OBJECT_CLASS (g_socket_listener_parent_class)
108 : 36 : ->finalize (object);
109 : 36 : }
110 : :
111 : : static void
112 : 1 : g_socket_listener_get_property (GObject *object,
113 : : guint prop_id,
114 : : GValue *value,
115 : : GParamSpec *pspec)
116 : : {
117 : 1 : GSocketListener *listener = G_SOCKET_LISTENER (object);
118 : :
119 : 1 : switch (prop_id)
120 : : {
121 : 1 : case PROP_LISTEN_BACKLOG:
122 : 1 : g_value_set_int (value, listener->priv->listen_backlog);
123 : 1 : break;
124 : :
125 : 0 : default:
126 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
127 : : }
128 : 1 : }
129 : :
130 : : static void
131 : 62 : g_socket_listener_set_property (GObject *object,
132 : : guint prop_id,
133 : : const GValue *value,
134 : : GParamSpec *pspec)
135 : : {
136 : 62 : GSocketListener *listener = G_SOCKET_LISTENER (object);
137 : :
138 : 62 : switch (prop_id)
139 : : {
140 : 62 : case PROP_LISTEN_BACKLOG:
141 : 62 : g_socket_listener_set_backlog (listener, g_value_get_int (value));
142 : 62 : break;
143 : :
144 : 0 : default:
145 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
146 : : }
147 : 62 : }
148 : :
149 : : static void
150 : 12 : g_socket_listener_class_init (GSocketListenerClass *klass)
151 : : {
152 : 12 : GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
153 : :
154 : 12 : gobject_class->finalize = g_socket_listener_finalize;
155 : 12 : gobject_class->set_property = g_socket_listener_set_property;
156 : 12 : gobject_class->get_property = g_socket_listener_get_property;
157 : :
158 : : /**
159 : : * GSocketListener:listen-backlog:
160 : : *
161 : : * The number of outstanding connections in the listen queue.
162 : : *
163 : : * Since: 2.22
164 : : */
165 : 12 : g_object_class_install_property (gobject_class, PROP_LISTEN_BACKLOG,
166 : : g_param_spec_int ("listen-backlog", NULL, NULL,
167 : : 0,
168 : : 2000,
169 : : 10,
170 : : G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
171 : :
172 : : /**
173 : : * GSocketListener::event:
174 : : * @listener: the #GSocketListener
175 : : * @event: the event that is occurring
176 : : * @socket: the #GSocket the event is occurring on
177 : : *
178 : : * Emitted when @listener's activity on @socket changes state.
179 : : * Note that when @listener is used to listen on both IPv4 and
180 : : * IPv6, a separate set of signals will be emitted for each, and
181 : : * the order they happen in is undefined.
182 : : *
183 : : * Since: 2.46
184 : : */
185 : 12 : signals[EVENT] =
186 : 12 : g_signal_new (I_("event"),
187 : : G_TYPE_FROM_CLASS (gobject_class),
188 : : G_SIGNAL_RUN_LAST,
189 : : G_STRUCT_OFFSET (GSocketListenerClass, event),
190 : : NULL, NULL,
191 : : _g_cclosure_marshal_VOID__ENUM_OBJECT,
192 : : G_TYPE_NONE, 2,
193 : : G_TYPE_SOCKET_LISTENER_EVENT,
194 : : G_TYPE_SOCKET);
195 : 12 : g_signal_set_va_marshaller (signals[EVENT],
196 : : G_TYPE_FROM_CLASS (gobject_class),
197 : : _g_cclosure_marshal_VOID__ENUM_OBJECTv);
198 : :
199 : 12 : source_quark = g_quark_from_static_string ("g-socket-listener-source");
200 : 12 : }
201 : :
202 : : static void
203 : 62 : g_socket_listener_init (GSocketListener *listener)
204 : : {
205 : 62 : listener->priv = g_socket_listener_get_instance_private (listener);
206 : 124 : listener->priv->sockets =
207 : 62 : g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
208 : 62 : listener->priv->listen_backlog = 10;
209 : 62 : }
210 : :
211 : : /**
212 : : * g_socket_listener_new:
213 : : *
214 : : * Creates a new #GSocketListener with no sockets to listen for.
215 : : * New listeners can be added with e.g. g_socket_listener_add_address()
216 : : * or g_socket_listener_add_inet_port().
217 : : *
218 : : * Returns: a new #GSocketListener.
219 : : *
220 : : * Since: 2.22
221 : : */
222 : : GSocketListener *
223 : 4 : g_socket_listener_new (void)
224 : : {
225 : 4 : return g_object_new (G_TYPE_SOCKET_LISTENER, NULL);
226 : : }
227 : :
228 : : static gboolean
229 : 353 : check_listener (GSocketListener *listener,
230 : : GError **error)
231 : : {
232 : 353 : if (listener->priv->closed)
233 : : {
234 : 0 : g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
235 : : _("Listener is already closed"));
236 : 0 : return FALSE;
237 : : }
238 : :
239 : 353 : return TRUE;
240 : : }
241 : :
242 : : static void
243 : 55 : add_socket (GSocketListener *listener,
244 : : GSocket *socket,
245 : : GObject *source_object,
246 : : gboolean set_non_blocking)
247 : : {
248 : 55 : if (source_object)
249 : 0 : g_object_set_qdata_full (G_OBJECT (socket), source_quark,
250 : : g_object_ref (source_object),
251 : : g_object_unref);
252 : :
253 : 55 : g_ptr_array_add (listener->priv->sockets, g_object_ref (socket));
254 : :
255 : : /* Because the implementation of `GSocketListener` uses polling and `GSource`s
256 : : * to wait for connections, we absolutely do *not* need `GSocket`’s internal
257 : : * implementation of blocking operations to get in the way. Otherwise we end
258 : : * up calling poll() on the results of poll(), which is racy and confusing.
259 : : *
260 : : * Unfortunately, the existence of g_socket_listener_add_socket() to add a
261 : : * socket which is used elsewhere, means that we need an escape hatch
262 : : * (`!set_non_blocking`) to allow sockets to remain in blocking mode if the
263 : : * caller really wants it. */
264 : 55 : if (set_non_blocking)
265 : 23 : g_socket_set_blocking (socket, FALSE);
266 : 55 : }
267 : :
268 : : /**
269 : : * g_socket_listener_add_socket:
270 : : * @listener: a #GSocketListener
271 : : * @socket: a listening #GSocket
272 : : * @source_object: (nullable): Optional #GObject identifying this source
273 : : * @error: #GError for error reporting, or %NULL to ignore.
274 : : *
275 : : * Adds @socket to the set of sockets that we try to accept
276 : : * new clients from. The socket must be bound to a local
277 : : * address and listened to.
278 : : *
279 : : * For parallel calls to [class@Gio.SocketListener] methods to work, the socket
280 : : * must be in non-blocking mode. (See [property@Gio.Socket:blocking].)
281 : : *
282 : : * @source_object will be passed out in the various calls
283 : : * to accept to identify this particular source, which is
284 : : * useful if you're listening on multiple addresses and do
285 : : * different things depending on what address is connected to.
286 : : *
287 : : * The @socket will not be automatically closed when the @listener is finalized
288 : : * unless the listener held the final reference to the socket. Before GLib 2.42,
289 : : * the @socket was automatically closed on finalization of the @listener, even
290 : : * if references to it were held elsewhere.
291 : : *
292 : : * Returns: %TRUE on success, %FALSE on error.
293 : : *
294 : : * Since: 2.22
295 : : */
296 : : gboolean
297 : 32 : g_socket_listener_add_socket (GSocketListener *listener,
298 : : GSocket *socket,
299 : : GObject *source_object,
300 : : GError **error)
301 : : {
302 : 32 : if (!check_listener (listener, error))
303 : 0 : return FALSE;
304 : :
305 : : /* TODO: Check that socket it is bound & not closed? */
306 : :
307 : 32 : if (g_socket_is_closed (socket))
308 : : {
309 : 0 : g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
310 : : _("Added socket is closed"));
311 : 0 : return FALSE;
312 : : }
313 : :
314 : 32 : add_socket (listener, socket, source_object, FALSE);
315 : :
316 : 32 : if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
317 : 29 : G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
318 : :
319 : 32 : return TRUE;
320 : : }
321 : :
322 : : /**
323 : : * g_socket_listener_add_address:
324 : : * @listener: a #GSocketListener
325 : : * @address: a #GSocketAddress
326 : : * @type: a #GSocketType
327 : : * @protocol: a #GSocketProtocol
328 : : * @source_object: (nullable): Optional #GObject identifying this source
329 : : * @effective_address: (out) (optional): location to store the address that was bound to, or %NULL.
330 : : * @error: #GError for error reporting, or %NULL to ignore.
331 : : *
332 : : * Creates a socket of type @type and protocol @protocol, binds
333 : : * it to @address and adds it to the set of sockets we're accepting
334 : : * sockets from.
335 : : *
336 : : * Note that adding an IPv6 address, depending on the platform,
337 : : * may or may not result in a listener that also accepts IPv4
338 : : * connections. For more deterministic behavior, see
339 : : * g_socket_listener_add_inet_port().
340 : : *
341 : : * @source_object will be passed out in the various calls
342 : : * to accept to identify this particular source, which is
343 : : * useful if you're listening on multiple addresses and do
344 : : * different things depending on what address is connected to.
345 : : *
346 : : * If successful and @effective_address is non-%NULL then it will
347 : : * be set to the address that the binding actually occurred at. This
348 : : * is helpful for determining the port number that was used for when
349 : : * requesting a binding to port 0 (ie: "any port"). This address, if
350 : : * requested, belongs to the caller and must be freed.
351 : : *
352 : : * Call g_socket_listener_close() to stop listening on @address; this will not
353 : : * be done automatically when you drop your final reference to @listener, as
354 : : * references may be held internally.
355 : : *
356 : : * Returns: %TRUE on success, %FALSE on error.
357 : : *
358 : : * Since: 2.22
359 : : */
360 : : gboolean
361 : 33 : g_socket_listener_add_address (GSocketListener *listener,
362 : : GSocketAddress *address,
363 : : GSocketType type,
364 : : GSocketProtocol protocol,
365 : : GObject *source_object,
366 : : GSocketAddress **effective_address,
367 : : GError **error)
368 : : {
369 : : GSocketAddress *local_address;
370 : : GSocketFamily family;
371 : : GSocket *socket;
372 : :
373 : 33 : if (!check_listener (listener, error))
374 : 0 : return FALSE;
375 : :
376 : 33 : family = g_socket_address_get_family (address);
377 : 33 : socket = g_socket_new (family, type, protocol, error);
378 : 33 : if (socket == NULL)
379 : 0 : return FALSE;
380 : :
381 : 33 : g_socket_set_listen_backlog (socket, listener->priv->listen_backlog);
382 : :
383 : 33 : g_signal_emit (listener, signals[EVENT], 0,
384 : : G_SOCKET_LISTENER_BINDING, socket);
385 : :
386 : 33 : if (!g_socket_bind (socket, address, TRUE, error))
387 : : {
388 : 1 : g_object_unref (socket);
389 : 1 : return FALSE;
390 : : }
391 : :
392 : 32 : g_signal_emit (listener, signals[EVENT], 0,
393 : : G_SOCKET_LISTENER_BOUND, socket);
394 : 32 : g_signal_emit (listener, signals[EVENT], 0,
395 : : G_SOCKET_LISTENER_LISTENING, socket);
396 : :
397 : 32 : if (!g_socket_listen (socket, error))
398 : : {
399 : 0 : g_object_unref (socket);
400 : 0 : return FALSE;
401 : : }
402 : :
403 : 32 : g_signal_emit (listener, signals[EVENT], 0,
404 : : G_SOCKET_LISTENER_LISTENED, socket);
405 : :
406 : 32 : local_address = NULL;
407 : 32 : if (effective_address)
408 : : {
409 : 11 : local_address = g_socket_get_local_address (socket, error);
410 : 11 : if (local_address == NULL)
411 : : {
412 : 0 : g_object_unref (socket);
413 : 0 : return FALSE;
414 : : }
415 : : }
416 : :
417 : 32 : if (!g_socket_listener_add_socket (listener, socket,
418 : : source_object,
419 : : error))
420 : : {
421 : 0 : if (local_address)
422 : 0 : g_object_unref (local_address);
423 : 0 : g_object_unref (socket);
424 : 0 : return FALSE;
425 : : }
426 : :
427 : 32 : if (effective_address)
428 : 11 : *effective_address = local_address;
429 : :
430 : 32 : g_object_unref (socket); /* add_socket refs this */
431 : :
432 : 32 : return TRUE;
433 : : }
434 : :
435 : : /**
436 : : * g_socket_listener_add_inet_port:
437 : : * @listener: a #GSocketListener
438 : : * @port: an IP port number (non-zero)
439 : : * @source_object: (nullable): Optional #GObject identifying this source
440 : : * @error: #GError for error reporting, or %NULL to ignore.
441 : : *
442 : : * Helper function for g_socket_listener_add_address() that
443 : : * creates a TCP/IP socket listening on IPv4 and IPv6 (if
444 : : * supported) on the specified port on all interfaces.
445 : : *
446 : : * If possible, the [class@Gio.SocketListener] will listen on both IPv4 and
447 : : * IPv6 (listening on the same port on both). If listening on one of the socket
448 : : * families fails, the [class@Gio.SocketListener] will only listen on the other.
449 : : * If listening on both fails, an error will be returned.
450 : : *
451 : : * If you need to distinguish whether listening on IPv4 or IPv6 or both was
452 : : * successful, connect to [signal@Gio.SocketListener::event].
453 : : *
454 : : * @source_object will be passed out in the various calls
455 : : * to accept to identify this particular source, which is
456 : : * useful if you're listening on multiple addresses and do
457 : : * different things depending on what address is connected to.
458 : : *
459 : : * Call g_socket_listener_close() to stop listening on @port; this will not
460 : : * be done automatically when you drop your final reference to @listener, as
461 : : * references may be held internally.
462 : : *
463 : : * Returns: %TRUE on success, %FALSE on error.
464 : : *
465 : : * Since: 2.22
466 : : */
467 : : gboolean
468 : 11 : g_socket_listener_add_inet_port (GSocketListener *listener,
469 : : guint16 port,
470 : : GObject *source_object,
471 : : GError **error)
472 : : {
473 : 11 : gboolean need_ipv4_socket = TRUE;
474 : 11 : GSocket *socket4 = NULL;
475 : : GSocket *socket6;
476 : 11 : GError *socket4_create_error = NULL;
477 : 11 : GError *socket4_listen_error = NULL, *socket6_listen_error = NULL;
478 : :
479 : 11 : g_return_val_if_fail (listener != NULL, FALSE);
480 : 11 : g_return_val_if_fail (port != 0, FALSE);
481 : :
482 : 11 : if (!check_listener (listener, error))
483 : 0 : return FALSE;
484 : :
485 : : /* first try to create an IPv6 socket */
486 : 11 : socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6,
487 : : G_SOCKET_TYPE_STREAM,
488 : : G_SOCKET_PROTOCOL_DEFAULT,
489 : : NULL);
490 : :
491 : 11 : if (socket6 != NULL)
492 : : /* IPv6 is supported on this platform, so if we fail now it is
493 : : * a result of being unable to bind to our port. Don't fail
494 : : * silently as a result of this!
495 : : */
496 : : {
497 : : GInetAddress *inet_address;
498 : : GSocketAddress *address;
499 : :
500 : 9 : inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
501 : 9 : address = g_inet_socket_address_new (inet_address, port);
502 : 9 : g_object_unref (inet_address);
503 : :
504 : 9 : g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog);
505 : :
506 : 9 : g_signal_emit (listener, signals[EVENT], 0,
507 : : G_SOCKET_LISTENER_BINDING, socket6);
508 : :
509 : 9 : if (!g_socket_bind (socket6, address, TRUE, error))
510 : : {
511 : 2 : g_object_unref (address);
512 : 2 : g_object_unref (socket6);
513 : 2 : return FALSE;
514 : : }
515 : :
516 : 7 : g_object_unref (address);
517 : :
518 : 7 : g_signal_emit (listener, signals[EVENT], 0,
519 : : G_SOCKET_LISTENER_BOUND, socket6);
520 : 7 : g_signal_emit (listener, signals[EVENT], 0,
521 : : G_SOCKET_LISTENER_LISTENING, socket6);
522 : :
523 : 7 : if (g_socket_listen (socket6, &socket6_listen_error))
524 : : {
525 : 4 : g_signal_emit (listener, signals[EVENT], 0,
526 : : G_SOCKET_LISTENER_LISTENED, socket6);
527 : :
528 : : /* If this socket already speaks IPv4 then we are done. */
529 : 4 : if (g_socket_speaks_ipv4 (socket6))
530 : 4 : need_ipv4_socket = FALSE;
531 : : }
532 : : }
533 : :
534 : 9 : if (need_ipv4_socket)
535 : : /* We are here for exactly one of the following reasons:
536 : : *
537 : : * - our platform doesn't support IPv6
538 : : * - we successfully created an IPv6 socket but it's V6ONLY
539 : : *
540 : : * In either case, we need to go ahead and create an IPv4 socket
541 : : * and fail the call if we can't bind to it.
542 : : */
543 : : {
544 : 5 : socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4,
545 : : G_SOCKET_TYPE_STREAM,
546 : : G_SOCKET_PROTOCOL_DEFAULT,
547 : : &socket4_create_error);
548 : :
549 : 5 : if (socket4 != NULL)
550 : : /* IPv4 is supported on this platform, so if we fail now it is
551 : : * a result of being unable to bind to our port. Don't fail
552 : : * silently as a result of this!
553 : : */
554 : : {
555 : : GInetAddress *inet_address;
556 : : GSocketAddress *address;
557 : :
558 : 4 : inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
559 : 4 : address = g_inet_socket_address_new (inet_address, port);
560 : 4 : g_object_unref (inet_address);
561 : :
562 : 4 : g_socket_set_listen_backlog (socket4,
563 : 4 : listener->priv->listen_backlog);
564 : :
565 : 4 : g_signal_emit (listener, signals[EVENT], 0,
566 : : G_SOCKET_LISTENER_BINDING, socket4);
567 : :
568 : 4 : if (!g_socket_bind (socket4, address, TRUE, error))
569 : : {
570 : 0 : g_clear_object (&address);
571 : 0 : g_clear_object (&socket4);
572 : 0 : g_clear_object (&socket6);
573 : 0 : g_clear_error (&socket6_listen_error);
574 : :
575 : 0 : return FALSE;
576 : : }
577 : :
578 : 4 : g_object_unref (address);
579 : :
580 : 4 : g_signal_emit (listener, signals[EVENT], 0,
581 : : G_SOCKET_LISTENER_BOUND, socket4);
582 : 4 : g_signal_emit (listener, signals[EVENT], 0,
583 : : G_SOCKET_LISTENER_LISTENING, socket4);
584 : :
585 : 4 : if (g_socket_listen (socket4, &socket4_listen_error))
586 : : {
587 : 3 : g_signal_emit (listener, signals[EVENT], 0,
588 : : G_SOCKET_LISTENER_LISTENED, socket4);
589 : : }
590 : : }
591 : : else
592 : : /* Ok. So IPv4 is not supported on this platform. If we
593 : : * succeeded at creating an IPv6 socket then that's OK, but
594 : : * otherwise we need to tell the user we failed.
595 : : */
596 : : {
597 : 1 : if (socket6 == NULL || socket6_listen_error != NULL)
598 : : {
599 : 1 : g_clear_object (&socket6);
600 : 1 : g_clear_error (&socket6_listen_error);
601 : 1 : g_propagate_error (error, g_steal_pointer (&socket4_create_error));
602 : 1 : return FALSE;
603 : : }
604 : : }
605 : : }
606 : :
607 : : /* Only error out if both listen() calls failed. */
608 : 8 : if ((socket6 == NULL || socket6_listen_error != NULL) &&
609 : 4 : (socket4 == NULL || socket4_listen_error != NULL))
610 : : {
611 : 2 : GError **set_error = ((socket6_listen_error != NULL) ?
612 : 1 : &socket6_listen_error :
613 : : &socket4_listen_error);
614 : 1 : g_propagate_error (error, g_steal_pointer (set_error));
615 : :
616 : 1 : g_clear_error (&socket6_listen_error);
617 : 1 : g_clear_error (&socket4_listen_error);
618 : :
619 : 1 : g_clear_object (&socket6);
620 : 1 : g_clear_object (&socket4);
621 : :
622 : 1 : return FALSE;
623 : : }
624 : :
625 : 7 : g_assert (socket6 != NULL || socket4 != NULL);
626 : :
627 : 7 : if (socket6 != NULL)
628 : 6 : add_socket (listener, socket6, source_object, TRUE);
629 : :
630 : 7 : if (socket4 != NULL)
631 : 3 : add_socket (listener, socket4, source_object, TRUE);
632 : :
633 : 7 : if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
634 : 7 : G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
635 : :
636 : 7 : g_clear_error (&socket6_listen_error);
637 : 7 : g_clear_error (&socket4_listen_error);
638 : :
639 : 7 : g_clear_object (&socket6);
640 : 7 : g_clear_object (&socket4);
641 : :
642 : 7 : return TRUE;
643 : : }
644 : :
645 : : static GList *
646 : 277 : add_sources (GSocketListener *listener,
647 : : GSocketSourceFunc callback,
648 : : gpointer callback_data,
649 : : GCancellable *cancellable,
650 : : GMainContext *context)
651 : : {
652 : : GSocket *socket;
653 : : GSource *source;
654 : : GList *sources;
655 : : guint i;
656 : :
657 : 277 : sources = NULL;
658 : 576 : for (i = 0; i < listener->priv->sockets->len; i++)
659 : : {
660 : 299 : socket = listener->priv->sockets->pdata[i];
661 : :
662 : 299 : source = g_socket_create_source (socket, G_IO_IN, cancellable);
663 : 299 : g_source_set_callback (source,
664 : : (GSourceFunc) callback,
665 : : callback_data, NULL);
666 : 299 : g_source_attach (source, context);
667 : :
668 : 299 : sources = g_list_prepend (sources, source);
669 : : }
670 : :
671 : 277 : return sources;
672 : : }
673 : :
674 : : static void
675 : 254 : free_sources (GList *sources)
676 : : {
677 : : GSource *source;
678 : 528 : while (sources != NULL)
679 : : {
680 : 274 : source = sources->data;
681 : 274 : sources = g_list_delete_link (sources, sources);
682 : 274 : g_source_destroy (source);
683 : 274 : g_source_unref (source);
684 : : }
685 : 254 : }
686 : :
687 : : struct AcceptData {
688 : : GMainLoop *loop;
689 : : GSocket *socket;
690 : : };
691 : :
692 : : static gboolean
693 : 0 : accept_callback (GSocket *socket,
694 : : GIOCondition condition,
695 : : gpointer user_data)
696 : : {
697 : 0 : struct AcceptData *data = user_data;
698 : :
699 : 0 : data->socket = socket;
700 : 0 : g_main_loop_quit (data->loop);
701 : :
702 : 0 : return TRUE;
703 : : }
704 : :
705 : : /**
706 : : * g_socket_listener_accept_socket:
707 : : * @listener: a #GSocketListener
708 : : * @source_object: (out) (transfer none) (optional) (nullable): location where #GObject pointer will be stored, or %NULL.
709 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
710 : : * @error: #GError for error reporting, or %NULL to ignore.
711 : : *
712 : : * Blocks waiting for a client to connect to any of the sockets added
713 : : * to the listener. Returns the #GSocket that was accepted.
714 : : *
715 : : * If you want to accept the high-level #GSocketConnection, not a #GSocket,
716 : : * which is often the case, then you should use g_socket_listener_accept()
717 : : * instead.
718 : : *
719 : : * If @source_object is not %NULL it will be filled out with the source
720 : : * object specified when the corresponding socket or address was added
721 : : * to the listener.
722 : : *
723 : : * If @cancellable is not %NULL, then the operation can be cancelled by
724 : : * triggering the cancellable object from another thread. If the operation
725 : : * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
726 : : *
727 : : * Returns: (transfer full): a #GSocket on success, %NULL on error.
728 : : *
729 : : * Since: 2.22
730 : : */
731 : : GSocket *
732 : 0 : g_socket_listener_accept_socket (GSocketListener *listener,
733 : : GObject **source_object,
734 : : GCancellable *cancellable,
735 : : GError **error)
736 : : {
737 : : GSocket *accept_socket, *socket;
738 : :
739 : 0 : g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
740 : :
741 : 0 : if (!check_listener (listener, error))
742 : 0 : return NULL;
743 : :
744 : 0 : if (listener->priv->sockets->len == 1)
745 : : {
746 : 0 : accept_socket = listener->priv->sockets->pdata[0];
747 : 0 : if (!g_socket_condition_wait (accept_socket, G_IO_IN,
748 : : cancellable, error))
749 : 0 : return NULL;
750 : : }
751 : : else
752 : : {
753 : : GList *sources;
754 : : struct AcceptData data;
755 : : GMainLoop *loop;
756 : :
757 : 0 : if (listener->priv->main_context == NULL)
758 : 0 : listener->priv->main_context = g_main_context_new ();
759 : :
760 : 0 : loop = g_main_loop_new (listener->priv->main_context, FALSE);
761 : 0 : data.loop = loop;
762 : 0 : sources = add_sources (listener,
763 : : accept_callback,
764 : : &data,
765 : : cancellable,
766 : 0 : listener->priv->main_context);
767 : 0 : g_main_loop_run (loop);
768 : 0 : accept_socket = data.socket;
769 : 0 : free_sources (sources);
770 : 0 : g_main_loop_unref (loop);
771 : : }
772 : :
773 : 0 : if (!(socket = g_socket_accept (accept_socket, cancellable, error)))
774 : 0 : return NULL;
775 : :
776 : 0 : if (source_object)
777 : 0 : *source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
778 : :
779 : 0 : return socket;
780 : : }
781 : :
782 : : /**
783 : : * g_socket_listener_accept:
784 : : * @listener: a #GSocketListener
785 : : * @source_object: (out) (transfer none) (optional) (nullable): location where #GObject pointer will be stored, or %NULL
786 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
787 : : * @error: #GError for error reporting, or %NULL to ignore.
788 : : *
789 : : * Blocks waiting for a client to connect to any of the sockets added
790 : : * to the listener. Returns a #GSocketConnection for the socket that was
791 : : * accepted.
792 : : *
793 : : * If @source_object is not %NULL it will be filled out with the source
794 : : * object specified when the corresponding socket or address was added
795 : : * to the listener.
796 : : *
797 : : * If @cancellable is not %NULL, then the operation can be cancelled by
798 : : * triggering the cancellable object from another thread. If the operation
799 : : * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
800 : : *
801 : : * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
802 : : *
803 : : * Since: 2.22
804 : : */
805 : : GSocketConnection *
806 : 0 : g_socket_listener_accept (GSocketListener *listener,
807 : : GObject **source_object,
808 : : GCancellable *cancellable,
809 : : GError **error)
810 : : {
811 : : GSocketConnection *connection;
812 : : GSocket *socket;
813 : :
814 : 0 : socket = g_socket_listener_accept_socket (listener,
815 : : source_object,
816 : : cancellable,
817 : : error);
818 : 0 : if (socket == NULL)
819 : 0 : return NULL;
820 : :
821 : 0 : connection = g_socket_connection_factory_create_connection (socket);
822 : 0 : g_object_unref (socket);
823 : :
824 : 0 : return connection;
825 : : }
826 : :
827 : : typedef struct
828 : : {
829 : : GList *sources; /* (element-type GSource) */
830 : : } AcceptSocketAsyncData;
831 : :
832 : : static void
833 : 254 : accept_socket_async_data_free (AcceptSocketAsyncData *data)
834 : : {
835 : 254 : free_sources (data->sources);
836 : 254 : g_free (data);
837 : 254 : }
838 : :
839 : : static gboolean
840 : 260 : accept_ready (GSocket *accept_socket,
841 : : GIOCondition condition,
842 : : gpointer user_data)
843 : : {
844 : 260 : GTask *task = user_data;
845 : 260 : GError *error = NULL;
846 : : GSocket *socket;
847 : : GObject *source_object;
848 : :
849 : : /* Don’t call g_task_return_*() multiple times if we have multiple incoming
850 : : * connections in the same `GMainContext` iteration. We expect `GMainContext`
851 : : * to guarantee this behaviour, but let’s double check that the other sources
852 : : * have been destroyed correctly. */
853 : 260 : g_assert (!g_source_is_destroyed (g_main_current_source ()));
854 : :
855 : 260 : socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error);
856 : 260 : if (socket)
857 : : {
858 : 232 : source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
859 : 232 : if (source_object)
860 : 0 : g_object_set_qdata_full (G_OBJECT (task),
861 : : source_quark,
862 : : g_object_ref (source_object), g_object_unref);
863 : 232 : g_task_return_pointer (task, socket, g_object_unref);
864 : : }
865 : : else
866 : : {
867 : : /* This can happen if there are multiple pending g_socket_listener_accept_async()
868 : : * calls (say N), and fewer queued incoming connections (say C) than that
869 : : * on this `GSocket`, in a single `GMainContext` iteration.
870 : : * (There may still be queued incoming connections on other `GSocket`s in
871 : : * the `GSocketListener`.)
872 : : *
873 : : * If so, the `GSocketSource`s for that pending g_socket_listener_accept_async()
874 : : * call will all raise `G_IO_IN` in this `GMainContext` iteration. The
875 : : * first C calls to accept_ready() succeed, but the following N-C calls
876 : : * would block, as all the queued incoming connections on this `GSocket`
877 : : * have been accepted by then. The `GSocketSource`s for these remaining
878 : : * g_socket_listener_accept_async() calls will not have been destroyed,
879 : : * because there’s an independent set of `GSocketSource`s for each
880 : : * g_socket_listener_accept_async() call, rather than one `GSocketSource`
881 : : * for each socket in the `GSocketListener`.
882 : : *
883 : : * This is why we need sockets in the `GSocketListener` to be non-blocking:
884 : : * otherwise the above g_socket_accept() call would block. */
885 : 28 : if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
886 : : {
887 : 6 : g_clear_error (&error);
888 : 6 : return G_SOURCE_CONTINUE;
889 : : }
890 : :
891 : 22 : g_task_return_error (task, error);
892 : : }
893 : :
894 : : /* Explicitly clear the task data so we know the other sources are destroyed. */
895 : 254 : g_task_set_task_data (task, NULL, NULL);
896 : :
897 : : /* Drop the final reference to the @task. */
898 : 254 : g_object_unref (task);
899 : :
900 : 254 : return G_SOURCE_REMOVE;
901 : : }
902 : :
903 : : /**
904 : : * g_socket_listener_accept_socket_async:
905 : : * @listener: a #GSocketListener
906 : : * @cancellable: (nullable): a #GCancellable, or %NULL
907 : : * @callback: (scope async): a #GAsyncReadyCallback
908 : : * @user_data: user data for the callback
909 : : *
910 : : * This is the asynchronous version of g_socket_listener_accept_socket().
911 : : *
912 : : * When the operation is finished @callback will be
913 : : * called. You can then call g_socket_listener_accept_socket_finish()
914 : : * to get the result of the operation.
915 : : *
916 : : * Since: 2.22
917 : : */
918 : : void
919 : 277 : g_socket_listener_accept_socket_async (GSocketListener *listener,
920 : : GCancellable *cancellable,
921 : : GAsyncReadyCallback callback,
922 : : gpointer user_data)
923 : : {
924 : : GTask *task;
925 : 277 : GError *error = NULL;
926 : 277 : AcceptSocketAsyncData *data = NULL;
927 : :
928 : 277 : task = g_task_new (listener, cancellable, callback, user_data);
929 : 277 : g_task_set_source_tag (task, g_socket_listener_accept_socket_async);
930 : :
931 : 277 : if (!check_listener (listener, &error))
932 : : {
933 : 0 : g_task_return_error (task, error);
934 : 0 : g_object_unref (task);
935 : 0 : return;
936 : : }
937 : :
938 : : /* This transfers the one strong ref of @task to all of the sources. The first
939 : : * source to be ready will call g_socket_accept() and take ownership of the
940 : : * @task. The other callbacks have to return early (if dispatched) after
941 : : * that. */
942 : 277 : data = g_new0 (AcceptSocketAsyncData, 1);
943 : 277 : data->sources = add_sources (listener,
944 : : accept_ready,
945 : : task,
946 : : cancellable,
947 : : g_main_context_get_thread_default ());
948 : 277 : g_task_set_task_data (task, g_steal_pointer (&data),
949 : : (GDestroyNotify) accept_socket_async_data_free);
950 : : }
951 : :
952 : : /**
953 : : * g_socket_listener_accept_socket_finish:
954 : : * @listener: a #GSocketListener
955 : : * @result: a #GAsyncResult.
956 : : * @source_object: (out) (transfer none) (optional) (nullable): Optional #GObject identifying this source
957 : : * @error: a #GError location to store the error occurring, or %NULL to
958 : : * ignore.
959 : : *
960 : : * Finishes an async accept operation. See g_socket_listener_accept_socket_async()
961 : : *
962 : : * Returns: (transfer full): a #GSocket on success, %NULL on error.
963 : : *
964 : : * Since: 2.22
965 : : */
966 : : GSocket *
967 : 251 : g_socket_listener_accept_socket_finish (GSocketListener *listener,
968 : : GAsyncResult *result,
969 : : GObject **source_object,
970 : : GError **error)
971 : : {
972 : 251 : g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
973 : 251 : g_return_val_if_fail (g_task_is_valid (result, listener), NULL);
974 : :
975 : 251 : if (source_object)
976 : 244 : *source_object = g_object_get_qdata (G_OBJECT (result), source_quark);
977 : :
978 : 251 : return g_task_propagate_pointer (G_TASK (result), error);
979 : : }
980 : :
981 : : /**
982 : : * g_socket_listener_accept_async:
983 : : * @listener: a #GSocketListener
984 : : * @cancellable: (nullable): a #GCancellable, or %NULL
985 : : * @callback: (scope async): a #GAsyncReadyCallback
986 : : * @user_data: user data for the callback
987 : : *
988 : : * This is the asynchronous version of g_socket_listener_accept().
989 : : *
990 : : * When the operation is finished @callback will be
991 : : * called. You can then call g_socket_listener_accept_finish()
992 : : * to get the result of the operation.
993 : : *
994 : : * Since: 2.22
995 : : */
996 : : void
997 : 277 : g_socket_listener_accept_async (GSocketListener *listener,
998 : : GCancellable *cancellable,
999 : : GAsyncReadyCallback callback,
1000 : : gpointer user_data)
1001 : : {
1002 : 277 : g_socket_listener_accept_socket_async (listener,
1003 : : cancellable,
1004 : : callback,
1005 : : user_data);
1006 : 277 : }
1007 : :
1008 : : /**
1009 : : * g_socket_listener_accept_finish:
1010 : : * @listener: a #GSocketListener
1011 : : * @result: a #GAsyncResult.
1012 : : * @source_object: (out) (transfer none) (optional) (nullable): Optional #GObject identifying this source
1013 : : * @error: a #GError location to store the error occurring, or %NULL to
1014 : : * ignore.
1015 : : *
1016 : : * Finishes an async accept operation. See g_socket_listener_accept_async()
1017 : : *
1018 : : * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1019 : : *
1020 : : * Since: 2.22
1021 : : */
1022 : : GSocketConnection *
1023 : 251 : g_socket_listener_accept_finish (GSocketListener *listener,
1024 : : GAsyncResult *result,
1025 : : GObject **source_object,
1026 : : GError **error)
1027 : : {
1028 : : GSocket *socket;
1029 : : GSocketConnection *connection;
1030 : :
1031 : 251 : socket = g_socket_listener_accept_socket_finish (listener,
1032 : : result,
1033 : : source_object,
1034 : : error);
1035 : 251 : if (socket == NULL)
1036 : 19 : return NULL;
1037 : :
1038 : 232 : connection = g_socket_connection_factory_create_connection (socket);
1039 : 232 : g_object_unref (socket);
1040 : 232 : return connection;
1041 : : }
1042 : :
1043 : : /**
1044 : : * g_socket_listener_set_backlog:
1045 : : * @listener: a #GSocketListener
1046 : : * @listen_backlog: an integer
1047 : : *
1048 : : * Sets the listen backlog on the sockets in the listener. This must be called
1049 : : * before adding any sockets, addresses or ports to the #GSocketListener (for
1050 : : * example, by calling g_socket_listener_add_inet_port()) to be effective.
1051 : : *
1052 : : * See g_socket_set_listen_backlog() for details
1053 : : *
1054 : : * Since: 2.22
1055 : : */
1056 : : void
1057 : 62 : g_socket_listener_set_backlog (GSocketListener *listener,
1058 : : int listen_backlog)
1059 : : {
1060 : : GSocket *socket;
1061 : : guint i;
1062 : :
1063 : 62 : if (listener->priv->closed)
1064 : 0 : return;
1065 : :
1066 : 62 : listener->priv->listen_backlog = listen_backlog;
1067 : :
1068 : 62 : for (i = 0; i < listener->priv->sockets->len; i++)
1069 : : {
1070 : 0 : socket = listener->priv->sockets->pdata[i];
1071 : 0 : g_socket_set_listen_backlog (socket, listen_backlog);
1072 : : }
1073 : : }
1074 : :
1075 : : /**
1076 : : * g_socket_listener_close:
1077 : : * @listener: a #GSocketListener
1078 : : *
1079 : : * Closes all the sockets in the listener.
1080 : : *
1081 : : * Since: 2.22
1082 : : */
1083 : : void
1084 : 23 : g_socket_listener_close (GSocketListener *listener)
1085 : : {
1086 : : GSocket *socket;
1087 : : guint i;
1088 : :
1089 : 23 : g_return_if_fail (G_IS_SOCKET_LISTENER (listener));
1090 : :
1091 : 23 : if (listener->priv->closed)
1092 : 0 : return;
1093 : :
1094 : 43 : for (i = 0; i < listener->priv->sockets->len; i++)
1095 : : {
1096 : 20 : socket = listener->priv->sockets->pdata[i];
1097 : 20 : g_socket_close (socket, NULL);
1098 : : }
1099 : 23 : listener->priv->closed = TRUE;
1100 : : }
1101 : :
1102 : : /**
1103 : : * g_socket_listener_add_any_inet_port:
1104 : : * @listener: a #GSocketListener
1105 : : * @source_object: (nullable): Optional #GObject identifying this source
1106 : : * @error: a #GError location to store the error occurring, or %NULL to
1107 : : * ignore.
1108 : : *
1109 : : * Listens for TCP connections on any available port number for both
1110 : : * IPv6 and IPv4 (if each is available).
1111 : : *
1112 : : * This is useful if you need to have a socket for incoming connections
1113 : : * but don't care about the specific port number.
1114 : : *
1115 : : * If possible, the [class@Gio.SocketListener] will listen on both IPv4 and
1116 : : * IPv6 (listening on the same port on both). If listening on one of the socket
1117 : : * families fails, the [class@Gio.SocketListener] will only listen on the other.
1118 : : * If listening on both fails, an error will be returned.
1119 : : *
1120 : : * If you need to distinguish whether listening on IPv4 or IPv6 or both was
1121 : : * successful, connect to [signal@Gio.SocketListener::event].
1122 : : *
1123 : : * @source_object will be passed out in the various calls
1124 : : * to accept to identify this particular source, which is
1125 : : * useful if you're listening on multiple addresses and do
1126 : : * different things depending on what address is connected to.
1127 : : *
1128 : : * Returns: the port number, or 0 in case of failure.
1129 : : *
1130 : : * Since: 2.24
1131 : : **/
1132 : : guint16
1133 : 19 : g_socket_listener_add_any_inet_port (GSocketListener *listener,
1134 : : GObject *source_object,
1135 : : GError **error)
1136 : : {
1137 : 19 : GSList *sockets_to_close = NULL;
1138 : 19 : guint16 candidate_port = 0;
1139 : 19 : GSocket *socket6 = NULL;
1140 : 19 : GSocket *socket4 = NULL;
1141 : 19 : gint attempts = 37;
1142 : 19 : GError *socket4_listen_error = NULL, *socket6_listen_error = NULL;
1143 : :
1144 : : /*
1145 : : * multi-step process:
1146 : : * - first, create an IPv6 socket.
1147 : : * - if that fails, create an IPv4 socket and bind it to port 0 and
1148 : : * that's it. no retries if that fails (why would it?).
1149 : : * - if our IPv6 socket also speaks IPv4 then we are done.
1150 : : * - if not, then we need to create a IPv4 socket with the same port
1151 : : * number. this might fail, of course. so we try this a bunch of
1152 : : * times -- leaving the old IPv6 sockets open so that we get a
1153 : : * different port number to try each time.
1154 : : * - if all that fails then just give up.
1155 : : */
1156 : :
1157 : 19 : while (attempts--)
1158 : : {
1159 : : GInetAddress *inet_address;
1160 : : GSocketAddress *address;
1161 : : gboolean result;
1162 : :
1163 : 19 : g_assert (socket6 == NULL);
1164 : 19 : socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6,
1165 : : G_SOCKET_TYPE_STREAM,
1166 : : G_SOCKET_PROTOCOL_DEFAULT,
1167 : : NULL);
1168 : :
1169 : 19 : if (socket6 != NULL)
1170 : : {
1171 : 17 : inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
1172 : 17 : address = g_inet_socket_address_new (inet_address, 0);
1173 : 17 : g_object_unref (inet_address);
1174 : :
1175 : 17 : g_signal_emit (listener, signals[EVENT], 0,
1176 : : G_SOCKET_LISTENER_BINDING, socket6);
1177 : :
1178 : 17 : result = g_socket_bind (socket6, address, TRUE, error);
1179 : 17 : g_object_unref (address);
1180 : :
1181 : 32 : if (!result ||
1182 : 15 : !(address = g_socket_get_local_address (socket6, error)))
1183 : : {
1184 : 2 : g_clear_object (&socket6);
1185 : 2 : break;
1186 : : }
1187 : :
1188 : 15 : g_signal_emit (listener, signals[EVENT], 0,
1189 : : G_SOCKET_LISTENER_BOUND, socket6);
1190 : :
1191 : 15 : g_assert (G_IS_INET_SOCKET_ADDRESS (address));
1192 : : candidate_port =
1193 : 15 : g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
1194 : 15 : g_assert (candidate_port != 0);
1195 : 15 : g_object_unref (address);
1196 : :
1197 : 15 : if (g_socket_speaks_ipv4 (socket6))
1198 : 14 : break;
1199 : : }
1200 : :
1201 : 3 : g_assert (socket4 == NULL);
1202 : 3 : socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4,
1203 : : G_SOCKET_TYPE_STREAM,
1204 : : G_SOCKET_PROTOCOL_DEFAULT,
1205 : 3 : socket6 ? NULL : error);
1206 : :
1207 : 3 : if (socket4 == NULL)
1208 : : /* IPv4 not supported.
1209 : : * if IPv6 is supported then candidate_port will be non-zero
1210 : : * (and the error parameter above will have been NULL)
1211 : : * if IPv6 is unsupported then candidate_port will be zero
1212 : : * (and error will have been set by the above call)
1213 : : */
1214 : 1 : break;
1215 : :
1216 : 2 : inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
1217 : 2 : address = g_inet_socket_address_new (inet_address, candidate_port);
1218 : 2 : g_object_unref (inet_address);
1219 : :
1220 : 2 : g_signal_emit (listener, signals[EVENT], 0,
1221 : : G_SOCKET_LISTENER_BINDING, socket4);
1222 : :
1223 : : /* a note on the 'error' clause below:
1224 : : *
1225 : : * if candidate_port is 0 then we report the error right away
1226 : : * since it is strange that this binding would fail at all.
1227 : : * otherwise, we ignore the error message (ie: NULL).
1228 : : *
1229 : : * the exception to this rule is the last time through the loop
1230 : : * (ie: attempts == 0) in which case we want to set the error
1231 : : * because failure here means that the entire call will fail and
1232 : : * we need something to show to the user.
1233 : : *
1234 : : * an english summary of the situation: "if we gave a candidate
1235 : : * port number AND we have more attempts to try, then ignore the
1236 : : * error for now".
1237 : : */
1238 : 3 : result = g_socket_bind (socket4, address, TRUE,
1239 : 1 : (candidate_port && attempts) ? NULL : error);
1240 : 2 : g_object_unref (address);
1241 : :
1242 : 2 : if (candidate_port)
1243 : : {
1244 : 1 : g_assert (socket6 != NULL);
1245 : :
1246 : 1 : if (result)
1247 : : /* got our candidate port successfully */
1248 : : {
1249 : 1 : g_signal_emit (listener, signals[EVENT], 0,
1250 : : G_SOCKET_LISTENER_BOUND, socket4);
1251 : 1 : break;
1252 : : }
1253 : : else
1254 : : /* we failed to bind to the specified port. try again. */
1255 : : {
1256 : 0 : g_clear_object (&socket4);
1257 : :
1258 : : /* keep this open so we get a different port number */
1259 : 0 : sockets_to_close = g_slist_prepend (sockets_to_close,
1260 : : g_steal_pointer (&socket6));
1261 : 0 : candidate_port = 0;
1262 : : }
1263 : : }
1264 : : else
1265 : : /* we didn't tell it a port. this means two things.
1266 : : * - if we failed, then something really bad happened.
1267 : : * - if we succeeded, then we need to find out the port number.
1268 : : */
1269 : : {
1270 : 1 : g_assert (socket6 == NULL);
1271 : :
1272 : 2 : if (!result ||
1273 : 1 : !(address = g_socket_get_local_address (socket4, error)))
1274 : : {
1275 : 0 : g_clear_object (&socket4);
1276 : 0 : break;
1277 : : }
1278 : :
1279 : 1 : g_signal_emit (listener, signals[EVENT], 0,
1280 : : G_SOCKET_LISTENER_BOUND, socket4);
1281 : :
1282 : 1 : g_assert (G_IS_INET_SOCKET_ADDRESS (address));
1283 : : candidate_port =
1284 : 1 : g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
1285 : 1 : g_assert (candidate_port != 0);
1286 : 1 : g_object_unref (address);
1287 : 1 : break;
1288 : : }
1289 : : }
1290 : :
1291 : : /* should only be non-zero if we have a socket */
1292 : 19 : g_assert ((candidate_port != 0) == (socket4 || socket6));
1293 : :
1294 : 19 : g_slist_free_full (g_steal_pointer (&sockets_to_close), g_object_unref);
1295 : :
1296 : : /* now we actually listen() the sockets and add them to the listener. If
1297 : : * either of the listen()s fails, only return the other socket. Fail if both
1298 : : * failed. */
1299 : 19 : if (socket6 != NULL)
1300 : : {
1301 : 15 : g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog);
1302 : :
1303 : 15 : g_signal_emit (listener, signals[EVENT], 0,
1304 : : G_SOCKET_LISTENER_LISTENING, socket6);
1305 : :
1306 : 15 : if (g_socket_listen (socket6, &socket6_listen_error))
1307 : : {
1308 : 12 : g_signal_emit (listener, signals[EVENT], 0,
1309 : : G_SOCKET_LISTENER_LISTENED, socket6);
1310 : :
1311 : 12 : add_socket (listener, socket6, source_object, TRUE);
1312 : : }
1313 : : else
1314 : : {
1315 : 3 : g_clear_object (&socket6);
1316 : : }
1317 : : }
1318 : :
1319 : 19 : if (socket4 != NULL)
1320 : : {
1321 : 2 : g_socket_set_listen_backlog (socket4, listener->priv->listen_backlog);
1322 : :
1323 : 2 : g_signal_emit (listener, signals[EVENT], 0,
1324 : : G_SOCKET_LISTENER_LISTENING, socket4);
1325 : :
1326 : 2 : if (g_socket_listen (socket4, &socket4_listen_error))
1327 : : {
1328 : 2 : g_signal_emit (listener, signals[EVENT], 0,
1329 : : G_SOCKET_LISTENER_LISTENED, socket4);
1330 : :
1331 : 2 : add_socket (listener, socket4, source_object, TRUE);
1332 : : }
1333 : : else
1334 : : {
1335 : 0 : g_clear_object (&socket4);
1336 : : }
1337 : : }
1338 : :
1339 : : /* Error out if both listen() calls failed (or if there’s no separate IPv4
1340 : : * socket and the IPv6 listen() call failed). */
1341 : 19 : if (socket6_listen_error != NULL &&
1342 : 3 : (socket4 == NULL || socket4_listen_error != NULL))
1343 : : {
1344 : 4 : GError **set_error = ((socket6_listen_error != NULL) ?
1345 : 2 : &socket6_listen_error :
1346 : : &socket4_listen_error);
1347 : 2 : g_propagate_error (error, g_steal_pointer (set_error));
1348 : :
1349 : 2 : g_clear_error (&socket6_listen_error);
1350 : 2 : g_clear_error (&socket4_listen_error);
1351 : :
1352 : 2 : g_clear_object (&socket6);
1353 : 2 : g_clear_object (&socket4);
1354 : :
1355 : 2 : return 0;
1356 : : }
1357 : :
1358 : 17 : g_clear_error (&socket6_listen_error);
1359 : 17 : g_clear_error (&socket4_listen_error);
1360 : :
1361 : 17 : if ((socket4 != NULL || socket6 != NULL) &&
1362 : 14 : G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
1363 : 9 : G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
1364 : :
1365 : 17 : g_clear_object (&socket6);
1366 : 17 : g_clear_object (&socket4);
1367 : :
1368 : 17 : return candidate_port;
1369 : : }
|