aboutsummaryrefslogtreecommitdiffstats
path: root/src/libimcv
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2011-12-11 22:01:49 +0100
committerAndreas Steffen <andreas.steffen@strongswan.org>2011-12-11 22:01:49 +0100
commit63179fd459fcf9c98ca10cd2d03a8ffcc3097725 (patch)
tree067b4f76c3f738452886beb5306977e3807c50ea /src/libimcv
parent6f04ccff5e485d6d8c447351ac983bee8ac26313 (diff)
downloadstrongswan-63179fd459fcf9c98ca10cd2d03a8ffcc3097725.tar.bz2
strongswan-63179fd459fcf9c98ca10cd2d03a8ffcc3097725.tar.xz
upgraded Test IMC/IMV pair to fully support multple IMC IDs
Diffstat (limited to 'src/libimcv')
-rw-r--r--src/libimcv/plugins/imc_test/imc_test.c79
-rw-r--r--src/libimcv/plugins/imv_test/imv_test.c58
-rw-r--r--src/libimcv/plugins/imv_test/imv_test_state.c77
-rw-r--r--src/libimcv/plugins/imv_test/imv_test_state.h11
4 files changed, 144 insertions, 81 deletions
diff --git a/src/libimcv/plugins/imc_test/imc_test.c b/src/libimcv/plugins/imc_test/imc_test.c
index b7858c5e7..9ca73facf 100644
--- a/src/libimcv/plugins/imc_test/imc_test.c
+++ b/src/libimcv/plugins/imc_test/imc_test.c
@@ -83,6 +83,7 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
return TNC_RESULT_NOT_INITIALIZED;
}
+
switch (new_state)
{
case TNC_CONNECTION_STATE_CREATE:
@@ -91,6 +92,7 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
retry = lib->settings->get_bool(lib->settings,
"libimcv.plugins.imc-test.retry", FALSE);
state = imc_test_state_create(connection_id, command, retry);
+ test_state = (imc_test_state_t*)state;
result = imc_test->create_state(imc_test, state);
if (result != TNC_RESULT_SUCCESS)
@@ -112,7 +114,6 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
"multiple IMC IDs", imc_id, imc_name);
return TNC_RESULT_SUCCESS;
}
- test_state = (imc_test_state_t*)state;
while (additional_ids-- > 0)
{
@@ -178,52 +179,28 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
}
}
-static TNC_Result send_message(TNC_ConnectionID connection_id)
+static TNC_Result send_message(imc_state_t *state, TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id)
{
+ imc_test_state_t *test_state;
pa_tnc_msg_t *msg;
pa_tnc_attr_t *attr;
- imc_state_t *state;
- imc_test_state_t *test_state;
- enumerator_t *enumerator;
- void *pointer;
- TNC_UInt32 imc_id;
+ bool excl;
+ TNC_ConnectionID connection_id;
TNC_Result result;
- if (!imc_test->get_state(imc_test, connection_id, &state))
- {
- return TNC_RESULT_FATAL;
- }
+ connection_id = state->get_connection_id(state);
test_state = (imc_test_state_t*)state;
-
- /* send PA message for primary IMC ID */
attr = ita_attr_command_create(test_state->get_command(test_state));
attr->set_noskip_flag(attr, TRUE);
msg = pa_tnc_msg_create();
msg->add_attribute(msg, attr);
msg->build(msg);
- result = imc_test->send_message(imc_test, connection_id, FALSE, 0,
- TNC_IMVID_ANY, msg->get_encoding(msg));
+ excl = dst_imv_id != TNC_IMVID_ANY;
+ result = imc_test->send_message(imc_test, connection_id, excl, src_imc_id,
+ dst_imv_id, msg->get_encoding(msg));
msg->destroy(msg);
- /* send PA messages for additional IMC IDs */
- enumerator = test_state->create_id_enumerator(test_state);
- while (result == TNC_RESULT_SUCCESS &&
- enumerator->enumerate(enumerator, &pointer))
- {
- /* interpret pointer as scalar value */
- imc_id = (TNC_UInt32)pointer;
-
- attr = ita_attr_command_create(test_state->get_command(test_state));
- attr->set_noskip_flag(attr, TRUE);
- msg = pa_tnc_msg_create();
- msg->add_attribute(msg, attr);
- msg->build(msg);
- result = imc_test->send_message(imc_test, connection_id, FALSE, imc_id,
- TNC_IMVID_ANY, msg->get_encoding(msg));
- msg->destroy(msg);
- }
- enumerator->destroy(enumerator);
-
return result;
}
@@ -233,12 +210,41 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
TNC_ConnectionID connection_id)
{
+ imc_state_t *state;
+ imc_test_state_t *test_state;
+ enumerator_t *enumerator;
+ void *pointer;
+ TNC_UInt32 additional_id;
+ TNC_Result result;
+
if (!imc_test)
{
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
return TNC_RESULT_NOT_INITIALIZED;
}
- return send_message(connection_id);
+
+ /* get current IMC state */
+ if (!imc_test->get_state(imc_test, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+ test_state = (imc_test_state_t*)state;
+
+ /* send PA message for primary IMC ID */
+ result = send_message(state, imc_id, TNC_IMVID_ANY);
+
+ /* send PA messages for additional IMC IDs */
+ enumerator = test_state->create_id_enumerator(test_state);
+ while (result == TNC_RESULT_SUCCESS &&
+ enumerator->enumerate(enumerator, &pointer))
+ {
+ /* interpret pointer as scalar value */
+ additional_id = (TNC_UInt32)pointer;
+ result = send_message(state, additional_id, TNC_IMVID_ANY);
+ }
+ enumerator->destroy(enumerator);
+
+ return result;
}
static TNC_Result receive_message(TNC_IMCID imc_id,
@@ -300,7 +306,8 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
pa_tnc_msg->destroy(pa_tnc_msg);
/* if no error occurred then always return the same response */
- return fatal_error ? TNC_RESULT_FATAL : send_message(connection_id);
+ return fatal_error ? TNC_RESULT_FATAL :
+ send_message(state, dst_imc_id, src_imv_id);
}
/**
diff --git a/src/libimcv/plugins/imv_test/imv_test.c b/src/libimcv/plugins/imv_test/imv_test.c
index be5aa98a6..0afd81aec 100644
--- a/src/libimcv/plugins/imv_test/imv_test.c
+++ b/src/libimcv/plugins/imv_test/imv_test.c
@@ -71,9 +71,6 @@ TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
TNC_ConnectionState new_state)
{
imv_state_t *state;
- imv_test_state_t *test_state;
- TNC_Result result;
- int rounds;
if (!imv_test)
{
@@ -87,44 +84,12 @@ TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
return imv_test->create_state(imv_test, state);
case TNC_CONNECTION_STATE_DELETE:
return imv_test->delete_state(imv_test, connection_id);
- case TNC_CONNECTION_STATE_HANDSHAKE:
- /* get updated IMV state */
- result = imv_test->change_state(imv_test, connection_id,
- new_state, &state);
- if (result != TNC_RESULT_SUCCESS)
- {
- return result;
- }
- test_state = (imv_test_state_t*)state;
-
- /* set the number of measurement rounds */
- rounds = lib->settings->get_int(lib->settings,
- "libimcv.plugins.imv-test.rounds", 0);
- test_state->set_rounds(test_state, rounds);
- return TNC_RESULT_SUCCESS;
default:
return imv_test->change_state(imv_test, connection_id,
new_state, NULL);
}
}
-static TNC_Result send_message(TNC_ConnectionID connection_id)
-{
- pa_tnc_msg_t *msg;
- pa_tnc_attr_t *attr;
- TNC_Result result;
-
- attr = ita_attr_command_create("repeat");
- msg = pa_tnc_msg_create();
- msg->add_attribute(msg, attr);
- msg->build(msg);
- result = imv_test->send_message(imv_test, connection_id, FALSE, 0,
- TNC_IMCID_ANY, msg->get_encoding(msg));
- msg->destroy(msg);
-
- return result;
-}
-
static TNC_Result receive_message(TNC_IMVID imv_id,
TNC_ConnectionID connection_id,
TNC_UInt32 msg_flags,
@@ -137,9 +102,10 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
pa_tnc_msg_t *pa_tnc_msg;
pa_tnc_attr_t *attr;
imv_state_t *state;
- imv_test_state_t *imv_test_state;
+ imv_test_state_t *test_state;
enumerator_t *enumerator;
TNC_Result result;
+ int rounds;
bool fatal_error, retry = FALSE;
if (!imv_test)
@@ -153,6 +119,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
{
return TNC_RESULT_FATAL;
}
+ test_state = (imv_test_state_t*)state;
/* parse received PA-TNC message and automatically handle any errors */
result = imv_test->receive_message(imv_test, state, msg, msg_vid,
@@ -167,6 +134,11 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
/* preprocess any IETF standard error attributes */
fatal_error = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg);
+ /* add any new IMC and set its number of rounds */
+ rounds = lib->settings->get_int(lib->settings,
+ "libimcv.plugins.imv-test.rounds", 0);
+ test_state->add_imc(test_state, src_imc_id, rounds);
+
/* analyze PA-TNC attributes */
enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
while (enumerator->enumerate(enumerator, &attr))
@@ -225,15 +197,23 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
/* request a handshake retry ? */
if (retry)
{
+ test_state->set_rounds(test_state, rounds);
return imv_test->request_handshake_retry(imv_id, connection_id,
TNC_RETRY_REASON_IMV_SERIOUS_EVENT);
}
/* repeat the measurement ? */
- imv_test_state = (imv_test_state_t*)state;
- if (imv_test_state->another_round(imv_test_state))
+ if (test_state->another_round(test_state, src_imc_id))
{
- return send_message(connection_id);
+ attr = ita_attr_command_create("repeat");
+ pa_tnc_msg = pa_tnc_msg_create();
+ pa_tnc_msg->add_attribute(pa_tnc_msg, attr);
+ pa_tnc_msg->build(pa_tnc_msg);
+ result = imv_test->send_message(imv_test, connection_id, TRUE, imv_id,
+ src_imc_id, pa_tnc_msg->get_encoding(pa_tnc_msg));
+ pa_tnc_msg->destroy(pa_tnc_msg);
+
+ return result;
}
return imv_test->provide_recommendation(imv_test, connection_id);
diff --git a/src/libimcv/plugins/imv_test/imv_test_state.c b/src/libimcv/plugins/imv_test/imv_test_state.c
index 9df117a27..530090af7 100644
--- a/src/libimcv/plugins/imv_test/imv_test_state.c
+++ b/src/libimcv/plugins/imv_test/imv_test_state.c
@@ -15,6 +15,7 @@
#include "imv_test_state.h"
#include <utils/lexparser.h>
+#include <utils/linked_list.h>
#include <debug.h>
typedef struct private_imv_test_state_t private_imv_test_state_t;
@@ -60,10 +61,20 @@ struct private_imv_test_state_t {
TNC_IMV_Evaluation_Result eval;
/**
- * IMC-IMV round-trip count
+ * List of IMCs
*/
- int rounds;
+ linked_list_t *imcs;
+
+};
+
+typedef struct imc_entry_t imc_entry_t;
+/**
+ * Define an internal IMC entry
+ */
+struct imc_entry_t {
+ TNC_UInt32 imc_id;
+ int rounds;
};
typedef struct entry_t entry_t;
@@ -180,19 +191,73 @@ METHOD(imv_state_t, get_reason_string, bool,
METHOD(imv_state_t, destroy, void,
private_imv_test_state_t *this)
{
+ this->imcs->destroy_function(this->imcs, free);
free(this);
}
+METHOD(imv_test_state_t, add_imc, void,
+ private_imv_test_state_t *this, TNC_UInt32 imc_id, int rounds)
+{
+ enumerator_t *enumerator;
+ imc_entry_t *imc_entry;
+ bool found = FALSE;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc_entry))
+ {
+ if (imc_entry->imc_id == imc_id)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ imc_entry = malloc_thing(imc_entry_t);
+ imc_entry->imc_id = imc_id;
+ imc_entry->rounds = rounds;
+ this->imcs->insert_last(this->imcs, imc_entry);
+ }
+}
+
METHOD(imv_test_state_t, set_rounds, void,
private_imv_test_state_t *this, int rounds)
{
- this->rounds = rounds;
+ enumerator_t *enumerator;
+ imc_entry_t *imc_entry;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc_entry))
+ {
+ imc_entry->rounds = rounds;
+ }
+ enumerator->destroy(enumerator);
}
METHOD(imv_test_state_t, another_round, bool,
- private_imv_test_state_t *this)
+ private_imv_test_state_t *this, TNC_UInt32 imc_id)
{
- return (this->rounds-- > 0);
+ enumerator_t *enumerator;
+ imc_entry_t *imc_entry;
+ bool not_finished = FALSE;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc_entry))
+ {
+ if (imc_entry->rounds > 0)
+ {
+ not_finished = TRUE;
+ }
+ if (imc_entry->imc_id == imc_id)
+ {
+ imc_entry->rounds--;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return not_finished;
}
/**
@@ -215,6 +280,7 @@ imv_state_t *imv_test_state_create(TNC_ConnectionID connection_id)
.get_reason_string = _get_reason_string,
.destroy = _destroy,
},
+ .add_imc = _add_imc,
.set_rounds = _set_rounds,
.another_round = _another_round,
},
@@ -222,6 +288,7 @@ imv_state_t *imv_test_state_create(TNC_ConnectionID connection_id)
.rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
.eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
.connection_id = connection_id,
+ .imcs = linked_list_create(),
);
return &this->public.interface;
diff --git a/src/libimcv/plugins/imv_test/imv_test_state.h b/src/libimcv/plugins/imv_test/imv_test_state.h
index 7e7b3a8f3..af78d1470 100644
--- a/src/libimcv/plugins/imv_test/imv_test_state.h
+++ b/src/libimcv/plugins/imv_test/imv_test_state.h
@@ -37,6 +37,14 @@ struct imv_test_state_t {
imv_state_t interface;
/**
+ * Add an IMC
+ *
+ * @param imc_id ID of the IMC to be added
+ * @param rounds number of re-measurement rounds
+ */
+ void (*add_imc)(imv_test_state_t *this, TNC_UInt32 imc_id, int rounds);
+
+ /**
* Set the IMC-IMV round-trip count
*
* @param rounds number of re-measurement rounds
@@ -46,9 +54,10 @@ struct imv_test_state_t {
/**
* Check and decrease IMC-IMV round-trip count
*
+ * @param imc_id ID of the IMC to be checked
* @return new connection state
*/
- bool (*another_round)(imv_test_state_t *this);
+ bool (*another_round)(imv_test_state_t *this, TNC_UInt32 imc_id);
};
/**