Change LGPL-2.1+ to LGPL-2.1-or-later
[platform/upstream/glib.git] / gio / gnetworkmonitor.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright 2011 Red Hat, Inc
4  *
5  * SPDX-License-Identifier: LGPL-2.1-or-later
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include "config.h"
22 #include "glib.h"
23 #include "glibintl.h"
24
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"
31 #include "gtask.h"
32
33 /**
34  * SECTION:gnetworkmonitor
35  * @title: GNetworkMonitor
36  * @short_description: Network status monitor
37  * @include: gio/gio.h
38  *
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
42  * on NetworkManager.
43  *
44  * There is also an implementation for use inside Flatpak sandboxes.
45  */
46
47 /**
48  * GNetworkMonitor:
49  *
50  * #GNetworkMonitor monitors the status of network connections and
51  * indicates when a possibly-user-visible change has occurred.
52  *
53  * Since: 2.32
54  */
55
56 /**
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()
66  *
67  * The virtual function table for #GNetworkMonitor.
68  *
69  * Since: 2.32
70  */
71
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))
74
75
76 enum {
77   NETWORK_CHANGED,
78   LAST_SIGNAL
79 };
80
81 static guint signals[LAST_SIGNAL] = { 0 };
82 static GNetworkMonitor *network_monitor_default_singleton = NULL;  /* (owned) (atomic) */
83
84 /**
85  * g_network_monitor_get_default:
86  *
87  * Gets the default #GNetworkMonitor for the system.
88  *
89  * Returns: (not nullable) (transfer none): a #GNetworkMonitor, which will be
90  *     a dummy object if no network monitor is available
91  *
92  * Since: 2.32
93  */
94 GNetworkMonitor *
95 g_network_monitor_get_default (void)
96 {
97   if (g_once_init_enter (&network_monitor_default_singleton))
98     {
99       GNetworkMonitor *singleton;
100
101       singleton = _g_io_module_get_default (G_NETWORK_MONITOR_EXTENSION_POINT_NAME,
102                                             "GIO_USE_NETWORK_MONITOR",
103                                             NULL);
104
105       g_once_init_leave (&network_monitor_default_singleton, singleton);
106     }
107
108   return network_monitor_default_singleton;
109 }
110
111 /**
112  * g_network_monitor_get_network_available:
113  * @monitor: the #GNetworkMonitor
114  *
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.
119  *
120  * Returns: whether the network is available
121  *
122  * Since: 2.32
123  */
124 gboolean
125 g_network_monitor_get_network_available (GNetworkMonitor *monitor)
126 {
127   gboolean available = FALSE;
128
129   g_object_get (G_OBJECT (monitor), "network-available", &available, NULL);
130   return available;
131 }
132
133 /**
134  * g_network_monitor_get_network_metered:
135  * @monitor: the #GNetworkMonitor
136  *
137  * Checks if the network is metered.
138  * See #GNetworkMonitor:network-metered for more details.
139  *
140  * Returns: whether the connection is metered
141  *
142  * Since: 2.46
143  */
144 gboolean
145 g_network_monitor_get_network_metered (GNetworkMonitor *monitor)
146 {
147   gboolean metered = FALSE;
148
149   g_object_get (G_OBJECT (monitor), "network-metered", &metered, NULL);
150   return metered;
151 }
152
153 /**
154  * g_network_monitor_get_connectivity:
155  * @monitor: the #GNetworkMonitor
156  *
157  * Gets a more detailed networking state than
158  * g_network_monitor_get_network_available().
159  *
160  * If #GNetworkMonitor:network-available is %FALSE, then the
161  * connectivity state will be %G_NETWORK_CONNECTIVITY_LOCAL.
162  *
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).
170  *
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.
176  *
177  * Return value: the network connectivity state
178  *
179  * Since: 2.44
180  */
181 GNetworkConnectivity
182 g_network_monitor_get_connectivity (GNetworkMonitor *monitor)
183 {
184   GNetworkConnectivity connectivity;
185
186   g_object_get (G_OBJECT (monitor), "connectivity", &connectivity, NULL);
187
188   return connectivity;
189 }
190
191 /**
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
197  *
198  * Attempts to determine whether or not the host pointed to by
199  * @connectable can be reached, without actually trying to connect to
200  * it.
201  *
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.
205  *
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).
210  *
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().
215  *
216  * Returns: %TRUE if @connectable is reachable, %FALSE if not.
217  *
218  * Since: 2.32
219  */
220 gboolean
221 g_network_monitor_can_reach (GNetworkMonitor     *monitor,
222                              GSocketConnectable  *connectable,
223                              GCancellable        *cancellable,
224                              GError             **error)
225 {
226   GNetworkMonitorInterface *iface;
227
228   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
229   return iface->can_reach (monitor, connectable, cancellable, error);
230 }
231
232 static void
233 g_network_monitor_real_can_reach_async (GNetworkMonitor     *monitor,
234                                         GSocketConnectable  *connectable,
235                                         GCancellable        *cancellable,
236                                         GAsyncReadyCallback  callback,
237                                         gpointer             user_data)
238 {
239   GTask *task;
240   GError *error = NULL;
241
242   task = g_task_new (monitor, cancellable, callback, user_data);
243   g_task_set_source_tag (task, g_network_monitor_real_can_reach_async);
244
245   if (g_network_monitor_can_reach (monitor, connectable, cancellable, &error))
246     g_task_return_boolean (task, TRUE);
247   else
248     g_task_return_error (task, error);
249   g_object_unref (task);
250 }
251
252 /**
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
260  *
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.
264  *
265  * For more details, see g_network_monitor_can_reach().
266  *
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.
270  */
271 void
272 g_network_monitor_can_reach_async (GNetworkMonitor     *monitor,
273                                    GSocketConnectable  *connectable,
274                                    GCancellable        *cancellable,
275                                    GAsyncReadyCallback  callback,
276                                    gpointer             user_data)
277 {
278   GNetworkMonitorInterface *iface;
279
280   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
281   iface->can_reach_async (monitor, connectable, cancellable, callback, user_data);
282 }
283
284 static gboolean
285 g_network_monitor_real_can_reach_finish (GNetworkMonitor  *monitor,
286                                          GAsyncResult     *result,
287                                          GError          **error)
288 {
289   g_return_val_if_fail (g_task_is_valid (result, monitor), FALSE);
290
291   return g_task_propagate_boolean (G_TASK (result), error);
292 }
293
294 /**
295  * g_network_monitor_can_reach_finish:
296  * @monitor: a #GNetworkMonitor
297  * @result: a #GAsyncResult
298  * @error: return location for errors, or %NULL
299  *
300  * Finishes an async network connectivity test.
301  * See g_network_monitor_can_reach_async().
302  *
303  * Returns: %TRUE if network is reachable, %FALSE if not.
304  */
305 gboolean
306 g_network_monitor_can_reach_finish (GNetworkMonitor     *monitor,
307                                     GAsyncResult        *result,
308                                     GError             **error)
309 {
310   GNetworkMonitorInterface *iface;
311
312   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
313   return iface->can_reach_finish (monitor, result, error);
314 }
315
316 static void
317 g_network_monitor_default_init (GNetworkMonitorInterface *iface)
318 {
319   iface->can_reach_async  = g_network_monitor_real_can_reach_async;
320   iface->can_reach_finish = g_network_monitor_real_can_reach_finish;
321
322   /**
323    * GNetworkMonitor::network-changed:
324    * @monitor: a #GNetworkMonitor
325    * @network_available: the current value of #GNetworkMonitor:network-available
326    *
327    * Emitted when the network configuration changes.
328    *
329    * Since: 2.32
330    */
331   signals[NETWORK_CHANGED] =
332     g_signal_new (I_("network-changed"),
333                   G_TYPE_NETWORK_MONITOR,
334                   G_SIGNAL_RUN_LAST,
335                   G_STRUCT_OFFSET (GNetworkMonitorInterface, network_changed),
336                   NULL, NULL,
337                   NULL,
338                   G_TYPE_NONE, 1,
339                   G_TYPE_BOOLEAN);
340
341   /**
342    * GNetworkMonitor:network-available:
343    *
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.
346    *
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
358    * in its UI.)
359    *
360    * See also #GNetworkMonitor::network-changed.
361    *
362    * Since: 2.32
363    */
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"),
368                                                              FALSE,
369                                                              G_PARAM_READABLE |
370                                                              G_PARAM_STATIC_STRINGS));
371
372   /**
373    * GNetworkMonitor:network-metered:
374    *
375    * Whether the network is considered metered.
376    *
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.
387    *
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).
391    *
392    * If this information is not available then no networks will be
393    * marked as metered.
394    *
395    * See also #GNetworkMonitor:network-available.
396    *
397    * Since: 2.46
398    */
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"),
403                                                              FALSE,
404                                                              G_PARAM_READABLE |
405                                                              G_PARAM_STATIC_STRINGS));
406
407   /**
408    * GNetworkMonitor:connectivity:
409    *
410    * More detailed information about the host's network connectivity.
411    * See g_network_monitor_get_connectivity() and
412    * #GNetworkConnectivity for more details.
413    *
414    * Since: 2.44
415    */
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,
422                                                           G_PARAM_READABLE |
423                                                           G_PARAM_STATIC_STRINGS));
424 }