Previously, the logger installed by the controller always announced
LEVEL_PRIVATE(4), which produced completely useless logging calls with
the common clients (vici/stroke) whose default log level is LEVEL_CTRL(1).
This can produce quite some overhead if there are e.g. a lot of concurrent
initiate() calls.
Until we know which IKE_SA is affected by an initiate() or terminate_*()
command, unrelated log messages that don't have any IKE context (i.e.
the passed `ike_sa` is NULL) would previously get logged.
If no CHILD_SA is initiated, we wait for a state change to IKE_ESTABLISHED
but that will never happen for already established IKE_SAs.
References strongswan/strongswan#1553
If no callback is specified, terminate_ike_execute() is invoked without the
listener waiting on the IKE state change.
Now, if 'force' is false, then ike_sa->delete() just queues an
IKE_DELETE task, and returns SUCCESS - indicating successful task
manager initiation.
However, terminate_ike_execute() ignored this success and set the
status to FAILED.
This is not ideal, as it will be the overall return code of
terminate_ike(), although no failure did occur. This eventually leads
vici's "terminate" to return "Command failed: terminating SA failed",
as seen in this example:
In [9]: list(session.terminate({'ike-id': 2960, 'timeout': -1}))
---------------------------------------------------------------------------
CommandException Traceback (most recent call last)
<ipython-input-9-5f95b5cea88f> in <module>()
----> 1 list(session.terminate({'ike-id': 2960, 'timeout': -1}))
vici/session.pyc in streamed_request(self, command, event_stream_type, message)
136 raise CommandException(
137 "Command failed: {errmsg}".format(
--> 138 errmsg=command_response["errmsg"]
139 )
140 )
CommandException: Command failed: terminating SA failed
If we consider both queueing the task and actually destroying the IKS_SA
a success, we can just always return SUCCESS if we don't have a
callback. There is also no need to explicitly set the status to FAILED
if a listener is waiting as that's the default anyway.
Co-authored-by: Tobias Brunner <tobias@strongswan.org>
Closesstrongswan/strongswan#185.
In very early versions routed CHILD_SAs were attached to IKE_SAs, since
that's not the case anymore (they are handled via trap manager), we can
remove this special handling.
We actually want to wait until the IKE_SA is destroyed, not any of the
CHILD_SAs (even though there might not be that much of a difference
depending on the number of CHILD_SAs).
Fixes#2261.
This ensures the listeners don't miss any events after the SAs have been
checked out in the asynchronously executed jobs. This is a matter of
memory visibility and not primary a matter of exclusive access.
Jobs are now destroyed by the processor, but they are allowed to
reschedule themselves. That is, parts of the reschedule functionality
already provided by callback_job_t is moved to the processor. Not yet
fully supported is JOB_REQUEUE_DIRECT and canceling jobs.
Note: job_t.destroy() is now called not only for queued jobs but also
after execution or cancellation of jobs. job_t.status can be used to
decide what to do in said method.
This also allows us to generate the log message only once for all
loggers that need it (avoids calls to custom printf specifier callbacks).
To update the log levels loggers can simply be registered again.
The new interface does not allow loggers to unregister themselves from
the bus. This allows us to use a rwlock_t for them.
The latter also means that loggers can now be called concurrently by
multiple threads.
Because the thread that is actually terminating the SA and thus checking
it in again is not be the same thread that previously checked it out and
queued the termination job, the thread local SA on the bus has to be reset
manually, similar to how it is set in the job which is executing the job.