Merge branch '976-disable-assert-checks' into 'master'
[glib.git] / gio / gnetworkmonitor.c
blob657c7047a9fae5e9225aaa197d8670f601942cbd
1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright 2011 Red Hat, Inc
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include "config.h"
20 #include "glib.h"
21 #include "glibintl.h"
23 #include "gnetworkmonitor.h"
24 #include "ginetaddress.h"
25 #include "ginetsocketaddress.h"
26 #include "ginitable.h"
27 #include "gioenumtypes.h"
28 #include "giomodule-priv.h"
29 #include "gtask.h"
31 /**
32 * SECTION:gnetworkmonitor
33 * @title: GNetworkMonitor
34 * @short_description: Network status monitor
35 * @include: gio/gio.h
37 * #GNetworkMonitor provides an easy-to-use cross-platform API
38 * for monitoring network connectivity. On Linux, the available
39 * implementations are based on the kernel's netlink interface and
40 * on NetworkManager.
42 * There is also an implementation for use inside Flatpak sandboxes.
45 /**
46 * GNetworkMonitor:
48 * #GNetworkMonitor monitors the status of network connections and
49 * indicates when a possibly-user-visible change has occurred.
51 * Since: 2.32
54 /**
55 * GNetworkMonitorInterface:
56 * @g_iface: The parent interface.
57 * @network_changed: the virtual function pointer for the
58 * GNetworkMonitor::network-changed signal.
59 * @can_reach: the virtual function pointer for g_network_monitor_can_reach()
60 * @can_reach_async: the virtual function pointer for
61 * g_network_monitor_can_reach_async()
62 * @can_reach_finish: the virtual function pointer for
63 * g_network_monitor_can_reach_finish()
65 * The virtual function table for #GNetworkMonitor.
67 * Since: 2.32
70 G_DEFINE_INTERFACE_WITH_CODE (GNetworkMonitor, g_network_monitor, G_TYPE_OBJECT,
71 g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_INITABLE);)
74 enum {
75 NETWORK_CHANGED,
76 LAST_SIGNAL
79 static guint signals[LAST_SIGNAL] = { 0 };
81 /**
82 * g_network_monitor_get_default:
84 * Gets the default #GNetworkMonitor for the system.
86 * Returns: (transfer none): a #GNetworkMonitor
88 * Since: 2.32
90 GNetworkMonitor *
91 g_network_monitor_get_default (void)
93 return _g_io_module_get_default (G_NETWORK_MONITOR_EXTENSION_POINT_NAME,
94 "GIO_USE_NETWORK_MONITOR",
95 NULL);
98 /**
99 * g_network_monitor_get_network_available:
100 * @monitor: the #GNetworkMonitor
102 * Checks if the network is available. "Available" here means that the
103 * system has a default route available for at least one of IPv4 or
104 * IPv6. It does not necessarily imply that the public Internet is
105 * reachable. See #GNetworkMonitor:network-available for more details.
107 * Returns: whether the network is available
109 * Since: 2.32
111 gboolean
112 g_network_monitor_get_network_available (GNetworkMonitor *monitor)
114 gboolean available = FALSE;
116 g_object_get (G_OBJECT (monitor), "network-available", &available, NULL);
117 return available;
121 * g_network_monitor_get_network_metered:
122 * @monitor: the #GNetworkMonitor
124 * Checks if the network is metered.
125 * See #GNetworkMonitor:network-metered for more details.
127 * Returns: whether the connection is metered
129 * Since: 2.46
131 gboolean
132 g_network_monitor_get_network_metered (GNetworkMonitor *monitor)
134 gboolean metered = FALSE;
136 g_object_get (G_OBJECT (monitor), "network-metered", &metered, NULL);
137 return metered;
141 * g_network_monitor_get_connectivity:
142 * @monitor: the #GNetworkMonitor
144 * Gets a more detailed networking state than
145 * g_network_monitor_get_network_available().
147 * If #GNetworkMonitor:network-available is %FALSE, then the
148 * connectivity state will be %G_NETWORK_CONNECTIVITY_LOCAL.
150 * If #GNetworkMonitor:network-available is %TRUE, then the
151 * connectivity state will be %G_NETWORK_CONNECTIVITY_FULL (if there
152 * is full Internet connectivity), %G_NETWORK_CONNECTIVITY_LIMITED (if
153 * the host has a default route, but appears to be unable to actually
154 * reach the full Internet), or %G_NETWORK_CONNECTIVITY_PORTAL (if the
155 * host is trapped behind a "captive portal" that requires some sort
156 * of login or acknowledgement before allowing full Internet access).
158 * Note that in the case of %G_NETWORK_CONNECTIVITY_LIMITED and
159 * %G_NETWORK_CONNECTIVITY_PORTAL, it is possible that some sites are
160 * reachable but others are not. In this case, applications can
161 * attempt to connect to remote servers, but should gracefully fall
162 * back to their "offline" behavior if the connection attempt fails.
164 * Return value: the network connectivity state
166 * Since: 2.44
168 GNetworkConnectivity
169 g_network_monitor_get_connectivity (GNetworkMonitor *monitor)
171 GNetworkConnectivity connectivity;
173 g_object_get (G_OBJECT (monitor), "connectivity", &connectivity, NULL);
175 return connectivity;
179 * g_network_monitor_can_reach:
180 * @monitor: a #GNetworkMonitor
181 * @connectable: a #GSocketConnectable
182 * @cancellable: (nullable): a #GCancellable, or %NULL
183 * @error: return location for a #GError, or %NULL
185 * Attempts to determine whether or not the host pointed to by
186 * @connectable can be reached, without actually trying to connect to
187 * it.
189 * This may return %TRUE even when #GNetworkMonitor:network-available
190 * is %FALSE, if, for example, @monitor can determine that
191 * @connectable refers to a host on a local network.
193 * If @monitor believes that an attempt to connect to @connectable
194 * will succeed, it will return %TRUE. Otherwise, it will return
195 * %FALSE and set @error to an appropriate error (such as
196 * %G_IO_ERROR_HOST_UNREACHABLE).
198 * Note that although this does not attempt to connect to
199 * @connectable, it may still block for a brief period of time (eg,
200 * trying to do multicast DNS on the local network), so if you do not
201 * want to block, you should use g_network_monitor_can_reach_async().
203 * Returns: %TRUE if @connectable is reachable, %FALSE if not.
205 * Since: 2.32
207 gboolean
208 g_network_monitor_can_reach (GNetworkMonitor *monitor,
209 GSocketConnectable *connectable,
210 GCancellable *cancellable,
211 GError **error)
213 GNetworkMonitorInterface *iface;
215 iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
216 return iface->can_reach (monitor, connectable, cancellable, error);
219 static void
220 g_network_monitor_real_can_reach_async (GNetworkMonitor *monitor,
221 GSocketConnectable *connectable,
222 GCancellable *cancellable,
223 GAsyncReadyCallback callback,
224 gpointer user_data)
226 GTask *task;
227 GError *error = NULL;
229 task = g_task_new (monitor, cancellable, callback, user_data);
230 g_task_set_source_tag (task, g_network_monitor_real_can_reach_async);
232 if (g_network_monitor_can_reach (monitor, connectable, cancellable, &error))
233 g_task_return_boolean (task, TRUE);
234 else
235 g_task_return_error (task, error);
236 g_object_unref (task);
240 * g_network_monitor_can_reach_async:
241 * @monitor: a #GNetworkMonitor
242 * @connectable: a #GSocketConnectable
243 * @cancellable: (nullable): a #GCancellable, or %NULL
244 * @callback: (scope async): a #GAsyncReadyCallback to call when the
245 * request is satisfied
246 * @user_data: (closure): the data to pass to callback function
248 * Asynchronously attempts to determine whether or not the host
249 * pointed to by @connectable can be reached, without actually
250 * trying to connect to it.
252 * For more details, see g_network_monitor_can_reach().
254 * When the operation is finished, @callback will be called.
255 * You can then call g_network_monitor_can_reach_finish()
256 * to get the result of the operation.
258 void
259 g_network_monitor_can_reach_async (GNetworkMonitor *monitor,
260 GSocketConnectable *connectable,
261 GCancellable *cancellable,
262 GAsyncReadyCallback callback,
263 gpointer user_data)
265 GNetworkMonitorInterface *iface;
267 iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
268 iface->can_reach_async (monitor, connectable, cancellable, callback, user_data);
271 static gboolean
272 g_network_monitor_real_can_reach_finish (GNetworkMonitor *monitor,
273 GAsyncResult *result,
274 GError **error)
276 g_return_val_if_fail (g_task_is_valid (result, monitor), FALSE);
278 return g_task_propagate_boolean (G_TASK (result), error);
282 * g_network_monitor_can_reach_finish:
283 * @monitor: a #GNetworkMonitor
284 * @result: a #GAsyncResult
285 * @error: return location for errors, or %NULL
287 * Finishes an async network connectivity test.
288 * See g_network_monitor_can_reach_async().
290 * Returns: %TRUE if network is reachable, %FALSE if not.
292 gboolean
293 g_network_monitor_can_reach_finish (GNetworkMonitor *monitor,
294 GAsyncResult *result,
295 GError **error)
297 GNetworkMonitorInterface *iface;
299 iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
300 return iface->can_reach_finish (monitor, result, error);
303 static void
304 g_network_monitor_default_init (GNetworkMonitorInterface *iface)
306 iface->can_reach_async = g_network_monitor_real_can_reach_async;
307 iface->can_reach_finish = g_network_monitor_real_can_reach_finish;
310 * GNetworkMonitor::network-changed:
311 * @monitor: a #GNetworkMonitor
312 * @network_available: the current value of #GNetworkMonitor:network-available
314 * Emitted when the network configuration changes.
316 * Since: 2.32
318 signals[NETWORK_CHANGED] =
319 g_signal_new (I_("network-changed"),
320 G_TYPE_NETWORK_MONITOR,
321 G_SIGNAL_RUN_LAST,
322 G_STRUCT_OFFSET (GNetworkMonitorInterface, network_changed),
323 NULL, NULL,
324 g_cclosure_marshal_VOID__BOOLEAN,
325 G_TYPE_NONE, 1,
326 G_TYPE_BOOLEAN);
329 * GNetworkMonitor:network-available:
331 * Whether the network is considered available. That is, whether the
332 * system has a default route for at least one of IPv4 or IPv6.
334 * Real-world networks are of course much more complicated than
335 * this; the machine may be connected to a wifi hotspot that
336 * requires payment before allowing traffic through, or may be
337 * connected to a functioning router that has lost its own upstream
338 * connectivity. Some hosts might only be accessible when a VPN is
339 * active. Other hosts might only be accessible when the VPN is
340 * not active. Thus, it is best to use g_network_monitor_can_reach()
341 * or g_network_monitor_can_reach_async() to test for reachability
342 * on a host-by-host basis. (On the other hand, when the property is
343 * %FALSE, the application can reasonably expect that no remote
344 * hosts at all are reachable, and should indicate this to the user
345 * in its UI.)
347 * See also #GNetworkMonitor::network-changed.
349 * Since: 2.32
351 g_object_interface_install_property (iface,
352 g_param_spec_boolean ("network-available",
353 P_("Network available"),
354 P_("Whether the network is available"),
355 FALSE,
356 G_PARAM_READABLE |
357 G_PARAM_STATIC_STRINGS));
360 * GNetworkMonitor:network-metered:
362 * Whether the network is considered metered. That is, whether the
363 * system has traffic flowing through the default connection that is
364 * subject to limitations set by service providers. For example, traffic
365 * might be billed by the amount of data transmitted, or there might be a
366 * quota on the amount of traffic per month. This is typical with tethered
367 * connections (3G and 4G) and in such situations, bandwidth intensive
368 * applications may wish to avoid network activity where possible if it will
369 * cost the user money or use up their limited quota.
371 * If more information is required about specific devices then the
372 * system network management API should be used instead (for example,
373 * NetworkManager or ConnMan).
375 * If this information is not available then no networks will be
376 * marked as metered.
378 * See also #GNetworkMonitor:network-available.
380 * Since: 2.46
382 g_object_interface_install_property (iface,
383 g_param_spec_boolean ("network-metered",
384 P_("Network metered"),
385 P_("Whether the network is metered"),
386 FALSE,
387 G_PARAM_READABLE |
388 G_PARAM_STATIC_STRINGS));
391 * GNetworkMonitor:connectivity:
393 * More detailed information about the host's network connectivity.
394 * See g_network_monitor_get_connectivity() and
395 * #GNetworkConnectivity for more details.
397 * Since: 2.44
399 g_object_interface_install_property (iface,
400 g_param_spec_enum ("connectivity",
401 P_("Network connectivity"),
402 P_("Level of network connectivity"),
403 G_TYPE_NETWORK_CONNECTIVITY,
404 G_NETWORK_CONNECTIVITY_FULL,
405 G_PARAM_READABLE |
406 G_PARAM_STATIC_STRINGS));