/* Get IF-M segmentation contract for this subtype if any */
contracts = this->state->get_contracts(this->state);
- contract = contracts->get_contract(contracts, this->msg_type, FALSE);
+ contract = contracts->get_contract(contracts, this->msg_type,
+ FALSE, this->dst_id);
while (this->attr_list->get_count(this->attr_list))
{
return TNC_RESULT_FATAL;
}
+ /* determine target IMC ID */
+ target_imc_id = (this->dst_id != TNC_IMCID_ANY) ?
+ this->dst_id : this->agent->get_id(this->agent);
+
/* process any IF-M segmentation contracts */
enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
while (enumerator->enumerate(enumerator, &attr))
attr_cast->get_attr_size(attr_cast, &max_attr_size,
&max_seg_size);
contract = contracts->get_contract(contracts, this->msg_type,
- FALSE);
+ FALSE, this->src_id);
if (contract)
{
contract->set_max_size(contract, max_attr_size,
{
contract = seg_contract_create(this->msg_type, max_attr_size,
max_seg_size, FALSE, this->src_id, TRUE);
+ contract->set_responder(contract, target_imc_id);
contracts->add_contract(contracts, contract);
}
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
attr_cast->get_attr_size(attr_cast, &max_attr_size,
&max_seg_size);
contract = contracts->get_contract(contracts, this->msg_type,
- TRUE);
+ TRUE, this->src_id);
+ if (!contract)
+ {
+ contract = contracts->get_contract(contracts, this->msg_type,
+ TRUE, TNC_IMCID_ANY);
+ if (contract)
+ {
+ contract = contract->clone(contract);
+ contract->set_responder(contract, this->src_id);
+ contracts->add_contract(contracts, contract);
+ }
+ }
if (contract)
{
contract->get_max_size(contract, &my_max_attr_size,
base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
contract = contracts->get_contract(contracts, this->msg_type,
- TRUE);
+ TRUE, this->src_id);
if (!contract)
{
DBG2(DBG_IMC, "no contract for received attribute segment "
base_attr_id = attr_cast->get_base_attr_id(attr_cast);
contract = contracts->get_contract(contracts, this->msg_type,
- FALSE);
+ FALSE, this->src_id);
if (!contract)
{
/* TODO no contract - generate error message */
}
enumerator->destroy(enumerator);
- /* determine target IMC ID */
- target_imc_id = (this->dst_id != TNC_IMCID_ANY) ?
- this->dst_id : this->agent->get_id(this->agent);
-
/* preprocess any received IETF standard error attributes */
non_fatal_types = this->agent->get_non_fatal_attr_types(this->agent);
*fatal_error = this->pa_msg->process_ietf_std_errors(this->pa_msg,
/* Get IF-M segmentation contract for this subtype if any */
contracts = this->state->get_contracts(this->state);
- contract = contracts->get_contract(contracts, this->msg_type, FALSE);
+ contract = contracts->get_contract(contracts, this->msg_type,
+ FALSE, this->dst_id);
while (this->attr_list->get_count(this->attr_list))
{
private_imv_msg_t *this, imv_msg_t *out_msg, bool *fatal_error)
{
TNC_Result result = TNC_RESULT_SUCCESS;
+ TNC_UInt32 target_imv_id;
linked_list_t *non_fatal_types;
enumerator_t *enumerator;
pa_tnc_attr_t *attr;
return TNC_RESULT_FATAL;
}
+ /* determine target IMV ID */
+ target_imv_id = (this->dst_id != TNC_IMVID_ANY) ?
+ this->dst_id : this->agent->get_id(this->agent);
+
/* process IF-M segmentation attributes */
enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
while (enumerator->enumerate(enumerator, &attr))
attr_cast->get_attr_size(attr_cast, &max_attr_size,
&max_seg_size);
contract = contracts->get_contract(contracts, this->msg_type,
- FALSE);
+ FALSE, this->src_id);
if (contract)
{
contract->set_max_size(contract, max_attr_size,
{
contract = seg_contract_create(this->msg_type, max_attr_size,
max_seg_size, FALSE, this->src_id, FALSE);
+ contract->set_responder(contract, target_imv_id);
contracts->add_contract(contracts, contract);
}
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
attr_cast->get_attr_size(attr_cast, &max_attr_size,
&max_seg_size);
contract = contracts->get_contract(contracts, this->msg_type,
- TRUE);
+ TRUE, this->src_id);
+ if (!contract)
+ {
+ contract = contracts->get_contract(contracts, this->msg_type,
+ TRUE, TNC_IMCID_ANY);
+ if (contract)
+ {
+ contract = contract->clone(contract);
+ contract->set_responder(contract, this->src_id);
+ contracts->add_contract(contracts, contract);
+ }
+ }
if (contract)
{
contract->get_max_size(contract, &my_max_attr_size,
base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
contract = contracts->get_contract(contracts, this->msg_type,
- TRUE);
+ TRUE, this->src_id);
if (!contract)
{
DBG2(DBG_IMV, "no contract for received attribute segment "
base_attr_id = attr_cast->get_base_attr_id(attr_cast);
contract = contracts->get_contract(contracts, this->msg_type,
- FALSE);
+ FALSE, this->src_id);
if (!contract)
{
/* TODO no contract - generate error message */
bool is_issuer;
/**
- * Issuer ID (either IMV ID or IMC ID)
+ * Issuer ID (either IMV or IMC ID)
*/
TNC_UInt32 issuer_id;
+ /**
+ * Responder ID (either IMC or IMV ID)
+ */
+ TNC_UInt32 responder_id;
+
/**
* IMC/IMV role
*/
return this->is_null;
}
+METHOD(seg_contract_t, set_responder, void,
+ private_seg_contract_t *this, TNC_UInt32 responder_id)
+{
+ this->responder_id = responder_id;
+}
+
+METHOD(seg_contract_t, get_responder, TNC_UInt32,
+ private_seg_contract_t *this)
+{
+ return this->responder_id;
+}
+
+METHOD(seg_contract_t, get_issuer, TNC_UInt32,
+ private_seg_contract_t *this)
+{
+ return this->issuer_id;
+}
+
+METHOD(seg_contract_t, clone_, seg_contract_t*,
+ private_seg_contract_t *this)
+{
+ private_seg_contract_t *clone;
+
+ clone = malloc_thing(private_seg_contract_t);
+ memcpy(clone, this, sizeof(private_seg_contract_t));
+ clone->seg_envs = linked_list_create();
+
+ return &clone->public;
+}
+
METHOD(seg_contract_t, get_info_string, void,
private_seg_contract_t *this, char *buf, size_t len, bool request)
{
}
else
{
- written = snprintf(pos, len, "received");
+ written = snprintf(pos, len, "%s %d received",
+ this->is_imc ? "IMC" : "IMV",
+ this->is_issuer ? this->issuer_id :
+ this->responder_id);
}
if (written < 0 || written > len)
{
len -= written;
written = snprintf(pos, len, " a %ssegmentation contract%s ",
- this->is_null ? "null" : "", request ? "" : " response");
+ this->is_null ? "null" : "", request ?
+ (this->is_issuer ? "" : " request") : " response");
if (written < 0 || written > len)
{
return;
pos += written;
len -= written;
- if (!this->is_issuer && this->issuer_id != TNC_IMVID_ANY)
+ if ((!this->is_issuer && this->issuer_id != TNC_IMVID_ANY) ||
+ ( this->is_issuer && this->responder_id != TNC_IMVID_ANY))
{
written = snprintf(pos, len, "from %s %d ",
- this->is_imc ? "IMV" : "IMC", this->issuer_id);
+ this->is_imc ? "IMV" : "IMC",
+ this->is_issuer ? this->responder_id :
+ this->issuer_id);
if (written < 0 || written > len)
{
return;
.add_segment = _add_segment,
.is_issuer = _is_issuer,
.is_null = _is_null,
+ .set_responder = _set_responder,
+ .get_responder = _get_responder,
+ .get_issuer = _get_issuer,
+ .clone = _clone_,
.get_info_string = _get_info_string,
.destroy = _destroy,
},
.seg_envs = linked_list_create(),
.is_issuer = is_issuer,
.issuer_id = issuer_id,
+ .responder_id = is_imc ? TNC_IMVID_ANY : TNC_IMCID_ANY,
.is_imc = is_imc,
.is_null = max_attr_size == SEG_CONTRACT_MAX_SIZE_VALUE &&
max_seg_size == SEG_CONTRACT_MAX_SIZE_VALUE,
*/
bool (*is_null)(seg_contract_t *this);
+ /**
+ * Set the responder ID
+ *
+ * @param responder IMC or IMV ID of responder
+ */
+ void (*set_responder)(seg_contract_t *this, TNC_UInt32 responder);
+
+ /**
+ * Get the responder ID
+ *
+ * @return IMC or IMV ID of responder
+ */
+ TNC_UInt32 (*get_responder)(seg_contract_t *this);
+
+ /**
+ * Get the issuer ID
+ *
+ * @return IMC or IMV ID of issuer
+ */
+ TNC_UInt32 (*get_issuer)(seg_contract_t *this);
+
+ /**
+ * Clone a contract
+ *
+ * @return Cloned contract
+ */
+ seg_contract_t* (*clone)(seg_contract_t *this);
+
/**
* Get an info string about the contract
*
}
METHOD(seg_contract_manager_t, get_contract, seg_contract_t*,
- private_seg_contract_manager_t *this, pen_type_t msg_type, bool is_issuer)
+ private_seg_contract_manager_t *this, pen_type_t msg_type, bool is_issuer,
+ TNC_UInt32 id)
{
enumerator_t *enumerator;
seg_contract_t *contract, *found = NULL;
while (enumerator->enumerate(enumerator, &contract))
{
if (contract->is_issuer(contract) == is_issuer &&
- pen_type_equals(contract->get_msg_type(contract), msg_type))
+ pen_type_equals(contract->get_msg_type(contract), msg_type) &&
+ id == (is_issuer ? contract->get_responder(contract) :
+ contract->get_issuer(contract)))
{
found = contract;
break;
*
* @param msg_type PA-TNC message type governed by contract
* @param is_issuer If TRUE get only issuer contracts
+ * @param id Match either issuer or responder ID
*/
seg_contract_t* (*get_contract)(seg_contract_manager_t *this,
- pen_type_t msg_type, bool is_issuer);
+ pen_type_t msg_type, bool is_issuer,
+ TNC_UInt32 id);
/**
* Destroys a seg_contract_manager_t object.