[kdbus] KDBUS_ITEM_PAYLOAD_OFF items are (once again) relative to msg header
[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 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 implementation
39  * is based on the kernel's netlink interface.
40  */
41
42 /**
43  * GNetworkMonitor:
44  *
45  * #GNetworkMonitor monitors the status of network connections and
46  * indicates when a possibly-user-visible change has occurred.
47  *
48  * Since: 2.32
49  */
50
51 G_DEFINE_INTERFACE_WITH_CODE (GNetworkMonitor, g_network_monitor, G_TYPE_OBJECT,
52                               g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_INITABLE);)
53
54
55 enum {
56   NETWORK_CHANGED,
57   LAST_SIGNAL
58 };
59
60 static guint signals[LAST_SIGNAL] = { 0 };
61
62 /**
63  * g_network_monitor_get_default:
64  *
65  * Gets the default #GNetworkMonitor for the system.
66  *
67  * Returns: (transfer none): a #GNetworkMonitor
68  *
69  * Since: 2.32
70  */
71 GNetworkMonitor *
72 g_network_monitor_get_default (void)
73 {
74   return _g_io_module_get_default (G_NETWORK_MONITOR_EXTENSION_POINT_NAME,
75                                    "GIO_USE_NETWORK_MONITOR",
76                                    NULL);
77 }
78
79 /**
80  * g_network_monitor_get_network_available:
81  * @monitor: the #GNetworkMonitor
82  *
83  * Checks if the network is available. "Available" here means that the
84  * system has a default route available for at least one of IPv4 or
85  * IPv6. It does not necessarily imply that the public Internet is
86  * reachable. See #GNetworkMonitor:network-available for more details.
87  *
88  * Returns: whether the network is available
89  *
90  * Since: 2.32
91  */
92 gboolean
93 g_network_monitor_get_network_available (GNetworkMonitor *monitor)
94 {
95   gboolean available = FALSE;
96
97   g_object_get (G_OBJECT (monitor), "network-available", &available, NULL);
98   return available;
99 }
100
101 /**
102  * g_network_monitor_can_reach:
103  * @monitor: a #GNetworkMonitor
104  * @connectable: a #GSocketConnectable
105  * @cancellable: (allow-none): a #GCancellable, or %NULL
106  * @error: return location for a #GError, or %NULL
107  *
108  * Attempts to determine whether or not the host pointed to by
109  * @connectable can be reached, without actually trying to connect to
110  * it.
111  *
112  * This may return %TRUE even when #GNetworkMonitor:network-available
113  * is %FALSE, if, for example, @monitor can determine that
114  * @connectable refers to a host on a local network.
115  *
116  * If @monitor believes that an attempt to connect to @connectable
117  * will succeed, it will return %TRUE. Otherwise, it will return
118  * %FALSE and set @error to an appropriate error (such as
119  * %G_IO_ERROR_HOST_UNREACHABLE).
120  *
121  * Note that although this does not attempt to connect to
122  * @connectable, it may still block for a brief period of time (eg,
123  * trying to do multicast DNS on the local network), so if you do not
124  * want to block, you should use g_network_monitor_can_reach_async().
125  *
126  * Returns: %TRUE if @connectable is reachable, %FALSE if not.
127  *
128  * Since: 2.32
129  */
130 gboolean
131 g_network_monitor_can_reach (GNetworkMonitor     *monitor,
132                              GSocketConnectable  *connectable,
133                              GCancellable        *cancellable,
134                              GError             **error)
135 {
136   GNetworkMonitorInterface *iface;
137
138   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
139   return iface->can_reach (monitor, connectable, cancellable, error);
140 }
141
142 static void
143 g_network_monitor_real_can_reach_async (GNetworkMonitor     *monitor,
144                                         GSocketConnectable  *connectable,
145                                         GCancellable        *cancellable,
146                                         GAsyncReadyCallback  callback,
147                                         gpointer             user_data)
148 {
149   GTask *task;
150   GError *error = NULL;
151
152   task = g_task_new (monitor, cancellable, callback, user_data);
153   if (g_network_monitor_can_reach (monitor, connectable, cancellable, &error))
154     g_task_return_boolean (task, TRUE);
155   else
156     g_task_return_error (task, error);
157   g_object_unref (task);
158 }
159
160 /**
161  * g_network_monitor_can_reach_async:
162  * @monitor: a #GNetworkMonitor
163  * @connectable: a #GSocketConnectable
164  * @cancellable: (allow-none): a #GCancellable, or %NULL
165  * @callback: (scope async): a #GAsyncReadyCallback to call when the
166  *     request is satisfied
167  * @user_data: (closure): the data to pass to callback function
168  *
169  * Asynchronously attempts to determine whether or not the host
170  * pointed to by @connectable can be reached, without actually
171  * trying to connect to it.
172  *
173  * For more details, see g_network_monitor_can_reach().
174  *
175  * When the operation is finished, @callback will be called.
176  * You can then call g_network_monitor_can_reach_finish()
177  * to get the result of the operation.
178  */
179 void
180 g_network_monitor_can_reach_async (GNetworkMonitor     *monitor,
181                                    GSocketConnectable  *connectable,
182                                    GCancellable        *cancellable,
183                                    GAsyncReadyCallback  callback,
184                                    gpointer             user_data)
185 {
186   GNetworkMonitorInterface *iface;
187
188   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
189   iface->can_reach_async (monitor, connectable, cancellable, callback, user_data);
190 }
191
192 static gboolean
193 g_network_monitor_real_can_reach_finish (GNetworkMonitor  *monitor,
194                                          GAsyncResult     *result,
195                                          GError          **error)
196 {
197   g_return_val_if_fail (g_task_is_valid (result, monitor), FALSE);
198
199   return g_task_propagate_boolean (G_TASK (result), error);
200 }
201
202 /**
203  * g_network_monitor_can_reach_finish:
204  * @monitor: a #GNetworkMonitor
205  * @result: a #GAsyncResult
206  * @error: return location for errors, or %NULL
207  *
208  * Finishes an async network connectivity test.
209  * See g_network_monitor_can_reach_async().
210  *
211  * Returns: %TRUE if network is reachable, %FALSE if not.
212  */
213 gboolean
214 g_network_monitor_can_reach_finish (GNetworkMonitor     *monitor,
215                                     GAsyncResult        *result,
216                                     GError             **error)
217 {
218   GNetworkMonitorInterface *iface;
219
220   iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
221   return iface->can_reach_finish (monitor, result, error);
222 }
223
224 static void
225 g_network_monitor_default_init (GNetworkMonitorInterface *iface)
226 {
227   iface->can_reach_async  = g_network_monitor_real_can_reach_async;
228   iface->can_reach_finish = g_network_monitor_real_can_reach_finish;
229
230   /**
231    * GNetworkMonitor::network-changed:
232    * @monitor: a #GNetworkMonitor
233    * @available: the current value of #GNetworkMonitor:network-available
234    *
235    * Emitted when the network configuration changes. If @available is
236    * %TRUE, then some hosts may be reachable that were not reachable
237    * before, while others that were reachable before may no longer be
238    * reachable. If @available is %FALSE, then no remote hosts are
239    * reachable.
240    *
241    * Since: 2.32
242    */
243   signals[NETWORK_CHANGED] =
244     g_signal_new (I_("network-changed"),
245                   G_TYPE_NETWORK_MONITOR,
246                   G_SIGNAL_RUN_LAST,
247                   G_STRUCT_OFFSET (GNetworkMonitorInterface, network_changed),
248                   NULL, NULL,
249                   g_cclosure_marshal_VOID__BOOLEAN,
250                   G_TYPE_NONE, 1,
251                   G_TYPE_BOOLEAN);
252
253   /**
254    * GNetworkMonitor:network-available:
255    *
256    * Whether the network is considered available. That is, whether the
257    * system has a default route for at least one of IPv4 or IPv6.
258    *
259    * Real-world networks are of course much more complicated than
260    * this; the machine may be connected to a wifi hotspot that
261    * requires payment before allowing traffic through, or may be
262    * connected to a functioning router that has lost its own upstream
263    * connectivity. Some hosts might only be accessible when a VPN is
264    * active. Other hosts might only be accessible when the VPN is
265    * not active. Thus, it is best to use g_network_monitor_can_reach()
266    * or g_network_monitor_can_reach_async() to test for reachability
267    * on a host-by-host basis. (On the other hand, when the property is
268    * %FALSE, the application can reasonably expect that no remote
269    * hosts at all are reachable, and should indicate this to the user
270    * in its UI.)
271    *
272    * See also #GNetworkMonitor::network-changed.
273    *
274    * Since: 2.32
275    */
276   g_object_interface_install_property (iface,
277                                        g_param_spec_boolean ("network-available",
278                                                              P_("Network available"),
279                                                              P_("Whether the network is available"),
280                                                              FALSE,
281                                                              G_PARAM_READABLE |
282                                                              G_PARAM_STATIC_STRINGS));
283 }