Commit graph

83 commits

Author SHA1 Message Date
Beniamino Galvani
5df69330b5 dns: sd-resolved: honor dns-priority
Honor dns-priority by using the preprocessed list of domains provided
by the manager.
2018-05-14 15:22:50 +02:00
Beniamino Galvani
6409e7719c dns: dnsmasq: honor dns-priority
Honor dns-priority by using the preprocessed list of domains provided
by the manager.
2018-05-14 15:22:50 +02:00
Beniamino Galvani
dd1e671fe5 dns: use dns-priority to provide a preprocessed domain list to plugins
Do some preprocessing on the DNS configuration sent to plugins:

 - add the '~' default routing (lookup) domain to IP configurations
   with the default route or, when there is none, to all non-VPN
   IP configurations

 - use the dns-priority to decide which connection to use in case
   multiple connections have the same domain

 - consider a negative dns-priority value as a way to 'shadow' all
   subdomains from other connections

 - compute reverse DNS domains

and add the resulting domain list to NMDnsIPConfigData so that
split-DNS plugins can use that directly instead of reimplementing the
same logic themselves.
2018-05-14 15:22:50 +02:00
Beniamino Galvani
14b6e330e2 dns: dnsmasq: fix adding multiple domains
Fixes: e91f1a7d2a
2018-05-14 15:22:50 +02:00
Beniamino Galvani
1b5925ce88 all: remove consecutive empty lines
Normalize coding style by removing consecutive empty lines from C
sources and headers.

https://github.com/NetworkManager/NetworkManager/pull/108
2018-04-30 16:24:52 +02:00
Thomas Haller
64708c3443 dns: fix logging path name in update_resolv_conf() 2018-04-04 16:38:18 +02:00
Thomas Haller
e49a32936c all: use nm_utils_hash_keys_to_array() 2018-03-27 09:58:00 +02:00
Thomas Haller
cd48bc74b6 config: cleanup fields in NMGlobalDnsConfig
- consistently set options, searches, domains fields to %NULL,
  if there are no values.

- in nm_global_dns_config_update_checksum(), ensure that we uniquely
  hash values. E.g. a config with "searches[a], options=[b]" should
  hash differently from "searches=[ab], options=[]".

- in nm_global_dns_config_to_dbus(), reuse the sorted domain list.
  We already have it, and it guarantees a consistent ordering of
  fields.

- in global_dns_domain_from_dbus(), fix memleaks if D-Bus strdict
  contains duplicate entries.
2018-03-27 09:58:00 +02:00
Thomas Haller
e762eba05a dns: remove unused nm_dns_manager_get_resolv_conf_explicit() function 2018-03-20 21:03:20 +01:00
Thomas Haller
57ab9fd60f core/dbus: rework creating numbered D-Bus export path by putting counter into class
I dislike the static hash table to cache the integer counter for
numbered paths. Let's instead cache the counter at the class instance
itself -- since the class contains the information how the export
path should be exported.

However, we cannot use a plain integer field inside the class structure,
because the class is copied between derived classes. For example,
NMDeviceEthernet and NMDeviceBridge both get a copy of the NMDeviceClass
instance. Hence, the class doesn't contain the counter directly, but
a pointer to one counter that can be shared between sibling classes.
2018-03-13 11:29:18 +01:00
Thomas Haller
297d4985ab core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.

Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.

This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.

This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.

Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.

Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.

Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.

Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.

Numbers (for contrib/rpm --without debug on x86_64):

- the patch changes the code size of NetworkManager by
  - 2809360 bytes
  + 2537528 bytes (-9.7%)

- Runtime measurements are harder because there is a large variance
  during testing. In other words, the numbers are not reproducible.
  Currently, the implementation performs no caching of GVariants at all,
  but it would be rather simple to add it, if that turns out to be
  useful.
  Anyway, without strong claim, it seems that the new form tends to
  perform slightly better. That would be no surprise.

  $ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .;  done)
  - real    1m39.355s
  + real    1m37.432s

  $ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
  - real    0m26.843s
  + real    0m25.281s

- Regarding RSS size, just looking at the processes in similar
  conditions, doesn't give a large difference. On my system they
  consume about 19MB RSS. It seems that the new version has a
  slightly smaller RSS size.
  - 19356 RSS
  + 18660 RSS
2018-03-12 18:37:08 +01:00
Thomas Haller
a1f37964f0 core: rename "nm-bus-manager.h" to "nm-dbus-manager.h"
The next commit will completely rework NMBusManager and replace
NMExportedObject by a new type NMDBusObject.

Originally, NMDBusObject was added along NMExportedObject to ease
the rework and have compilable, intermediate stages of refactoring. Now,
I think the new name is better, because NMDBusObject is very strongly related
to the bus manager and the old name NMExportedObject didn't make that
clear.

I also slighly prefer the name NMDBusObject over NMBusObject, hence
for consistancy, also rename NMBusManager to NMDBusManager.

This commit only renames the file for a nicer diff in the next commit.
It does not actually update the type name in sources. That will be done
later.
2018-03-12 18:03:07 +01:00
Thomas Haller
70b24819a0 dns: don't leak cached config_variant on exit
Not really serious as it's only on shutdown, but shows up as leak in valgrind.
2018-03-10 16:49:30 +01:00
Beniamino Galvani
37eed6984b dns: on quit only update resolv.conf if dns=dnsmasq
Previously we always updated resolv.conf on quit. When we are using
systemd-resolved the update is not necessary because the resolver on
127.0.0.53 would still be reachable after NM quits. Also, when NM
manages resolv.conf directly there is no need to update the file
again. Let's rewrite resolv.conf only when using dnsmasq.

https://bugzilla.redhat.com/show_bug.cgi?id=1541031
2018-02-09 12:00:16 +01:00
Beniamino Galvani
10ef61408e dns: fix compilation error
Fixes the following error when building with gcc 4.8.5 and address
sanitizer:

src/dns/nm-dns-dnsmasq.c: In function 'update':
src/dns/nm-dns-dnsmasq.c:506:44: error: 'first_prio' may be used uninitialized in this function [-Werror=maybe-uninitialized]
    } else if (first_prio < 0 && first_prio != prio)
                                            ^
2018-02-08 11:18:06 +01:00
Beniamino Galvani
e91f1a7d2a dns: introduce routing domains
Similarly to what systemd-resolved does, introduce the concept of
"routing" domain, which is a domain in the search list that is used
only to decide the interface over which a query must be forwarded, but
is not used to complete unqualified host names. Routing domains are
those starting with a tilde ('~') before the actual domain name.

Domains without the initial tilde are used both for completing
unqualified names and for the routing decision.
2018-01-12 13:42:08 +01:00
Beniamino Galvani
42ea86fb7a dns: systemd-resolved: use generic ip-config functions 2018-01-12 13:42:08 +01:00
Beniamino Galvani
70550e2740 dns: export search list in the D-Bus "domain" attribute
The "domain" key of the D-Bus configuration dictionary specifies the
domains a configuration applies to. In DNS code we consider domains
and searches as equivalent, so they should be exported via D-Bus using
the same logic used to populate resolv.conf and for plugins.
2018-01-12 13:42:08 +01:00
Beniamino Galvani
b4db0e8362 dns: add @dup argument to add_dns_domains() and add_string_item()
Add a @dup argument that tells whether the new item should be
duplicated.
2018-01-12 13:42:08 +01:00
Beniamino Galvani
e78bfb63cd dns: split out domains retrieval 2018-01-12 13:42:08 +01:00
Thomas Haller
c03a534963 core: implement setting MDNS setting for systemd
The connection.mdns setting is a per-connection setting,
so one might expect that one activated device can only have
one MDNS setting at a time.

However, with certain VPN plugins (those that don't have their
own IP interface, like libreswan), the VPN configuration is merged
into the configuration of the device. So, in this case, there
might be multiple settings for one device that must be merged.

We already have a mechanism for that. It's NMIP4Config. Let NMIP4Config
track this piece of information. Although, stricitly speaking this
is not tied to IPv4, the alternative would be to introduce a new
object to track such data, which would be a tremendous effort
and more complicated then this.

Luckily, NMDnsManager and NMDnsPlugin are already equipped to
handle multiple NMIPConfig instances per device (IPv4 vs. IPv6,
and Device vs. VPN).

Also make "connection.mdns" configurable via global defaults in
NetworkManager.conf.
2018-01-09 14:24:54 +01:00
Thomas Haller
b40729ca5f core: rework tracking config in dns-manager to use ifindex
Don't track the per-device configuration in NMDnsManager by
the ifname, but by the ifindex. We should consistently treat
the ifindex as the ID of a link, like kernel does.

At the few places where we actually need the ifname, resolve
it by looking into the platform cache. That is not necessarily
the same as the ifname that is currently tracked by NMDevice,
because netdev interfaces can be renamed, and NMDevice updates
it's link properties delayed. However, the platform cache has
the most recent notion of the correct interface name for an
ifindex, so if we ever hit a race here, we do it now more
correctly.

This also temporarily drops support for mdns. Will be re-added next,
but differently.
2018-01-09 14:24:54 +01:00
Thomas Haller
fc40d91b97 core/trivial: rename local variable in merge_one_ip_config()
Next commit will unify naming of variables, do a trivial rename
first to make the diff smaller.
2018-01-09 14:24:54 +01:00
Thomas Haller
b0f1a54c9b dns: rework pending request-queue in NMDnsSystemdResolved
We had two separate queues, one for "SetLinkDNS" and one for
"SetLinkDomains". Merge them into one, and track the operation
as part of the new RequestItem structure.

A visible change to before is that we now would make all requests
per-interface first. Prevously, we would first make all SetLinkDNS
requests (for all interfaces) and then all SetLinkDomains requests.
It feels more correct to order the requests this way, not by
type.

The reason to merge is, that we will next get another operation
and in the current scheme we would need 3 GQueue instances.

While at it, refactor the code to use CList. We now anyway would
need a new struct to track the operation, requiring to allocate
and free it. Previously, we would only track the GVariant argument
as data of the GQueue.
2018-01-09 14:24:54 +01:00
Thomas Haller
4be4a3c21f dns: refactor update() in NMDnsSystemdResolved to use a hash table
Use a GHashTable instead of a GArray to construct the list of
@interfaces. Also, use NMCListElem instead of GList. With this,
the runtime is O(n*log(n)) instead of O(n^2).

I belive, we should take care that all our code has a reasonable
runtime complexity, even in common use-cases the number of elements
is small. This is not about performace, because likely we expect few
entries anyway, and the direct GArray implementation is likely faster
in those cases. It's about using the data structure that best suits the
access pattern.

The log(n) part comes from sorting the keys. I also believe we should
always aim for a stable behavior. When sending the D-Bus request to
resolved, the order of elements should be in ~some~ defined order.
2018-01-09 14:24:54 +01:00
Thomas Haller
7d4def2764 dns: merge IPv4 and IPv6 versions of add_ip_config() (part 2) 2018-01-09 14:24:53 +01:00
Thomas Haller
49fd1e4126 dns: merge IPv4 and IPv6 versions of add_ip_config() (part 1) 2018-01-09 14:24:53 +01:00
Thomas Haller
03cba93873 dns/trivial: move code 2018-01-09 14:24:53 +01:00
Thomas Haller
9d92848ada libnm: rename MDns flag UNKNOWN to DEFAULT
"UNKNOWN" is not a good name. If you don't set the property
in the connection explicitly, it should be "DEFAULT".

Also, make "DEFAULT" -1. For one, that ensures that the enum's
underlying integer type is signed. Otherwise, it's cumbersome
to test "if (mdns >= DEFAULT)" because in case of unsigned types,
the compiler will warn about the check always being true.
Also, it allows for "NO" to be zero. These are no strong reasons,
but I tend to think this is better.

Also, don't make the property of NMSettingConnection a CONSTRUCT property.
Initialize the default manually in the init function.

Also, order the numeric values so that DEFAULT < NO < RESOLVE < YES with
YES being largest because it enables *the most*.
2018-01-09 14:24:53 +01:00
Ismo Puustinen
25906eda9e dns: add mechanism for propagating mDNS setting.
Update nm-policy.c and nm-dns-manager.c so that the connection-specific
settings get propagated to DNS manger. Currently the only such value is
the mDNS status.

Add update_mdns() function to DNS plugin interface. If a DNS plugin
supports mDNS, it can set an interface with a given index to support
mDNS resolving or also register the current hostname.

The mDNS support is currently added only to systemd-resolved DNS plugin.
2018-01-09 14:24:53 +01:00
Thomas Haller
3d86429c9d core: reorder code in "src/dns/nm-dns-manager.c"
Just moving code around, no other changes.

Follow a certain prefered order of declarations
in source files.
2018-01-09 14:24:53 +01:00
Thomas Haller
41f608dd91 dns: rework write_to_netconfig()
The compiler warns when we ignore the return value from write().
And assigning it to an unused variable, causes another warning.
Make some use of it, at least to handle EINTR. All other errors
are still ignored.

While at it, rework the write code to first write to a buffer
in memory.
2017-12-18 15:46:41 +01:00
Thomas Haller
ad3bbda8e3 core: avoid compiler warnings in write_to_netconfig() and ifnet_update_parsers_by_connection()
src/dns/nm-dns-manager.c: In function ‘write_to_netconfig’:
    src/dns/nm-dns-manager.c:387:8: error: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Werror=unused-result]
      write (fd, str, strlen (str));
            ^

    src/settings/plugins/ifnet/nms-ifnet-connection-parser.c: In function ‘ifnet_update_parsers_by_connection’:
    src/settings/plugins/ifnet/nms-ifnet-connection-parser.c:2600:26: error: variable ‘pppoe’ set but not used [-Werror=unused-but-set-variable]
      gboolean wired = FALSE, pppoe = TRUE;
                              ^~~~~

While at it, don't log line breaks in ifnet_update_parsers_by_connection().

Fixes: e912b36d95
2017-12-18 15:03:43 +01:00
Lubomir Rintel
6672c5e92e all: get rid of a handful of unused-but-set variables 2017-12-18 13:29:32 +01:00
Thomas Haller
25267f9d27 dns: don't stat relative paths when detecting resolved use
NetworkManager daemon has no defined working directory.
It makes no sense to ever open or stat relative paths.
Just skip them.

https://bugzilla.gnome.org/show_bug.cgi?id=790446
2017-11-19 14:29:16 +01:00
Dimitri John Ledkov
e09503dcc4 dns: check for relative paths and stub-resolve.conf when detecting systemd-resolved
Fix resolved detection, the symlink target is usually relative to the
root, such that in chroots the file points to a file inside the
chroot. But keep absolute targets too, as these may have been in use
with older version of systemd. Add support for stub-resolv.conf
detection.

https://bugzilla.gnome.org/show_bug.cgi?id=790446
2017-11-19 14:25:59 +01:00
Thomas Haller
54bcbb85d3 core: merge IPv4 and IPv6 implementations in NMDnsManager 2017-11-09 09:29:39 +01:00
Thomas Haller
6246364747 core: replace nm_dns_ip_config_data_get_dns_priority()
Add instead nm_ip_config_get_dns_priority(). If we want to treat NMIP4Config/NMIP6Config
generically, then the accessor should be right there.
2017-11-08 14:46:31 +01:00
Thomas Haller
157932f7dd policy: merge IPv4 and IPv6 implementation of update_ip_dns() 2017-11-08 14:03:26 +01:00
Beniamino Galvani
d29115c138 core: use nm_close()
Use nm_close() in the core to catch any improper use of close().
2017-10-19 15:49:58 +02:00
Thomas Haller
5c299454b4 core: rework tracking of gateway/default-route in ip-config
Instead of having 3 properties @gateway, @never_default and @has_gateway
on NMIP4Config/NMIP6Config that determine the default-route, track the
default-route as a regular route.

The gateway setting is the configuration knob for the default-route.
Since an NMIP4Config/NMIP6Config instance only has one gateway property,
it cannot track more then one default-routes (see related bug rh#1445417).
Especially with policy routing, it might be interesting to configure a
default-route in multiple tables.

Also, later it might be interesting to allow adding default-routes as
regular static routes in a connection, so that the user can configure additional
route parameters for the default-route or add default-routes in multiple tables.

With this patch, default-routes now have a rt_source property according to their
origin.

Also, the previous commits of this branch broke handling of the
default-route :) . That should be working now again.
2017-10-10 08:46:47 +02:00
Thomas Haller
17ca5c4c0c dns: merge IPv4 and IPv6 implementation for update_add_ip_config()
How nice would it be to have a NMIPConfig class that is
agnostic for IPv4 and IPv6. Another small step, in unifying
v4 and v6.
2017-10-09 22:05:35 +02:00
Thomas Haller
0918b4914d core: support tracking default-route in NMIP4Config/NMIP6Config
Default-routes are for the most part like regular routes. Add support to
track them like regular routes in NMIP4Config/NMIP6Config.

One thing is, sometimes we need to figure out whether an ip-config
instance has a default-route. For that, keep track of the best
default-route (there might be multiple) and expose it. That is
the most complicated part of this patch, because there are so many
places where the list of routes gets modified (replace, intersect,
subtract, merge, add), and they all need to take care of updating
the best default-route.

In a next patch, NMDefaultRouteManager will be dropped and default-routes
will be tracked by NMIP4Config/NMIP6Config.
2017-09-08 11:11:21 +02:00
Thomas Haller
ac5350fef2 dns: use 127.0.0.53 address in /etc/resolv.conf with systemd-resolved
https://bugzilla.gnome.org/show_bug.cgi?id=787378
2017-09-07 15:29:57 +02:00
Thomas Haller
22edeb5b69 core: track addresses for NMIP4Config/NMIP6Config via NMDedupMultiIndex
Reasons:

 - it adds an O(1) lookup index for accessing NMIPxConfig's addresses.
   Hence, operations like merge/intersect have now runtime O(n) instead
   of O(n^2).
   Arguably, we expect low numbers of addresses in general. For low
   numbers, the O(n^2) doesn't matter and quite likely in those cases
   the previous implementation was just fine -- maybe even faster.
   But the simple case works fine either way. It's important to scale
   well in the exceptional case.
 - the tracked objects can be shared between the various NMPI4Config,
   NMIP6Config instances with NMPlatform and everybody else.
 - the NMPObject can be treated generically, meaning it enables code to
   handle both IPv4 and IPv6, or addresses and routes. See for example
   _nm_ip_config_add_obj().
 - I want core to evolve to somewhere where we don't keep copies of
   NMPlatformIP4Address, et al. instances. Instead they shall all be
   shared. I hope this will reduce memory consumption (although tracking a
   reference consumes some memory too). Also, it shortcuts nmp_object_equal()
   when comparing the same object. Calling nmp_object_equal() on the
   identical objects would be a common case after the hash function
   pre-evaluates equality.
2017-07-25 06:44:12 +02:00
Beniamino Galvani
5aa22ed8c9 dns: perform the public-suffix check only for the hostname-derived domain
The DNS manager drops from the search list domains that are public
suffixes to prevent a possible domain hijack when using two-labels
hostnames [1].

This is a problem now that every single-label domain can be a TLD
since this means that such domains can't be used in the search list.

While it's useful to apply such restriction to the domain
automatically derived from the system hostname, it seems wrong to drop
domains specified by users in the configuration or provided by DHCP.

This commit keeps the public-suffix check only for the
hostname-derived domain

[1] https://bugzilla.redhat.com/show_bug.cgi?id=812394

https://bugzilla.redhat.com/show_bug.cgi?id=1404350
2017-07-17 17:01:51 +02:00
Thomas Haller
cfd1851c00 core: refactor NMIP6Config to use dedup-index for IPv6 routes 2017-07-05 18:37:39 +02:00
Thomas Haller
935411e5c0 core: refactor NMIP4Config to use dedup-index for IPv4 routes
Eventually, every NMPlatformIP4Route, NMPlatformIP6Route,
NMPlatformIP4Address and NMPlatformIP6Address should be shared
an deduplicated via the global NMDedupMultiIndex instance.

As first proof of concept, refactor NMIP4Config to track
IPv4 routes via the shared multi_idx. There is later potential
for improvement, when we pass (deduplicated) NMPObject instances
around instead of plain NMPlatformIP4Route, which needs still
a lot of comparing and cloning.
2017-07-05 14:22:10 +02:00
Thomas Haller
19a98c6f61 dns: don't clone DNS configs list for nm_dns_plugin_update()
No need to clone the list anymore. Unfortunately, GPtrArray is not NULL
terminated (without extra effort), so we have to pass on the GPtrArray
instance for the length.
2017-06-19 15:12:49 +02:00
Thomas Haller
70792e51d9 dns: fix negative ipv4.dns-priority for systemd-resolved
A negative ipv4.dns-priority and ipv6.dns-priority has the meaning to configure
the DNS information of the connection exclusively. With systemd-resolved, that means
we must explicitly unset the configuration from other interfaces.

https://bugzilla.gnome.org/show_bug.cgi?id=783569
2017-06-19 15:12:49 +02:00