(root)/
glib-2.79.0/
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   * GNetworkMonitor:
      35   *
      36   * `GNetworkMonitor` provides an easy-to-use cross-platform API
      37   * for monitoring network connectivity. On Linux, the available
      38   * implementations are based on the kernel's netlink interface and
      39   * on NetworkManager.
      40   *
      41   * There is also an implementation for use inside Flatpak sandboxes.
      42   *
      43   * Since: 2.32
      44   */
      45  
      46  /**
      47   * GNetworkMonitorInterface:
      48   * @g_iface: The parent interface.
      49   * @network_changed: the virtual function pointer for the
      50   *  GNetworkMonitor::network-changed signal.
      51   * @can_reach: the virtual function pointer for g_network_monitor_can_reach()
      52   * @can_reach_async: the virtual function pointer for
      53   *  g_network_monitor_can_reach_async()
      54   * @can_reach_finish: the virtual function pointer for
      55   *  g_network_monitor_can_reach_finish()
      56   *
      57   * The virtual function table for #GNetworkMonitor.
      58   *
      59   * Since: 2.32
      60   */
      61  
      62  G_DEFINE_INTERFACE_WITH_CODE (GNetworkMonitor, g_network_monitor, G_TYPE_OBJECT,
      63                                g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_INITABLE))
      64  
      65  
      66  enum {
      67    NETWORK_CHANGED,
      68    LAST_SIGNAL
      69  };
      70  
      71  static guint signals[LAST_SIGNAL] = { 0 };
      72  static GNetworkMonitor *network_monitor_default_singleton = NULL;  /* (owned) (atomic) */
      73  
      74  /**
      75   * g_network_monitor_get_default:
      76   *
      77   * Gets the default #GNetworkMonitor for the system.
      78   *
      79   * Returns: (not nullable) (transfer none): a #GNetworkMonitor, which will be
      80   *     a dummy object if no network monitor is available
      81   *
      82   * Since: 2.32
      83   */
      84  GNetworkMonitor *
      85  g_network_monitor_get_default (void)
      86  {
      87    if (g_once_init_enter_pointer (&network_monitor_default_singleton))
      88      {
      89        GNetworkMonitor *singleton;
      90  
      91        singleton = _g_io_module_get_default (G_NETWORK_MONITOR_EXTENSION_POINT_NAME,
      92                                              "GIO_USE_NETWORK_MONITOR",
      93                                              NULL);
      94  
      95        g_once_init_leave_pointer (&network_monitor_default_singleton, singleton);
      96      }
      97  
      98    return network_monitor_default_singleton;
      99  }
     100  
     101  /**
     102   * g_network_monitor_get_network_available:
     103   * @monitor: the #GNetworkMonitor
     104   *
     105   * Checks if the network is available. "Available" here means that the
     106   * system has a default route available for at least one of IPv4 or
     107   * IPv6. It does not necessarily imply that the public Internet is
     108   * reachable. See #GNetworkMonitor:network-available for more details.
     109   *
     110   * Returns: whether the network is available
     111   *
     112   * Since: 2.32
     113   */
     114  gboolean
     115  g_network_monitor_get_network_available (GNetworkMonitor *monitor)
     116  {
     117    gboolean available = FALSE;
     118  
     119    g_object_get (G_OBJECT (monitor), "network-available", &available, NULL);
     120    return available;
     121  }
     122  
     123  /**
     124   * g_network_monitor_get_network_metered:
     125   * @monitor: the #GNetworkMonitor
     126   *
     127   * Checks if the network is metered.
     128   * See #GNetworkMonitor:network-metered for more details.
     129   *
     130   * Returns: whether the connection is metered
     131   *
     132   * Since: 2.46
     133   */
     134  gboolean
     135  g_network_monitor_get_network_metered (GNetworkMonitor *monitor)
     136  {
     137    gboolean metered = FALSE;
     138  
     139    g_object_get (G_OBJECT (monitor), "network-metered", &metered, NULL);
     140    return metered;
     141  }
     142  
     143  /**
     144   * g_network_monitor_get_connectivity:
     145   * @monitor: the #GNetworkMonitor
     146   *
     147   * Gets a more detailed networking state than
     148   * g_network_monitor_get_network_available().
     149   *
     150   * If #GNetworkMonitor:network-available is %FALSE, then the
     151   * connectivity state will be %G_NETWORK_CONNECTIVITY_LOCAL.
     152   *
     153   * If #GNetworkMonitor:network-available is %TRUE, then the
     154   * connectivity state will be %G_NETWORK_CONNECTIVITY_FULL (if there
     155   * is full Internet connectivity), %G_NETWORK_CONNECTIVITY_LIMITED (if
     156   * the host has a default route, but appears to be unable to actually
     157   * reach the full Internet), or %G_NETWORK_CONNECTIVITY_PORTAL (if the
     158   * host is trapped behind a "captive portal" that requires some sort
     159   * of login or acknowledgement before allowing full Internet access).
     160   *
     161   * Note that in the case of %G_NETWORK_CONNECTIVITY_LIMITED and
     162   * %G_NETWORK_CONNECTIVITY_PORTAL, it is possible that some sites are
     163   * reachable but others are not. In this case, applications can
     164   * attempt to connect to remote servers, but should gracefully fall
     165   * back to their "offline" behavior if the connection attempt fails.
     166   *
     167   * Return value: the network connectivity state
     168   *
     169   * Since: 2.44
     170   */
     171  GNetworkConnectivity
     172  g_network_monitor_get_connectivity (GNetworkMonitor *monitor)
     173  {
     174    GNetworkConnectivity connectivity;
     175  
     176    g_object_get (G_OBJECT (monitor), "connectivity", &connectivity, NULL);
     177  
     178    return connectivity;
     179  }
     180  
     181  /**
     182   * g_network_monitor_can_reach:
     183   * @monitor: a #GNetworkMonitor
     184   * @connectable: a #GSocketConnectable
     185   * @cancellable: (nullable): a #GCancellable, or %NULL
     186   * @error: return location for a #GError, or %NULL
     187   *
     188   * Attempts to determine whether or not the host pointed to by
     189   * @connectable can be reached, without actually trying to connect to
     190   * it.
     191   *
     192   * This may return %TRUE even when #GNetworkMonitor:network-available
     193   * is %FALSE, if, for example, @monitor can determine that
     194   * @connectable refers to a host on a local network.
     195   *
     196   * If @monitor believes that an attempt to connect to @connectable
     197   * will succeed, it will return %TRUE. Otherwise, it will return
     198   * %FALSE and set @error to an appropriate error (such as
     199   * %G_IO_ERROR_HOST_UNREACHABLE).
     200   *
     201   * Note that although this does not attempt to connect to
     202   * @connectable, it may still block for a brief period of time (eg,
     203   * trying to do multicast DNS on the local network), so if you do not
     204   * want to block, you should use g_network_monitor_can_reach_async().
     205   *
     206   * Returns: %TRUE if @connectable is reachable, %FALSE if not.
     207   *
     208   * Since: 2.32
     209   */
     210  gboolean
     211  g_network_monitor_can_reach (GNetworkMonitor     *monitor,
     212                               GSocketConnectable  *connectable,
     213                               GCancellable        *cancellable,
     214                               GError             **error)
     215  {
     216    GNetworkMonitorInterface *iface;
     217  
     218    iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
     219    return iface->can_reach (monitor, connectable, cancellable, error);
     220  }
     221  
     222  static void
     223  g_network_monitor_real_can_reach_async (GNetworkMonitor     *monitor,
     224                                          GSocketConnectable  *connectable,
     225                                          GCancellable        *cancellable,
     226                                          GAsyncReadyCallback  callback,
     227                                          gpointer             user_data)
     228  {
     229    GTask *task;
     230    GError *error = NULL;
     231  
     232    task = g_task_new (monitor, cancellable, callback, user_data);
     233    g_task_set_source_tag (task, g_network_monitor_real_can_reach_async);
     234  
     235    if (g_network_monitor_can_reach (monitor, connectable, cancellable, &error))
     236      g_task_return_boolean (task, TRUE);
     237    else
     238      g_task_return_error (task, error);
     239    g_object_unref (task);
     240  }
     241  
     242  /**
     243   * g_network_monitor_can_reach_async:
     244   * @monitor: a #GNetworkMonitor
     245   * @connectable: a #GSocketConnectable
     246   * @cancellable: (nullable): a #GCancellable, or %NULL
     247   * @callback: (scope async): a #GAsyncReadyCallback
     248   *     to call when the request is satisfied
     249   * @user_data: the data to pass to callback function
     250   *
     251   * Asynchronously attempts to determine whether or not the host
     252   * pointed to by @connectable can be reached, without actually
     253   * trying to connect to it.
     254   *
     255   * For more details, see g_network_monitor_can_reach().
     256   *
     257   * When the operation is finished, @callback will be called.
     258   * You can then call g_network_monitor_can_reach_finish()
     259   * to get the result of the operation.
     260   */
     261  void
     262  g_network_monitor_can_reach_async (GNetworkMonitor     *monitor,
     263                                     GSocketConnectable  *connectable,
     264                                     GCancellable        *cancellable,
     265                                     GAsyncReadyCallback  callback,
     266                                     gpointer             user_data)
     267  {
     268    GNetworkMonitorInterface *iface;
     269  
     270    iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
     271    iface->can_reach_async (monitor, connectable, cancellable, callback, user_data);
     272  }
     273  
     274  static gboolean
     275  g_network_monitor_real_can_reach_finish (GNetworkMonitor  *monitor,
     276                                           GAsyncResult     *result,
     277                                           GError          **error)
     278  {
     279    g_return_val_if_fail (g_task_is_valid (result, monitor), FALSE);
     280  
     281    return g_task_propagate_boolean (G_TASK (result), error);
     282  }
     283  
     284  /**
     285   * g_network_monitor_can_reach_finish:
     286   * @monitor: a #GNetworkMonitor
     287   * @result: a #GAsyncResult
     288   * @error: return location for errors, or %NULL
     289   *
     290   * Finishes an async network connectivity test.
     291   * See g_network_monitor_can_reach_async().
     292   *
     293   * Returns: %TRUE if network is reachable, %FALSE if not.
     294   */
     295  gboolean
     296  g_network_monitor_can_reach_finish (GNetworkMonitor     *monitor,
     297                                      GAsyncResult        *result,
     298                                      GError             **error)
     299  {
     300    GNetworkMonitorInterface *iface;
     301  
     302    iface = G_NETWORK_MONITOR_GET_INTERFACE (monitor);
     303    return iface->can_reach_finish (monitor, result, error);
     304  }
     305  
     306  static void
     307  g_network_monitor_default_init (GNetworkMonitorInterface *iface)
     308  {
     309    iface->can_reach_async  = g_network_monitor_real_can_reach_async;
     310    iface->can_reach_finish = g_network_monitor_real_can_reach_finish;
     311  
     312    /**
     313     * GNetworkMonitor::network-changed:
     314     * @monitor: a #GNetworkMonitor
     315     * @network_available: the current value of #GNetworkMonitor:network-available
     316     *
     317     * Emitted when the network configuration changes.
     318     *
     319     * Since: 2.32
     320     */
     321    signals[NETWORK_CHANGED] =
     322      g_signal_new (I_("network-changed"),
     323                    G_TYPE_NETWORK_MONITOR,
     324                    G_SIGNAL_RUN_LAST,
     325                    G_STRUCT_OFFSET (GNetworkMonitorInterface, network_changed),
     326                    NULL, NULL,
     327                    NULL,
     328                    G_TYPE_NONE, 1,
     329                    G_TYPE_BOOLEAN);
     330  
     331    /**
     332     * GNetworkMonitor:network-available:
     333     *
     334     * Whether the network is considered available. That is, whether the
     335     * system has a default route for at least one of IPv4 or IPv6.
     336     *
     337     * Real-world networks are of course much more complicated than
     338     * this; the machine may be connected to a wifi hotspot that
     339     * requires payment before allowing traffic through, or may be
     340     * connected to a functioning router that has lost its own upstream
     341     * connectivity. Some hosts might only be accessible when a VPN is
     342     * active. Other hosts might only be accessible when the VPN is
     343     * not active. Thus, it is best to use g_network_monitor_can_reach()
     344     * or g_network_monitor_can_reach_async() to test for reachability
     345     * on a host-by-host basis. (On the other hand, when the property is
     346     * %FALSE, the application can reasonably expect that no remote
     347     * hosts at all are reachable, and should indicate this to the user
     348     * in its UI.)
     349     *
     350     * See also #GNetworkMonitor::network-changed.
     351     *
     352     * Since: 2.32
     353     */
     354    g_object_interface_install_property (iface,
     355                                         g_param_spec_boolean ("network-available", NULL, NULL,
     356                                                               FALSE,
     357                                                               G_PARAM_READABLE |
     358                                                               G_PARAM_STATIC_STRINGS));
     359  
     360    /**
     361     * GNetworkMonitor:network-metered:
     362     *
     363     * Whether the network is considered metered.
     364     *
     365     * That is, whether the
     366     * system has traffic flowing through the default connection that is
     367     * subject to limitations set by service providers. For example, traffic
     368     * might be billed by the amount of data transmitted, or there might be a
     369     * quota on the amount of traffic per month. This is typical with tethered
     370     * connections (3G and 4G) and in such situations, bandwidth intensive
     371     * applications may wish to avoid network activity where possible if it will
     372     * cost the user money or use up their limited quota. Anything more than a
     373     * few hundreds of kilobytes of data usage per hour should be avoided without
     374     * asking permission from the user.
     375     *
     376     * If more information is required about specific devices then the
     377     * system network management API should be used instead (for example,
     378     * NetworkManager or ConnMan).
     379     *
     380     * If this information is not available then no networks will be
     381     * marked as metered.
     382     *
     383     * See also #GNetworkMonitor:network-available.
     384     *
     385     * Since: 2.46
     386     */
     387    g_object_interface_install_property (iface,
     388                                         g_param_spec_boolean ("network-metered", NULL, NULL,
     389                                                               FALSE,
     390                                                               G_PARAM_READABLE |
     391                                                               G_PARAM_STATIC_STRINGS));
     392  
     393    /**
     394     * GNetworkMonitor:connectivity:
     395     *
     396     * More detailed information about the host's network connectivity.
     397     * See g_network_monitor_get_connectivity() and
     398     * #GNetworkConnectivity for more details.
     399     *
     400     * Since: 2.44
     401     */
     402    g_object_interface_install_property (iface,
     403                                         g_param_spec_enum ("connectivity", NULL, NULL,
     404                                                            G_TYPE_NETWORK_CONNECTIVITY,
     405                                                            G_NETWORK_CONNECTIVITY_FULL,
     406                                                            G_PARAM_READABLE |
     407                                                            G_PARAM_STATIC_STRINGS));
     408  }