further mobike improvements, regarding to NAT-T

This commit is contained in:
Martin Willi
2007-06-27 13:10:55 +00:00
parent 6fa8bd61c1
commit fc2d1c420f
9 changed files with 83 additions and 70 deletions
+1 -1
View File
@@ -372,7 +372,7 @@ static void vsignal(private_bus_t *this, signal_t signal, level_t level,
active_listener->format = format;
va_copy(active_listener->args, args);
active_listener->state = REGISTERED;
pthread_cond_signal(&active_listener->cond);
pthread_cond_broadcast(&active_listener->cond);
}
}
+5 -5
View File
@@ -1645,7 +1645,7 @@ static status_t add_sa(private_kernel_interface_t *this,
protocol_id_t protocol, u_int32_t reqid,
u_int64_t expire_soft, u_int64_t expire_hard,
algorithm_t *enc_alg, algorithm_t *int_alg,
prf_plus_t *prf_plus, natt_conf_t *natt, mode_t mode,
prf_plus_t *prf_plus, mode_t mode, bool encap,
bool replace)
{
unsigned char request[BUFFER_SIZE];
@@ -1743,7 +1743,7 @@ static status_t add_sa(private_kernel_interface_t *this,
/* TODO: add IPComp here */
if (natt)
if (encap)
{
rthdr->rta_type = XFRMA_ENCAP;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_encap_tmpl));
@@ -1756,8 +1756,8 @@ static status_t add_sa(private_kernel_interface_t *this,
struct xfrm_encap_tmpl* encap = (struct xfrm_encap_tmpl*)RTA_DATA(rthdr);
encap->encap_type = UDP_ENCAP_ESPINUDP;
encap->encap_sport = htons(natt->sport);
encap->encap_dport = htons(natt->dport);
encap->encap_sport = htons(src->get_port(src));
encap->encap_dport = htons(dst->get_port(dst));
memset(&encap->encap_oa, 0, sizeof (xfrm_address_t));
/* encap_oa could probably be derived from the
* traffic selectors [rfc4306, p39]. In the netlink kernel implementation
@@ -2314,7 +2314,7 @@ kernel_interface_t *kernel_interface_create()
/* public functions */
this->public.get_spi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,protocol_id_t,u_int32_t,u_int32_t*))get_spi;
this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,algorithm_t*,algorithm_t*,prf_plus_t*,natt_conf_t*,mode_t,bool))add_sa;
this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,algorithm_t*,algorithm_t*,prf_plus_t*,mode_t,bool,bool))add_sa;
this->public.update_sa = (status_t(*)(kernel_interface_t*,u_int32_t,protocol_id_t,host_t*,host_t*,host_t*,host_t*))update_sa;
this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t*))query_sa;
this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t))del_sa;
+3 -15
View File
@@ -25,7 +25,6 @@
#ifndef KERNEL_INTERFACE_H_
#define KERNEL_INTERFACE_H_
typedef struct natt_conf_t natt_conf_t;
typedef enum policy_dir_t policy_dir_t;
typedef struct kernel_interface_t kernel_interface_t;
@@ -33,17 +32,6 @@ typedef struct kernel_interface_t kernel_interface_t;
#include <crypto/prf_plus.h>
#include <encoding/payloads/proposal_substructure.h>
/**
* Configuration for NAT-T
*
* @ingroup kernel
*/
struct natt_conf_t {
/** source port to use for UDP-encapsulated packets */
u_int16_t sport;
/** dest port to use for UDP-encapsulated packets */
u_int16_t dport;
};
/**
* Direction of a policy. These are equal to those
@@ -121,8 +109,8 @@ struct kernel_interface_t {
* @param enc_alg Algorithm to use for encryption (ESP only)
* @param int_alg Algorithm to use for integrity protection
* @param prf_plus PRF to derive keys from
* @param natt NAT-T Configuration, or NULL of no NAT-T used
* @param mode mode of the SA (tunnel, transport)
* @param encap enable UDP encapsulation for NAT traversal
* @param replace Should an already installed SA be updated?
* @return
* - SUCCESS
@@ -133,8 +121,8 @@ struct kernel_interface_t {
protocol_id_t protocol, u_int32_t reqid,
u_int64_t expire_soft, u_int64_t expire_hard,
algorithm_t *enc_alg, algorithm_t *int_alg,
prf_plus_t *prf_plus, natt_conf_t *natt,
mode_t mode, bool update);
prf_plus_t *prf_plus, mode_t mode, bool encap,
bool update);
/**
* @brief Update the hosts on an installed SA.
+8 -20
View File
@@ -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;
+5 -8
View File
@@ -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
View File
@@ -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);
}
+2
View File
@@ -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;
+37 -6
View File
@@ -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);
}
/**
+12 -12
View File
@@ -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;
}