further mobike improvements, regarding to NAT-T
This commit is contained in:
@@ -138,9 +138,9 @@ struct private_child_sa_t {
|
||||
child_sa_state_t state;
|
||||
|
||||
/**
|
||||
* Specifies if NAT traversal is used
|
||||
* Specifies if UDP encapsulation is enabled (NAT traversal)
|
||||
*/
|
||||
bool use_natt;
|
||||
bool encap;
|
||||
|
||||
/**
|
||||
* mode this SA uses, tunnel/transport
|
||||
@@ -494,7 +494,6 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal,
|
||||
algorithm_t int_algo_none = {AUTH_UNDEFINED, 0};
|
||||
host_t *src;
|
||||
host_t *dst;
|
||||
natt_conf_t *natt;
|
||||
status_t status;
|
||||
|
||||
this->protocol = proposal->get_protocol(proposal);
|
||||
@@ -561,18 +560,6 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal,
|
||||
int_algo = &int_algo_none;
|
||||
}
|
||||
|
||||
/* setup nat-t */
|
||||
if (this->use_natt)
|
||||
{
|
||||
natt = alloca(sizeof(natt_conf_t));
|
||||
natt->sport = src->get_port(src);
|
||||
natt->dport = dst->get_port(dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
natt = NULL;
|
||||
}
|
||||
|
||||
soft = this->config->get_lifetime(this->config, TRUE);
|
||||
hard = this->config->get_lifetime(this->config, FALSE);
|
||||
|
||||
@@ -582,7 +569,7 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal,
|
||||
src, dst, spi, this->protocol,
|
||||
this->reqid, mine ? soft : 0,
|
||||
hard, enc_algo, int_algo,
|
||||
prf_plus, natt, mode, mine);
|
||||
prf_plus, mode, this->encap, mine);
|
||||
|
||||
this->encryption = *enc_algo;
|
||||
this->integrity = *int_algo;
|
||||
@@ -784,7 +771,8 @@ static status_t get_use_time(private_child_sa_t *this, bool inbound, time_t *use
|
||||
/**
|
||||
* Implementation of child_sa_t.update_hosts.
|
||||
*/
|
||||
static status_t update_hosts(private_child_sa_t *this, host_t *me, host_t *other)
|
||||
static status_t update_hosts(private_child_sa_t *this,
|
||||
host_t *me, host_t *other, bool encap)
|
||||
{
|
||||
/* anything changed at all? */
|
||||
if (me->equals(me, this->me.addr) && other->equals(other, this->other.addr))
|
||||
@@ -937,7 +925,7 @@ static void destroy(private_child_sa_t *this)
|
||||
*/
|
||||
child_sa_t * child_sa_create(host_t *me, host_t* other,
|
||||
identification_t *my_id, identification_t *other_id,
|
||||
child_cfg_t *config, u_int32_t rekey, bool use_natt)
|
||||
child_cfg_t *config, u_int32_t rekey, bool encap)
|
||||
{
|
||||
static u_int32_t reqid = 0;
|
||||
private_child_sa_t *this = malloc_thing(private_child_sa_t);
|
||||
@@ -951,7 +939,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
||||
this->public.alloc = (status_t(*)(child_sa_t*,linked_list_t*))alloc;
|
||||
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,mode_t,prf_plus_t*))add;
|
||||
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,mode_t,prf_plus_t*))update;
|
||||
this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*))update_hosts;
|
||||
this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,bool))update_hosts;
|
||||
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*,mode_t))add_policies;
|
||||
this->public.get_traffic_selectors = (linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors;
|
||||
this->public.get_use_time = (status_t (*)(child_sa_t*,bool,time_t*))get_use_time;
|
||||
@@ -970,7 +958,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
||||
this->other.spi = 0;
|
||||
this->alloc_ah_spi = 0;
|
||||
this->alloc_esp_spi = 0;
|
||||
this->use_natt = use_natt;
|
||||
this->encap = encap;
|
||||
this->state = CHILD_CREATED;
|
||||
/* reuse old reqid if we are rekeying an existing CHILD_SA */
|
||||
this->reqid = rekey ? rekey : ++reqid;
|
||||
|
||||
@@ -34,11 +34,6 @@ typedef struct child_sa_t child_sa_t;
|
||||
#include <config/proposal.h>
|
||||
#include <config/child_cfg.h>
|
||||
|
||||
/**
|
||||
* Where we should start with reqid enumeration
|
||||
*/
|
||||
#define REQID_START 2000000000
|
||||
|
||||
/**
|
||||
* @brief States of a CHILD_SA
|
||||
*/
|
||||
@@ -207,9 +202,11 @@ struct child_sa_t {
|
||||
* @param this calling object
|
||||
* @param me the new local host
|
||||
* @param other the new remote host
|
||||
* @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);
|
||||
status_t (*update_hosts)(child_sa_t *this, host_t *me, host_t *other,
|
||||
bool encap);
|
||||
|
||||
/**
|
||||
* @brief Install the policies using some traffic selectors.
|
||||
@@ -295,13 +292,13 @@ struct child_sa_t {
|
||||
* @param other_id id of remote peer
|
||||
* @param config config to use for this CHILD_SA
|
||||
* @param reqid reqid of old CHILD_SA when rekeying, 0 otherwise
|
||||
* @param use_natt TRUE if NAT traversal is used
|
||||
* @param encap TRUE to enable UDP encapsulation (NAT traversal)
|
||||
* @return child_sa_t object
|
||||
*
|
||||
* @ingroup sa
|
||||
*/
|
||||
child_sa_t * child_sa_create(host_t *me, host_t *other,
|
||||
identification_t *my_id, identification_t* other_id,
|
||||
child_cfg_t *config, u_int32_t reqid, bool use_natt);
|
||||
child_cfg_t *config, u_int32_t reqid, bool encap);
|
||||
|
||||
#endif /*CHILD_SA_H_*/
|
||||
|
||||
+10
-3
@@ -469,6 +469,7 @@ static void set_condition(private_ike_sa_t *this, ike_condition_t condition,
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
this->conditions |= condition;
|
||||
switch (condition)
|
||||
{
|
||||
case COND_STALE:
|
||||
@@ -487,19 +488,24 @@ static void set_condition(private_ike_sa_t *this, ike_condition_t condition,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->conditions |= condition;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->conditions &= ~condition;
|
||||
switch (condition)
|
||||
{
|
||||
case COND_STALE:
|
||||
DBG1(DBG_IKE, "new route to %H found", this->other_host);
|
||||
break;
|
||||
case COND_NAT_HERE:
|
||||
case COND_NAT_THERE:
|
||||
set_condition(this, COND_NAT_ANY,
|
||||
has_condition(this, COND_NAT_HERE) ||
|
||||
has_condition(this, COND_NAT_THERE));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->conditions &= ~condition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -695,7 +701,8 @@ 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))
|
||||
{
|
||||
child_sa->update_hosts(child_sa, this->my_host, this->other_host);
|
||||
child_sa->update_hosts(child_sa, this->my_host, this->other_host,
|
||||
has_condition(this, COND_NAT_ANY));
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
||||
@@ -503,6 +503,8 @@ static ike_sa_t* checkout_by_peer(private_ike_sa_manager_t *this,
|
||||
host_t *found_my_host, *found_other_host;
|
||||
int wc;
|
||||
|
||||
break;
|
||||
|
||||
if (!wait_for_entry(this, entry))
|
||||
{
|
||||
continue;
|
||||
|
||||
@@ -143,6 +143,16 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
|
||||
flush_additional_addresses(this);
|
||||
break;
|
||||
}
|
||||
case NAT_DETECTION_SOURCE_IP:
|
||||
case NAT_DETECTION_DESTINATION_IP:
|
||||
{
|
||||
/* NAT check in this MOBIKE exchange, create subtask for it */
|
||||
if (this->natd == NULL)
|
||||
{
|
||||
this->natd = ike_natd_create(this->ike_sa, this->initiator);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -205,10 +215,12 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
|
||||
{ /* address change */
|
||||
message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, chunk_empty);
|
||||
build_address_list(this, message);
|
||||
/* TODO: NAT discovery */
|
||||
|
||||
/* set new addresses */
|
||||
this->ike_sa->update_hosts(this->ike_sa, this->me, this->other);
|
||||
if (this->natd)
|
||||
{
|
||||
this->natd->task.build(&this->natd->task, message);
|
||||
}
|
||||
}
|
||||
|
||||
return NEED_MORE;
|
||||
@@ -219,13 +231,19 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
|
||||
*/
|
||||
static status_t process_r(private_ike_mobike_t *this, message_t *message)
|
||||
{
|
||||
if ((message->get_exchange_type(message) == IKE_AUTH &&
|
||||
message->get_payload(message, SECURITY_ASSOCIATION)) ||
|
||||
message->get_exchange_type(message) == INFORMATIONAL)
|
||||
if (message->get_exchange_type(message) == IKE_AUTH &&
|
||||
message->get_payload(message, SECURITY_ASSOCIATION))
|
||||
{
|
||||
process_payloads(this, message);
|
||||
}
|
||||
|
||||
else if (message->get_exchange_type(message) == INFORMATIONAL)
|
||||
{
|
||||
process_payloads(this, message);
|
||||
if (this->natd)
|
||||
{
|
||||
this->natd->task.process(&this->natd->task, message);
|
||||
}
|
||||
}
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
@@ -246,6 +264,10 @@ static status_t build_r(private_ike_mobike_t *this, message_t *message)
|
||||
}
|
||||
else if (message->get_exchange_type(message) == INFORMATIONAL)
|
||||
{
|
||||
if (this->natd)
|
||||
{
|
||||
this->natd->task.build(&this->natd->task, message);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
return NEED_MORE;
|
||||
@@ -260,10 +282,16 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message)
|
||||
message->get_payload(message, SECURITY_ASSOCIATION))
|
||||
{
|
||||
process_payloads(this, message);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
else if (message->get_exchange_type(message) == INFORMATIONAL)
|
||||
{
|
||||
process_payloads(this, message);
|
||||
if (this->natd)
|
||||
{
|
||||
this->natd->task.process(&this->natd->task, message);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
return NEED_MORE;
|
||||
@@ -276,6 +304,9 @@ static void roam(private_ike_mobike_t *this, host_t *me, host_t *other)
|
||||
{
|
||||
this->me = me;
|
||||
this->other = other;
|
||||
|
||||
/* include NAT detection when roaming */
|
||||
this->natd = ike_natd_create(this->ike_sa, this->initiator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -204,15 +204,11 @@ static void process_payloads(private_ike_natd_t *this, message_t *message)
|
||||
if (this->src_seen && this->dst_seen)
|
||||
{
|
||||
this->ike_sa->enable_extension(this->ike_sa, EXT_NATT);
|
||||
|
||||
if (!this->dst_matched)
|
||||
{
|
||||
this->ike_sa->set_condition(this->ike_sa, COND_NAT_HERE, TRUE);
|
||||
}
|
||||
if (!this->src_matched)
|
||||
{
|
||||
this->ike_sa->set_condition(this->ike_sa, COND_NAT_THERE, TRUE);
|
||||
}
|
||||
|
||||
this->ike_sa->set_condition(this->ike_sa, COND_NAT_HERE,
|
||||
!this->dst_matched);
|
||||
this->ike_sa->set_condition(this->ike_sa, COND_NAT_THERE,
|
||||
!this->src_matched);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,8 +218,11 @@ static void process_payloads(private_ike_natd_t *this, message_t *message)
|
||||
static status_t process_i(private_ike_natd_t *this, message_t *message)
|
||||
{
|
||||
process_payloads(this, message);
|
||||
|
||||
if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
|
||||
|
||||
/* if peer supports NAT-T, we switch to port 4500 even
|
||||
* if no NAT is detected. MOBIKE requires this. */
|
||||
if (message->get_exchange_type(message) == IKE_SA_INIT &&
|
||||
this->ike_sa->supports_extension(this->ike_sa, EXT_NATT))
|
||||
{
|
||||
host_t *me, *other;
|
||||
|
||||
@@ -297,7 +296,8 @@ static status_t build_r(private_ike_natd_t *this, message_t *message)
|
||||
host_t *me, *other;
|
||||
|
||||
/* only add notifies on successfull responses. */
|
||||
if (message->get_payload(message, SECURITY_ASSOCIATION) == NULL)
|
||||
if (message->get_exchange_type(message) == IKE_SA_INIT &&
|
||||
message->get_payload(message, SECURITY_ASSOCIATION) == NULL)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user