From 6e10aeadabae48bf71ed91ed7dce6153af0f4888 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Fri, 24 Oct 2008 08:02:35 +0000 Subject: [PATCH] more CHILD_SA refactorings --- src/charon/plugins/stroke/stroke_list.c | 16 ++-- src/charon/sa/child_sa.c | 159 ++++++++++++++++---------------- src/charon/sa/child_sa.h | 65 +++++++------ src/charon/sa/ike_sa.c | 26 +++--- 4 files changed, 135 insertions(+), 131 deletions(-) diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c index 1de8b41..9ce89dc 100644 --- a/src/charon/plugins/stroke/stroke_list.c +++ b/src/charon/plugins/stroke/stroke_list.c @@ -123,20 +123,15 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all) static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) { u_int32_t rekey, now = time(NULL); - u_int32_t use_in, use_out, use_fwd; + u_int32_t use_in, use_out; encryption_algorithm_t encr_alg; integrity_algorithm_t int_alg; chunk_t encr_key, int_key; - ipsec_mode_t mode; - - child_sa->get_stats(child_sa, &mode, - &encr_alg, &encr_key, NULL, &int_alg, &int_key, NULL, - &rekey, &use_in, &use_out, &use_fwd); fprintf(out, "%12s{%d}: %N, %N", child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), child_sa_state_names, child_sa->get_state(child_sa), - ipsec_mode_names, mode); + ipsec_mode_names, child_sa->get_mode(child_sa)); if (child_sa->get_state(child_sa) == CHILD_INSTALLED) { @@ -162,6 +157,8 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) if (child_sa->get_protocol(child_sa) == PROTO_ESP) { + encr_alg = child_sa->get_encryption(child_sa, TRUE, &encr_key); + switch (encr_alg) { /* Algorithms with variable key size. @@ -185,6 +182,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) break; } } + int_alg = child_sa->get_integrity(child_sa, TRUE, &int_key); switch (int_alg) { case AUTH_UNDEFINED: @@ -195,6 +193,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) } fprintf(out, ", rekeying "); + rekey = child_sa->get_lifetime(child_sa, FALSE); if (rekey) { fprintf(out, "in %#V", &now, &rekey); @@ -205,7 +204,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) } fprintf(out, ", last use: "); - use_in = max(use_in, use_fwd); + use_in = child_sa->get_usetime(child_sa, TRUE); if (use_in) { fprintf(out, "%ds_i ", now - use_in); @@ -214,6 +213,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) { fprintf(out, "no_i "); } + use_out = child_sa->get_usetime(child_sa, FALSE); if (use_out) { fprintf(out, "%ds_o ", now - use_out); diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c index 445d9b9..03a0282 100644 --- a/src/charon/sa/child_sa.c +++ b/src/charon/sa/child_sa.c @@ -107,14 +107,14 @@ struct private_child_sa_t { chunk_t int_key[2]; /** - * time, on which SA was installed + * absolute time when rekeying is scheduled */ - time_t install_time; + time_t rekey_time; /** - * absolute time when rekeying is scheduled + * absolute time when the SA expires */ - time_t rekey_time; + time_t expire_time; /** * state of the CHILD_SA @@ -343,54 +343,83 @@ static enumerator_t* create_policy_enumerator(private_child_sa_t *this) } /** - * Implementation of child_sa_t.get_stats. + * Implementation of child_sa_t.get_usetime */ -static void get_stats(private_child_sa_t *this, ipsec_mode_t *mode, - encryption_algorithm_t *encr_algo, - chunk_t *encr_key_in, chunk_t *encr_key_out, - integrity_algorithm_t *int_algo, - chunk_t *int_key_in, chunk_t *int_key_out, - u_int32_t *rekey, u_int32_t *use_in, u_int32_t *use_out, - u_int32_t *use_fwd) +static u_int32_t get_usetime(private_child_sa_t *this, bool inbound) { - traffic_selector_t *my_ts, *other_ts; enumerator_t *enumerator; - u_int32_t in = 0, out = 0, fwd = 0, time; - + traffic_selector_t *my_ts, *other_ts; + u_int32_t last_use = 0; + enumerator = create_policy_enumerator(this); while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { - - if (charon->kernel_interface->query_policy(charon->kernel_interface, - other_ts, my_ts, POLICY_IN, &time) == SUCCESS) - { - in = max(in, time); - } - if (charon->kernel_interface->query_policy(charon->kernel_interface, - my_ts, other_ts, POLICY_OUT, &time) == SUCCESS) + u_int32_t in, out, fwd; + + if (inbound) { - out = max(out, time); + if (charon->kernel_interface->query_policy(charon->kernel_interface, + other_ts, my_ts, POLICY_IN, &in) == SUCCESS) + { + last_use = max(last_use, in); + } + if (charon->kernel_interface->query_policy(charon->kernel_interface, + other_ts, my_ts, POLICY_FWD, &fwd) == SUCCESS) + { + last_use = max(last_use, fwd); + } } - if (charon->kernel_interface->query_policy(charon->kernel_interface, - other_ts, my_ts, POLICY_FWD, &time) == SUCCESS) + else { - fwd = max(fwd, time); + if (charon->kernel_interface->query_policy(charon->kernel_interface, + my_ts, other_ts, POLICY_OUT, &out) == SUCCESS) + { + last_use = max(last_use, out); + } } } enumerator->destroy(enumerator); + return last_use; +} + +/** + * Implementation of child_sa_t.get_lifetime + */ +static u_int32_t get_lifetime(private_child_sa_t *this, bool hard) +{ + if (hard) + { + return this->expire_time; + } + return this->rekey_time; +} -#define SET_PTR_IF(x, y) if (x) { *x = y; } - SET_PTR_IF(mode, this->mode); - SET_PTR_IF(encr_algo, this->enc_alg); - SET_PTR_IF(encr_key_in, this->enc_key[0]); - SET_PTR_IF(encr_key_out, this->enc_key[1]); - SET_PTR_IF(int_algo, this->int_alg); - SET_PTR_IF(int_key_in, this->int_key[0]); - SET_PTR_IF(int_key_out, this->int_key[1]); - SET_PTR_IF(rekey, this->rekey_time); - SET_PTR_IF(use_in, in); - SET_PTR_IF(use_out, out); - SET_PTR_IF(use_fwd, fwd); +/** + * Implementation of child_sa_t.get_integrity + */ +static integrity_algorithm_t get_integrity(private_child_sa_t *this, + bool inbound, chunk_t *key) +{ + *key = this->int_key[!!inbound]; + return this->int_alg; +} + +/** + * Implementation of child_sa_t.get_encryption + */ +static encryption_algorithm_t get_encryption(private_child_sa_t *this, + bool inbound, chunk_t *key) +{ + *key = this->enc_key[!!inbound]; + return this->enc_alg; +} + +/** + * Implementation of child_sa_t.get_mode + */ +static ipsec_mode_t get_mode(private_child_sa_t *this) +{ + return this->mode; } /** @@ -470,7 +499,7 @@ static status_t alloc(private_child_sa_t *this, linked_list_t *proposals) static status_t install(private_child_sa_t *this, proposal_t *proposal, ipsec_mode_t mode, prf_plus_t *prf_plus, bool mine) { - u_int32_t spi, cpi, soft, hard; + u_int32_t spi, cpi, soft, hard, now; host_t *src, *dst; status_t status; int add_keymat; @@ -600,8 +629,9 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, this->int_alg, this->int_key[!!mine], mode, IPCOMP_NONE, this->encap, mine); - this->install_time = time(NULL); - this->rekey_time = this->install_time + soft; + now = time(NULL); + this->rekey_time = now + soft; + this->expire_time = now + hard; return status; } @@ -744,44 +774,6 @@ static linked_list_t *get_traffic_selectors(private_child_sa_t *this, bool local } /** - * Implementation of child_sa_t.get_use_time - */ -static status_t get_use_time(private_child_sa_t *this, - bool inbound, time_t *use_time) -{ - enumerator_t *enumerator; - traffic_selector_t *my_ts, *other_ts; - status_t status = FAILED; - - *use_time = UNDEFINED_TIME; - - enumerator = create_policy_enumerator(this); - while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) - { - if (inbound) - { - time_t in = UNDEFINED_TIME, fwd = UNDEFINED_TIME; - - status = charon->kernel_interface->query_policy( - charon->kernel_interface, other_ts, my_ts, - POLICY_IN, (u_int32_t*)&in); - status |= charon->kernel_interface->query_policy( - charon->kernel_interface, other_ts, my_ts, - POLICY_FWD, (u_int32_t*)&fwd); - *use_time = max(in, fwd); - } - else - { - status = charon->kernel_interface->query_policy( - charon->kernel_interface, my_ts, other_ts, - POLICY_OUT, (u_int32_t*)use_time); - } - } - enumerator->destroy(enumerator); - return status; -} - -/** * Implementation of child_sa_t.update_hosts. */ static status_t update_hosts(private_child_sa_t *this, @@ -996,7 +988,11 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, 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.get_stats = (void(*)(child_sa_t*, ipsec_mode_t*,encryption_algorithm_t*,chunk_t*,chunk_t*,integrity_algorithm_t*,chunk_t*,chunk_t*,u_int32_t*,u_int32_t*,u_int32_t*,u_int32_t*))get_stats; + this->public.get_mode = (ipsec_mode_t(*)(child_sa_t*))get_mode; + this->public.get_encryption = (encryption_algorithm_t(*)(child_sa_t*, bool, chunk_t*))get_encryption; + this->public.get_integrity = (integrity_algorithm_t(*)(child_sa_t*, bool, chunk_t*))get_integrity; + 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,prf_plus_t*))add; this->public.update = (status_t(*)(child_sa_t*,proposal_t*,ipsec_mode_t,prf_plus_t*))update; @@ -1004,7 +1000,6 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, 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.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.get_use_time = (status_t (*)(child_sa_t*,bool,time_t*))get_use_time; 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; diff --git a/src/charon/sa/child_sa.h b/src/charon/sa/child_sa.h index 11c3a0a..3e99986 100644 --- a/src/charon/sa/child_sa.h +++ b/src/charon/sa/child_sa.h @@ -148,25 +148,45 @@ struct child_sa_t { protocol_id_t (*get_protocol) (child_sa_t *this); /** - * Get info and statistics about this CHILD_SA. + * Get the IPsec mode of this CHILD_SA. * - * @param mode mode this IKE_SA uses - * @param encr_algo encryption algorithm used by this CHILD_SA. - * @param encr_key encryption key - * @param int_algo integrity algorithm used by this CHILD_SA - * @param int_key integrity key - * @param rekey time when rekeying is scheduled - * @param use_in time when last traffic was seen coming in - * @param use_out time when last traffic was seen going out - * @param use_fwd time when last traffic was getting forwarded + * @return TUNNEL | TRANSPORT | BEET */ - void (*get_stats)(child_sa_t *this, ipsec_mode_t *mode, - encryption_algorithm_t *encr, - chunk_t *encr_key_in, chunk_t *encr_key_out, - integrity_algorithm_t *int_algo, - chunk_t *int_key_in, chunk_t *int_key_out, - u_int32_t *rekey, u_int32_t *use_in, u_int32_t *use_out, - u_int32_t *use_fwd); + ipsec_mode_t (*get_mode)(child_sa_t *this); + + /** + * Get the IPsec encryption key. + * + * @param inbound TRUE for inbound, FALSE for outbound key + * @param key chunk where to write key pointer and length + * @return encryption algorithm + */ + encryption_algorithm_t (*get_encryption)(child_sa_t *this, bool inbound, + chunk_t *key); + /** + * Get the IPsec integrity. + * + * @param inbound TRUE for inbound, FALSE for outbound key + * @param key chunk where to write key pointer and length + * @return integrity algorithm + */ + integrity_algorithm_t (*get_integrity)(child_sa_t *this, bool inbound, + chunk_t *key); + /** + * Get the lifetime of the CHILD_SA. + * + * @param hard TRUE for hard lifetime, FALSE for soft (rekey) lifetime + * @return lifetime in seconds + */ + u_int32_t (*get_lifetime)(child_sa_t *this, bool hard); + + /** + * Get last use time of the CHILD_SA. + * + * @param inbound TRUE for inbound traffic, FALSE for outbound + * @return time of last use in seconds + */ + u_int32_t (*get_usetime)(child_sa_t *this, bool inbound); /** * Allocate SPIs for given proposals. @@ -251,15 +271,6 @@ struct child_sa_t { enumerator_t* (*create_policy_enumerator)(child_sa_t *this); /** - * Get the time of this child_sa_t's last use (i.e. last use of any of its policies) - * - * @param inbound query for in- or outbound usage - * @param use_time the time - * @return SUCCESS or FAILED - */ - status_t (*get_use_time) (child_sa_t *this, bool inbound, time_t *use_time); - - /** * Get the state of the CHILD_SA. */ child_sa_state_t (*get_state) (child_sa_t *this); @@ -285,7 +296,7 @@ struct child_sa_t { * @param other_cpi other Compression Parameter Index */ void (*activate_ipcomp) (child_sa_t *this, ipcomp_transform_t ipcomp, - u_int16_t other_cpi); + u_int16_t other_cpi); /** * Returns the Compression Parameter Index (CPI) allocated from the kernel. diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c index 1d45acb..1e824c4 100644 --- a/src/charon/sa/ike_sa.c +++ b/src/charon/sa/ike_sa.c @@ -304,28 +304,26 @@ struct private_ike_sa_t { */ static time_t get_use_time(private_ike_sa_t* this, bool inbound) { - iterator_t *iterator; + enumerator_t *enumerator; child_sa_t *child_sa; - time_t latest = 0, use_time; - - iterator = this->child_sas->create_iterator(this->child_sas, TRUE); - while (iterator->iterate(iterator, (void**)&child_sa)) - { - if (child_sa->get_use_time(child_sa, inbound, &use_time) == SUCCESS) - { - latest = max(latest, use_time); - } - } - iterator->destroy(iterator); + time_t use_time; if (inbound) { - return max(this->time.inbound, latest); + use_time = this->time.inbound; } else { - return max(this->time.outbound, latest); + use_time = this->time.outbound; } + enumerator = this->child_sas->create_enumerator(this->child_sas); + while (enumerator->enumerate(enumerator, &child_sa)) + { + use_time = max(use_time, child_sa->get_usetime(child_sa, inbound)); + } + enumerator->destroy(enumerator); + + return use_time; } /** -- 2.7.4