aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/plugins/stroke
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2013-09-19 10:59:20 +0200
committerTobias Brunner <tobias@strongswan.org>2013-10-17 10:23:32 +0200
commit32fef0c6e9e934eef2e63286eef13ff491df5aaf (patch)
tree1fd1abb3f3c01c3d4dca23ff7b016374b63918fb /src/libcharon/plugins/stroke
parent6278e64230ad436edd29cef967a086bc3487b646 (diff)
downloadstrongswan-32fef0c6e9e934eef2e63286eef13ff491df5aaf.tar.bz2
strongswan-32fef0c6e9e934eef2e63286eef13ff491df5aaf.tar.xz
stroke: Reuse reqids of established CHILD_SAs when routing connections
Diffstat (limited to 'src/libcharon/plugins/stroke')
-rw-r--r--src/libcharon/plugins/stroke/stroke_control.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c
index fdd1635a6..b583bfc53 100644
--- a/src/libcharon/plugins/stroke/stroke_control.c
+++ b/src/libcharon/plugins/stroke/stroke_control.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2013 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -580,12 +581,54 @@ METHOD(stroke_control_t, purge_ike, void,
}
/**
+ * Find an existing CHILD_SA/reqid
+ */
+static u_int32_t find_reqid(child_cfg_t *child_cfg)
+{
+ enumerator_t *enumerator, *children;
+ child_sa_t *child_sa;
+ ike_sa_t *ike_sa;
+ char *name;
+ u_int32_t reqid;
+
+ reqid = charon->traps->find_reqid(charon->traps, child_cfg);
+ if (reqid)
+ { /* already trapped */
+ return reqid;
+ }
+
+ name = child_cfg->get_name(child_cfg);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ children = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (children->enumerate(children, (void**)&child_sa))
+ {
+ if (streq(name, child_sa->get_name(child_sa)))
+ {
+ reqid = child_sa->get_reqid(child_sa);
+ break;
+ }
+ }
+ children->destroy(children);
+ if (reqid)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return reqid;
+}
+
+/**
* call charon to install a shunt or trap
*/
static void charon_route(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
char *name, FILE *out)
{
ipsec_mode_t mode;
+ u_int32_t reqid;
mode = child_cfg->get_mode(child_cfg);
if (mode == MODE_PASS || mode == MODE_DROP)
@@ -603,7 +646,8 @@ static void charon_route(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
}
else
{
- if (charon->traps->install(charon->traps, peer_cfg, child_cfg, 0))
+ reqid = find_reqid(child_cfg);
+ if (charon->traps->install(charon->traps, peer_cfg, child_cfg, reqid))
{
fprintf(out, "'%s' routed\n", name);
}