Imported Upstream version 2.66.6
[platform/upstream/glib.git] / gio / gnetworkmonitor.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright 2011 Red Hat, Inc
4  *
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.
9  *
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.
14  *
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/>.
17  */
18
19 #include "config.h"
20 #include "glib.h"
21 #include "glibintl.h"
22
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"
30
31 /**
32  * SECTION:gnetworkmonitor
33  * @title: GNetworkMonitor
34  * @short_description: Network status monitor
35  * @include: gio/gio.h
36  *
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.
41  *
42  * There is also an implementation for use inside Flatpak sandboxes.
43  */
44
45 /**
46  * GNetworkMonitor:
47  *
48  * #GNetworkMonitor monitors the status of network connections and
49  * indicates when a possibly-user-visible change has occurred.
50  *
51  * Since: 2.32
52  */
53
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()
64  *
65  * The virtual function table for #GNetworkMonitor.
66  *
67  * Since: 2.32
68  */
69
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))
72
73
74 enum {
75   NETWORK_CHANGED,
76   LAST_SIGNAL
77 };
78
79 static guint signals[LAST_SIGNAL] = { 0 };
80
81 /**
82  * g_network_monitor_get_default:
83  *
84  * Gets the default #GNetworkMonitor for the system.
85  *
86  * Returns: (transfer none): a #GNetworkMonitor
87  *
88  * Since: 2.32
89  */
90 GNetworkMonitor *
91 g_network_monitor_get_default (void)
92 {
93   return _g_io_module_get_default (G_NETWORK_MONITOR_EXTENSION_POINT_NAME,
94                                    "GIO_USE_NETWORK_MONITOR",
95                                    NULL);
96 }
97
98 /**
99  * g_network_monitor_get_network_available:
100  * @monitor: the #GNetworkMonitor
101  *
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.
106  *
107  * Returns: whether the network is available
108  *
109  * Since: 2.32
110  */
111 gboolean
112 g_network_monitor_get_network_available (GNetworkMonitor *monitor)
113 {
114   gboolean available = FALSE;
115
116   g_object_get (G_OBJECT (monitor), "network-available", &available, NULL);
117   return available;
118 }
119
120 /**
121  * g_network_monitor_get_network_metered:
122  * @monitor: the #GNetworkMonitor
123  *
124  * Checks if the network is metered.
125  * See #GNetworkMonitor:network-metered for more details.
126  *
127  * Returns: whether the connection is metered
128  *
129  * Since: 2.46
130  */
131 gboolean
132 g_network_monitor_get_network_metered (GNetworkMonitor *monitor)
133 {
134   gboolean metered = FALSE;
135
136   g_object_get (G_OBJECT (monitor), "network-metered", &metered, NULL);
137   return metered;
138 }
139
140 /**
141  * g_network_monitor_get_connectivity:
142  * @monitor: the #GNetworkMonitor
143  *
144  * Gets a more detailed networking state than
145  * g_network_monitor_get_network_available().
146  *
147  * If #GNetworkMonitor:network-available is %FALSE, then the
148  * connectivity state will be %G_NETWORK_CONNECTIVITY_LOCAL.
149  *
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).
157  *
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.
163  *
164  * Return value: the network connectivity state
165  *
166  * Since: 2.44
167  */
168 GNetworkConnectivity
169 g_network_monitor_get_connectivity (GNetworkMonitor *monitor)
170 {
171   GNetworkConnectivity connectivity;
172
173   g_object_get (G_OBJECT (monitor), "connectivity", &connectivity, NULL);
174
175   return connectivity;
176 }
177
178 /**
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
184  *
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.
188  *
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.
192  *
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).
197  *
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().
202  *
203  * Returns: %TRUE if @connectable is reachable, %FALSE if not.
204  *
205  * Since: 2.32
206  */
207 gboolean
208 g_network_monitor_can_reach (GNetworkMonitor     *monitor,
209                              GSocketConnectable  *connectable,
210                              GCancellable        *cancellable,
211                              GError             **error)
212 {
213   GNetworkMonitorInterface *iface;
214
215   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
216   return iface->can_reach (monitor, connectable, cancellable, error);
217 }
218
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)
225 {
226   GTask *task;
227   GError *error = NULL;
228
229   task = g_task_new (monitor, cancellable, callback, user_data);
230   g_task_set_source_tag (task, g_network_monitor_real_can_reach_async);
231
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);
237 }
238
239 /**
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
247  *
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.
251  *
252  * For more details, see g_network_monitor_can_reach().
253  *
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.
257  */
258 void
259 g_network_monitor_can_reach_async (GNetworkMonitor     *monitor,
260                                    GSocketConnectable  *connectable,
261                                    GCancellable        *cancellable,
262                                    GAsyncReadyCallback  callback,
263                                    gpointer             user_data)
264 {
265   GNetworkMonitorInterface *iface;
266
267   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
268   iface->can_reach_async (monitor, connectable, cancellable, callback, user_data);
269 }
270
271 static gboolean
272 g_network_monitor_real_can_reach_finish (GNetworkMonitor  *monitor,
273                                          GAsyncResult     *result,
274                                          GError          **error)
275 {
276   g_return_val_if_fail (g_task_is_valid (result, monitor), FALSE);
277
278   return g_task_propagate_boolean (G_TASK (result), error);
279 }
280
281 /**
282  * g_network_monitor_can_reach_finish:
283  * @monitor: a #GNetworkMonitor
284  * @result: a #GAsyncResult
285  * @error: return location for errors, or %NULL
286  *
287  * Finishes an async network connectivity test.
288  * See g_network_monitor_can_reach_async().
289  *
290  * Returns: %TRUE if network is reachable, %FALSE if not.
291  */
292 gboolean
293 g_network_monitor_can_reach_finish (GNetworkMonitor     *monitor,
294                                     GAsyncResult        *result,
295                                     GError             **error)
296 {
297   GNetworkMonitorInterface *iface;
298
299   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
300   return iface->can_reach_finish (monitor, result, error);
301 }
302
303 static void
304 g_network_monitor_default_init (GNetworkMonitorInterface *iface)
305 {
306   iface->can_reach_async  = g_network_monitor_real_can_reach_async;
307   iface->can_reach_finish = g_network_monitor_real_can_reach_finish;
308
309   /**
310    * GNetworkMonitor::network-changed:
311    * @monitor: a #GNetworkMonitor
312    * @network_available: the current value of #GNetworkMonitor:network-available
313    *
314    * Emitted when the network configuration changes.
315    *
316    * Since: 2.32
317    */
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                   NULL,
325                   G_TYPE_NONE, 1,
326                   G_TYPE_BOOLEAN);
327
328   /**
329    * GNetworkMonitor:network-available:
330    *
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.
333    *
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.)
346    *
347    * See also #GNetworkMonitor::network-changed.
348    *
349    * Since: 2.32
350    */
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));
358
359   /**
360    * GNetworkMonitor:network-metered:
361    *
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.
370    *
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).
374    *
375    * If this information is not available then no networks will be
376    * marked as metered.
377    *
378    * See also #GNetworkMonitor:network-available.
379    *
380    * Since: 2.46
381    */
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));
389
390   /**
391    * GNetworkMonitor:connectivity:
392    *
393    * More detailed information about the host's network connectivity.
394    * See g_network_monitor_get_connectivity() and
395    * #GNetworkConnectivity for more details.
396    *
397    * Since: 2.44
398    */
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));
407 }