summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/stroke/stroke_control.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/stroke/stroke_control.c')
-rw-r--r--src/libcharon/plugins/stroke/stroke_control.c193
1 files changed, 144 insertions, 49 deletions
diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c
index 3541ab8f9..4943ee670 100644
--- a/src/libcharon/plugins/stroke/stroke_control.c
+++ b/src/libcharon/plugins/stroke/stroke_control.c
@@ -92,48 +92,94 @@ static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
return found;
}
+/**
+ * call the charon controller to initiate the connection
+ */
+static void charon_initiate(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
+ stroke_msg_t *msg, FILE *out)
+{
+ if (msg->output_verbosity < 0)
+ {
+ charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
+ NULL, NULL);
+ }
+ else
+ {
+ stroke_log_info_t info = { msg->output_verbosity, out };
+
+ charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
+ (controller_cb_t)stroke_log, &info);
+ }
+}
+
METHOD(stroke_control_t, initiate, void,
private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
+ child_cfg_t *child_cfg = NULL;
peer_cfg_t *peer_cfg;
- child_cfg_t *child_cfg;
- stroke_log_info_t info;
+ enumerator_t *enumerator;
+ bool empty = TRUE;
peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
msg->initiate.name);
- if (peer_cfg == NULL)
- {
- DBG1(DBG_CFG, "no config named '%s'\n", msg->initiate.name);
- return;
- }
- if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ if (peer_cfg)
{
- DBG1(DBG_CFG, "ignoring initiation request for IKEv%d config",
- peer_cfg->get_ike_version(peer_cfg));
- peer_cfg->destroy(peer_cfg);
- return;
- }
+ if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ {
+ DBG1(DBG_CFG, "ignoring initiation request for IKEv%d config",
+ peer_cfg->get_ike_version(peer_cfg));
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
- child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
- if (child_cfg == NULL)
- {
- DBG1(DBG_CFG, "no child config named '%s'\n", msg->initiate.name);
- peer_cfg->destroy(peer_cfg);
- return;
- }
+ child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
+ if (child_cfg == NULL)
+ {
+ enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
+ while (enumerator->enumerate(enumerator, &child_cfg))
+ {
+ empty = FALSE;
+ charon_initiate(peer_cfg->get_ref(peer_cfg),
+ child_cfg->get_ref(child_cfg), msg, out);
+ }
+ enumerator->destroy(enumerator);
- if (msg->output_verbosity < 0)
- {
- charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
- NULL, NULL);
+ if (empty)
+ {
+ DBG1(DBG_CFG, "no child config named '%s'", msg->initiate.name);
+ fprintf(out, "no child config named '%s'\n", msg->initiate.name);
+ }
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
}
else
{
- info.out = out;
- info.level = msg->output_verbosity;
- charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
- (controller_cb_t)stroke_log, &info);
+ enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
+ NULL, NULL, NULL, NULL);
+ while (enumerator->enumerate(enumerator, &peer_cfg))
+ {
+ if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ {
+ continue;
+ }
+ child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
+ if (child_cfg)
+ {
+ peer_cfg->get_ref(peer_cfg);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (child_cfg == NULL)
+ {
+ DBG1(DBG_CFG, "no config named '%s'", msg->initiate.name);
+ fprintf(out, "no config named '%s'\n", msg->initiate.name);
+ return;
+ }
}
+ charon_initiate(peer_cfg, child_cfg, msg, out);
}
/**
@@ -470,41 +516,90 @@ METHOD(stroke_control_t, purge_ike, void,
list->destroy(list);
}
+/**
+ * call charon to install a trap
+ */
+static void charon_route(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
+ char *name, FILE *out)
+{
+ if (charon->traps->install(charon->traps, peer_cfg, child_cfg))
+ {
+ fprintf(out, "'%s' routed\n", name);
+ }
+ else
+ {
+ fprintf(out, "routing '%s' failed\n", name);
+ }
+}
+
METHOD(stroke_control_t, route, void,
private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
+ child_cfg_t *child_cfg = NULL;
peer_cfg_t *peer_cfg;
- child_cfg_t *child_cfg;
+ enumerator_t *enumerator;
+ bool empty = TRUE;
peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
msg->route.name);
- if (peer_cfg == NULL)
- {
- fprintf(out, "no config named '%s'\n", msg->route.name);
- return;
- }
- if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ if (peer_cfg)
{
- peer_cfg->destroy(peer_cfg);
- return;
- }
+ if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ {
+ DBG1(DBG_CFG, "ignoring initiation request for IKEv%d config",
+ peer_cfg->get_ike_version(peer_cfg));
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
- child_cfg = get_child_from_peer(peer_cfg, msg->route.name);
- if (child_cfg == NULL)
- {
- fprintf(out, "no child config named '%s'\n", msg->route.name);
- peer_cfg->destroy(peer_cfg);
- return;
- }
+ child_cfg = get_child_from_peer(peer_cfg, msg->route.name);
+ if (child_cfg == NULL)
+ {
+ enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
+ while (enumerator->enumerate(enumerator, &child_cfg))
+ {
+ empty = FALSE;
+ charon_route(peer_cfg, child_cfg, child_cfg->get_name(child_cfg),
+ out);
+ }
+ enumerator->destroy(enumerator);
- if (charon->traps->install(charon->traps, peer_cfg, child_cfg))
- {
- fprintf(out, "configuration '%s' routed\n", msg->route.name);
+ if (empty)
+ {
+ DBG1(DBG_CFG, "no child config named '%s'", msg->route.name);
+ fprintf(out, "no child config named '%s'\n", msg->route.name);
+ }
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
}
else
{
- fprintf(out, "routing configuration '%s' failed\n", msg->route.name);
+ enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
+ NULL, NULL, NULL, NULL);
+ while (enumerator->enumerate(enumerator, &peer_cfg))
+ {
+ if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ {
+ continue;
+ }
+ child_cfg = get_child_from_peer(peer_cfg, msg->route.name);
+ if (child_cfg)
+ {
+ peer_cfg->get_ref(peer_cfg);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (child_cfg == NULL)
+ {
+ DBG1(DBG_CFG, "no config named '%s'", msg->route.name);
+ fprintf(out, "no config named '%s'\n", msg->route.name);
+ return;
+ }
}
+ charon_route(peer_cfg, child_cfg, msg->route.name, out);
peer_cfg->destroy(peer_cfg);
child_cfg->destroy(child_cfg);
}