diff options
| author | Sebastien Bacher <seb128@ubuntu.com> | 2019-05-10 15:07:08 +0200 |
|---|---|---|
| committer | Sebastien Bacher <seb128@ubuntu.com> | 2019-05-22 13:41:30 +0200 |
| commit | d57a1dd26f8e9859252b0983c2d2ec3b95eb5714 (patch) | |
| tree | 46f1146e87af8cc7b58b751f7e575bd0abb2f59d /src/dns | |
| parent | ad9ed8bfb963266b4eea524131845f406cfc55d7 (diff) | |
| parent | 85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (diff) | |
Import Debian changes 1.18.0-1ubuntu1
network-manager (1.18.0-1ubuntu1) eoan; urgency=medium
* Update to 1.18, merge on Debian, new version includes nwe support for
policy routing rules and for VLAN filtering for Linux bridge.
* Remaining Ubuntu changes
- Use systemd-resolved instead of dnsmasq
- debian/control:
+ Depend on isc-dhcp-client instead of recommends
+ Recommend network-manager-pptp
+ Suggest avahi-autoipd for IPv4LL support
- debian/rules, debian/network-manager.postinst:
+ Don't restart NetworkManager on upgrade but recommend restarting
the computer
- debian/rules, debian/network-manager.postinst:
+ Don't install sysvinit scripts or migrate from sysvinit
- debian/network-manager.postinst:
+ Don't add the netdev group.
+ drop in an empty override file for NetworkManager to manage all
devices for upgrade from any version, as long as there is no
netplan configuration yet.
- debian/default-wifi-powersave-on.conf, debian/rules:
+ Install a config file to enable WiFi powersave
- Enable build tests
- Add autopkgtests
- debian/source_network-manager.py, debian/network-manager.install,
debian/network-manager.links: Add apport hook
- Add network-manager-config-connectivity-ubuntu package
- NetworkManager.conf: disable MAC randomization feature. There is no
easy way for desktop users to disable this feature yet. And there are
reports that it doesn't work well with some systems.
- Update Vcs links to point to Ubuntu branch
- Add patches. See patch descriptions for more details:
+ Provide-access-to-some-of-NM-s-interfaces-to-whoopsie.patch
+ Update-dnsmasq-parameters.patch
+ Disable-general-with-expect.patch
+ libnm-Check-self-still-NMManager-or-not.patch
+ dns-manager-don-t-merge-split-DNS-search-domains.patch (but disabled)
+ Read-system-connections-from-run.patch
- debian/tests/urfkill-integration - don't stop/start network manager
- Revert "Add Conflicts to network-manager-dev against deprecated libraries"
This reverts commit b4acc5e03e2b821e1cccc69529bb70826c741942. We're still
building libnm-glib for now, so these packages have a use in Ubuntu.
* Removed delta, not needed anymore
- debian/network-manager.maintscript
+ Remove /etc/dbus-1/system.d/nm-ofono.conf
Diffstat (limited to 'src/dns')
| -rw-r--r-- | src/dns/nm-dns-manager.c | 11 | ||||
| -rw-r--r-- | src/dns/nm-dns-systemd-resolved.c | 283 | ||||
| -rw-r--r-- | src/dns/nm-dns-systemd-resolved.h | 2 |
3 files changed, 231 insertions, 65 deletions
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index c7c561c4..27c3e710 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -347,13 +347,20 @@ gboolean nm_dns_manager_has_systemd_resolved (NMDnsManager *self) { NMDnsManagerPrivate *priv; + NMDnsSystemdResolved *plugin = NULL; g_return_val_if_fail (NM_IS_DNS_MANAGER (self), FALSE); priv = NM_DNS_MANAGER_GET_PRIVATE (self); - return priv->sd_resolve_plugin - || NM_IS_DNS_SYSTEMD_RESOLVED (priv->plugin); + if (priv->sd_resolve_plugin) { + nm_assert (!NM_IS_DNS_SYSTEMD_RESOLVED (priv->plugin)); + plugin = NM_DNS_SYSTEMD_RESOLVED (priv->sd_resolve_plugin); + } else if (NM_IS_DNS_SYSTEMD_RESOLVED (priv->plugin)) + plugin = NM_DNS_SYSTEMD_RESOLVED (priv->plugin); + + return plugin + && nm_dns_systemd_resolved_is_running (plugin); } /*****************************************************************************/ diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c index 10797b86..5d262ba3 100644 --- a/src/dns/nm-dns-systemd-resolved.c +++ b/src/dns/nm-dns-systemd-resolved.c @@ -31,7 +31,7 @@ #include <sys/stat.h> #include <linux/if.h> -#include "nm-utils/nm-c-list.h" +#include "nm-glib-aux/nm-c-list.h" #include "nm-core-internal.h" #include "platform/nm-platform.h" #include "nm-utils.h" @@ -42,9 +42,11 @@ #include "nm-setting-connection.h" #include "devices/nm-device.h" #include "NetworkManagerUtils.h" +#include "nm-std-aux/nm-dbus-compat.h" -#define SYSTEMD_RESOLVED_DBUS_SERVICE "org.freedesktop.resolve1" -#define SYSTEMD_RESOLVED_DBUS_PATH "/org/freedesktop/resolve1" +#define SYSTEMD_RESOLVED_DBUS_SERVICE "org.freedesktop.resolve1" +#define SYSTEMD_RESOLVED_MANAGER_IFACE "org.freedesktop.resolve1.Manager" +#define SYSTEMD_RESOLVED_DBUS_PATH "/org/freedesktop/resolve1" /*****************************************************************************/ @@ -62,10 +64,14 @@ typedef struct { /*****************************************************************************/ typedef struct { - GDBusProxy *resolve; - GCancellable *init_cancellable; - GCancellable *update_cancellable; + GDBusConnection *dbus_connection; + GCancellable *cancellable; CList request_queue_lst_head; + guint name_owner_changed_id; + bool send_updates_warn_ratelimited:1; + bool try_start_blocked:1; + bool dbus_has_owner:1; + bool dbus_initied:1; } NMDnsSystemdResolvedPrivate; struct _NMDnsSystemdResolved { @@ -121,17 +127,26 @@ _interface_config_free (InterfaceConfig *config) static void call_done (GObject *source, GAsyncResult *r, gpointer user_data) { - GVariant *v; - GError *error = NULL; + gs_unref_variant GVariant *v = NULL; + gs_free_error GError *error = NULL; NMDnsSystemdResolved *self = (NMDnsSystemdResolved *) user_data; + NMDnsSystemdResolvedPrivate *priv; + + v = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), r, &error); + if ( !v + && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), r, &error); if (!v) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - _LOGW ("Failed: %s", error->message); - g_error_free (error); - } + if (!priv->send_updates_warn_ratelimited) { + priv->send_updates_warn_ratelimited = TRUE; + _LOGW ("send-updates failed to update systemd-resolved: %s", error->message); + } else + _LOGD ("send-updates failed: %s", error->message); + } else + priv->send_updates_warn_ratelimited = FALSE; } static void @@ -175,12 +190,11 @@ static void free_pending_updates (NMDnsSystemdResolved *self) { NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - RequestItem *request_item, *request_item_safe; + RequestItem *request_item; - c_list_for_each_entry_safe (request_item, - request_item_safe, - &priv->request_queue_lst_head, - request_queue_lst) + while ((request_item = c_list_first_entry (&priv->request_queue_lst_head, + RequestItem, + request_queue_lst))) _request_item_free (request_item); } @@ -267,27 +281,74 @@ static void send_updates (NMDnsSystemdResolved *self) { NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - RequestItem *request_item, *request_item_safe; + RequestItem *request_item; + + if (c_list_is_empty (&priv->request_queue_lst_head)) { + /* nothing to do. */ + return; + } + + if (!priv->dbus_initied) { + _LOGT ("send-updates: D-Bus connection not ready"); + return; + } - nm_clear_g_cancellable (&priv->update_cancellable); + if (!priv->dbus_has_owner) { + if (priv->try_start_blocked) { + /* we have no name owner and we already tried poking the service to + * autostart. */ + _LOGT ("send-updates: no name owner"); + return; + } - if (!priv->resolve) + _LOGT ("send-updates: no name owner. Try start service..."); + priv->try_start_blocked = TRUE; + + g_dbus_connection_call (priv->dbus_connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "StartServiceByName", + g_variant_new ("(su)", SYSTEMD_RESOLVED_DBUS_SERVICE, 0u), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); return; + } - priv->update_cancellable = g_cancellable_new (); - - c_list_for_each_entry_safe (request_item, - request_item_safe, - &priv->request_queue_lst_head, - request_queue_lst) { - g_dbus_proxy_call (priv->resolve, - request_item->operation, - request_item->argument, - G_DBUS_CALL_FLAGS_NONE, - -1, - priv->update_cancellable, - call_done, - self); + _LOGT ("send-updates: start %lu requests", + c_list_length (&priv->request_queue_lst_head)); + + nm_clear_g_cancellable (&priv->cancellable); + + priv->cancellable = g_cancellable_new (); + + while ((request_item = c_list_first_entry (&priv->request_queue_lst_head, + RequestItem, + request_queue_lst))) { + /* Above we explicitly call "StartServiceByName" trying to avoid D-Bus activating systmd-resolved + * multiple times. There is still a race, were we might hit this line although actually + * the service just quit this very moment. In that case, we would try to D-Bus activate the + * service multiple times during each call (something we wanted to avoid). + * + * But this is hard to avoid, because we'd have to check the error failure to detect the reason + * and retry. The race is not critical, because at worst it results in logging a warning + * about failure to start systemd.resolved. */ + g_dbus_connection_call (priv->dbus_connection, + SYSTEMD_RESOLVED_DBUS_SERVICE, + SYSTEMD_RESOLVED_DBUS_PATH, + SYSTEMD_RESOLVED_MANAGER_IFACE, + request_item->operation, + request_item->argument, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->cancellable, + call_done, + self); _request_item_free (request_item); } } @@ -361,28 +422,100 @@ get_name (NMDnsPlugin *plugin) /*****************************************************************************/ static void -resolved_proxy_created (GObject *source, GAsyncResult *r, gpointer user_data) +name_owner_changed (NMDnsSystemdResolved *self, + const char *owner) { - NMDnsSystemdResolved *self = (NMDnsSystemdResolved *) user_data; + NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); + + owner = nm_str_not_empty (owner); + + if (!owner) + _LOGT ("D-Bus name for systemd-resolved has no owner"); + else + _LOGT ("D-Bus name for systemd-resolved has owner %s", owner); + + priv->dbus_has_owner = !!owner; + if (owner) + priv->try_start_blocked = FALSE; + + send_updates (self); +} + +static void +name_owner_changed_cb (GDBusConnection *connection, + const char *sender_name, + const char *object_path, + const char *interface_name, + const char *signal_name, + GVariant *parameters, + gpointer user_data) +{ + NMDnsSystemdResolved *self = user_data; + NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); + const char *new_owner; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sss)"))) + return; + + g_variant_get (parameters, + "(&s&s&s)", + NULL, + NULL, + &new_owner); + + if (!priv->dbus_initied) { + /* There was a race and we got a NameOwnerChanged signal before GetNameOwner + * returns. */ + priv->dbus_initied = TRUE; + nm_clear_g_cancellable (&priv->cancellable); + } + + name_owner_changed (user_data, new_owner); +} + +static void +get_name_owner_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + NMDnsSystemdResolved *self; NMDnsSystemdResolvedPrivate *priv; + gs_unref_variant GVariant *ret = NULL; gs_free_error GError *error = NULL; - GDBusProxy *resolve; + const char *owner = NULL; - resolve = g_dbus_proxy_new_finish (r, &error); - if ( !resolve + ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), res, &error); + if ( !ret && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; + if (ret) + g_variant_get (ret, "(&s)", &owner); + + self = user_data; priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - g_clear_object (&priv->init_cancellable); - if (!resolve) { - _LOGW ("failed to connect to resolved via DBus: %s", error->message); - g_signal_emit_by_name (self, NM_DNS_PLUGIN_FAILED); - return; - } - priv->resolve = resolve; - send_updates (self); + g_clear_object (&priv->cancellable); + + priv->dbus_initied = TRUE; + + name_owner_changed (self, owner); +} + +/*****************************************************************************/ + +gboolean +nm_dns_systemd_resolved_is_running (NMDnsSystemdResolved *self) +{ + NMDnsSystemdResolvedPrivate *priv; + + g_return_val_if_fail (NM_IS_DNS_SYSTEMD_RESOLVED (self), FALSE); + + priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); + + return priv->dbus_initied + && ( priv->dbus_has_owner + || !priv->try_start_blocked); } /*****************************************************************************/ @@ -394,17 +527,35 @@ nm_dns_systemd_resolved_init (NMDnsSystemdResolved *self) c_list_init (&priv->request_queue_lst_head); - priv->init_cancellable = g_cancellable_new (); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | - G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, - NULL, - SYSTEMD_RESOLVED_DBUS_SERVICE, - SYSTEMD_RESOLVED_DBUS_PATH, - SYSTEMD_RESOLVED_DBUS_SERVICE ".Manager", - priv->init_cancellable, - resolved_proxy_created, - self); + priv->dbus_connection = nm_g_object_ref (nm_dbus_manager_get_dbus_connection (nm_dbus_manager_get ())); + if (!priv->dbus_connection) { + _LOGD ("no D-Bus connection"); + return; + } + + priv->name_owner_changed_id = g_dbus_connection_signal_subscribe (priv->dbus_connection, + DBUS_SERVICE_DBUS, + DBUS_INTERFACE_DBUS, + "NameOwnerChanged", + DBUS_PATH_DBUS, + SYSTEMD_RESOLVED_DBUS_SERVICE, + G_DBUS_SIGNAL_FLAGS_NONE, + name_owner_changed_cb, + self, + NULL); + priv->cancellable = g_cancellable_new (); + g_dbus_connection_call (priv->dbus_connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetNameOwner", + g_variant_new ("(s)", SYSTEMD_RESOLVED_DBUS_SERVICE), + G_VARIANT_TYPE ("(s)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->cancellable, + get_name_owner_cb, + self); } NMDnsPlugin * @@ -420,9 +571,15 @@ dispose (GObject *object) NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); free_pending_updates (self); - g_clear_object (&priv->resolve); - nm_clear_g_cancellable (&priv->init_cancellable); - nm_clear_g_cancellable (&priv->update_cancellable); + + if (priv->name_owner_changed_id != 0) { + g_dbus_connection_signal_unsubscribe (priv->dbus_connection, + nm_steal_int (&priv->name_owner_changed_id)); + } + + nm_clear_g_cancellable (&priv->cancellable); + + g_clear_object (&priv->dbus_connection); G_OBJECT_CLASS (nm_dns_systemd_resolved_parent_class)->dispose (object); } diff --git a/src/dns/nm-dns-systemd-resolved.h b/src/dns/nm-dns-systemd-resolved.h index 800a60c1..b79ff5e4 100644 --- a/src/dns/nm-dns-systemd-resolved.h +++ b/src/dns/nm-dns-systemd-resolved.h @@ -36,4 +36,6 @@ GType nm_dns_systemd_resolved_get_type (void); NMDnsPlugin *nm_dns_systemd_resolved_new (void); +gboolean nm_dns_systemd_resolved_is_running (NMDnsSystemdResolved *self); + #endif /* __NETWORKMANAGER_DNS_SYSTEMD_RESOLVED_H__ */ |