summaryrefslogtreecommitdiff
path: root/src/charon/config/child_cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/config/child_cfg.c')
-rw-r--r--src/charon/config/child_cfg.c143
1 files changed, 80 insertions, 63 deletions
diff --git a/src/charon/config/child_cfg.c b/src/charon/config/child_cfg.c
index 990ee3fd6..8410b3fe5 100644
--- a/src/charon/config/child_cfg.c
+++ b/src/charon/config/child_cfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2009 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -25,7 +25,7 @@ ENUM(action_names, ACTION_NONE, ACTION_RESTART,
"restart",
);
-ENUM_BEGIN(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_NONE,
+ENUM_BEGIN(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_NONE,
"IPCOMP_NONE");
ENUM_NEXT(ipcomp_transform_names, IPCOMP_OUI, IPCOMP_LZJH, IPCOMP_NONE,
"IPCOMP_OUI",
@@ -45,79 +45,73 @@ struct private_child_cfg_t {
* Public part
*/
child_cfg_t public;
-
+
/**
* Number of references hold by others to this child_cfg
*/
refcount_t refcount;
-
+
/**
* Name of the child_cfg, used to query it
*/
char *name;
-
+
/**
* list for all proposals
*/
linked_list_t *proposals;
-
+
/**
* list for traffic selectors for my site
*/
linked_list_t *my_ts;
-
+
/**
* list for traffic selectors for others site
*/
linked_list_t *other_ts;
-
+
/**
* updown script
*/
char *updown;
-
+
/**
* allow host access
*/
bool hostaccess;
-
+
/**
* Mode to propose for a initiated CHILD: tunnel/transport
*/
ipsec_mode_t mode;
-
+
/**
* action to take on DPD
*/
action_t dpd_action;
-
+
/**
* action to take on CHILD_SA close
*/
action_t close_action;
-
- /**
- * Time before an SA gets invalid
- */
- u_int32_t lifetime;
-
- /**
- * Time before an SA gets rekeyed
- */
- u_int32_t rekeytime;
-
+
/**
- * Time, which specifies the range of a random value
- * substracted from rekeytime.
+ * CHILD_SA lifetime config
*/
- u_int32_t jitter;
-
+ lifetime_cfg_t lifetime;
+
/**
* enable IPComp
*/
bool use_ipcomp;
/**
+ * Inactivity timeout
+ */
+ u_int32_t inactivity;
+
+ /**
* set up IPsec transport SA in MIPv6 proxy mode
*/
bool proxy_mode;
@@ -152,7 +146,7 @@ static linked_list_t* get_proposals(private_child_cfg_t *this, bool strip_dh)
enumerator_t *enumerator;
proposal_t *current;
linked_list_t *proposals = linked_list_create();
-
+
enumerator = this->proposals->create_enumerator(this->proposals);
while (enumerator->enumerate(enumerator, &current))
{
@@ -164,7 +158,7 @@ static linked_list_t* get_proposals(private_child_cfg_t *this, bool strip_dh)
proposals->insert_last(proposals, current);
}
enumerator->destroy(enumerator);
-
+
return proposals;
}
@@ -172,14 +166,15 @@ static linked_list_t* get_proposals(private_child_cfg_t *this, bool strip_dh)
* Implementation of child_cfg_t.select_proposal.
*/
static proposal_t* select_proposal(private_child_cfg_t*this,
- linked_list_t *proposals, bool strip_dh)
+ linked_list_t *proposals, bool strip_dh,
+ bool private)
{
enumerator_t *stored_enum, *supplied_enum;
proposal_t *stored, *supplied, *selected = NULL;
-
+
stored_enum = this->proposals->create_enumerator(this->proposals);
supplied_enum = proposals->create_enumerator(proposals);
-
+
/* compare all stored proposals with all supplied. Stored ones are preferred. */
while (stored_enum->enumerate(stored_enum, &stored))
{
@@ -190,7 +185,7 @@ static proposal_t* select_proposal(private_child_cfg_t*this,
{
stored->strip_dh(stored);
}
- selected = stored->select(stored, supplied);
+ selected = stored->select(stored, supplied, private);
if (selected)
{
DBG2(DBG_CFG, "received proposals: %#P", proposals);
@@ -205,7 +200,7 @@ static proposal_t* select_proposal(private_child_cfg_t*this,
break;
}
supplied_enum->destroy(supplied_enum);
- supplied_enum = proposals->create_enumerator(proposals);
+ supplied_enum = proposals->create_enumerator(proposals);
}
stored_enum->destroy(stored_enum);
supplied_enum->destroy(supplied_enum);
@@ -243,7 +238,7 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
enumerator_t *e1, *e2;
traffic_selector_t *ts1, *ts2, *selected;
linked_list_t *result = linked_list_create();
-
+
if (local)
{
e1 = this->my_ts->create_enumerator(this->my_ts);
@@ -252,11 +247,11 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
{
e1 = this->other_ts->create_enumerator(this->other_ts);
}
-
+
/* no list supplied, just fetch the stored traffic selectors */
if (supplied == NULL)
{
- DBG2(DBG_CFG, "proposing traffic selectors for %s:",
+ DBG2(DBG_CFG, "proposing traffic selectors for %s:",
local ? "us" : "other");
while (e1->enumerate(e1, &ts1))
{
@@ -273,7 +268,7 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
}
else
{
- DBG2(DBG_CFG, "selecting traffic selectors for %s:",
+ DBG2(DBG_CFG, "selecting traffic selectors for %s:",
local ? "us" : "other");
e2 = supplied->create_enumerator(supplied);
/* iterate over all stored selectors */
@@ -285,7 +280,7 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
{
ts1->set_address(ts1, host);
}
-
+
/* iterate over all supplied traffic selectors */
while (e2->enumerate(e2, &ts2))
{
@@ -309,7 +304,7 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
e1->destroy(e1);
e2->destroy(e2);
}
-
+
/* remove any redundant traffic selectors in the list */
e1 = result->create_enumerator(result);
e2 = result->create_enumerator(result);
@@ -340,7 +335,7 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
}
e1->destroy(e1);
e2->destroy(e2);
-
+
return result;
}
@@ -361,19 +356,32 @@ static bool get_hostaccess(private_child_cfg_t *this)
}
/**
- * Implementation of child_cfg_t.get_lifetime.
+ * Applies jitter to the rekey value. Returns the new rekey value.
+ * Note: The distribution of random values is not perfect, but it
+ * should get the job done.
*/
-static u_int32_t get_lifetime(private_child_cfg_t *this, bool rekey)
+static u_int64_t apply_jitter(u_int64_t rekey, u_int64_t jitter)
{
- if (rekey)
+ if (jitter == 0)
{
- if (this->jitter == 0)
- {
- return this->rekeytime;
- }
- return this->rekeytime - (random() % this->jitter);
+ return rekey;
}
- return this->lifetime;
+ jitter = (jitter == UINT64_MAX) ? jitter : jitter + 1;
+ return rekey - jitter * (random() / (RAND_MAX + 1.0));
+}
+#define APPLY_JITTER(l) l.rekey = apply_jitter(l.rekey, l.jitter)
+
+/**
+ * Implementation of child_cfg_t.get_lifetime.
+ */
+static lifetime_cfg_t *get_lifetime(private_child_cfg_t *this)
+{
+ lifetime_cfg_t *lft = malloc_thing(lifetime_cfg_t);
+ memcpy(lft, &this->lifetime, sizeof(lifetime_cfg_t));
+ APPLY_JITTER(lft->time);
+ APPLY_JITTER(lft->bytes);
+ APPLY_JITTER(lft->packets);
+ return lft;
}
/**
@@ -408,7 +416,7 @@ static diffie_hellman_group_t get_dh_group(private_child_cfg_t *this)
enumerator_t *enumerator;
proposal_t *proposal;
u_int16_t dh_group = MODP_NONE;
-
+
enumerator = this->proposals->create_enumerator(this->proposals);
while (enumerator->enumerate(enumerator, &proposal))
{
@@ -430,6 +438,14 @@ static bool use_ipcomp(private_child_cfg_t *this)
}
/**
+ * Implementation of child_cfg_t.get_inactivity.
+ */
+static u_int32_t get_inactivity(private_child_cfg_t *this)
+{
+ return this->inactivity;
+}
+
+/**
* Implementation of child_cfg_t.set_mipv6_options.
*/
static void set_mipv6_options(private_child_cfg_t *this, bool proxy_mode,
@@ -486,10 +502,11 @@ static void destroy(private_child_cfg_t *this)
/*
* Described in header-file
*/
-child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
- u_int32_t rekeytime, u_int32_t jitter,
- char *updown, bool hostaccess, ipsec_mode_t mode,
- action_t dpd_action, action_t close_action, bool ipcomp)
+child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime,
+ char *updown, bool hostaccess,
+ ipsec_mode_t mode, action_t dpd_action,
+ action_t close_action, bool ipcomp,
+ u_int32_t inactivity)
{
private_child_cfg_t *this = malloc_thing(private_child_cfg_t);
@@ -498,37 +515,37 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
this->public.get_traffic_selectors = (linked_list_t*(*)(child_cfg_t*,bool,linked_list_t*,host_t*))get_traffic_selectors;
this->public.add_proposal = (void (*) (child_cfg_t*,proposal_t*))add_proposal;
this->public.get_proposals = (linked_list_t* (*) (child_cfg_t*,bool))get_proposals;
- this->public.select_proposal = (proposal_t* (*) (child_cfg_t*,linked_list_t*,bool))select_proposal;
+ this->public.select_proposal = (proposal_t* (*) (child_cfg_t*,linked_list_t*,bool,bool))select_proposal;
this->public.get_updown = (char* (*) (child_cfg_t*))get_updown;
this->public.get_hostaccess = (bool (*) (child_cfg_t*))get_hostaccess;
this->public.get_mode = (ipsec_mode_t (*) (child_cfg_t *))get_mode;
this->public.get_dpd_action = (action_t (*) (child_cfg_t *))get_dpd_action;
this->public.get_close_action = (action_t (*) (child_cfg_t *))get_close_action;
- this->public.get_lifetime = (u_int32_t (*) (child_cfg_t *,bool))get_lifetime;
+ this->public.get_lifetime = (lifetime_cfg_t* (*) (child_cfg_t *))get_lifetime;
this->public.get_dh_group = (diffie_hellman_group_t(*)(child_cfg_t*)) get_dh_group;
this->public.set_mipv6_options = (void (*) (child_cfg_t*,bool,bool))set_mipv6_options;
this->public.use_ipcomp = (bool (*) (child_cfg_t *))use_ipcomp;
+ this->public.get_inactivity = (u_int32_t (*) (child_cfg_t *))get_inactivity;
this->public.use_proxy_mode = (bool (*) (child_cfg_t *))use_proxy_mode;
this->public.install_policy = (bool (*) (child_cfg_t *))install_policy;
this->public.get_ref = (child_cfg_t* (*) (child_cfg_t*))get_ref;
this->public.destroy = (void (*) (child_cfg_t*))destroy;
-
+
this->name = strdup(name);
- this->lifetime = lifetime;
- this->rekeytime = rekeytime;
- this->jitter = jitter;
this->updown = updown ? strdup(updown) : NULL;
this->hostaccess = hostaccess;
this->mode = mode;
this->dpd_action = dpd_action;
this->close_action = close_action;
- this->use_ipcomp = ipcomp;
+ this->use_ipcomp = ipcomp;
+ this->inactivity = inactivity;
this->proxy_mode = FALSE;
- this->install_policy = TRUE;
+ this->install_policy = TRUE;
this->refcount = 1;
this->proposals = linked_list_create();
this->my_ts = linked_list_create();
this->other_ts = linked_list_create();
+ memcpy(&this->lifetime, lifetime, sizeof(lifetime_cfg_t));
return &this->public;
}