summaryrefslogtreecommitdiff
path: root/src/charon/sa/child_sa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/sa/child_sa.c')
-rw-r--r--src/charon/sa/child_sa.c231
1 files changed, 76 insertions, 155 deletions
diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c
index 19131389d..1e7b6cb2c 100644
--- a/src/charon/sa/child_sa.c
+++ b/src/charon/sa/child_sa.c
@@ -27,7 +27,6 @@
#include <stdio.h>
#include <string.h>
-#include <printf.h>
#include <daemon.h>
@@ -154,9 +153,9 @@ struct private_child_sa_t {
host_t *virtual_ip;
/**
- * policy used to create this child
+ * config used to create this child
*/
- policy_t *policy;
+ child_cfg_t *config;
};
/**
@@ -164,7 +163,7 @@ struct private_child_sa_t {
*/
static char *get_name(private_child_sa_t *this)
{
- return this->policy->get_name(this->policy);;
+ return this->config->get_name(this->config);
}
/**
@@ -204,11 +203,57 @@ static child_sa_state_t get_state(private_child_sa_t *this)
}
/**
- * Implements child_sa_t.get_policy
+ * Implements child_sa_t.get_config
*/
-static policy_t* get_policy(private_child_sa_t *this)
+static child_cfg_t* get_config(private_child_sa_t *this)
{
- return this->policy;
+ return this->config;
+}
+
+/**
+ * Implementation of child_sa_t.get_stats.
+ */
+static void get_stats(private_child_sa_t *this, mode_t *mode,
+ encryption_algorithm_t *encr_algo, size_t *encr_len,
+ integrity_algorithm_t *int_algo, size_t *int_len,
+ u_int32_t *rekey, u_int32_t *use_in, u_int32_t *use_out,
+ u_int32_t *use_fwd)
+{
+ sa_policy_t *policy;
+ iterator_t *iterator;
+ u_int32_t in = 0, out = 0, fwd = 0, time;
+
+ iterator = this->policies->create_iterator(this->policies, TRUE);
+ while (iterator->iterate(iterator, (void**)&policy))
+ {
+
+ if (charon->kernel_interface->query_policy(charon->kernel_interface,
+ policy->other_ts, policy->my_ts, POLICY_IN, &time) == SUCCESS)
+ {
+ in = max(in, time);
+ }
+ if (charon->kernel_interface->query_policy(charon->kernel_interface,
+ policy->my_ts, policy->other_ts, POLICY_OUT, &time) == SUCCESS)
+ {
+ out = max(out, time);
+ }
+ if (charon->kernel_interface->query_policy(charon->kernel_interface,
+ policy->other_ts, policy->my_ts, POLICY_FWD, &time) == SUCCESS)
+ {
+ fwd = max(fwd, time);
+ }
+ }
+ iterator->destroy(iterator);
+
+ *mode = this->mode;
+ *encr_algo = this->encryption.algorithm;
+ *encr_len = this->encryption.key_size;
+ *int_algo = this->integrity.algorithm;
+ *int_len = this->integrity.key_size;
+ *rekey = this->rekey_time;
+ *use_in = in;
+ *use_out = out;
+ *use_fwd = fwd;
}
/**
@@ -220,7 +265,7 @@ static void updown(private_child_sa_t *this, bool up)
iterator_t *iterator;
char *script;
- script = this->policy->get_updown(this->policy);
+ script = this->config->get_updown(this->config);
if (script == NULL)
{
@@ -300,7 +345,7 @@ static void updown(private_child_sa_t *this, bool up)
policy->my_ts->is_host(policy->my_ts,
this->me.addr) ? "-host" : "-client",
this->me.addr->get_family(this->me.addr) == AF_INET ? "" : "-ipv6",
- this->policy->get_name(this->policy),
+ this->config->get_name(this->config),
ifname ? ifname : "(unknown)",
this->reqid,
this->me.addr,
@@ -316,7 +361,7 @@ static void updown(private_child_sa_t *this, bool up)
policy->other_ts->get_from_port(policy->other_ts),
policy->other_ts->get_protocol(policy->other_ts),
virtual_ip,
- this->policy->get_hostaccess(this->policy) ?
+ this->config->get_hostaccess(this->config) ?
"PLUTO_HOST_ACCESS='1' " : "",
script);
free(ifname);
@@ -528,8 +573,8 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal,
natt = NULL;
}
- soft = this->policy->get_soft_lifetime(this->policy);
- hard = this->policy->get_hard_lifetime(this->policy);
+ soft = this->config->get_lifetime(this->config, TRUE);
+ hard = this->config->get_lifetime(this->config, FALSE);
/* send SA down to the kernel */
DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
@@ -542,7 +587,7 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal,
this->encryption = *enc_algo;
this->integrity = *int_algo;
this->install_time = time(NULL);
- this->rekey_time = soft;
+ this->rekey_time = this->install_time + soft;
return status;
}
@@ -628,7 +673,7 @@ static status_t add_policies(private_child_sa_t *this,
if (my_ts->get_type(my_ts) != other_ts->get_type(other_ts))
{
DBG2(DBG_CHD,
- "CHILD_SA policy uses two different IP families, ignored");
+ "CHILD_SA policy uses two different IP families - ignored");
continue;
}
@@ -637,7 +682,7 @@ static status_t add_policies(private_child_sa_t *this,
my_ts->get_protocol(my_ts) && other_ts->get_protocol(other_ts))
{
DBG2(DBG_CHD,
- "CHILD_SA policy uses two different protocols, ignored");
+ "CHILD_SA policy uses two different protocols - ignored");
continue;
}
@@ -665,10 +710,10 @@ static status_t add_policies(private_child_sa_t *this,
policy = malloc_thing(sa_policy_t);
policy->my_ts = my_ts->clone(my_ts);
policy->other_ts = other_ts->clone(other_ts);
- this->policies->insert_last(this->policies, (void*)policy);
+ this->policies->insert_last(this->policies, policy);
/* add to separate list to query them via get_*_traffic_selectors() */
- this->my_ts->insert_last(this->my_ts, (void*)policy->my_ts);
- this->other_ts->insert_last(this->other_ts, (void*)policy->other_ts);
+ this->my_ts->insert_last(this->my_ts, policy->my_ts);
+ this->other_ts->insert_last(this->other_ts, policy->other_ts);
}
}
my_iter->destroy(my_iter);
@@ -685,18 +730,14 @@ static status_t add_policies(private_child_sa_t *this,
}
/**
- * Implementation of child_sa_t.get_my_traffic_selectors.
+ * Implementation of child_sa_t.get_traffic_selectors.
*/
-static linked_list_t *get_my_traffic_selectors(private_child_sa_t *this)
-{
- return this->my_ts;
-}
-
-/**
- * Implementation of child_sa_t.get_my_traffic_selectors.
- */
-static linked_list_t *get_other_traffic_selectors(private_child_sa_t *this)
+static linked_list_t *get_traffic_selectors(private_child_sa_t *this, bool local)
{
+ if (local)
+ {
+ return this->my_ts;
+ }
return this->other_ts;
}
@@ -741,126 +782,6 @@ static status_t get_use_time(private_child_sa_t *this, bool inbound, time_t *use
}
/**
- * output handler in printf()
- */
-static int print(FILE *stream, const struct printf_info *info,
- const void *const *args)
-{
- private_child_sa_t *this = *((private_child_sa_t**)(args[0]));
- iterator_t *iterator;
- sa_policy_t *policy;
- u_int32_t now, rekeying;
- u_int32_t use, use_in, use_fwd;
- status_t status;
- size_t written = 0;
-
- if (this == NULL)
- {
- return fprintf(stream, "(null)");
- }
-
- now = time(NULL);
-
- written += fprintf(stream, "%12s{%d}: %N, %N",
- this->policy->get_name(this->policy), this->reqid,
- child_sa_state_names, this->state,
- mode_names, this->mode);
-
- if (this->state == CHILD_INSTALLED)
- {
- written += fprintf(stream, ", %N SPIs: 0x%0x_i 0x%0x_o",
- protocol_id_names, this->protocol,
- htonl(this->me.spi), htonl(this->other.spi));
-
- if (info->alt)
- {
- written += fprintf(stream, "\n%12s{%d}: ",
- this->policy->get_name(this->policy),
- this->reqid);
-
- if (this->protocol == PROTO_ESP)
- {
- written += fprintf(stream, "%N", encryption_algorithm_names,
- this->encryption.algorithm);
-
- if (this->encryption.key_size)
- {
- written += fprintf(stream, "-%d", this->encryption.key_size);
- }
- written += fprintf(stream, "/");
- }
-
- written += fprintf(stream, "%N", integrity_algorithm_names,
- this->integrity.algorithm);
- if (this->integrity.key_size)
- {
- written += fprintf(stream, "-%d", this->integrity.key_size);
- }
- written += fprintf(stream, ", rekeying ");
-
- /* calculate rekey times */
- if (this->rekey_time)
- {
- rekeying = this->install_time + this->rekey_time - now;
- written += fprintf(stream, "in %ds", rekeying);
- }
- else
- {
- written += fprintf(stream, "disabled");
- }
- }
- }
- iterator = this->policies->create_iterator(this->policies, TRUE);
- while (iterator->iterate(iterator, (void**)&policy))
- {
- written += fprintf(stream, "\n%12s{%d}: %R===%R, last use: ",
- this->policy->get_name(this->policy), this->reqid,
- policy->my_ts, policy->other_ts);
-
- /* query time of last policy use */
-
- /* inbound: POLICY_IN or POLICY_FWD */
- status = charon->kernel_interface->query_policy(charon->kernel_interface,
- policy->other_ts, policy->my_ts, POLICY_IN, &use_in);
- use_in = (status == SUCCESS)? use_in : 0;
- status = charon->kernel_interface->query_policy(charon->kernel_interface,
- policy->other_ts, policy->my_ts, POLICY_FWD, &use_fwd);
- use_fwd = (status == SUCCESS)? use_fwd : 0;
- use = max(use_in, use_fwd);
- if (use)
- {
- written += fprintf(stream, "%ds_i ", now - use);
- }
- else
- {
- written += fprintf(stream, "no_i ");
- }
-
- /* outbound: POLICY_OUT */
- status = charon->kernel_interface->query_policy(charon->kernel_interface,
- policy->my_ts, policy->other_ts, POLICY_OUT, &use);
- if (status == SUCCESS && use)
- {
- written += fprintf(stream, "%ds_o ", now - use);
- }
- else
- {
- written += fprintf(stream, "no_o ");
- }
- }
- iterator->destroy(iterator);
- return written;
-}
-
-/**
- * register printf() handlers
- */
-static void __attribute__ ((constructor))print_register()
-{
- register_printf_function(PRINTF_CHILD_SA, print, arginfo_ptr);
-}
-
-/**
* Update the host adress/port of a SA
*/
static status_t update_sa_hosts(private_child_sa_t *this, host_t *new_me, host_t *new_other,
@@ -1066,7 +987,7 @@ static void destroy(private_child_sa_t *this)
this->other.addr->destroy(this->other.addr);
this->me.id->destroy(this->me.id);
this->other.id->destroy(this->other.id);
- this->policy->destroy(this->policy);
+ this->config->destroy(this->config);
DESTROY_IF(this->virtual_ip);
free(this);
}
@@ -1076,7 +997,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,
- policy_t *policy, u_int32_t rekey, bool use_natt)
+ child_cfg_t *config, u_int32_t rekey, bool use_natt)
{
static u_int32_t reqid = 0;
private_child_sa_t *this = malloc_thing(private_child_sa_t);
@@ -1086,17 +1007,17 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->public.get_reqid = (u_int32_t(*)(child_sa_t*))get_reqid;
this->public.get_spi = (u_int32_t(*)(child_sa_t*, bool))get_spi;
this->public.get_protocol = (protocol_id_t(*)(child_sa_t*))get_protocol;
+ this->public.get_stats = (void(*)(child_sa_t*, mode_t*,encryption_algorithm_t*,size_t*,integrity_algorithm_t*,size_t*,u_int32_t*,u_int32_t*,u_int32_t*,u_int32_t*))get_stats;
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*,host_diff_t,host_diff_t))update_hosts;
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*,mode_t))add_policies;
- this->public.get_my_traffic_selectors = (linked_list_t*(*)(child_sa_t*))get_my_traffic_selectors;
- this->public.get_other_traffic_selectors = (linked_list_t*(*)(child_sa_t*))get_other_traffic_selectors;
+ 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;
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_policy = (policy_t*(*)(child_sa_t*))get_policy;
+ this->public.get_config = (child_cfg_t*(*)(child_sa_t*))get_config;
this->public.set_virtual_ip = (void(*)(child_sa_t*,host_t*))set_virtual_ip;
this->public.destroy = (void(*)(child_sa_t*))destroy;
@@ -1123,8 +1044,8 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->protocol = PROTO_NONE;
this->mode = MODE_TUNNEL;
this->virtual_ip = NULL;
- this->policy = policy;
- policy->get_ref(policy);
+ this->config = config;
+ config->get_ref(config);
return &this->public;
}