Support of multiple directed segmentation contracts
This commit is contained in:
@@ -117,7 +117,8 @@ METHOD(imc_msg_t, send_, TNC_Result,
|
|||||||
|
|
||||||
/* Get IF-M segmentation contract for this subtype if any */
|
/* Get IF-M segmentation contract for this subtype if any */
|
||||||
contracts = this->state->get_contracts(this->state);
|
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))
|
while (this->attr_list->get_count(this->attr_list))
|
||||||
{
|
{
|
||||||
@@ -287,6 +288,10 @@ METHOD(imc_msg_t, receive, TNC_Result,
|
|||||||
return TNC_RESULT_FATAL;
|
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 */
|
/* process any IF-M segmentation contracts */
|
||||||
enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
|
enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
|
||||||
while (enumerator->enumerate(enumerator, &attr))
|
while (enumerator->enumerate(enumerator, &attr))
|
||||||
@@ -316,7 +321,7 @@ METHOD(imc_msg_t, receive, TNC_Result,
|
|||||||
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
||||||
&max_seg_size);
|
&max_seg_size);
|
||||||
contract = contracts->get_contract(contracts, this->msg_type,
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
FALSE);
|
FALSE, this->src_id);
|
||||||
if (contract)
|
if (contract)
|
||||||
{
|
{
|
||||||
contract->set_max_size(contract, max_attr_size,
|
contract->set_max_size(contract, max_attr_size,
|
||||||
@@ -326,6 +331,7 @@ METHOD(imc_msg_t, receive, TNC_Result,
|
|||||||
{
|
{
|
||||||
contract = seg_contract_create(this->msg_type, max_attr_size,
|
contract = seg_contract_create(this->msg_type, max_attr_size,
|
||||||
max_seg_size, FALSE, this->src_id, TRUE);
|
max_seg_size, FALSE, this->src_id, TRUE);
|
||||||
|
contract->set_responder(contract, target_imc_id);
|
||||||
contracts->add_contract(contracts, contract);
|
contracts->add_contract(contracts, contract);
|
||||||
}
|
}
|
||||||
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
||||||
@@ -364,7 +370,18 @@ METHOD(imc_msg_t, receive, TNC_Result,
|
|||||||
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
||||||
&max_seg_size);
|
&max_seg_size);
|
||||||
contract = contracts->get_contract(contracts, this->msg_type,
|
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)
|
if (contract)
|
||||||
{
|
{
|
||||||
contract->get_max_size(contract, &my_max_attr_size,
|
contract->get_max_size(contract, &my_max_attr_size,
|
||||||
@@ -397,7 +414,7 @@ METHOD(imc_msg_t, receive, TNC_Result,
|
|||||||
base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
|
base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
|
||||||
|
|
||||||
contract = contracts->get_contract(contracts, this->msg_type,
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
TRUE);
|
TRUE, this->src_id);
|
||||||
if (!contract)
|
if (!contract)
|
||||||
{
|
{
|
||||||
DBG2(DBG_IMC, "no contract for received attribute segment "
|
DBG2(DBG_IMC, "no contract for received attribute segment "
|
||||||
@@ -430,7 +447,7 @@ METHOD(imc_msg_t, receive, TNC_Result,
|
|||||||
base_attr_id = attr_cast->get_base_attr_id(attr_cast);
|
base_attr_id = attr_cast->get_base_attr_id(attr_cast);
|
||||||
|
|
||||||
contract = contracts->get_contract(contracts, this->msg_type,
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
FALSE);
|
FALSE, this->src_id);
|
||||||
if (!contract)
|
if (!contract)
|
||||||
{
|
{
|
||||||
/* TODO no contract - generate error message */
|
/* TODO no contract - generate error message */
|
||||||
@@ -457,10 +474,6 @@ METHOD(imc_msg_t, receive, TNC_Result,
|
|||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
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 */
|
/* preprocess any received IETF standard error attributes */
|
||||||
non_fatal_types = this->agent->get_non_fatal_attr_types(this->agent);
|
non_fatal_types = this->agent->get_non_fatal_attr_types(this->agent);
|
||||||
*fatal_error = this->pa_msg->process_ietf_std_errors(this->pa_msg,
|
*fatal_error = this->pa_msg->process_ietf_std_errors(this->pa_msg,
|
||||||
|
|||||||
@@ -134,7 +134,8 @@ METHOD(imv_msg_t, send_, TNC_Result,
|
|||||||
|
|
||||||
/* Get IF-M segmentation contract for this subtype if any */
|
/* Get IF-M segmentation contract for this subtype if any */
|
||||||
contracts = this->state->get_contracts(this->state);
|
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))
|
while (this->attr_list->get_count(this->attr_list))
|
||||||
{
|
{
|
||||||
@@ -270,6 +271,7 @@ METHOD(imv_msg_t, receive, TNC_Result,
|
|||||||
private_imv_msg_t *this, imv_msg_t *out_msg, bool *fatal_error)
|
private_imv_msg_t *this, imv_msg_t *out_msg, bool *fatal_error)
|
||||||
{
|
{
|
||||||
TNC_Result result = TNC_RESULT_SUCCESS;
|
TNC_Result result = TNC_RESULT_SUCCESS;
|
||||||
|
TNC_UInt32 target_imv_id;
|
||||||
linked_list_t *non_fatal_types;
|
linked_list_t *non_fatal_types;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
pa_tnc_attr_t *attr;
|
pa_tnc_attr_t *attr;
|
||||||
@@ -322,6 +324,10 @@ METHOD(imv_msg_t, receive, TNC_Result,
|
|||||||
return TNC_RESULT_FATAL;
|
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 */
|
/* process IF-M segmentation attributes */
|
||||||
enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
|
enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
|
||||||
while (enumerator->enumerate(enumerator, &attr))
|
while (enumerator->enumerate(enumerator, &attr))
|
||||||
@@ -351,7 +357,7 @@ METHOD(imv_msg_t, receive, TNC_Result,
|
|||||||
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
||||||
&max_seg_size);
|
&max_seg_size);
|
||||||
contract = contracts->get_contract(contracts, this->msg_type,
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
FALSE);
|
FALSE, this->src_id);
|
||||||
if (contract)
|
if (contract)
|
||||||
{
|
{
|
||||||
contract->set_max_size(contract, max_attr_size,
|
contract->set_max_size(contract, max_attr_size,
|
||||||
@@ -361,6 +367,7 @@ METHOD(imv_msg_t, receive, TNC_Result,
|
|||||||
{
|
{
|
||||||
contract = seg_contract_create(this->msg_type, max_attr_size,
|
contract = seg_contract_create(this->msg_type, max_attr_size,
|
||||||
max_seg_size, FALSE, this->src_id, FALSE);
|
max_seg_size, FALSE, this->src_id, FALSE);
|
||||||
|
contract->set_responder(contract, target_imv_id);
|
||||||
contracts->add_contract(contracts, contract);
|
contracts->add_contract(contracts, contract);
|
||||||
}
|
}
|
||||||
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
||||||
@@ -399,7 +406,18 @@ METHOD(imv_msg_t, receive, TNC_Result,
|
|||||||
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
||||||
&max_seg_size);
|
&max_seg_size);
|
||||||
contract = contracts->get_contract(contracts, this->msg_type,
|
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)
|
if (contract)
|
||||||
{
|
{
|
||||||
contract->get_max_size(contract, &my_max_attr_size,
|
contract->get_max_size(contract, &my_max_attr_size,
|
||||||
@@ -432,7 +450,7 @@ METHOD(imv_msg_t, receive, TNC_Result,
|
|||||||
base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
|
base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
|
||||||
|
|
||||||
contract = contracts->get_contract(contracts, this->msg_type,
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
TRUE);
|
TRUE, this->src_id);
|
||||||
if (!contract)
|
if (!contract)
|
||||||
{
|
{
|
||||||
DBG2(DBG_IMV, "no contract for received attribute segment "
|
DBG2(DBG_IMV, "no contract for received attribute segment "
|
||||||
@@ -465,7 +483,7 @@ METHOD(imv_msg_t, receive, TNC_Result,
|
|||||||
base_attr_id = attr_cast->get_base_attr_id(attr_cast);
|
base_attr_id = attr_cast->get_base_attr_id(attr_cast);
|
||||||
|
|
||||||
contract = contracts->get_contract(contracts, this->msg_type,
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
FALSE);
|
FALSE, this->src_id);
|
||||||
if (!contract)
|
if (!contract)
|
||||||
{
|
{
|
||||||
/* TODO no contract - generate error message */
|
/* TODO no contract - generate error message */
|
||||||
|
|||||||
@@ -72,10 +72,15 @@ struct private_seg_contract_t {
|
|||||||
bool is_issuer;
|
bool is_issuer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Issuer ID (either IMV ID or IMC ID)
|
* Issuer ID (either IMV or IMC ID)
|
||||||
*/
|
*/
|
||||||
TNC_UInt32 issuer_id;
|
TNC_UInt32 issuer_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responder ID (either IMC or IMV ID)
|
||||||
|
*/
|
||||||
|
TNC_UInt32 responder_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IMC/IMV role
|
* IMC/IMV role
|
||||||
*/
|
*/
|
||||||
@@ -290,6 +295,36 @@ METHOD(seg_contract_t, is_null, bool,
|
|||||||
return this->is_null;
|
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,
|
METHOD(seg_contract_t, get_info_string, void,
|
||||||
private_seg_contract_t *this, char *buf, size_t len, bool request)
|
private_seg_contract_t *this, char *buf, size_t len, bool request)
|
||||||
{
|
{
|
||||||
@@ -308,7 +343,10 @@ METHOD(seg_contract_t, get_info_string, void,
|
|||||||
}
|
}
|
||||||
else
|
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)
|
if (written < 0 || written > len)
|
||||||
{
|
{
|
||||||
@@ -318,7 +356,8 @@ METHOD(seg_contract_t, get_info_string, void,
|
|||||||
len -= written;
|
len -= written;
|
||||||
|
|
||||||
written = snprintf(pos, len, " a %ssegmentation contract%s ",
|
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)
|
if (written < 0 || written > len)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -326,10 +365,13 @@ METHOD(seg_contract_t, get_info_string, void,
|
|||||||
pos += written;
|
pos += written;
|
||||||
len -= 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 ",
|
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)
|
if (written < 0 || written > len)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -413,6 +455,10 @@ seg_contract_t *seg_contract_create(pen_type_t msg_type,
|
|||||||
.add_segment = _add_segment,
|
.add_segment = _add_segment,
|
||||||
.is_issuer = _is_issuer,
|
.is_issuer = _is_issuer,
|
||||||
.is_null = _is_null,
|
.is_null = _is_null,
|
||||||
|
.set_responder = _set_responder,
|
||||||
|
.get_responder = _get_responder,
|
||||||
|
.get_issuer = _get_issuer,
|
||||||
|
.clone = _clone_,
|
||||||
.get_info_string = _get_info_string,
|
.get_info_string = _get_info_string,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
@@ -422,6 +468,7 @@ seg_contract_t *seg_contract_create(pen_type_t msg_type,
|
|||||||
.seg_envs = linked_list_create(),
|
.seg_envs = linked_list_create(),
|
||||||
.is_issuer = is_issuer,
|
.is_issuer = is_issuer,
|
||||||
.issuer_id = issuer_id,
|
.issuer_id = issuer_id,
|
||||||
|
.responder_id = is_imc ? TNC_IMVID_ANY : TNC_IMCID_ANY,
|
||||||
.is_imc = is_imc,
|
.is_imc = is_imc,
|
||||||
.is_null = max_attr_size == SEG_CONTRACT_MAX_SIZE_VALUE &&
|
.is_null = max_attr_size == SEG_CONTRACT_MAX_SIZE_VALUE &&
|
||||||
max_seg_size == SEG_CONTRACT_MAX_SIZE_VALUE,
|
max_seg_size == SEG_CONTRACT_MAX_SIZE_VALUE,
|
||||||
|
|||||||
@@ -117,6 +117,34 @@ struct seg_contract_t {
|
|||||||
*/
|
*/
|
||||||
bool (*is_null)(seg_contract_t *this);
|
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
|
* Get an info string about the contract
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ METHOD(seg_contract_manager_t, add_contract, void,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(seg_contract_manager_t, get_contract, seg_contract_t*,
|
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;
|
enumerator_t *enumerator;
|
||||||
seg_contract_t *contract, *found = NULL;
|
seg_contract_t *contract, *found = NULL;
|
||||||
@@ -51,7 +52,9 @@ METHOD(seg_contract_manager_t, get_contract, seg_contract_t*,
|
|||||||
while (enumerator->enumerate(enumerator, &contract))
|
while (enumerator->enumerate(enumerator, &contract))
|
||||||
{
|
{
|
||||||
if (contract->is_issuer(contract) == is_issuer &&
|
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;
|
found = contract;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -43,9 +43,11 @@ struct seg_contract_manager_t {
|
|||||||
*
|
*
|
||||||
* @param msg_type PA-TNC message type governed by contract
|
* @param msg_type PA-TNC message type governed by contract
|
||||||
* @param is_issuer If TRUE get only issuer contracts
|
* @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,
|
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.
|
* Destroys a seg_contract_manager_t object.
|
||||||
|
|||||||
Reference in New Issue
Block a user