diff options
Diffstat (limited to 'src/charon/config/child_cfg.c')
-rw-r--r-- | src/charon/config/child_cfg.c | 143 |
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, ¤t)) { @@ -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; } |