This fixes cases where `start_action = trap|start` is used and an acquire
is triggered while the SA is initiated (granted if narrowing is expected,
that's not a recommended configuration as the responder can only use
the first config when there is no packet TS). The resulting second
create-child task will potentially get dropped by the duplicate check,
so the temporary state won't get removed and traffic is blocked until
that expires, neither can acquires get triggered for traffic that doesn't
match the initial SA's policies.
Optionally with "dynamic" traffic selectors resolved. A new method
is added for those cases where we actually want to select potentially
narrowed traffic selectors using a supplied list. The latter now also
always logs details, while the former does not.
Either use the sequence number from the kernel (and potentially update
it if the acquire was retriggered), or generate our own sequence
numbers, which simplifies matching acquires to established/destroyed
CHILD_SAs.
This allows managing trap policies outside of the trap manager.
We'll use this to create trap policies with generic labels if trap policies
can't (or won't) be used (e.g. as responder for roadwarriors).
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.
There was a race condition between install() and uninstall()
where one thread was in the process of installing a trap
entry, and had destroyed the child_sa, while the other
thread was uninstalling the same trap entry and ended up
trying to destroy the already destroyed child_sa, resulting
in a segmentation fault in the destroy_entry() function.
The uninstall() function needs to wait until all the threads
are done with the installing before proceeding to uninstall
a trap entry.
Closesstrongswan/strongswan#131.
Although being already logged on level 2, these messages are usually just
confusing if they pop up randomly in the log when e.g. querying the configs
or installing traps. So after this the log messages will only be logged when
actually proposing or selecting traffic selectors during IKE.
Reqids for the same traffic selectors are now stable so we don't have to
pass reqids of previously installed CHILD_SAs. Likewise, we don't need
to know the reqid of the newly installed trap policy as we now uninstall
by name.
Initiation might later fail, of course, but we don't really
require an IP address when installing, that is, unless the remote
traffic selector is dynamic. As that would result in installing a
0.0.0.0/0 remote TS which is not ideal when a single IP is expected as
remote.
If there is currently no route to reach the other peer we just default
to left=%any. The local address is only really used to resolve
leftsubnet=%dynamic anyway (and perhaps for MIPv6 proxy transport mode).
Fixes#1375.
When flush() is called there might be threads in install() waiting for
trap policies to get installed (without holding the lock). We have to
wait until they updated the entries with the respective CHILD_SAs before
destroying the list.
We also have to prevent further trap policy installations (and wait until
threads in install() are really finished), otherwise we might end up
destroying CHILD_SA objects after the kernel interface implementations
have already been unloaded (avoiding this is the whole point of calling
flush() before unloading the plugins).
This fixes potential race conditions in case complete() or flush() is
executed before or concurrently with a thread that handles an acquire.
It will also simplify tracking multiple acquires created for the same
trap policy in the future.
Also fixes the behavior in some error situations.
This basically reverts f4e822c1b4 ("trap-manager: don't check-in
nonexisting IKE_SA if acquire fails"). As checkout_by_config() could
return an already existing and established IKE_SA we have to properly
destroy it, for instance, in case other threads are waiting to check
it out. checkin_and_destroy() should handle the case of a new SA
properly (it produces a log message on level 1, though).
The specific traffic selectors from the acquire events, which are derived
from the triggering packet, are usually prepended to those from the
config. Some implementations might not be able to handle these properly.
References #860.
As we now use the same reqid for multiple CHILD_SAs with the same selectors,
having marks based on the reqid makes not that much sense anymore. Instead we
use unique marks that use a custom identifier. This identifier is reused during
rekeying, keeping the marks constant for any rule relying on it (for example
installed by updown).
This also simplifies handling of reqid allocation, as we do not have to query
the marks that is not yet assigned for an unknown reqid.
Because the write lock was held while calling add_policies() on
child_sa_t, which finishes with a call to child_state_change() on bus_t,
a deadlock would ensue if CHILD_SAs are concurrently being established,
which also causes a call to child_state_change() that will require
the read lock in trap_manager_t.
No locks are now being held while creating the CHILD_SA and installing the
trap policies.