summaryrefslogtreecommitdiff
path: root/src/charon/sa/child_sa.c
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2009-10-21 11:14:02 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2009-10-21 11:14:02 +0000
commit7410d3c6d6a9a1cd7aa55083c938946af6ff9498 (patch)
tree3291beffa55649f9be28b4a98a7d503d334fbcf2 /src/charon/sa/child_sa.c
parent41787e147279ff0695e9d759487266a60b80867b (diff)
downloadvyos-strongswan-7410d3c6d6a9a1cd7aa55083c938946af6ff9498.tar.gz
vyos-strongswan-7410d3c6d6a9a1cd7aa55083c938946af6ff9498.zip
[svn-upgrade] Integrating new upstream version, strongswan (4.3.4)
Diffstat (limited to 'src/charon/sa/child_sa.c')
-rw-r--r--src/charon/sa/child_sa.c135
1 files changed, 123 insertions, 12 deletions
diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c
index 9202e972e..14d174ab5 100644
--- a/src/charon/sa/child_sa.c
+++ b/src/charon/sa/child_sa.c
@@ -136,6 +136,26 @@ struct private_child_sa_t {
* config used to create this child
*/
child_cfg_t *config;
+
+ /**
+ * time of last use in seconds (inbound)
+ */
+ u_int32_t my_usetime;
+
+ /**
+ * time of last use in seconds (outbound)
+ */
+ u_int32_t other_usetime;
+
+ /**
+ * last number of inbound bytes
+ */
+ u_int64_t my_usebytes;
+
+ /**
+ * last number of outbound bytes
+ */
+ u_int64_t other_usebytes;
};
/**
@@ -355,20 +375,72 @@ static enumerator_t* create_policy_enumerator(private_child_sa_t *this)
}
/**
- * Implementation of child_sa_t.get_usetime
+ * update the cached usebytes
+ * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
+ * are available, and NOT_SUPPORTED if the kernel interface does not support
+ * querying the usebytes.
+ */
+static status_t update_usebytes(private_child_sa_t *this, bool inbound)
+{
+ status_t status = FAILED;
+ u_int64_t bytes;
+
+ if (inbound)
+ {
+ if (this->my_spi)
+ {
+ status = charon->kernel_interface->query_sa(
+ charon->kernel_interface,
+ this->other_addr, this->my_addr,
+ this->my_spi, this->protocol, &bytes);
+ if (status == SUCCESS)
+ {
+ if (bytes > this->my_usebytes)
+ {
+ this->my_usebytes = bytes;
+ return SUCCESS;
+ }
+ return FAILED;
+ }
+ }
+ }
+ else
+ {
+ if (this->other_spi)
+ {
+ status = charon->kernel_interface->query_sa(
+ charon->kernel_interface,
+ this->my_addr, this->other_addr,
+ this->other_spi, this->protocol, &bytes);
+ if (status == SUCCESS)
+ {
+ if (bytes > this->other_usebytes)
+ {
+ this->other_usebytes = bytes;
+ return SUCCESS;
+ }
+ return FAILED;
+ }
+ }
+ }
+ return status;
+}
+
+/**
+ * updates the cached usetime
*/
-static u_int32_t get_usetime(private_child_sa_t *this, bool inbound)
+static void update_usetime(private_child_sa_t *this, bool inbound)
{
enumerator_t *enumerator;
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))
{
u_int32_t in, out, fwd;
- if (inbound)
+ if (inbound)
{
if (charon->kernel_interface->query_policy(charon->kernel_interface,
other_ts, my_ts, POLICY_IN, &in) == SUCCESS)
@@ -394,7 +466,42 @@ static u_int32_t get_usetime(private_child_sa_t *this, bool inbound)
}
}
enumerator->destroy(enumerator);
- return last_use;
+
+ if (last_use == 0)
+ {
+ return;
+ }
+ if (inbound)
+ {
+ this->my_usetime = last_use;
+ }
+ else
+ {
+ this->other_usetime = last_use;
+ }
+}
+
+/**
+ * Implementation of child_sa_t.get_usestats
+ */
+static void get_usestats(private_child_sa_t *this, bool inbound,
+ time_t *time, u_int64_t *bytes)
+{
+ if (update_usebytes(this, inbound) != FAILED)
+ {
+ /* there was traffic since last update or the kernel interface
+ * does not support querying the number of usebytes.
+ */
+ update_usetime(this, inbound);
+ }
+ if (time)
+ {
+ *time = inbound ? this->my_usetime : this->other_usetime;
+ }
+ if (bytes)
+ {
+ *bytes = inbound ? this->my_usebytes : this->other_usebytes;
+ }
}
/**
@@ -566,13 +673,13 @@ static status_t add_policies(private_child_sa_t *this,
* Implementation of child_sa_t.update.
*/
static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
- host_t *vip, bool encap)
+ host_t *vip, bool encap)
{
child_sa_state_t old;
bool transport_proxy_mode;
/* anything changed at all? */
- if (me->equals(me, this->my_addr) &&
+ if (me->equals(me, this->my_addr) &&
other->equals(other, this->other_addr) && this->encap == encap)
{
return SUCCESS;
@@ -661,7 +768,7 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
me, other, my_ts, other_ts, POLICY_OUT, this->other_spi,
this->protocol, this->reqid, this->mode, this->ipcomp,
this->other_cpi, FALSE);
- charon->kernel_interface->add_policy(charon->kernel_interface,
+ charon->kernel_interface->add_policy(charon->kernel_interface,
other, me, other_ts, my_ts, POLICY_IN, this->my_spi,
this->protocol, this->reqid, this->mode, this->ipcomp,
this->my_cpi, FALSE);
@@ -775,7 +882,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->public.get_proposal = (proposal_t*(*)(child_sa_t*))get_proposal;
this->public.set_proposal = (void(*)(child_sa_t*, proposal_t *proposal))set_proposal;
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.get_usestats = (void(*)(child_sa_t*,bool,time_t*,u_int64_t*))get_usestats;
this->public.has_encap = (bool(*)(child_sa_t*))has_encap;
this->public.get_ipcomp = (ipcomp_transform_t(*)(child_sa_t*))get_ipcomp;
this->public.set_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t))set_ipcomp;
@@ -798,6 +905,10 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->encap = encap;
this->ipcomp = IPCOMP_NONE;
this->state = CHILD_CREATED;
+ this->my_usetime = 0;
+ this->other_usetime = 0;
+ this->my_usebytes = 0;
+ this->other_usebytes = 0;
/* reuse old reqid if we are rekeying an existing CHILD_SA */
this->reqid = rekey ? rekey : ++reqid;
this->my_ts = linked_list_create();
@@ -810,7 +921,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->config = config;
config->get_ref(config);
- /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
+ /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
if (config->get_mode(config) == MODE_TRANSPORT &&
config->use_proxy_mode(config))
{
@@ -837,7 +948,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
host = host_create_from_chunk(family, addr, 0);
free(addr.ptr);
DBG1(DBG_CHD, "my address: %H is a transport mode proxy for %H",
- this->my_addr, host);
+ this->my_addr, host);
this->my_addr->destroy(this->my_addr);
this->my_addr = host;
}
@@ -858,7 +969,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
host = host_create_from_chunk(family, addr, 0);
free(addr.ptr);
DBG1(DBG_CHD, "other address: %H is a transport mode proxy for %H",
- this->other_addr, host);
+ this->other_addr, host);
this->other_addr->destroy(this->other_addr);
this->other_addr = host;
}