summaryrefslogtreecommitdiff
path: root/src/charon/plugins/stroke/stroke_control.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/plugins/stroke/stroke_control.c')
-rw-r--r--src/charon/plugins/stroke/stroke_control.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/src/charon/plugins/stroke/stroke_control.c b/src/charon/plugins/stroke/stroke_control.c
index 2956b1576..ed9dd7b16 100644
--- a/src/charon/plugins/stroke/stroke_control.c
+++ b/src/charon/plugins/stroke/stroke_control.c
@@ -18,6 +18,7 @@
#include "stroke_control.h"
#include <daemon.h>
+#include <processing/jobs/delete_ike_sa_job.h>
typedef struct private_stroke_control_t private_stroke_control_t;
@@ -55,7 +56,7 @@ struct stroke_log_info_t {
* logging to the stroke interface
*/
static bool stroke_log(stroke_log_info_t *info, signal_t signal, level_t level,
- ike_sa_t *ike_sa, char *format, va_list args)
+ ike_sa_t *ike_sa, void *data, char *format, va_list args)
{
if (level <= info->level)
{
@@ -240,6 +241,75 @@ static void terminate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *o
}
/**
+ * Implementation of stroke_control_t.terminate_srcip.
+ */
+static void terminate_srcip(private_stroke_control_t *this,
+ stroke_msg_t *msg, FILE *out)
+{
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ host_t *start = NULL, *end = NULL, *vip;
+ chunk_t chunk_start, chunk_end, chunk_vip;
+
+ if (msg->terminate_srcip.start)
+ {
+ start = host_create_from_string(msg->terminate_srcip.start, 0);
+ }
+ if (!start)
+ {
+ DBG1(DBG_CFG, "invalid start address: %s", msg->terminate_srcip.start);
+ return;
+ }
+ chunk_start = start->get_address(start);
+ if (msg->terminate_srcip.end)
+ {
+ end = host_create_from_string(msg->terminate_srcip.end, 0);
+ if (!end)
+ {
+ DBG1(DBG_CFG, "invalid end address: %s", msg->terminate_srcip.end);
+ start->destroy(start);
+ return;
+ }
+ chunk_end = end->get_address(end);
+ }
+
+ enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
+ if (!vip)
+ {
+ continue;
+ }
+ if (!end)
+ {
+ if (!vip->ip_equals(vip, start))
+ {
+ continue;
+ }
+ }
+ else
+ {
+ chunk_vip = vip->get_address(vip);
+ if (chunk_vip.len != chunk_start.len ||
+ chunk_vip.len != chunk_end.len ||
+ memcmp(chunk_vip.ptr, chunk_start.ptr, chunk_vip.len) < 0 ||
+ memcmp(chunk_vip.ptr, chunk_end.ptr, chunk_vip.len) > 0)
+ {
+ continue;
+ }
+ }
+
+ /* schedule delete asynchronously */
+ charon->processor->queue_job(charon->processor, (job_t*)
+ delete_ike_sa_job_create(ike_sa->get_id(ike_sa), TRUE));
+ }
+ enumerator->destroy(enumerator);
+ start->destroy(start);
+ DESTROY_IF(end);
+}
+
+/**
* Implementation of stroke_control_t.route.
*/
static void route(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
@@ -336,6 +406,7 @@ stroke_control_t *stroke_control_create()
this->public.initiate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))initiate;
this->public.terminate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate;
+ this->public.terminate_srcip = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate_srcip;
this->public.route = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))route;
this->public.unroute = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))unroute;
this->public.destroy = (void(*)(stroke_control_t*))destroy;