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 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/>.
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"
32 * SECTION:gnetworkmonitor
33 * @title: GNetworkMonitor
34 * @short_description: Network status monitor
37 * #GNetworkMonitor provides an easy-to-use cross-platform API
38 * for monitoring network connectivity. On Linux, the implementation
39 * is based on the kernel's netlink interface.
45 * #GNetworkMonitor monitors the status of network connections and
46 * indicates when a possibly-user-visible change has occurred.
52 * GNetworkMonitorInterface:
53 * @g_iface: The parent interface.
54 * @network_changed: the virtual function pointer for the
55 * GNetworkMonitor::network-changed signal.
56 * @can_reach: the virtual function pointer for g_network_monitor_can_reach()
57 * @can_reach_async: the virtual function pointer for
58 * g_network_monitor_can_reach_async()
59 * @can_reach_finish: the virtual function pointer for
60 * g_network_monitor_can_reach_finish()
62 * The virtual function table for #GNetworkMonitor.
67 G_DEFINE_INTERFACE_WITH_CODE (GNetworkMonitor
, g_network_monitor
, G_TYPE_OBJECT
,
68 g_type_interface_add_prerequisite (g_define_type_id
, G_TYPE_INITABLE
);)
76 static guint signals
[LAST_SIGNAL
] = { 0 };
79 * g_network_monitor_get_default:
81 * Gets the default #GNetworkMonitor for the system.
83 * Returns: (transfer none): a #GNetworkMonitor
88 g_network_monitor_get_default (void)
90 return _g_io_module_get_default (G_NETWORK_MONITOR_EXTENSION_POINT_NAME
,
91 "GIO_USE_NETWORK_MONITOR",
96 * g_network_monitor_get_network_available:
97 * @monitor: the #GNetworkMonitor
99 * Checks if the network is available. "Available" here means that the
100 * system has a default route available for at least one of IPv4 or
101 * IPv6. It does not necessarily imply that the public Internet is
102 * reachable. See #GNetworkMonitor:network-available for more details.
104 * Returns: whether the network is available
109 g_network_monitor_get_network_available (GNetworkMonitor
*monitor
)
111 gboolean available
= FALSE
;
113 g_object_get (G_OBJECT (monitor
), "network-available", &available
, NULL
);
118 * g_network_monitor_get_network_metered:
119 * @monitor: the #GNetworkMonitor
121 * Checks if the network is metered.
122 * See #GNetworkMonitor:network-metered for more details.
124 * Returns: whether the connection is metered
129 g_network_monitor_get_network_metered (GNetworkMonitor
*monitor
)
131 gboolean metered
= FALSE
;
133 g_object_get (G_OBJECT (monitor
), "network-metered", &metered
, NULL
);
138 * g_network_monitor_get_connectivity:
139 * @monitor: the #GNetworkMonitor
141 * Gets a more detailed networking state than
142 * g_network_monitor_get_network_available().
144 * If #GNetworkMonitor:network-available is %FALSE, then the
145 * connectivity state will be %G_NETWORK_CONNECTIVITY_LOCAL.
147 * If #GNetworkMonitor:network-available is %TRUE, then the
148 * connectivity state will be %G_NETWORK_CONNECTIVITY_FULL (if there
149 * is full Internet connectivity), %G_NETWORK_CONNECTIVITY_LIMITED (if
150 * the host has a default route, but appears to be unable to actually
151 * reach the full Internet), or %G_NETWORK_CONNECTIVITY_PORTAL (if the
152 * host is trapped behind a "captive portal" that requires some sort
153 * of login or acknowledgement before allowing full Internet access).
155 * Note that in the case of %G_NETWORK_CONNECTIVITY_LIMITED and
156 * %G_NETWORK_CONNECTIVITY_PORTAL, it is possible that some sites are
157 * reachable but others are not. In this case, applications can
158 * attempt to connect to remote servers, but should gracefully fall
159 * back to their "offline" behavior if the connection attempt fails.
161 * Return value: the network connectivity state
166 g_network_monitor_get_connectivity (GNetworkMonitor
*monitor
)
168 GNetworkConnectivity connectivity
;
170 g_object_get (G_OBJECT (monitor
), "connectivity", &connectivity
, NULL
);
176 * g_network_monitor_can_reach:
177 * @monitor: a #GNetworkMonitor
178 * @connectable: a #GSocketConnectable
179 * @cancellable: (nullable): a #GCancellable, or %NULL
180 * @error: return location for a #GError, or %NULL
182 * Attempts to determine whether or not the host pointed to by
183 * @connectable can be reached, without actually trying to connect to
186 * This may return %TRUE even when #GNetworkMonitor:network-available
187 * is %FALSE, if, for example, @monitor can determine that
188 * @connectable refers to a host on a local network.
190 * If @monitor believes that an attempt to connect to @connectable
191 * will succeed, it will return %TRUE. Otherwise, it will return
192 * %FALSE and set @error to an appropriate error (such as
193 * %G_IO_ERROR_HOST_UNREACHABLE).
195 * Note that although this does not attempt to connect to
196 * @connectable, it may still block for a brief period of time (eg,
197 * trying to do multicast DNS on the local network), so if you do not
198 * want to block, you should use g_network_monitor_can_reach_async().
200 * Returns: %TRUE if @connectable is reachable, %FALSE if not.
205 g_network_monitor_can_reach (GNetworkMonitor
*monitor
,
206 GSocketConnectable
*connectable
,
207 GCancellable
*cancellable
,
210 GNetworkMonitorInterface
*iface
;
212 iface
= G_NETWORK_MONITOR_GET_INTERFACE (monitor
);
213 return iface
->can_reach (monitor
, connectable
, cancellable
, error
);
217 g_network_monitor_real_can_reach_async (GNetworkMonitor
*monitor
,
218 GSocketConnectable
*connectable
,
219 GCancellable
*cancellable
,
220 GAsyncReadyCallback callback
,
224 GError
*error
= NULL
;
226 task
= g_task_new (monitor
, cancellable
, callback
, user_data
);
227 g_task_set_source_tag (task
, g_network_monitor_real_can_reach_async
);
229 if (g_network_monitor_can_reach (monitor
, connectable
, cancellable
, &error
))
230 g_task_return_boolean (task
, TRUE
);
232 g_task_return_error (task
, error
);
233 g_object_unref (task
);
237 * g_network_monitor_can_reach_async:
238 * @monitor: a #GNetworkMonitor
239 * @connectable: a #GSocketConnectable
240 * @cancellable: (nullable): a #GCancellable, or %NULL
241 * @callback: (scope async): a #GAsyncReadyCallback to call when the
242 * request is satisfied
243 * @user_data: (closure): the data to pass to callback function
245 * Asynchronously attempts to determine whether or not the host
246 * pointed to by @connectable can be reached, without actually
247 * trying to connect to it.
249 * For more details, see g_network_monitor_can_reach().
251 * When the operation is finished, @callback will be called.
252 * You can then call g_network_monitor_can_reach_finish()
253 * to get the result of the operation.
256 g_network_monitor_can_reach_async (GNetworkMonitor
*monitor
,
257 GSocketConnectable
*connectable
,
258 GCancellable
*cancellable
,
259 GAsyncReadyCallback callback
,
262 GNetworkMonitorInterface
*iface
;
264 iface
= G_NETWORK_MONITOR_GET_INTERFACE (monitor
);
265 iface
->can_reach_async (monitor
, connectable
, cancellable
, callback
, user_data
);
269 g_network_monitor_real_can_reach_finish (GNetworkMonitor
*monitor
,
270 GAsyncResult
*result
,
273 g_return_val_if_fail (g_task_is_valid (result
, monitor
), FALSE
);
275 return g_task_propagate_boolean (G_TASK (result
), error
);
279 * g_network_monitor_can_reach_finish:
280 * @monitor: a #GNetworkMonitor
281 * @result: a #GAsyncResult
282 * @error: return location for errors, or %NULL
284 * Finishes an async network connectivity test.
285 * See g_network_monitor_can_reach_async().
287 * Returns: %TRUE if network is reachable, %FALSE if not.
290 g_network_monitor_can_reach_finish (GNetworkMonitor
*monitor
,
291 GAsyncResult
*result
,
294 GNetworkMonitorInterface
*iface
;
296 iface
= G_NETWORK_MONITOR_GET_INTERFACE (monitor
);
297 return iface
->can_reach_finish (monitor
, result
, error
);
301 g_network_monitor_default_init (GNetworkMonitorInterface
*iface
)
303 iface
->can_reach_async
= g_network_monitor_real_can_reach_async
;
304 iface
->can_reach_finish
= g_network_monitor_real_can_reach_finish
;
307 * GNetworkMonitor::network-changed:
308 * @monitor: a #GNetworkMonitor
309 * @available: the current value of #GNetworkMonitor:network-available
311 * Emitted when the network configuration changes. If @available is
312 * %TRUE, then some hosts may be reachable that were not reachable
313 * before, while others that were reachable before may no longer be
314 * reachable. If @available is %FALSE, then no remote hosts are
319 signals
[NETWORK_CHANGED
] =
320 g_signal_new (I_("network-changed"),
321 G_TYPE_NETWORK_MONITOR
,
323 G_STRUCT_OFFSET (GNetworkMonitorInterface
, network_changed
),
325 g_cclosure_marshal_VOID__BOOLEAN
,
330 * GNetworkMonitor:network-available:
332 * Whether the network is considered available. That is, whether the
333 * system has a default route for at least one of IPv4 or IPv6.
335 * Real-world networks are of course much more complicated than
336 * this; the machine may be connected to a wifi hotspot that
337 * requires payment before allowing traffic through, or may be
338 * connected to a functioning router that has lost its own upstream
339 * connectivity. Some hosts might only be accessible when a VPN is
340 * active. Other hosts might only be accessible when the VPN is
341 * not active. Thus, it is best to use g_network_monitor_can_reach()
342 * or g_network_monitor_can_reach_async() to test for reachability
343 * on a host-by-host basis. (On the other hand, when the property is
344 * %FALSE, the application can reasonably expect that no remote
345 * hosts at all are reachable, and should indicate this to the user
348 * See also #GNetworkMonitor::network-changed.
352 g_object_interface_install_property (iface
,
353 g_param_spec_boolean ("network-available",
354 P_("Network available"),
355 P_("Whether the network is available"),
358 G_PARAM_STATIC_STRINGS
));
361 * GNetworkMonitor:network-metered:
363 * Whether the network is considered metered. That is, whether the
364 * system has traffic flowing through the default connection that is
365 * subject to limitations set by service providers. For example, traffic
366 * might be billed by the amount of data transmitted, or there might be a
367 * quota on the amount of traffic per month. This is typical with tethered
368 * connections (3G and 4G) and in such situations, bandwidth intensive
369 * applications may wish to avoid network activity where possible if it will
370 * cost the user money or use up their limited quota.
372 * If more information is required about specific devices then the
373 * system network management API should be used instead (for example,
374 * NetworkManager or ConnMan).
376 * If this information is not available then no networks will be
379 * See also #GNetworkMonitor:network-available.
383 g_object_interface_install_property (iface
,
384 g_param_spec_boolean ("network-metered",
385 P_("Network metered"),
386 P_("Whether the network is metered"),
389 G_PARAM_STATIC_STRINGS
));
392 * GNetworkMonitor:connectivity:
394 * More detailed information about the host's network connectivity.
395 * See g_network_monitor_get_connectivity() and
396 * #GNetworkConnectivity for more details.
400 g_object_interface_install_property (iface
,
401 g_param_spec_enum ("connectivity",
402 P_("Network connectivity"),
403 P_("Level of network connectivity"),
404 G_TYPE_NETWORK_CONNECTIVITY
,
405 G_NETWORK_CONNECTIVITY_FULL
,
407 G_PARAM_STATIC_STRINGS
));