]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
WIP accounting-hard-expire
authorTobias Brunner <tobias@strongswan.org>
Fri, 27 Mar 2015 15:14:45 +0000 (16:14 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 21 May 2015 13:42:24 +0000 (15:42 +0200)
We could extend the expire event so it includes the last usage values of
the expired SA.  One issue with that is that we only get one direction,
so we'd have to query the other direction before we delete the SA (there
could be a race if it expired shortly after the first one -  we could
increase the lifetime of one direction a bit, though, so we would have
enough time for this).  Also, we currently don't cache usage data on the
child_sa_t object, which we had to do to report the final numbers via
get_usestats().  And we'd also need to actually trigger child_updown
for such SAs even after they were rekeyed (not possible for IKEv2 at
the moment).  This may all be a bit overkill as for the general use case
this should not be an issue.

Basically, if the other peer uses an SA after it got rekeyed the usage
numbers won't be accurate. That is, all data transmitted since the last
update before expiration won't be accounted for (child_rekey, or interim
update - so this is less of an issue with interim updates, or with
relatively short rekeymargin). The peer will also only be able to send
data on the inbound SA (from the server's point of view), as the server
will always use the latest outbound SA.  But the same problem occurs if
no rekeying is used, as in that case SAs will simply expire at some point
and no current data can be queried anymore (but I guess that's a rather
unusual use case).

src/libcharon/plugins/eap_radius/eap_radius_accounting.c
src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c

index cef19305c532e7db0ab38f460329998dba7c98f3..cc09e9dcb5d8a5f5f68f83b893032898ab8b1ee7 100644 (file)
@@ -190,6 +190,13 @@ static void destroy_entry(entry_t *this)
        free(this);
 }
 
+
+static void log_sa(sa_entry_t *sa)
+{
+       DBG1(DBG_CFG, "===  sa [%u]  b(i): %llu, b(o): %llu, p(i): %llu, p(o): %llu",
+                sa->id, sa->usage.bytes.received, sa->usage.bytes.sent, sa->usage.packets.received, sa->usage.packets.sent);
+}
+
 /**
  * Accounting message status types
  */
@@ -347,6 +354,8 @@ static void cleanup_sas(private_eap_radius_accounting_t *this, ike_sa_t *ike_sa,
                {
                        /* SA is gone, add its latest stats to the total for this IKE_SA
                         * and remove the cache entry */
+                       DBG1(DBG_CFG, "=== cached SA is gone in cleanup");
+                       log_sa(sa);
                        add_usage(&entry->usage, sa->usage);
                        array_remove_at(entry->cached, enumerator);
                        free(sa);
@@ -744,9 +753,11 @@ static void send_stop(private_eap_radius_accounting_t *this, ike_sa_t *ike_sa)
                        destroy_entry(entry);
                        return;
                }
+               DBG1(DBG_CFG, "=== report cached in stop");
                enumerator = array_create_enumerator(entry->cached);
                while (enumerator->enumerate(enumerator, &sa))
                {
+                       log_sa(sa);
                        add_usage(&entry->usage, sa->usage);
                }
                enumerator->destroy(enumerator);
index f22e07d95c50d7393f90ea5478a5da4359178928..f18cb130bd01596ad9b076969e8162957f9b4f3a 100644 (file)
@@ -885,6 +885,11 @@ static void process_expire(private_kernel_netlink_ipsec_t *this,
                dst = xfrm2host(expire->state.family, &expire->state.id.daddr, 0);
                if (dst)
                {
+                       if (expire->hard)
+                       {
+                               DBG1(DBG_KNL, "=== received hard expire for CHILD_SA 0x%08x/%H, p: %llu, b: %llu",
+                                        ntohl(spi), dst, expire->state.curlft.packets, expire->state.curlft.bytes);
+                       }
                        hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
                                                                                        spi, dst, expire->hard != 0);
                        dst->destroy(dst);