From: Tobias Brunner Date: Fri, 27 Mar 2015 15:14:45 +0000 (+0100) Subject: WIP X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Faccounting-hard-expire;p=thirdparty%2Fstrongswan.git WIP 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). --- diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c index cef19305c5..cc09e9dcb5 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c @@ -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); diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c index f22e07d95c..f18cb130bd 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -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);