*/
TNC_IMCID id;
+ /**
+ * List of additional IMC IDs assigned by TNCC
+ */
+ linked_list_t *additional_ids;
+
/**
* list of TNCC connection entries
*/
return TNC_RESULT_SUCCESS;
}
-METHOD(imc_agent_t, reserve_additional_id, TNC_Result,
- private_imc_agent_t *this, TNC_UInt32 *id)
+METHOD(imc_agent_t, reserve_additional_ids, TNC_Result,
+ private_imc_agent_t *this, int count)
{
+ TNC_Result result;
+ TNC_UInt32 id;
+ void *pointer;
+
if (!this->reserve_additional_id)
{
+ DBG1(DBG_IMC, "IMC %u \"%s\" did not detect the capability to reserve "
+ "additional IMC IDs from the TNCC", this->id, this->name);
return TNC_RESULT_ILLEGAL_OPERATION;
}
- return this->reserve_additional_id(this->id, id);
+ while (count > 0)
+ {
+ result = this->reserve_additional_id(this->id, &id);
+ if (result != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_IMC, "IMC %u \"%s\" failed to reserve %d additional IMC IDs",
+ this->id, this->name, count);
+ return result;
+ }
+ count--;
+
+ /* store the scalar value in the pointer */
+ pointer = (void*)id;
+ this->additional_ids->insert_last(this->additional_ids, pointer);
+ DBG2(DBG_IMC, "IMC %u \"%s\" reserved additional ID %u",
+ this->id, this->name, id);
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imc_agent_t, count_additional_ids, int,
+ private_imc_agent_t *this)
+{
+ return this->additional_ids->get_count(this->additional_ids);
+}
+
+METHOD(imc_agent_t, create_id_enumerator, enumerator_t*,
+ private_imc_agent_t *this)
+{
+ return this->additional_ids->create_enumerator(this->additional_ids);
}
METHOD(imc_agent_t, destroy, void,
private_imc_agent_t *this)
{
DBG1(DBG_IMC, "IMC %u \"%s\" terminated", this->id, this->name);
+ this->additional_ids->destroy(this->additional_ids);
this->connections->destroy_function(this->connections, free);
this->connection_lock->destroy(this->connection_lock);
free(this);
.get_state = _get_state,
.send_message = _send_message,
.receive_message = _receive_message,
- .reserve_additional_id = _reserve_additional_id,
+ .reserve_additional_ids = _reserve_additional_ids,
+ .count_additional_ids = _count_additional_ids,
+ .create_id_enumerator = _create_id_enumerator,
.destroy = _destroy,
},
.name = name,
.vendor_id = vendor_id,
.subtype = subtype,
.id = id,
+ .additional_ids = linked_list_create(),
.connections = linked_list_create(),
.connection_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
);
pa_tnc_msg_t **pa_tnc_msg);
/**
- * Reserve an additional IMC ID
+ * Reserve additional IMC IDs from TNCC
*
- * @param id additional IMC ID assigned by TNCC
+ * @param count number of additional IMC IDs to be assigned
* @return TNC result code
*/
- TNC_Result (*reserve_additional_id)(imc_agent_t *this, TNC_UInt32 *id);
+ TNC_Result (*reserve_additional_ids)(imc_agent_t *this, int count);
+
+ /**
+ * Return the number of additional IMC IDs assigned by the TNCC
+ *
+ * @return number of additional IMC IDs
+ */
+ int (*count_additional_ids)(imc_agent_t *this);
+
+ /**
+ * Create an enumerator for the additional IMC IDs
+ */
+ enumerator_t* (*create_id_enumerator)(imc_agent_t *this);
/**
* Destroys an imc_agent_t object
*/
TNC_IMVID id;
+ /**
+ * List of additional IMV IDs assigned by TNCS
+ */
+ linked_list_t *additional_ids;
+
/**
* list of TNCS connection entries
*/
return this->provide_recommendation(this->id, connection_id, rec, eval);
}
-METHOD(imv_agent_t, reserve_additional_id, TNC_Result,
- private_imv_agent_t *this, TNC_UInt32 *id)
+METHOD(imv_agent_t, reserve_additional_ids, TNC_Result,
+ private_imv_agent_t *this, int count)
{
+ TNC_Result result;
+ TNC_UInt32 id;
+ void *pointer;
+
if (!this->reserve_additional_id)
{
+ DBG1(DBG_IMV, "IMV %u \"%s\" did not detect the capability to reserve "
+ "additional IMV IDs from the TNCS", this->id, this->name);
return TNC_RESULT_ILLEGAL_OPERATION;
}
- return this->reserve_additional_id(this->id, id);
+ while (count > 0)
+ {
+ result = this->reserve_additional_id(this->id, &id);
+ if (result != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_IMV, "IMV %u \"%s\" failed to reserve %d additional IMV IDs",
+ this->id, this->name, count);
+ return result;
+ }
+ count--;
+
+ /* store the scalar value in the pointer */
+ pointer = (void*)id;
+ this->additional_ids->insert_last(this->additional_ids, pointer);
+ DBG2(DBG_IMV, "IMV %u \"%s\" reserved additional ID %u",
+ this->id, this->name, id);
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imv_agent_t, count_additional_ids, int,
+ private_imv_agent_t *this)
+{
+ return this->additional_ids->get_count(this->additional_ids);
+}
+
+METHOD(imv_agent_t, create_id_enumerator, enumerator_t*,
+ private_imv_agent_t *this)
+{
+ return this->additional_ids->create_enumerator(this->additional_ids);
}
METHOD(imv_agent_t, destroy, void,
private_imv_agent_t *this)
{
DBG1(DBG_IMV, "IMV %u \"%s\" terminated", this->id, this->name);
+ this->additional_ids->destroy(this->additional_ids);
this->connections->destroy_offset(this->connections,
offsetof(imv_state_t, destroy));
this->connection_lock->destroy(this->connection_lock);
.receive_message = _receive_message,
.set_recommendation = _set_recommendation,
.provide_recommendation = _provide_recommendation,
- .reserve_additional_id = _reserve_additional_id,
+ .reserve_additional_ids = _reserve_additional_ids,
+ .count_additional_ids = _count_additional_ids,
+ .create_id_enumerator = _create_id_enumerator,
.destroy = _destroy,
},
.name = name,
.vendor_id = vendor_id,
.subtype = subtype,
.id = id,
+ .additional_ids = linked_list_create(),
.connections = linked_list_create(),
.connection_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
);
TNC_ConnectionID connection_id);
/**
- * Reserve an additional IMV ID
+ * Reserve additional IMV IDs from TNCS
*
- * @param id additional IMV ID assigned by TNCS
+ * @param count number of additional IMV IDs to be assigned
* @return TNC result code
*/
- TNC_Result (*reserve_additional_id)(imv_agent_t *this, TNC_UInt32 *id);
+ TNC_Result (*reserve_additional_ids)(imv_agent_t *this, int count);
+
+ /**
+ * Return the number of additional IMV IDs assigned by the TNCS
+ *
+ * @return number of additional IMV IDs
+ */
+ int (*count_additional_ids)(imv_agent_t *this);
+
+ /**
+ * Create an enumerator for the additional IMV IDs
+ */
+ enumerator_t* (*create_id_enumerator)(imv_agent_t *this);
/**
* Destroys an imv_agent_t object
imc_state_t *state;
imc_test_state_t *test_state;
TNC_Result result;
- TNC_UInt32 new_imc_id;
char *command;
bool retry;
int additional_ids;
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)
return result;
}
- /* Do we want to reserve additional IMC IDs? */
+ /* Optionally reserve additional IMC IDs */
additional_ids = lib->settings->get_int(lib->settings,
- "libimcv.plugins.imc-test.additional_ids", 0);
- if (additional_ids < 1)
- {
- return TNC_RESULT_SUCCESS;
- }
-
- if (!state->has_long(state))
- {
- DBG1(DBG_IMC, "IMC %u \"%s\" did not detect support of "
- "multiple IMC IDs", imc_id, imc_name);
- return TNC_RESULT_SUCCESS;
- }
+ "libimcv.plugins.imc-test.additional_ids", 0);
+ imc_test->reserve_additional_ids(imc_test, additional_ids -
+ imc_test->count_additional_ids(imc_test));
- while (additional_ids-- > 0)
- {
- if (imc_test->reserve_additional_id(imc_test, &new_imc_id) !=
- TNC_RESULT_SUCCESS)
- {
- DBG1(DBG_IMC, "IMC %u \"%s\" failed to reserve "
- "%d additional IMC IDs",
- imc_id, imc_name, additional_ids);
- break;
- }
- DBG2(DBG_IMC, "IMC %u \"%s\" reserved additional ID %u",
- imc_id, imc_name, new_imc_id);
- test_state->add_id(test_state, new_imc_id);
- }
return TNC_RESULT_SUCCESS;
case TNC_CONNECTION_STATE_HANDSHAKE:
TNC_ConnectionID connection_id)
{
imc_state_t *state;
- imc_test_state_t *test_state;
enumerator_t *enumerator;
void *pointer;
TNC_UInt32 additional_id;
{
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);
-
+
+ /* Exit if there are no additional IMC IDs */
+ if (!imc_test->count_additional_ids(imc_test))
+ {
+ return result;
+ }
+
+ /* Do we have support for transporting multiple IMC IDs? */
+ if (!state->has_long(state))
+ {
+ DBG1(DBG_IMC, "IMC %u \"%s\" did not detect support for transporting "
+ "multiple IMC IDs", imc_id, imc_name);
+ return result;
+ }
+
/* send PA messages for additional IMC IDs */
- enumerator = test_state->create_id_enumerator(test_state);
+ enumerator = imc_test->create_id_enumerator(imc_test);
while (result == TNC_RESULT_SUCCESS &&
enumerator->enumerate(enumerator, &pointer))
{
* Do a handshake retry
*/
bool handshake_retry;
-
- /**
- * List of additional IMC IDs
- */
- linked_list_t *additional_ids;
};
METHOD(imc_state_t, destroy, void,
private_imc_test_state_t *this)
{
- this->additional_ids->destroy(this->additional_ids);
free(this->command);
free(this);
}
return retry;
}
-METHOD(imc_test_state_t, add_id, void,
- private_imc_test_state_t *this, TNC_IMCID id)
-{
- void *pointer;
-
- /* store the scalar value in the pointer */
- pointer = (void*)id;
- this->additional_ids->insert_last(this->additional_ids, pointer);
-}
-
-METHOD(imc_test_state_t, create_id_enumerator, enumerator_t*,
- private_imc_test_state_t *this)
-{
- return this->additional_ids->create_enumerator(this->additional_ids);
-}
-
/**
* Described in header.
*/
.set_command = _set_command,
.is_first_handshake = _is_first_handshake,
.do_handshake_retry = _do_handshake_retry,
- .add_id = _add_id,
- .create_id_enumerator = _create_id_enumerator,
},
.state = TNC_CONNECTION_STATE_CREATE,
.connection_id = connection_id,
.command = strdup(command),
.first_handshake = TRUE,
.handshake_retry = retry,
- .additional_ids = linked_list_create(),
);
return &this->public.interface;
*/
bool (*do_handshake_retry)(imc_test_state_t *this);
- /**
- * Add and additional IMC ID
- *
- * @param id Additional IMC ID
- */
- void (*add_id)(imc_test_state_t *this, TNC_IMCID id);
-
- /**
- * Create an enumerator for additional IMC IDs
- */
- enumerator_t* (*create_id_enumerator)(imc_test_state_t *this);
};
/**