1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright 2011 Red Hat, Inc
5 * SPDX-License-Identifier: LGPL-2.1-or-later
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.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "gnetworkmonitor.h"
26 #include "ginetaddress.h"
27 #include "ginetsocketaddress.h"
28 #include "ginitable.h"
29 #include "gioenumtypes.h"
30 #include "giomodule-priv.h"
34 * SECTION:gnetworkmonitor
35 * @title: GNetworkMonitor
36 * @short_description: Network status monitor
39 * #GNetworkMonitor provides an easy-to-use cross-platform API
40 * for monitoring network connectivity. On Linux, the available
41 * implementations are based on the kernel's netlink interface and
44 * There is also an implementation for use inside Flatpak sandboxes.
50 * #GNetworkMonitor monitors the status of network connections and
51 * indicates when a possibly-user-visible change has occurred.
57 * GNetworkMonitorInterface:
58 * @g_iface: The parent interface.
59 * @network_changed: the virtual function pointer for the
60 * GNetworkMonitor::network-changed signal.
61 * @can_reach: the virtual function pointer for g_network_monitor_can_reach()
62 * @can_reach_async: the virtual function pointer for
63 * g_network_monitor_can_reach_async()
64 * @can_reach_finish: the virtual function pointer for
65 * g_network_monitor_can_reach_finish()
67 * The virtual function table for #GNetworkMonitor.
72 G_DEFINE_INTERFACE_WITH_CODE (GNetworkMonitor, g_network_monitor, G_TYPE_OBJECT,
73 g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_INITABLE))
81 static guint signals[LAST_SIGNAL] = { 0 };
82 static GNetworkMonitor *network_monitor_default_singleton = NULL; /* (owned) (atomic) */
85 * g_network_monitor_get_default:
87 * Gets the default #GNetworkMonitor for the system.
89 * Returns: (not nullable) (transfer none): a #GNetworkMonitor, which will be
90 * a dummy object if no network monitor is available
95 g_network_monitor_get_default (void)
97 if (g_once_init_enter (&network_monitor_default_singleton))
99 GNetworkMonitor *singleton;
101 singleton = _g_io_module_get_default (G_NETWORK_MONITOR_EXTENSION_POINT_NAME,
102 "GIO_USE_NETWORK_MONITOR",
105 g_once_init_leave (&network_monitor_default_singleton, singleton);
108 return network_monitor_default_singleton;
112 * g_network_monitor_get_network_available:
113 * @monitor: the #GNetworkMonitor
115 * Checks if the network is available. "Available" here means that the
116 * system has a default route available for at least one of IPv4 or
117 * IPv6. It does not necessarily imply that the public Internet is
118 * reachable. See #GNetworkMonitor:network-available for more details.
120 * Returns: whether the network is available
125 g_network_monitor_get_network_available (GNetworkMonitor *monitor)
127 gboolean available = FALSE;
129 g_object_get (G_OBJECT (monitor), "network-available", &available, NULL);
134 * g_network_monitor_get_network_metered:
135 * @monitor: the #GNetworkMonitor
137 * Checks if the network is metered.
138 * See #GNetworkMonitor:network-metered for more details.
140 * Returns: whether the connection is metered
145 g_network_monitor_get_network_metered (GNetworkMonitor *monitor)
147 gboolean metered = FALSE;
149 g_object_get (G_OBJECT (monitor), "network-metered", &metered, NULL);
154 * g_network_monitor_get_connectivity:
155 * @monitor: the #GNetworkMonitor
157 * Gets a more detailed networking state than
158 * g_network_monitor_get_network_available().
160 * If #GNetworkMonitor:network-available is %FALSE, then the
161 * connectivity state will be %G_NETWORK_CONNECTIVITY_LOCAL.
163 * If #GNetworkMonitor:network-available is %TRUE, then the
164 * connectivity state will be %G_NETWORK_CONNECTIVITY_FULL (if there
165 * is full Internet connectivity), %G_NETWORK_CONNECTIVITY_LIMITED (if
166 * the host has a default route, but appears to be unable to actually
167 * reach the full Internet), or %G_NETWORK_CONNECTIVITY_PORTAL (if the
168 * host is trapped behind a "captive portal" that requires some sort
169 * of login or acknowledgement before allowing full Internet access).
171 * Note that in the case of %G_NETWORK_CONNECTIVITY_LIMITED and
172 * %G_NETWORK_CONNECTIVITY_PORTAL, it is possible that some sites are
173 * reachable but others are not. In this case, applications can
174 * attempt to connect to remote servers, but should gracefully fall
175 * back to their "offline" behavior if the connection attempt fails.
177 * Return value: the network connectivity state
182 g_network_monitor_get_connectivity (GNetworkMonitor *monitor)
184 GNetworkConnectivity connectivity;
186 g_object_get (G_OBJECT (monitor), "connectivity", &connectivity, NULL);
192 * g_network_monitor_can_reach:
193 * @monitor: a #GNetworkMonitor
194 * @connectable: a #GSocketConnectable
195 * @cancellable: (nullable): a #GCancellable, or %NULL
196 * @error: return location for a #GError, or %NULL
198 * Attempts to determine whether or not the host pointed to by
199 * @connectable can be reached, without actually trying to connect to
202 * This may return %TRUE even when #GNetworkMonitor:network-available
203 * is %FALSE, if, for example, @monitor can determine that
204 * @connectable refers to a host on a local network.
206 * If @monitor believes that an attempt to connect to @connectable
207 * will succeed, it will return %TRUE. Otherwise, it will return
208 * %FALSE and set @error to an appropriate error (such as
209 * %G_IO_ERROR_HOST_UNREACHABLE).
211 * Note that although this does not attempt to connect to
212 * @connectable, it may still block for a brief period of time (eg,
213 * trying to do multicast DNS on the local network), so if you do not
214 * want to block, you should use g_network_monitor_can_reach_async().
216 * Returns: %TRUE if @connectable is reachable, %FALSE if not.
221 g_network_monitor_can_reach (GNetworkMonitor *monitor,
222 GSocketConnectable *connectable,
223 GCancellable *cancellable,
226 GNetworkMonitorInterface *iface;
228 iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
229 return iface->can_reach (monitor, connectable, cancellable, error);
233 g_network_monitor_real_can_reach_async (GNetworkMonitor *monitor,
234 GSocketConnectable *connectable,
235 GCancellable *cancellable,
236 GAsyncReadyCallback callback,
240 GError *error = NULL;
242 task = g_task_new (monitor, cancellable, callback, user_data);
243 g_task_set_source_tag (task, g_network_monitor_real_can_reach_async);
245 if (g_network_monitor_can_reach (monitor, connectable, cancellable, &error))
246 g_task_return_boolean (task, TRUE);
248 g_task_return_error (task, error);
249 g_object_unref (task);
253 * g_network_monitor_can_reach_async:
254 * @monitor: a #GNetworkMonitor
255 * @connectable: a #GSocketConnectable
256 * @cancellable: (nullable): a #GCancellable, or %NULL
257 * @callback: (scope async): a #GAsyncReadyCallback
258 * to call when the request is satisfied
259 * @user_data: the data to pass to callback function
261 * Asynchronously attempts to determine whether or not the host
262 * pointed to by @connectable can be reached, without actually
263 * trying to connect to it.
265 * For more details, see g_network_monitor_can_reach().
267 * When the operation is finished, @callback will be called.
268 * You can then call g_network_monitor_can_reach_finish()
269 * to get the result of the operation.
272 g_network_monitor_can_reach_async (GNetworkMonitor *monitor,
273 GSocketConnectable *connectable,
274 GCancellable *cancellable,
275 GAsyncReadyCallback callback,
278 GNetworkMonitorInterface *iface;
280 iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
281 iface->can_reach_async (monitor, connectable, cancellable, callback, user_data);
285 g_network_monitor_real_can_reach_finish (GNetworkMonitor *monitor,
286 GAsyncResult *result,
289 g_return_val_if_fail (g_task_is_valid (result, monitor), FALSE);
291 return g_task_propagate_boolean (G_TASK (result), error);
295 * g_network_monitor_can_reach_finish:
296 * @monitor: a #GNetworkMonitor
297 * @result: a #GAsyncResult
298 * @error: return location for errors, or %NULL
300 * Finishes an async network connectivity test.
301 * See g_network_monitor_can_reach_async().
303 * Returns: %TRUE if network is reachable, %FALSE if not.
306 g_network_monitor_can_reach_finish (GNetworkMonitor *monitor,
307 GAsyncResult *result,
310 GNetworkMonitorInterface *iface;
312 iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
313 return iface->can_reach_finish (monitor, result, error);
317 g_network_monitor_default_init (GNetworkMonitorInterface *iface)
319 iface->can_reach_async = g_network_monitor_real_can_reach_async;
320 iface->can_reach_finish = g_network_monitor_real_can_reach_finish;
323 * GNetworkMonitor::network-changed:
324 * @monitor: a #GNetworkMonitor
325 * @network_available: the current value of #GNetworkMonitor:network-available
327 * Emitted when the network configuration changes.
331 signals[NETWORK_CHANGED] =
332 g_signal_new (I_("network-changed"),
333 G_TYPE_NETWORK_MONITOR,
335 G_STRUCT_OFFSET (GNetworkMonitorInterface, network_changed),
342 * GNetworkMonitor:network-available:
344 * Whether the network is considered available. That is, whether the
345 * system has a default route for at least one of IPv4 or IPv6.
347 * Real-world networks are of course much more complicated than
348 * this; the machine may be connected to a wifi hotspot that
349 * requires payment before allowing traffic through, or may be
350 * connected to a functioning router that has lost its own upstream
351 * connectivity. Some hosts might only be accessible when a VPN is
352 * active. Other hosts might only be accessible when the VPN is
353 * not active. Thus, it is best to use g_network_monitor_can_reach()
354 * or g_network_monitor_can_reach_async() to test for reachability
355 * on a host-by-host basis. (On the other hand, when the property is
356 * %FALSE, the application can reasonably expect that no remote
357 * hosts at all are reachable, and should indicate this to the user
360 * See also #GNetworkMonitor::network-changed.
364 g_object_interface_install_property (iface,
365 g_param_spec_boolean ("network-available",
366 P_("Network available"),
367 P_("Whether the network is available"),
370 G_PARAM_STATIC_STRINGS));
373 * GNetworkMonitor:network-metered:
375 * Whether the network is considered metered.
377 * That is, whether the
378 * system has traffic flowing through the default connection that is
379 * subject to limitations set by service providers. For example, traffic
380 * might be billed by the amount of data transmitted, or there might be a
381 * quota on the amount of traffic per month. This is typical with tethered
382 * connections (3G and 4G) and in such situations, bandwidth intensive
383 * applications may wish to avoid network activity where possible if it will
384 * cost the user money or use up their limited quota. Anything more than a
385 * few hundreds of kilobytes of data usage per hour should be avoided without
386 * asking permission from the user.
388 * If more information is required about specific devices then the
389 * system network management API should be used instead (for example,
390 * NetworkManager or ConnMan).
392 * If this information is not available then no networks will be
395 * See also #GNetworkMonitor:network-available.
399 g_object_interface_install_property (iface,
400 g_param_spec_boolean ("network-metered",
401 P_("Network metered"),
402 P_("Whether the network is metered"),
405 G_PARAM_STATIC_STRINGS));
408 * GNetworkMonitor:connectivity:
410 * More detailed information about the host's network connectivity.
411 * See g_network_monitor_get_connectivity() and
412 * #GNetworkConnectivity for more details.
416 g_object_interface_install_property (iface,
417 g_param_spec_enum ("connectivity",
418 P_("Network connectivity"),
419 P_("Level of network connectivity"),
420 G_TYPE_NETWORK_CONNECTIVITY,
421 G_NETWORK_CONNECTIVITY_FULL,
423 G_PARAM_STATIC_STRINGS));