Commit graph

20111 commits

Author SHA1 Message Date
Thomas Haller
3a2fbab09b core: don't consider deactivating active-connection when checking for concurrent activations
At various places we check whether we have an active-connection already.

For example, when activating a new connection in _internal_activate_device(),
we might want to "nm_device_steal_connection()" if the same profile is
already active.

However, the max-state argument was not accurate in several cases. For
the purpose of finding concurrent activations, we don't care about
active-connections that are already in state DEACTIVATING. Only those
that are ACTIVATED or before.
2018-04-30 16:36:30 +02:00
Thomas Haller
36ed7ef084 manager: minor refactoring of active_connection_find_by_connection()
active_connection_find_by_connection() (or how it was called previously) is
a simpler wrapper around active_connection_find(), which accepts a NMConnection
argument, that may or may not be a NMSettingsConnection.

It always passed NM_ACTIVE_CONNECTION_STATE_DEACTIVATING as max_state, and I think
that one of the two callers don't should do that. A later commit will change that.
So, we also want to pass @max_state as argument to active_connection_find_by_connection().
At that point, make active_connection_find_by_connection() identical to
active_connection_find(), with the only exception, that it accepts a
NMConnection and does automatically do the right thing (either lookup by
pointer equality or by uuid).
2018-04-30 16:36:29 +02:00
Thomas Haller
9424aa0562 manager: extend helper function to find all matching active-connections
... instead of just the first.

It's not used yet, and there is no change in behavior.
2018-04-30 16:36:29 +02:00
Thomas Haller
9c2785f31c core: only abort conflicting activations for certain activation types
There are various places where we do an internal activation (with an
internal auth-subject). In several of these places, the
ACTIVATION_REASON is USER_REQUEST.

I think it is wrong to generally abort all internal activations, except
AUTOCONNECT_SLAVES ones. I think, aborting an activation should be
opt-in instead of opt-out.

To me it seems, we want to abort the activation based on the activation
reason. For now, opt-in to EXTERNAL, ASSUME and AUTOCONNECT only. If
there are additional cases where we should abort activation, we should
add yet another reason and not use USER_REQUEST.
2018-04-30 16:36:29 +02:00
Thomas Haller
5a1f84b085 core: add activation-reasons for external/assume connections
Until now, we only really cared about whether a connection was activated
with reason NM_ACTIVATION_REASON_AUTOCONNECT_SLAVES or not.

Now however, we will care about whether a connection was activated via
(genuine) autoconnect by NMPolicy, or external/assume by NMManager.
Add a new reason to distinguish between them.
2018-04-30 16:36:29 +02:00
Thomas Haller
feb1ec1e87 settings: avoid lookup in nm_settings_has_connection()
There is no need to perform a lookup by path. NMSettings is a singleton,
it has the connection exactly iff the connection is linked.

Also add an assertion to double-check that the results agree with
the previous implementation.
2018-04-30 16:36:29 +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
Beniamino Galvani
e09b2314b9 manager: fix assertion in nm_manager_activate_connection()
nm_manager_activate_connection() should not require a device to be
passed in for VPN connections because when the argument is NULL the
actual device will be determined by _new_active_connection().

Fixes: 10753c3616
https://bugzilla.redhat.com/show_bug.cgi?id=1570545
https://github.com/NetworkManager/NetworkManager/pull/109
2018-04-30 16:23:01 +02:00
Stas Solovey
416b2c020b po: updated Russian (ru) translation (bgo #794738)
https://bugzilla.gnome.org/show_bug.cgi?id=794738
2018-04-27 13:33:58 +02:00
Thomas Haller
bca6bdb9f8 connectivity: merge branch 'th/connectivity-check-on-activated'
https://github.com/NetworkManager/NetworkManager/pull/103
2018-04-27 12:33:36 +02:00
Thomas Haller
2b8802d8ec device/connectivity: refactor concheck_periodic_schedule_do()
Instead of passing the interval for the timeout, let concheck_periodic_schedule_do()
figure it out on its own. It only depends on cur-interval and
cur-basetime.

Additionally, pass now_ns timestamp, because we already made
decisions based on this particular timestamp. We don't want to
re-evalutate the current time but ensure to use the same timestamp.

There is no change in behavior, it just seems nicer this way.
2018-04-27 12:33:19 +02:00
Thomas Haller
25ccd3d95d device: force a connectivity check when reaching device-state "activated"
When the device-state changes to "activated", force a connectivity check
right away. Something possibly happened that affected connectivity.

Also, reduce the interval time down to CONCHECK_P_PROBE_INTERVAL to
start probing again.
2018-04-27 12:33:19 +02:00
Thomas Haller
bca28c8c0c libnm/doc: explicitly point out privacy issue of setting wifi.hidden 2018-04-26 16:52:40 +02:00
Thomas Haller
701ef05d4f iwd: fix crash updating scan list when comparing new APs
Fixes: d7b1a911d9
2018-04-24 21:55:56 +02:00
Andreas Henriksson
be28790183 iwd: fix assertion failure when requesting scan
if device *is* a NM_DEVICE_IWD, then make sure to not pass that to
_nm_device_wifi_request_scan (which asserts on anything else than a
NM_DEVICE_WIFI device).

The crash can be triggered by enabling wifi.backend=iwd and clicking
on the 'select network' item in gnome shell for example. The journal
output looks like this:

NetworkManager[1861]: invalid cast from 'NMDeviceIwd' to 'NMDeviceWifi'
NetworkManager[1861]: **
NetworkManager[1861]: NetworkManager:ERROR:src/devices/wifi/nm-device-wifi.c:1127:_nm_device_wifi_request_scan: assertion failed: ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((_obj)); GType __t = ((nm_device_wifi_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))
systemd[1]: NetworkManager.service: Main process exited, code=dumped, status=6/ABRT
systemd[1]: NetworkManager.service: Failed with result 'core-dump'.

Fixes: 297d4985ab

https://github.com/NetworkManager/NetworkManager/pull/107
2018-04-24 21:27:25 +02:00
Thomas Haller
9731b06b78 device: fix nm_device_get_type_description() for veth devices
Without this, nm_device_get_type_description() would quite likely
return "ethernet" for NMDeviceVeth types. This is wrong and was
broken recently.

Fixes: 0775602574
2018-04-24 21:00:17 +02:00
Thomas Haller
5f8f427361 core: merge branch 'th/core-fixes-for-shutdown'
https://github.com/NetworkManager/NetworkManager/pull/98
2018-04-24 12:30:40 +02:00
Thomas Haller
3d2da8cd05 core/dbus: stop NMDBusManager and reject future method calls
During shutdown, we will need to still iterate the main loop
to do a coordinated shutdown. Currently we do not, and we just
exit, leaving a lot of objects hanging.

If we are going to fix that, we need during shutdown tell
NMDBusManager to reject all future operations.

Note that property getters and "GetManagerObjects" call is not
blocked. It continues to work.

Certainly for some operations, we want to allow them to be called even
during shutdown. However, these have to opt-in.

This also fixes an uglyness, where nm_dbus_manager_start() would
get the set-property-handler and the @manager as user-data. However,
NMDBusManager will always outlife NMManager, hence, after NMManager
is destroyed, the user-data would be a dangling pointer. Currently
that is not an issue, because
  - we always leak NMManager
  - we don't run the mainloop during shutdown
2018-04-24 10:25:26 +02:00
Thomas Haller
5b199b2e7d core/trivial: add FIXME comments about clean shutdown at exit 2018-04-24 10:25:26 +02:00
Thomas Haller
8b5f641211 settings: pass in authentication subject to nm_settings_add_connection_dbus()
nm_settings_add_connection_dbus() has two callers. One of them is NMManager
during AddAndActivate. In this case, the NMActiveConnection already created
an auth-subject. Re-use it.

Note how creating an auth-subject involves reading procfs to determine
whether the process still exists. This is not about the additional
overhead of that, but about the race where the process could drop
of in the meantime. The calling process might be gone now, and we would
fail creating the auth-subject. There is no need for that, because we
already evaluated all information we need. Quite likely, in the case
of this race, PolicyKit will also determine that the process is gone
and fail authorization too. But that's PolicyKit's decision to make,
not nm_settings_add_connection_dbus()'s.
2018-04-24 10:25:26 +02:00
Thomas Haller
f4fc62bad8 manager: track pending authorizations for activating connections
We cannot just fire off asynchronous actions without keeping a handle
to them. Otherwise, it's impossible for NMManager to know which
asynchronous operations are pending, and more importantly: it cannot
cancel them.

One day, I want that we do a clean shutdown, where NetworkManager stops
all pending operations, and cleans up everything. That implies, that
every operation is cancellable in a timely manner.

Rework pending nm_active_connection_authorize() calls to be tracked in a
list, so that they are still reachable to NMManager. Note that currently
NMManager does not yet try to cancel these operations ever. However, it
would now be possible to do so.
2018-04-24 10:25:26 +02:00
Thomas Haller
dc2004ddfb core: fix cancelling of authorization request for active connection
The async authorization request also carries user-data and its result
must always be handled. For example, it might carry a GDBusMethodInvocation
context, which must be returned and freed.

Hence, when cancelling the request, we must always invoke the callback.

Also, when the NMActiveConnection progresses to state disconnected,
automatically abort the authorization request.
2018-04-24 10:23:14 +02:00
Thomas Haller
9a579171b5 core: fix unreachable assertion in nm_active_connection_set_state() 2018-04-24 09:03:39 +02:00
Thomas Haller
e8c3fcae2a manager: use nm_utils_user_data_pack() instead of explicit AddAndActivateInfo structure 2018-04-24 09:03:39 +02:00
Thomas Haller
9abe3dc1a4 core: rework passing user-data to nm_active_connection_authorize()
Previously, nm_active_connection_authorize() accepts two user-data
pointers for convenience.

nm_active_connection_authorize() has three callers. One only requires
one user-data, one passes two user-data pointers, and one requires
three pointer.

Also, the way how the third passes the user data (via
g_object_set_qdata_full()) is not great.

Let's only use one user-data pointer. We commonly do that, and it's easy
enough to allocate a buffer to pack multiple pointers together.
2018-04-24 09:03:39 +02:00
Thomas Haller
dc138da420 shared: add nm_utils_user_data_pack() and unpack helpers 2018-04-24 09:03:39 +02:00
Thomas Haller
45fe57aea4 contrib/rpm: build config-connectivity-fedora package conditionally
On RHEL, we don't have NetworkManager-config-connectivity-fedora package.
Hence, the spec files for RHEL differ from upstream in this regard.

The aim is that contrib/rpm's spec file can be used almost as-is for
RHEL, Fedora and possibly other distros. Hence, build the subpackage
conditionally to minimize the difference.
2018-04-23 18:40:47 +02:00
Beniamino Galvani
3d509f6d63 merge: branch 'bg/dns-resolved-fix'
https://github.com/NetworkManager/NetworkManager/pull/102
2018-04-23 17:21:23 +02:00
Beniamino Galvani
4672499b95 core: fix bus initialization order
We currently start the bus manager only after the creation of a
NMManager because the NMManager is needed to handle set-property bus
calls. However, objects created by NMManager
(e.g. NMDnsSystemdResolved) need a bus connection and so their
initialization currently fail.

To fix this, split nm_dbus_manager_start() in two parts: first only
create the connection and acquire the bus.  After this step the
NMManager can be set up. In the second step, set NMManager as the
set-property handler and start exporting objects on the bus.

Fixes: 297d4985ab
2018-04-23 17:21:13 +02:00
Beniamino Galvani
0498c5487f libnm-core: fix validation of connection.mdns setting
Commit 9d92848ada ("libnm: rename MDns flag UNKNOWN to DEFAULT")
changed the enum order without updating verify().

Fixes: 9d92848ada
2018-04-23 17:21:13 +02:00
Beniamino Galvani
ff9ecbad62 core: fix misspellings of 'acquire' 2018-04-23 17:21:13 +02:00
Thomas Haller
6daafb1df6 core,cli: merge branch 'th/dhcp-options-sort'
https://github.com/NetworkManager/NetworkManager/pull/101
2018-04-23 15:52:57 +02:00
Thomas Haller
f2109cb810 cli: sort DHCP options in connection show output
Otherwise, the output is unstable and changes every time.
2018-04-23 15:44:44 +02:00
Thomas Haller
5e69b8b9f1 cli: merge IPv4 and IPv6 variants of print_dhcp_config() 2018-04-23 15:43:39 +02:00
Thomas Haller
e96b1270a6 core: sort DHCP options that are exported on D-Bus
Otherwise, the order is undefined and unstable. If you call
GetManagedObjects() on D-Bus multiple times, it's a very nice
property if the diff is small and not full not noise.
2018-04-23 15:43:39 +02:00
Thomas Haller
86b54a65e6 core: add nm_utils_strdict_to_variant() helper 2018-04-23 15:43:39 +02:00
Thomas Haller
9329844929 systemd: merge branch systemd into master 2018-04-23 13:35:52 +02:00
Thomas Haller
5d5b9d7ce0 release: bump version to 1.11.3 (development) 2018-04-23 10:43:42 +02:00
Thomas Haller
c4dd620889 systemd: update code from upstream (2018-04-23)
This is a direct dump from systemd git.

======

SYSTEMD_DIR=../systemd
COMMIT=41d0da0f6a800b7f1d56d6d15cf90edb6c062050

(
  cd "$SYSTEMD_DIR"
  git checkout "$COMMIT"
  git reset --hard
  git clean -fdx
)

git ls-files :/src/systemd/src/ \
             :/shared/nm-utils/siphash24.c \
             :/shared/nm-utils/siphash24.h \
             :/shared/nm-utils/unaligned.h | \
  xargs -d '\n' rm -f

nm_copy_sd() {
    mkdir -p "./src/systemd/$(dirname "$1")"
    cp "$SYSTEMD_DIR/$1" "./src/systemd/$1"
}

nm_copy_sd_shared() {
    mkdir -p "./shared/nm-utils/"
    cp "$SYSTEMD_DIR/$1" "./shared/nm-utils/${1##*/}"
}

nm_copy_sd "src/basic/alloc-util.c"
nm_copy_sd "src/basic/alloc-util.h"
nm_copy_sd "src/basic/async.h"
nm_copy_sd "src/basic/escape.c"
nm_copy_sd "src/basic/escape.h"
nm_copy_sd "src/basic/ether-addr-util.c"
nm_copy_sd "src/basic/ether-addr-util.h"
nm_copy_sd "src/basic/extract-word.c"
nm_copy_sd "src/basic/extract-word.h"
nm_copy_sd "src/basic/fileio.c"
nm_copy_sd "src/basic/fileio.h"
nm_copy_sd "src/basic/fd-util.c"
nm_copy_sd "src/basic/fd-util.h"
nm_copy_sd "src/basic/fs-util.c"
nm_copy_sd "src/basic/fs-util.h"
nm_copy_sd "src/basic/hash-funcs.c"
nm_copy_sd "src/basic/hash-funcs.h"
nm_copy_sd "src/basic/hashmap.c"
nm_copy_sd "src/basic/hashmap.h"
nm_copy_sd "src/basic/hexdecoct.c"
nm_copy_sd "src/basic/hexdecoct.h"
nm_copy_sd "src/basic/hostname-util.c"
nm_copy_sd "src/basic/hostname-util.h"
nm_copy_sd "src/basic/in-addr-util.c"
nm_copy_sd "src/basic/in-addr-util.h"
nm_copy_sd "src/basic/io-util.c"
nm_copy_sd "src/basic/io-util.h"
nm_copy_sd "src/basic/list.h"
nm_copy_sd "src/basic/log.h"
nm_copy_sd "src/basic/macro.h"
nm_copy_sd "src/basic/mempool.h"
nm_copy_sd "src/basic/mempool.c"
nm_copy_sd "src/basic/parse-util.c"
nm_copy_sd "src/basic/parse-util.h"
nm_copy_sd "src/basic/path-util.c"
nm_copy_sd "src/basic/path-util.h"
nm_copy_sd "src/basic/prioq.h"
nm_copy_sd "src/basic/prioq.c"
nm_copy_sd "src/basic/process-util.h"
nm_copy_sd "src/basic/process-util.c"
nm_copy_sd "src/basic/random-util.c"
nm_copy_sd "src/basic/random-util.h"
nm_copy_sd "src/basic/refcnt.h"
nm_copy_sd "src/basic/set.h"
nm_copy_sd "src/basic/signal-util.h"
nm_copy_sd_shared "src/basic/siphash24.c"
nm_copy_sd_shared "src/basic/siphash24.h"
nm_copy_sd "src/basic/socket-util.c"
nm_copy_sd "src/basic/socket-util.h"
nm_copy_sd "src/basic/sparse-endian.h"
nm_copy_sd "src/basic/stdio-util.h"
nm_copy_sd "src/basic/string-table.c"
nm_copy_sd "src/basic/string-table.h"
nm_copy_sd "src/basic/string-util.c"
nm_copy_sd "src/basic/string-util.h"
nm_copy_sd "src/basic/strv.c"
nm_copy_sd "src/basic/strv.h"
nm_copy_sd "src/basic/time-util.c"
nm_copy_sd "src/basic/time-util.h"
nm_copy_sd "src/basic/umask-util.h"
nm_copy_sd_shared "src/basic/unaligned.h"
nm_copy_sd "src/basic/utf8.c"
nm_copy_sd "src/basic/utf8.h"
nm_copy_sd "src/basic/util.c"
nm_copy_sd "src/basic/util.h"
nm_copy_sd "src/libsystemd-network/arp-util.c"
nm_copy_sd "src/libsystemd-network/arp-util.h"
nm_copy_sd "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-network.c"
nm_copy_sd "src/libsystemd-network/dhcp-option.c"
nm_copy_sd "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd "src/libsystemd-network/lldp-internal.h"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd "src/libsystemd-network/lldp-network.c"
nm_copy_sd "src/libsystemd-network/lldp-network.h"
nm_copy_sd "src/libsystemd-network/network-internal.c"
nm_copy_sd "src/libsystemd-network/network-internal.h"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd "src/libsystemd-network/sd-lldp.c"
nm_copy_sd "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.h"
nm_copy_sd "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd "src/shared/dns-domain.c"
nm_copy_sd "src/shared/dns-domain.h"
nm_copy_sd "src/systemd/_sd-common.h"
nm_copy_sd "src/systemd/sd-dhcp6-client.h"
nm_copy_sd "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd "src/systemd/sd-dhcp-client.h"
nm_copy_sd "src/systemd/sd-dhcp-lease.h"
nm_copy_sd "src/systemd/sd-event.h"
nm_copy_sd "src/systemd/sd-ndisc.h"
nm_copy_sd "src/systemd/sd-id128.h"
nm_copy_sd "src/systemd/sd-ipv4acd.h"
nm_copy_sd "src/systemd/sd-ipv4ll.h"
nm_copy_sd "src/systemd/sd-lldp.h"
2018-04-23 10:20:55 +02:00
Lubomir Rintel
de8bf7421d n-acd: don't use a return value in deallocator
...so that its prototype is compatible with GDestroyNotify:

src/devices/nm-acd-manager.c: In function ‘destroy_address_info’:
/usr/include/glib-2.0/glib/gmem.h:120:31: error: cast between incompatible function types from ‘NAcd * (*)(NAcd *)’ {aka ‘struct NAcd * (*)(struct NAcd *)’} to ‘void (*)(void *)’ [-Werror=cast-function-type]
     GDestroyNotify _destroy = (GDestroyNotify) (destroy);                      \
                               ^
src/devices/nm-acd-manager.c:430:2: note: in expansion of macro ‘g_clear_pointer’
  g_clear_pointer (&info->acd, n_acd_free);
  ^~~~~~~~~~~~~~~

The same change was done upstream, so the subsequent subtree pull of n-acd
won't mess this up.
2018-04-23 09:50:12 +02:00
Lubomir Rintel
c898969110 test-common: drop unused variables
src/platform/tests/test-common.c:1500:17: error: unused variable 'dev' [-Werror,-Wunused-variable]
                gs_free char *dev = NULL;
                              ^
src/platform/tests/test-common.c:1501:17: error: unused variable 'local' [-Werror,-Wunused-variable]
                gs_free char *local = NULL, *remote = NULL;
                              ^
src/platform/tests/test-common.c:1501:32: error: unused variable 'remote' [-Werror,-Wunused-variable]
                gs_free char *local = NULL, *remote = NULL;
                                             ^
Fixes: bd8ab54b8e
2018-04-23 08:26:41 +02:00
Lubomir Rintel
40ce80cb50 auth-manager: drop an unused variable
src/nm-auth-manager.c:673:24: error: unused variable 'error_disposing' [-Werror,-Wunused-variable]
        gs_free_error GError *error_disposing = NULL;
                              ^

Fixes: 2ea2df3184
2018-04-23 08:26:05 +02:00
Lubomir Rintel
30814288c9 acd-manager: drop an unused variable
src/devices/nm-acd-manager.c:299:16: error: unused variable 'timeout_str' [-Werror,-Wunused-variable]
        gs_free char *timeout_str = NULL;
                      ^
Fixes: 9f79ae685d
2018-04-23 08:24:17 +02:00
Beniamino Galvani
c2fcf82e63 ifcfg-rh: merge branch 'bg/ifcfg-rh-tc-fixes'
https://github.com/NetworkManager/NetworkManager/pull/95
2018-04-21 22:10:38 +02:00
Beniamino Galvani
805cbe7439 ifcfg-rh: fix parse of tc qdiscs and filters
Fixes: 902bbfdb18
2018-04-21 22:09:05 +02:00
Beniamino Galvani
fa7af768a9 ifcfg-rh: add tests for tc config 2018-04-21 22:09:05 +02:00
Beniamino Galvani
7cea2398a6 manager: merge branch 'bg/manager-vpn-fixes'
https://github.com/NetworkManager/NetworkManager/pull/99
2018-04-20 16:26:46 +02:00
Beniamino Galvani
edcb80d1b0 manager: fix assertions when activating VPNs
_new_active_connection() can be called with both a device and a
specific object set when activating secondaries.

Fixes: 10753c3616
2018-04-20 16:26:26 +02:00
Beniamino Galvani
e732403a9b manager: fix activating VPN connections
nm_manager_activate_connection() is also called for VPNs.

Fixes: 3e3d53ce69
2018-04-20 16:26:26 +02:00
Thomas Haller
164e6b9e6b device/connectivity: fix periodic checks that take a long time to complete
It can easily happen that connectivity checks take a long time to
complete (up to 20 seconds, when they time out).

So, before, during the first 20 seconds no connectivity checks would
return and bump the periodic interval. That meant, for the first 20
seconds we would each second schedule a periodic check.
Then, the checks start timing out, each one second apart as we scheduled
them. Previously, during each completion of the checks, we would bump
the interval every second.

Fix that two ways:

1) when the timer expires, also check whether there are still uncomplete
periodic checks. If there are, already bump the interval at that point.

2) at the same time, when this happens mark the handle so that when
they later complete, that they no longer cause another increase of the
interval (no-bump).

Now the bumping is done either by the timeout, or by the completion of
the request. Whatever happens first.
2018-04-20 15:08:23 +02:00