When using the statement expression and a stack object along with
clang-11 and libasan, we get quite a lot of errors about reading
invalid memory. This is due to clang making the actual listener_t local
to the block, such that the access outside of the macros using
_assert_payload is (correctly) considered an error.
By using a heap allocated object, we can destroy it once the listener
returns FALSE (cleaning up properly), and since bus_t does not touch the
listener after that, we don't get any errors from libasan.
Co-authored-by: Tobias Brunner <[email protected]>
This could happen if an acquire is triggered while we respond to a
CREATE_CHILD_SA request from the peer, or if an acquire is triggered
while an IKE_SA (with its existing CHILD_SAs) is reestablished (also
with break-before-make reauthentication). Also catches multiple
manual initiations.
Note that this ignores the traffic selectors from acquires (narrowing to
them seems rare in practice anyway).
Duplicates can still get created if e.g. both peers initiate them
concurrently.
This is useful for kernel implementations where the ordering of SAs
is unpredictable and the new SA might otherwise not be used until the
DELETE response has been received, which is not ideal as the responder
might not keep the old SA around that long. On Linux, it makes no
difference as we switch to the new outbound SA immediately because the
updated outbound policy references its SPI.
We don't actually check that SA out (i.e. it's not registered with the
manager). That was originally different but had to be changed with
86993d6b90 to avoid that SAs created for rekeying don't block other
threads on the manager.
The peer might not have seen the CREATE_CHILD_SA response yet, receiving a
DELETE for the SA could then trigger it to abort the rekeying, causing
the deletion of the newly established SA (it can't know whether the
DELETE was sent due to an expire or because the user manually deleted
it). We just treat this SA as if we received a DELETE for it. This is
not an ideal situation anyway, as it causes some traffic to get dropped,
so it should usually be avoided by setting appropriate soft and hard limits.
References #2815.
This is currently not an issue for CHILD_SA rekeying tests as these only
check rekeyings of the CHILD_SA created with the IKE_SA, i.e. there is
no previous DH group to reuse.
This allows us to use it without having to initialize libcharon, which
was required for the logging (we probably could have included debug.h
instead of daemon.h to workaround that but this seems more correct).
This splits the SA installation also on the initiator, so we can avoid
installing the outbound SA if we lost a rekey collision, which might
have caused traffic loss depending on the timing of the DELETEs that are
sent in both directions.
After deleting a rekeyed CHILD_SA we uninstall the outbound SA but don't
destroy the CHILD_SA (and the inbound SA) immediately. We delay it
a few seconds or until the SA expires to allow delayed packets to get
processed. The CHILD_SA remains in state CHILD_DELETING until it finally
gets destroyed.
The responder has all the information needed to install both SAs before
the initiator does. So if the responder immediately installs the outbound
SA it might send packets using the new SA which the initiator is not yet
able to process. This can be avoided by delaying the installation of the
outbound SA until the replaced SA is deleted.
If charon.prefer_configured_proposals is disabled select() is called on
the received proposal. This incorrectly set the SPI to 0 as the
configured proposal has no SPI set.
Fixes#2190.