refactored and cleaned up child_sa interface
replaced add/update calls by a install() call allocating SPIs always externally support installation of non-allocated CHILD_SAs some other cleanups
This commit is contained in:
parent
9dd1229407
commit
3aaf7908d1
|
@ -110,7 +110,7 @@ static void execute(private_migrate_job_t *this)
|
|||
host->set_port(host, IKEV2_UDP_PORT);
|
||||
ike_sa->set_other_host(ike_sa, host);
|
||||
|
||||
if (child_sa->update_hosts(child_sa, this->local, this->remote,
|
||||
if (child_sa->update(child_sa, this->local, this->remote,
|
||||
ike_sa->get_virtual_ip(ike_sa, TRUE),
|
||||
ike_sa->has_condition(ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED)
|
||||
{
|
||||
|
|
|
@ -89,16 +89,6 @@ struct private_child_sa_t {
|
|||
*/
|
||||
linked_list_t *other_ts;
|
||||
|
||||
/**
|
||||
* Allocated SPI for a ESP proposal candidates
|
||||
*/
|
||||
u_int32_t alloc_esp_spi;
|
||||
|
||||
/**
|
||||
* Allocated SPI for a AH proposal candidates
|
||||
*/
|
||||
u_int32_t alloc_ah_spi;
|
||||
|
||||
/**
|
||||
* Protocol used to protect this SA, ESP|AH
|
||||
*/
|
||||
|
@ -134,11 +124,6 @@ struct private_child_sa_t {
|
|||
*/
|
||||
ipcomp_transform_t ipcomp;
|
||||
|
||||
/**
|
||||
* TRUE if we allocated (or tried to allocate) a CPI
|
||||
*/
|
||||
bool cpi_allocated;
|
||||
|
||||
/**
|
||||
* mode this SA uses, tunnel/transport
|
||||
*/
|
||||
|
@ -170,7 +155,32 @@ static u_int32_t get_reqid(private_child_sa_t *this)
|
|||
{
|
||||
return this->reqid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements child_sa_t.get_config
|
||||
*/
|
||||
static child_cfg_t* get_config(private_child_sa_t *this)
|
||||
{
|
||||
return this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements child_sa_t.set_state
|
||||
*/
|
||||
static void set_state(private_child_sa_t *this, child_sa_state_t state)
|
||||
{
|
||||
charon->bus->child_state_change(charon->bus, &this->public, state);
|
||||
this->state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements child_sa_t.get_state
|
||||
*/
|
||||
static child_sa_state_t get_state(private_child_sa_t *this)
|
||||
{
|
||||
return this->state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements child_sa_t.get_spi
|
||||
*/
|
||||
|
@ -195,6 +205,14 @@ protocol_id_t get_protocol(private_child_sa_t *this)
|
|||
return this->protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.set_protocol
|
||||
*/
|
||||
static void set_protocol(private_child_sa_t *this, protocol_id_t protocol)
|
||||
{
|
||||
this->protocol = protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.get_mode
|
||||
*/
|
||||
|
@ -203,6 +221,14 @@ static ipsec_mode_t get_mode(private_child_sa_t *this)
|
|||
return this->mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.set_mode
|
||||
*/
|
||||
static void set_mode(private_child_sa_t *this, ipsec_mode_t mode)
|
||||
{
|
||||
this->mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.has_encap
|
||||
*/
|
||||
|
@ -220,19 +246,35 @@ static ipcomp_transform_t get_ipcomp(private_child_sa_t *this)
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements child_sa_t.get_state
|
||||
* Implementation of child_sa_t.set_ipcomp.
|
||||
*/
|
||||
static child_sa_state_t get_state(private_child_sa_t *this)
|
||||
static void set_ipcomp(private_child_sa_t *this, ipcomp_transform_t ipcomp)
|
||||
{
|
||||
return this->state;
|
||||
this->ipcomp = ipcomp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements child_sa_t.get_config
|
||||
* Implementation of child_sa_t.get_proposal
|
||||
*/
|
||||
static child_cfg_t* get_config(private_child_sa_t *this)
|
||||
static proposal_t* get_proposal(private_child_sa_t *this)
|
||||
{
|
||||
return this->config;
|
||||
return this->proposal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.set_proposal
|
||||
*/
|
||||
static void set_proposal(private_child_sa_t *this, proposal_t *proposal)
|
||||
{
|
||||
this->proposal = proposal->clone(proposal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.get_traffic_selectors.
|
||||
*/
|
||||
static linked_list_t *get_traffic_selectors(private_child_sa_t *this, bool local)
|
||||
{
|
||||
return local ? this->my_ts : this->other_ts;
|
||||
}
|
||||
|
||||
typedef struct policy_enumerator_t policy_enumerator_t;
|
||||
|
@ -366,143 +408,100 @@ static u_int32_t get_lifetime(private_child_sa_t *this, bool hard)
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements child_sa_t.set_state
|
||||
* Implementation of child_sa_t.alloc_spi
|
||||
*/
|
||||
static void set_state(private_child_sa_t *this, child_sa_state_t state)
|
||||
static u_int32_t alloc_spi(private_child_sa_t *this, protocol_id_t protocol)
|
||||
{
|
||||
charon->bus->child_state_change(charon->bus, &this->public, state);
|
||||
this->state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate SPI for a single proposal
|
||||
*/
|
||||
static status_t alloc_proposal(private_child_sa_t *this, proposal_t *proposal)
|
||||
{
|
||||
protocol_id_t protocol = proposal->get_protocol(proposal);
|
||||
|
||||
if (protocol == PROTO_AH)
|
||||
switch (protocol)
|
||||
{
|
||||
/* get a new spi for AH, if not already done */
|
||||
if (this->alloc_ah_spi == 0)
|
||||
{
|
||||
if (charon->kernel_interface->get_spi(
|
||||
charon->kernel_interface,
|
||||
this->other_addr, this->my_addr,
|
||||
PROTO_AH, this->reqid,
|
||||
&this->alloc_ah_spi) != SUCCESS)
|
||||
case PROTO_AH:
|
||||
if (charon->kernel_interface->get_spi(charon->kernel_interface,
|
||||
this->other_addr, this->my_addr, PROTO_AH,
|
||||
this->reqid, &this->my_spi) == SUCCESS)
|
||||
{
|
||||
return FAILED;
|
||||
return this->my_spi;
|
||||
}
|
||||
}
|
||||
proposal->set_spi(proposal, this->alloc_ah_spi);
|
||||
}
|
||||
if (protocol == PROTO_ESP)
|
||||
{
|
||||
/* get a new spi for ESP, if not already done */
|
||||
if (this->alloc_esp_spi == 0)
|
||||
{
|
||||
if (charon->kernel_interface->get_spi(
|
||||
charon->kernel_interface,
|
||||
this->other_addr, this->my_addr,
|
||||
PROTO_ESP, this->reqid,
|
||||
&this->alloc_esp_spi) != SUCCESS)
|
||||
break;
|
||||
case PROTO_ESP:
|
||||
if (charon->kernel_interface->get_spi(charon->kernel_interface,
|
||||
this->other_addr, this->my_addr, PROTO_ESP,
|
||||
this->reqid, &this->my_spi) == SUCCESS)
|
||||
{
|
||||
return FAILED;
|
||||
return this->my_spi;
|
||||
}
|
||||
}
|
||||
proposal->set_spi(proposal, this->alloc_esp_spi);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements child_sa_t.alloc
|
||||
* Implementation of child_sa_t.alloc_cpi
|
||||
*/
|
||||
static status_t alloc(private_child_sa_t *this, linked_list_t *proposals)
|
||||
static u_int16_t alloc_cpi(private_child_sa_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
proposal_t *proposal;
|
||||
|
||||
/* iterator through proposals to update spis */
|
||||
iterator = proposals->create_iterator(proposals, TRUE);
|
||||
while(iterator->iterate(iterator, (void**)&proposal))
|
||||
if (charon->kernel_interface->get_cpi(charon->kernel_interface,
|
||||
this->other_addr, this->my_addr, this->reqid,
|
||||
&this->my_cpi) == SUCCESS)
|
||||
{
|
||||
if (alloc_proposal(this, proposal) != SUCCESS)
|
||||
{
|
||||
iterator->destroy(iterator);
|
||||
return FAILED;
|
||||
}
|
||||
return this->my_cpi;
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install an SA for one direction
|
||||
* Implementation of child_sa_t.install
|
||||
*/
|
||||
static status_t install(private_child_sa_t *this, proposal_t *proposal,
|
||||
ipsec_mode_t mode, chunk_t integ, chunk_t encr, bool in)
|
||||
static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
|
||||
u_int32_t spi, u_int16_t cpi, bool inbound)
|
||||
{
|
||||
u_int16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size;
|
||||
u_int32_t spi, soft, hard, now;
|
||||
u_int32_t soft, hard, now;
|
||||
host_t *src, *dst;
|
||||
status_t status;
|
||||
bool update = FALSE;
|
||||
|
||||
/* now we have to decide which spi to use. Use self allocated, if "in",
|
||||
* or the one in the proposal, if not "in" (others). Additionally,
|
||||
* source and dest host switch depending on the role */
|
||||
if (in)
|
||||
if (inbound)
|
||||
{
|
||||
/* if we have allocated SPIs for AH and ESP, we must delete the unused
|
||||
* one. */
|
||||
if (this->protocol == PROTO_ESP)
|
||||
{
|
||||
this->my_spi = this->alloc_esp_spi;
|
||||
if (this->alloc_ah_spi)
|
||||
{
|
||||
charon->kernel_interface->del_sa(charon->kernel_interface,
|
||||
this->my_addr, this->alloc_ah_spi, 0, PROTO_AH);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->my_spi = this->alloc_ah_spi;
|
||||
if (this->alloc_esp_spi)
|
||||
{
|
||||
charon->kernel_interface->del_sa(charon->kernel_interface,
|
||||
this->my_addr, this->alloc_esp_spi, 0, PROTO_ESP);
|
||||
}
|
||||
}
|
||||
spi = this->my_spi;
|
||||
dst = this->my_addr;
|
||||
src = this->other_addr;
|
||||
if (this->my_spi == spi)
|
||||
{ /* alloc_spi has been called, do an SA update */
|
||||
update = TRUE;
|
||||
}
|
||||
this->my_spi = spi;
|
||||
this->my_cpi = cpi;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->other_spi = proposal->get_spi(proposal);
|
||||
spi = this->other_spi;
|
||||
src = this->my_addr;
|
||||
dst = this->other_addr;
|
||||
this->other_spi = spi;
|
||||
this->other_cpi = cpi;
|
||||
}
|
||||
|
||||
DBG2(DBG_CHD, "adding %s %N SA", in ? "inbound" : "outbound",
|
||||
DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
|
||||
protocol_id_names, this->protocol);
|
||||
|
||||
/* send SA down to the kernel */
|
||||
DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
|
||||
|
||||
proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &enc_alg, &size);
|
||||
proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &int_alg, &size);
|
||||
this->proposal->get_algorithm(this->proposal, ENCRYPTION_ALGORITHM,
|
||||
&enc_alg, &size);
|
||||
this->proposal->get_algorithm(this->proposal, INTEGRITY_ALGORITHM,
|
||||
&int_alg, &size);
|
||||
|
||||
soft = this->config->get_lifetime(this->config, TRUE);
|
||||
hard = this->config->get_lifetime(this->config, FALSE);
|
||||
|
||||
|
||||
status = charon->kernel_interface->add_sa(charon->kernel_interface,
|
||||
src, dst, spi, this->protocol, this->reqid,
|
||||
in ? soft : 0, hard, enc_alg, encr, int_alg, integ,
|
||||
mode, this->ipcomp, in ? this->my_cpi : this->other_cpi,
|
||||
this->encap, in);
|
||||
inbound ? soft : 0, hard, enc_alg, encr, int_alg, integ,
|
||||
this->mode, this->ipcomp, cpi, this->encap, update);
|
||||
|
||||
now = time(NULL);
|
||||
this->rekey_time = now + soft;
|
||||
|
@ -510,84 +509,17 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal,
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.add
|
||||
*/
|
||||
static status_t add(private_child_sa_t *this,
|
||||
proposal_t *proposal, ipsec_mode_t mode,
|
||||
chunk_t integ_in, chunk_t integ_out,
|
||||
chunk_t encr_in, chunk_t encr_out)
|
||||
{
|
||||
this->proposal = proposal->clone(proposal);
|
||||
this->protocol = proposal->get_protocol(proposal);
|
||||
|
||||
/* get SPIs for inbound SAs, write to proposal */
|
||||
if (alloc_proposal(this, proposal) != SUCCESS)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
/* install inbound SAs using allocated SPI */
|
||||
if (install(this, proposal, mode, integ_in, encr_in, TRUE) != SUCCESS)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
/* install outbound SAs using received SPI*/
|
||||
if (install(this, this->proposal, mode, integ_out, encr_out, FALSE) != SUCCESS)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.update
|
||||
*/
|
||||
static status_t update(private_child_sa_t *this,
|
||||
proposal_t *proposal, ipsec_mode_t mode,
|
||||
chunk_t integ_in, chunk_t integ_out,
|
||||
chunk_t encr_in, chunk_t encr_out)
|
||||
{
|
||||
this->proposal = proposal->clone(proposal);
|
||||
this->protocol = proposal->get_protocol(proposal);
|
||||
|
||||
/* install outbound SAs */
|
||||
if (install(this, proposal, mode, integ_out, encr_out, FALSE) != SUCCESS)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
/* install inbound SAs */
|
||||
if (install(this, proposal, mode, integ_in, encr_in, TRUE) != SUCCESS)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.get_proposal
|
||||
*/
|
||||
static proposal_t* get_proposal(private_child_sa_t *this)
|
||||
{
|
||||
return this->proposal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.add_policies
|
||||
*/
|
||||
static status_t add_policies(private_child_sa_t *this,
|
||||
linked_list_t *my_ts_list, linked_list_t *other_ts_list,
|
||||
ipsec_mode_t mode, protocol_id_t proto)
|
||||
linked_list_t *my_ts_list, linked_list_t *other_ts_list)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
traffic_selector_t *my_ts, *other_ts;
|
||||
status_t status = SUCCESS;
|
||||
bool routed = (this->state == CHILD_CREATED);
|
||||
|
||||
if (this->protocol == PROTO_NONE)
|
||||
{ /* update if not set yet */
|
||||
this->protocol = proto;
|
||||
}
|
||||
|
||||
/* apply traffic selectors */
|
||||
enumerator = my_ts_list->create_enumerator(my_ts_list);
|
||||
while (enumerator->enumerate(enumerator, &my_ts))
|
||||
|
@ -611,19 +543,19 @@ static status_t add_policies(private_child_sa_t *this,
|
|||
/* install 3 policies: out, in and forward */
|
||||
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||
this->my_addr, this->other_addr, my_ts, other_ts, POLICY_OUT,
|
||||
this->other_spi, this->protocol, this->reqid, mode, this->ipcomp,
|
||||
this->other_cpi, routed);
|
||||
this->other_spi, this->protocol, this->reqid, this->mode,
|
||||
this->ipcomp, this->other_cpi, routed);
|
||||
|
||||
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||
this->other_addr, this->my_addr, other_ts, my_ts, POLICY_IN,
|
||||
this->my_spi, this->protocol, this->reqid, mode, this->ipcomp,
|
||||
this->my_cpi, routed);
|
||||
if (mode != MODE_TRANSPORT)
|
||||
this->my_spi, this->protocol, this->reqid, this->mode,
|
||||
this->ipcomp, this->my_cpi, routed);
|
||||
if (this->mode != MODE_TRANSPORT)
|
||||
{
|
||||
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||
this->other_addr, this->my_addr, other_ts, my_ts, POLICY_FWD,
|
||||
this->my_spi, this->protocol, this->reqid, mode, this->ipcomp,
|
||||
this->my_cpi, routed);
|
||||
this->my_spi, this->protocol, this->reqid, this->mode,
|
||||
this->ipcomp, this->my_cpi, routed);
|
||||
}
|
||||
|
||||
if (status != SUCCESS)
|
||||
|
@ -634,32 +566,18 @@ static status_t add_policies(private_child_sa_t *this,
|
|||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
if (status == SUCCESS)
|
||||
{
|
||||
/* switch to routed state if no SAD entry set up */
|
||||
if (this->state == CHILD_CREATED)
|
||||
{
|
||||
set_state(this, CHILD_ROUTED);
|
||||
}
|
||||
/* needed to update hosts */
|
||||
this->mode = mode;
|
||||
if (status == SUCCESS && this->state == CHILD_CREATED)
|
||||
{ /* switch to routed state if no SAD entry set up */
|
||||
set_state(this, CHILD_ROUTED);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.get_traffic_selectors.
|
||||
* Implementation of child_sa_t.update.
|
||||
*/
|
||||
static linked_list_t *get_traffic_selectors(private_child_sa_t *this, bool local)
|
||||
{
|
||||
return local ? this->my_ts : this->other_ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.update_hosts.
|
||||
*/
|
||||
static status_t update_hosts(private_child_sa_t *this,
|
||||
host_t *me, host_t *other, host_t *vip, bool encap)
|
||||
static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
|
||||
host_t *vip, bool encap)
|
||||
{
|
||||
child_sa_state_t old;
|
||||
bool transport_proxy_mode;
|
||||
|
@ -791,30 +709,6 @@ static status_t update_hosts(private_child_sa_t *this,
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.activate_ipcomp.
|
||||
*/
|
||||
static void activate_ipcomp(private_child_sa_t *this, ipcomp_transform_t ipcomp,
|
||||
u_int16_t other_cpi)
|
||||
{
|
||||
this->ipcomp = ipcomp;
|
||||
this->other_cpi = other_cpi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.allocate_cpi.
|
||||
*/
|
||||
static u_int16_t allocate_cpi(private_child_sa_t *this)
|
||||
{
|
||||
if (!this->cpi_allocated)
|
||||
{
|
||||
charon->kernel_interface->get_cpi(charon->kernel_interface,
|
||||
this->other_addr, this->my_addr, this->reqid, &this->my_cpi);
|
||||
this->cpi_allocated = TRUE;
|
||||
}
|
||||
return this->my_cpi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_sa_t.destroy.
|
||||
*/
|
||||
|
@ -833,16 +727,6 @@ static void destroy(private_child_sa_t *this)
|
|||
this->my_addr, this->my_spi, this->protocol,
|
||||
this->my_cpi);
|
||||
}
|
||||
if (this->alloc_esp_spi && this->alloc_esp_spi != this->my_spi)
|
||||
{
|
||||
charon->kernel_interface->del_sa(charon->kernel_interface,
|
||||
this->my_addr, this->alloc_esp_spi, PROTO_ESP, 0);
|
||||
}
|
||||
if (this->alloc_ah_spi && this->alloc_ah_spi != this->my_spi)
|
||||
{
|
||||
charon->kernel_interface->del_sa(charon->kernel_interface,
|
||||
this->my_addr, this->alloc_ah_spi, PROTO_AH, 0);
|
||||
}
|
||||
if (this->other_spi)
|
||||
{
|
||||
charon->kernel_interface->del_sa(charon->kernel_interface,
|
||||
|
@ -890,40 +774,39 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
|||
/* public functions */
|
||||
this->public.get_name = (char*(*)(child_sa_t*))get_name;
|
||||
this->public.get_reqid = (u_int32_t(*)(child_sa_t*))get_reqid;
|
||||
this->public.get_config = (child_cfg_t*(*)(child_sa_t*))get_config;
|
||||
this->public.get_state = (child_sa_state_t(*)(child_sa_t*))get_state;
|
||||
this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state;
|
||||
this->public.get_spi = (u_int32_t(*)(child_sa_t*, bool))get_spi;
|
||||
this->public.get_cpi = (u_int16_t(*)(child_sa_t*, bool))get_cpi;
|
||||
this->public.get_protocol = (protocol_id_t(*)(child_sa_t*))get_protocol;
|
||||
this->public.set_protocol = (void(*)(child_sa_t*, protocol_id_t protocol))set_protocol;
|
||||
this->public.get_mode = (ipsec_mode_t(*)(child_sa_t*))get_mode;
|
||||
this->public.get_ipcomp = (ipcomp_transform_t(*)(child_sa_t*))get_ipcomp;
|
||||
this->public.has_encap = (bool(*)(child_sa_t*))has_encap;
|
||||
this->public.set_mode = (void(*)(child_sa_t*, ipsec_mode_t mode))set_mode;
|
||||
this->public.get_proposal = (proposal_t*(*)(child_sa_t*))get_proposal;
|
||||
this->public.set_proposal = (void(*)(child_sa_t*, proposal_t *proposal))set_proposal;
|
||||
this->public.get_lifetime = (u_int32_t(*)(child_sa_t*, bool))get_lifetime;
|
||||
this->public.get_usetime = (u_int32_t(*)(child_sa_t*, bool))get_usetime;
|
||||
this->public.alloc = (status_t(*)(child_sa_t*,linked_list_t*))alloc;
|
||||
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,ipsec_mode_t,chunk_t,chunk_t,chunk_t,chunk_t))add;
|
||||
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,ipsec_mode_t,chunk_t,chunk_t,chunk_t,chunk_t))update;
|
||||
this->public.get_proposal = (proposal_t*(*)(child_sa_t*))get_proposal;
|
||||
this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,host_t*,bool))update_hosts;
|
||||
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*,ipsec_mode_t,protocol_id_t))add_policies;
|
||||
this->public.has_encap = (bool(*)(child_sa_t*))has_encap;
|
||||
this->public.get_ipcomp = (ipcomp_transform_t(*)(child_sa_t*))get_ipcomp;
|
||||
this->public.set_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t))set_ipcomp;
|
||||
this->public.alloc_spi = (u_int32_t(*)(child_sa_t*, protocol_id_t protocol))alloc_spi;
|
||||
this->public.alloc_cpi = (u_int16_t(*)(child_sa_t*))alloc_cpi;
|
||||
this->public.install = (status_t(*)(child_sa_t*, chunk_t encr, chunk_t integ, u_int32_t spi, u_int16_t cpi, bool inbound))install;
|
||||
this->public.update = (status_t (*)(child_sa_t*,host_t*,host_t*,host_t*,bool))update;
|
||||
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*))add_policies;
|
||||
this->public.get_traffic_selectors = (linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors;
|
||||
this->public.create_policy_enumerator = (enumerator_t*(*)(child_sa_t*))create_policy_enumerator;
|
||||
this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state;
|
||||
this->public.get_state = (child_sa_state_t(*)(child_sa_t*))get_state;
|
||||
this->public.get_config = (child_cfg_t*(*)(child_sa_t*))get_config;
|
||||
this->public.activate_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t,u_int16_t))activate_ipcomp;
|
||||
this->public.allocate_cpi = (u_int16_t(*)(child_sa_t*))allocate_cpi;
|
||||
this->public.destroy = (void(*)(child_sa_t*))destroy;
|
||||
|
||||
|
||||
/* private data */
|
||||
this->my_addr = me->clone(me);
|
||||
this->other_addr = other->clone(other);
|
||||
this->my_spi = 0;
|
||||
this->my_cpi = 0;
|
||||
this->other_spi = 0;
|
||||
this->my_cpi = 0;
|
||||
this->other_cpi = 0;
|
||||
this->alloc_ah_spi = 0;
|
||||
this->alloc_esp_spi = 0;
|
||||
this->encap = encap;
|
||||
this->cpi_allocated = FALSE;
|
||||
this->ipcomp = IPCOMP_NONE;
|
||||
this->state = CHILD_CREATED;
|
||||
/* reuse old reqid if we are rekeying an existing CHILD_SA */
|
||||
|
@ -935,7 +818,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
|||
this->proposal = NULL;
|
||||
this->config = config;
|
||||
config->get_ref(config);
|
||||
|
||||
|
||||
/* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
|
||||
if (config->get_mode(config) == MODE_TRANSPORT &&
|
||||
config->use_proxy_mode(config))
|
||||
|
@ -947,9 +830,9 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
|||
enumerator_t *enumerator;
|
||||
linked_list_t *my_ts_list, *other_ts_list;
|
||||
traffic_selector_t *my_ts, *other_ts;
|
||||
|
||||
|
||||
this->mode = MODE_TRANSPORT;
|
||||
|
||||
|
||||
my_ts_list = config->get_traffic_selectors(config, TRUE, NULL, me);
|
||||
enumerator = my_ts_list->create_enumerator(my_ts_list);
|
||||
if (enumerator->enumerate(enumerator, &my_ts))
|
||||
|
@ -970,7 +853,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
|||
}
|
||||
enumerator->destroy(enumerator);
|
||||
my_ts_list->destroy_offset(my_ts_list, offsetof(traffic_selector_t, destroy));
|
||||
|
||||
|
||||
other_ts_list = config->get_traffic_selectors(config, FALSE, NULL, other);
|
||||
enumerator = other_ts_list->create_enumerator(other_ts_list);
|
||||
if (enumerator->enumerate(enumerator, &other_ts))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2006-2008 Tobias Brunner
|
||||
* Copyright (C) 2006-2007 Martin Willi
|
||||
* Copyright (C) 2006-2008 Martin Willi
|
||||
* Copyright (C) 2006 Daniel Roethlisberger
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
|
@ -93,12 +93,13 @@ extern enum_name_t *child_sa_state_names;
|
|||
* SAs and the policies have the same reqid.
|
||||
*
|
||||
* The procedure for child sa setup is as follows:
|
||||
* - A gets SPIs for a proposal via child_sa_t.alloc
|
||||
* - A send the updated proposal to B
|
||||
* - A gets SPIs for a all protocols in its proposals via child_sa_t.alloc
|
||||
* - A send the proposals with the allocated SPIs to B
|
||||
* - B selects a suitable proposal
|
||||
* - B calls child_sa_t.add to add and update the selected proposal
|
||||
* - B sends the updated proposal to A
|
||||
* - A calls child_sa_t.update to update the already allocated SPIs with the chosen proposal
|
||||
* - B allocates an SPI for the selected protocol
|
||||
* - B calls child_sa_t.install for both, the allocated and received SPI
|
||||
* - B sends the proposal with the allocated SPI to A
|
||||
* - A calls child_sa_t.install for both, the allocated and recevied SPI
|
||||
*
|
||||
* Once SAs are set up, policies can be added using add_policies.
|
||||
*/
|
||||
|
@ -121,6 +122,27 @@ struct child_sa_t {
|
|||
*/
|
||||
u_int32_t (*get_reqid)(child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Get the config used to set up this child sa.
|
||||
*
|
||||
* @return child_cfg
|
||||
*/
|
||||
child_cfg_t* (*get_config) (child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Get the state of the CHILD_SA.
|
||||
*
|
||||
* @return CHILD_SA state
|
||||
*/
|
||||
child_sa_state_t (*get_state) (child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Set the state of the CHILD_SA.
|
||||
*
|
||||
* @param state state to set on CHILD_SA
|
||||
*/
|
||||
void (*set_state) (child_sa_t *this, child_sa_state_t state);
|
||||
|
||||
/**
|
||||
* Get the SPI of this CHILD_SA.
|
||||
*
|
||||
|
@ -152,6 +174,13 @@ struct child_sa_t {
|
|||
*/
|
||||
protocol_id_t (*get_protocol) (child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Set the negotiated protocol to use for this CHILD_SA.
|
||||
*
|
||||
* @param protocol AH | ESP
|
||||
*/
|
||||
void (*set_protocol)(child_sa_t *this, protocol_id_t protocol);
|
||||
|
||||
/**
|
||||
* Get the IPsec mode of this CHILD_SA.
|
||||
*
|
||||
|
@ -159,6 +188,13 @@ struct child_sa_t {
|
|||
*/
|
||||
ipsec_mode_t (*get_mode)(child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Set the negotiated IPsec mode to use.
|
||||
*
|
||||
* @param mode TUNNEL | TRANPORT | BEET
|
||||
*/
|
||||
void (*set_mode)(child_sa_t *this, ipsec_mode_t mode);
|
||||
|
||||
/**
|
||||
* Get the used IPComp algorithm.
|
||||
*
|
||||
|
@ -166,6 +202,27 @@ struct child_sa_t {
|
|||
*/
|
||||
ipcomp_transform_t (*get_ipcomp)(child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Set the IPComp algorithm to use.
|
||||
*
|
||||
* @param ipcomp the IPComp transform to use
|
||||
*/
|
||||
void (*set_ipcomp)(child_sa_t *this, ipcomp_transform_t ipcomp);
|
||||
|
||||
/**
|
||||
* Get the selected proposal.
|
||||
*
|
||||
* @return selected proposal
|
||||
*/
|
||||
proposal_t* (*get_proposal)(child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Set the negotiated proposal.
|
||||
*
|
||||
* @param proposal selected proposal
|
||||
*/
|
||||
void (*set_proposal)(child_sa_t *this, proposal_t *proposal);
|
||||
|
||||
/**
|
||||
* Check if this CHILD_SA uses UDP encapsulation.
|
||||
*
|
||||
|
@ -190,87 +247,7 @@ struct child_sa_t {
|
|||
u_int32_t (*get_usetime)(child_sa_t *this, bool inbound);
|
||||
|
||||
/**
|
||||
* Allocate SPIs for given proposals.
|
||||
*
|
||||
* Since the kernel manages SPIs for us, we need
|
||||
* to allocate them. If a proposal contains more
|
||||
* than one protocol, for each protocol an SPI is
|
||||
* allocated. SPIs are stored internally and written
|
||||
* back to the proposal.
|
||||
*
|
||||
* @param proposals list of proposals for which SPIs are allocated
|
||||
*/
|
||||
status_t (*alloc)(child_sa_t *this, linked_list_t* proposals);
|
||||
|
||||
/**
|
||||
* Install the kernel SAs for a proposal, without previous SPI allocation.
|
||||
*
|
||||
* @param proposal proposal for which SPIs are allocated
|
||||
* @param mode mode for the CHILD_SA
|
||||
* @param integ_in integrity key for inbound traffic
|
||||
* @param integ_out integrity key for outbound traffic
|
||||
* @param encr_in encryption key for inbound traffic
|
||||
* @param enc_out encryption key for outbound traffic
|
||||
* @return SUCCESS or FAILED
|
||||
*/
|
||||
status_t (*add)(child_sa_t *this, proposal_t *proposal, ipsec_mode_t mode,
|
||||
chunk_t integ_in, chunk_t integ_out,
|
||||
chunk_t encr_in, chunk_t encr_out);
|
||||
/**
|
||||
* Install the kernel SAs for a proposal, after SPIs have been allocated.
|
||||
*
|
||||
* Updates an SA, for which SPIs are already allocated via alloc().
|
||||
*
|
||||
* @param proposal proposal for which SPIs are allocated
|
||||
* @param mode mode for the CHILD_SA
|
||||
* @param integ_in integrity key for inbound traffic
|
||||
* @param integ_out integrity key for outbound traffic
|
||||
* @param encr_in encryption key for inbound traffic
|
||||
* @param enc_out encryption key for outbound traffic
|
||||
* @return SUCCESS or FAILED
|
||||
*/
|
||||
status_t (*update)(child_sa_t *this, proposal_t *proposal, ipsec_mode_t mode,
|
||||
chunk_t integ_in, chunk_t integ_out,
|
||||
chunk_t encr_in, chunk_t encr_out);
|
||||
/**
|
||||
* Get the selected proposal passed to add()/update().
|
||||
*
|
||||
* @return selected proposal
|
||||
*/
|
||||
proposal_t* (*get_proposal)(child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Update the hosts in the kernel SAs and policies.
|
||||
*
|
||||
* The CHILD must be INSTALLED to do this update.
|
||||
*
|
||||
* @param me the new local host
|
||||
* @param other the new remote host
|
||||
* @param vip virtual IP, if any
|
||||
* @param TRUE to use UDP encapsulation for NAT traversal
|
||||
* @return SUCCESS or FAILED
|
||||
*/
|
||||
status_t (*update_hosts)(child_sa_t *this, host_t *me, host_t *other,
|
||||
host_t *vip, bool encap);
|
||||
|
||||
/**
|
||||
* Install the policies using some traffic selectors.
|
||||
*
|
||||
* Supplied lists of traffic_selector_t's specify the policies
|
||||
* to use for this child sa.
|
||||
*
|
||||
* @param my_ts traffic selectors for local site
|
||||
* @param other_ts traffic selectors for remote site
|
||||
* @param mode mode for the SA: tunnel/transport
|
||||
* @param proto protocol for policy, ESP/AH
|
||||
* @return SUCCESS or FAILED
|
||||
*/
|
||||
status_t (*add_policies)(child_sa_t *this, linked_list_t *my_ts_list,
|
||||
linked_list_t *other_ts_list, ipsec_mode_t mode,
|
||||
protocol_id_t proto);
|
||||
|
||||
/**
|
||||
* Get the traffic selectors of added policies of local host.
|
||||
* Get the traffic selectors list added for one side.
|
||||
*
|
||||
* @param local TRUE for own traffic selectors, FALSE for remote
|
||||
* @return list of traffic selectors
|
||||
|
@ -285,40 +262,56 @@ struct child_sa_t {
|
|||
enumerator_t* (*create_policy_enumerator)(child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Get the state of the CHILD_SA.
|
||||
*/
|
||||
child_sa_state_t (*get_state) (child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Set the state of the CHILD_SA.
|
||||
* Allocate an SPI to include in a proposal.
|
||||
*
|
||||
* @param state state to set on CHILD_SA
|
||||
*/
|
||||
void (*set_state) (child_sa_t *this, child_sa_state_t state);
|
||||
* @param protocol protocol to allocate SPI for (ESP|AH)
|
||||
* @param spi SPI output pointer
|
||||
* @return SPI, 0 on failure
|
||||
*/
|
||||
u_int32_t (*alloc_spi)(child_sa_t *this, protocol_id_t protocol);
|
||||
|
||||
/**
|
||||
* Get the config used to set up this child sa.
|
||||
* Allocate a CPI to use for IPComp.
|
||||
*
|
||||
* @return child_cfg
|
||||
* @return CPI, 0 on failure
|
||||
*/
|
||||
child_cfg_t* (*get_config) (child_sa_t *this);
|
||||
u_int16_t (*alloc_cpi)(child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Activate IPComp by setting the transform ID and CPI values.
|
||||
*
|
||||
* @param ipcomp the IPComp transform to use
|
||||
* @param other_cpi other Compression Parameter Index
|
||||
* Install an IPsec SA for one direction.
|
||||
*
|
||||
* @param encr encryption key, if any
|
||||
* @param integ integrity key
|
||||
* @param spi SPI to use, allocated for inbound
|
||||
* @param cpi CPI to use, allocated for outbound
|
||||
* @param inbound TRUE to install an inbound SA, FALSE for outbound
|
||||
* @return SUCCESS or FAILED
|
||||
*/
|
||||
void (*activate_ipcomp) (child_sa_t *this, ipcomp_transform_t ipcomp,
|
||||
u_int16_t other_cpi);
|
||||
|
||||
status_t (*install)(child_sa_t *this, chunk_t encr, chunk_t integ,
|
||||
u_int32_t spi, u_int16_t cpi, bool inbound);
|
||||
/**
|
||||
* Returns the Compression Parameter Index (CPI) allocated from the kernel.
|
||||
*
|
||||
* @return allocated CPI
|
||||
* Install the policies using some traffic selectors.
|
||||
*
|
||||
* Supplied lists of traffic_selector_t's specify the policies
|
||||
* to use for this child sa.
|
||||
*
|
||||
* @param my_ts traffic selectors for local site
|
||||
* @param other_ts traffic selectors for remote site
|
||||
* @return SUCCESS or FAILED
|
||||
*/
|
||||
status_t (*add_policies)(child_sa_t *this, linked_list_t *my_ts_list,
|
||||
linked_list_t *other_ts_list);
|
||||
/**
|
||||
* Update hosts and ecapulation mode in the kernel SAs and policies.
|
||||
*
|
||||
* @param me the new local host
|
||||
* @param other the new remote host
|
||||
* @param vip virtual IP, if any
|
||||
* @param TRUE to use UDP encapsulation for NAT traversal
|
||||
* @return SUCCESS or FAILED
|
||||
*/
|
||||
u_int16_t (*allocate_cpi) (child_sa_t *this);
|
||||
|
||||
status_t (*update)(child_sa_t *this, host_t *me, host_t *other,
|
||||
host_t *vip, bool encap);
|
||||
/**
|
||||
* Destroys a child_sa.
|
||||
*/
|
||||
|
|
|
@ -874,7 +874,7 @@ static void update_hosts(private_ike_sa_t *this, host_t *me, host_t *other)
|
|||
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)&child_sa))
|
||||
{
|
||||
if (child_sa->update_hosts(child_sa, this->my_host,
|
||||
if (child_sa->update(child_sa, this->my_host,
|
||||
this->other_host, this->my_virtual_ip,
|
||||
has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED)
|
||||
{
|
||||
|
@ -1288,8 +1288,8 @@ static status_t route(private_ike_sa_t *this, child_cfg_t *child_cfg)
|
|||
my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, me);
|
||||
other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, other);
|
||||
|
||||
status = child_sa->add_policies(child_sa, my_ts, other_ts,
|
||||
child_cfg->get_mode(child_cfg), PROTO_NONE);
|
||||
child_sa->set_mode(child_sa, child_cfg->get_mode(child_cfg));
|
||||
status = child_sa->add_policies(child_sa, my_ts, other_ts);
|
||||
|
||||
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
|
||||
other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
|
||||
|
|
|
@ -117,7 +117,22 @@ struct private_child_create_t {
|
|||
ipcomp_transform_t ipcomp_received;
|
||||
|
||||
/**
|
||||
* Other Compression Parameter Index (CPI)
|
||||
* Own allocated SPI
|
||||
*/
|
||||
u_int32_t my_spi;
|
||||
|
||||
/**
|
||||
* SPI received in proposal
|
||||
*/
|
||||
u_int32_t other_spi;
|
||||
|
||||
/**
|
||||
* Own allocated Compression Parameter Index (CPI)
|
||||
*/
|
||||
u_int16_t my_cpi;
|
||||
|
||||
/**
|
||||
* Other Compression Parameter Index (CPI), received via IPCOMP_SUPPORTED
|
||||
*/
|
||||
u_int16_t other_cpi;
|
||||
|
||||
|
@ -188,6 +203,36 @@ static bool ts_list_is_host(linked_list_t *list, host_t *host)
|
|||
return is_host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate SPIs and update proposals
|
||||
*/
|
||||
static bool allocate_spi(private_child_create_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
proposal_t *proposal;
|
||||
|
||||
/* TODO: allocate additional SPI for AH if we have such proposals */
|
||||
this->my_spi = this->child_sa->alloc_spi(this->child_sa, PROTO_ESP);
|
||||
if (this->my_spi)
|
||||
{
|
||||
if (this->initiator)
|
||||
{
|
||||
enumerator = this->proposals->create_enumerator(this->proposals);
|
||||
while (enumerator->enumerate(enumerator, &proposal))
|
||||
{
|
||||
proposal->set_spi(proposal, this->my_spi);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->proposal->set_spi(this->proposal, this->my_spi);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a CHILD_SA for usage, return value:
|
||||
* - FAILED: no acceptable proposal
|
||||
|
@ -216,7 +261,7 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
|
|||
other = this->ike_sa->get_other_host(this->ike_sa);
|
||||
my_vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
|
||||
other_vip = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
|
||||
|
||||
|
||||
this->proposal = this->config->select_proposal(this->config, this->proposals,
|
||||
no_dh);
|
||||
if (this->proposal == NULL)
|
||||
|
@ -224,6 +269,14 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
|
|||
DBG1(DBG_IKE, "no acceptable proposal found");
|
||||
return FAILED;
|
||||
}
|
||||
this->other_spi = this->proposal->get_spi(this->proposal);
|
||||
|
||||
if (!this->initiator && !allocate_spi(this))
|
||||
{ /* responder has no SPI allocated yet */
|
||||
DBG1(DBG_IKE, "allocating SPI failed");
|
||||
return FAILED;
|
||||
}
|
||||
this->child_sa->set_proposal(this->child_sa, this->proposal);
|
||||
|
||||
if (!this->proposal->has_dh_group(this->proposal, this->dh_group))
|
||||
{
|
||||
|
@ -328,26 +381,33 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
|
|||
}
|
||||
|
||||
this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
|
||||
this->child_sa->set_ipcomp(this->child_sa, this->ipcomp);
|
||||
this->child_sa->set_mode(this->child_sa, this->mode);
|
||||
this->child_sa->set_protocol(this->child_sa,
|
||||
this->proposal->get_protocol(this->proposal));
|
||||
|
||||
if (this->ipcomp != IPCOMP_NONE)
|
||||
if (this->my_cpi == 0 || this->other_cpi == 0 || this->ipcomp == IPCOMP_NONE)
|
||||
{
|
||||
this->child_sa->activate_ipcomp(this->child_sa, this->ipcomp,
|
||||
this->other_cpi);
|
||||
this->my_cpi = this->other_cpi = 0;
|
||||
this->ipcomp = IPCOMP_NONE;
|
||||
}
|
||||
|
||||
status = FAILED;
|
||||
if (this->keymat->derive_child_keys(this->keymat, this->proposal,
|
||||
this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
|
||||
{
|
||||
if (this->initiator)
|
||||
{
|
||||
status = this->child_sa->update(this->child_sa, this->proposal,
|
||||
this->mode, integ_r, integ_i, encr_r, encr_i);
|
||||
status = this->child_sa->install(this->child_sa, encr_r, integ_r,
|
||||
this->my_spi, this->my_cpi, TRUE);
|
||||
status = this->child_sa->install(this->child_sa, encr_i, integ_i,
|
||||
this->other_spi, this->other_cpi, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = this->child_sa->add(this->child_sa, this->proposal,
|
||||
this->mode, integ_i, integ_r, encr_i, encr_r);
|
||||
status = this->child_sa->install(this->child_sa, encr_i, integ_i,
|
||||
this->my_spi, this->my_cpi, TRUE);
|
||||
status = this->child_sa->install(this->child_sa, encr_r, integ_r,
|
||||
this->other_spi, this->other_cpi, FALSE);
|
||||
}
|
||||
}
|
||||
chunk_clear(&integ_i);
|
||||
|
@ -361,8 +421,7 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
|
|||
return FAILED;
|
||||
}
|
||||
|
||||
status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts,
|
||||
this->mode, this->proposal->get_protocol(this->proposal));
|
||||
status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel");
|
||||
|
@ -436,33 +495,71 @@ static void build_payloads(private_child_create_t *this, message_t *message)
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds an IPCOMP_SUPPORTED notify to the message, if possible
|
||||
* Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
|
||||
*/
|
||||
static void build_ipcomp_supported_notify(private_child_create_t *this,
|
||||
message_t *message)
|
||||
static void add_ipcomp_notify(private_child_create_t *this,
|
||||
message_t *message, u_int8_t ipcomp)
|
||||
{
|
||||
u_int16_t cpi;
|
||||
u_int8_t tid;
|
||||
|
||||
if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
|
||||
{
|
||||
DBG1(DBG_IKE, "IPComp is not supported if either peer is natted, "
|
||||
"IPComp disabled");
|
||||
this->ipcomp = IPCOMP_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
cpi = this->child_sa->allocate_cpi(this->child_sa);
|
||||
tid = this->ipcomp;
|
||||
if (cpi)
|
||||
this->my_cpi = this->child_sa->alloc_cpi(this->child_sa);
|
||||
if (this->my_cpi)
|
||||
{
|
||||
message->add_notify(message, FALSE, IPCOMP_SUPPORTED,
|
||||
chunk_cata("cc", chunk_from_thing(cpi), chunk_from_thing(tid)));
|
||||
this->ipcomp = ipcomp;
|
||||
message->add_notify(message, FALSE, IPCOMP_SUPPORTED,
|
||||
chunk_cata("cc", chunk_from_thing(this->my_cpi),
|
||||
chunk_from_thing(ipcomp)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IKE, "unable to allocate a CPI from kernel, IPComp disabled");
|
||||
this->ipcomp = IPCOMP_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle a received notify payload
|
||||
*/
|
||||
static void handle_notify(private_child_create_t *this, notify_payload_t *notify)
|
||||
{
|
||||
switch (notify->get_notify_type(notify))
|
||||
{
|
||||
case USE_TRANSPORT_MODE:
|
||||
this->mode = MODE_TRANSPORT;
|
||||
break;
|
||||
case USE_BEET_MODE:
|
||||
this->mode = MODE_BEET;
|
||||
break;
|
||||
case IPCOMP_SUPPORTED:
|
||||
{
|
||||
ipcomp_transform_t ipcomp;
|
||||
u_int16_t cpi;
|
||||
chunk_t data;
|
||||
|
||||
data = notify->get_notification_data(notify);
|
||||
cpi = *(u_int16_t*)data.ptr;
|
||||
ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
|
||||
switch (ipcomp)
|
||||
{
|
||||
case IPCOMP_DEFLATE:
|
||||
this->other_cpi = cpi;
|
||||
this->ipcomp_received = ipcomp;
|
||||
break;
|
||||
case IPCOMP_LZS:
|
||||
case IPCOMP_LZJH:
|
||||
default:
|
||||
DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a "
|
||||
"transform ID we don't support %N",
|
||||
ipcomp_transform_names, ipcomp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -476,7 +573,6 @@ static void process_payloads(private_child_create_t *this, message_t *message)
|
|||
sa_payload_t *sa_payload;
|
||||
ke_payload_t *ke_payload;
|
||||
ts_payload_t *ts_payload;
|
||||
notify_payload_t *notify_payload;
|
||||
|
||||
/* defaults to TUNNEL mode */
|
||||
this->mode = MODE_TUNNEL;
|
||||
|
@ -512,37 +608,7 @@ static void process_payloads(private_child_create_t *this, message_t *message)
|
|||
this->tsr = ts_payload->get_traffic_selectors(ts_payload);
|
||||
break;
|
||||
case NOTIFY:
|
||||
notify_payload = (notify_payload_t*)payload;
|
||||
switch (notify_payload ->get_notify_type(notify_payload ))
|
||||
{
|
||||
case USE_TRANSPORT_MODE:
|
||||
this->mode = MODE_TRANSPORT;
|
||||
break;
|
||||
case USE_BEET_MODE:
|
||||
this->mode = MODE_BEET;
|
||||
break;
|
||||
case IPCOMP_SUPPORTED:
|
||||
{
|
||||
chunk_t data = notify_payload->get_notification_data(notify_payload);
|
||||
u_int16_t cpi = *(u_int16_t*)data.ptr;
|
||||
ipcomp_transform_t ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
|
||||
switch(ipcomp)
|
||||
{
|
||||
case IPCOMP_DEFLATE:
|
||||
this->other_cpi = cpi;
|
||||
this->ipcomp_received = ipcomp;
|
||||
break;
|
||||
case IPCOMP_LZS:
|
||||
case IPCOMP_LZJH:
|
||||
default:
|
||||
DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a transform"
|
||||
" ID we don't support %N", ipcomp_transform_names, ipcomp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
handle_notify(this, (notify_payload_t*)payload);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -559,7 +625,7 @@ static status_t build_i(private_child_create_t *this, message_t *message)
|
|||
host_t *me, *other, *vip;
|
||||
bool propose_all = FALSE;
|
||||
peer_cfg_t *peer_cfg;
|
||||
|
||||
|
||||
switch (message->get_exchange_type(message))
|
||||
{
|
||||
case IKE_SA_INIT:
|
||||
|
@ -641,7 +707,7 @@ static status_t build_i(private_child_create_t *this, message_t *message)
|
|||
this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
|
||||
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
|
||||
|
||||
if (this->child_sa->alloc(this->child_sa, this->proposals) != SUCCESS)
|
||||
if (!allocate_spi(this))
|
||||
{
|
||||
DBG1(DBG_IKE, "unable to allocate SPIs from kernel");
|
||||
return FAILED;
|
||||
|
@ -652,10 +718,10 @@ static status_t build_i(private_child_create_t *this, message_t *message)
|
|||
this->dh = this->keymat->create_dh(this->keymat, this->dh_group);
|
||||
}
|
||||
|
||||
if (this->config->use_ipcomp(this->config)) {
|
||||
if (this->config->use_ipcomp(this->config))
|
||||
{
|
||||
/* IPCOMP_DEFLATE is the only transform we support at the moment */
|
||||
this->ipcomp = IPCOMP_DEFLATE;
|
||||
build_ipcomp_supported_notify(this, message);
|
||||
add_ipcomp_notify(this, message, IPCOMP_DEFLATE);
|
||||
}
|
||||
|
||||
build_payloads(this, message);
|
||||
|
@ -821,16 +887,17 @@ static status_t build_r(private_child_create_t *this, message_t *message)
|
|||
this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
|
||||
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
|
||||
|
||||
if (this->config->use_ipcomp(this->config) &&
|
||||
this->ipcomp_received != IPCOMP_NONE)
|
||||
if (this->ipcomp_received != IPCOMP_NONE)
|
||||
{
|
||||
this->ipcomp = this->ipcomp_received;
|
||||
build_ipcomp_supported_notify(this, message);
|
||||
}
|
||||
else if (this->ipcomp_received != IPCOMP_NONE)
|
||||
{
|
||||
DBG1(DBG_IKE, "received %N notify but IPComp is disabled, ignoring",
|
||||
notify_type_names, IPCOMP_SUPPORTED);
|
||||
if (this->config->use_ipcomp(this->config))
|
||||
{
|
||||
add_ipcomp_notify(this, message, this->ipcomp_received);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IKE, "received %N notify but IPComp is disabled, ignoring",
|
||||
notify_type_names, IPCOMP_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
switch (select_and_install(this, no_dh))
|
||||
|
@ -1137,6 +1204,9 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config)
|
|||
this->mode = MODE_TUNNEL;
|
||||
this->ipcomp = IPCOMP_NONE;
|
||||
this->ipcomp_received = IPCOMP_NONE;
|
||||
this->my_spi = 0;
|
||||
this->other_spi = 0;
|
||||
this->my_cpi = 0;
|
||||
this->other_cpi = 0;
|
||||
this->reqid = 0;
|
||||
this->established = FALSE;
|
||||
|
|
|
@ -251,7 +251,7 @@ static void update_children(private_ike_mobike_t *this)
|
|||
iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa);
|
||||
while (iterator->iterate(iterator, (void**)&child_sa))
|
||||
{
|
||||
if (child_sa->update_hosts(child_sa,
|
||||
if (child_sa->update(child_sa,
|
||||
this->ike_sa->get_my_host(this->ike_sa),
|
||||
this->ike_sa->get_other_host(this->ike_sa),
|
||||
this->ike_sa->get_virtual_ip(this->ike_sa, TRUE),
|
||||
|
|
Loading…
Reference in New Issue