From 15ad172a847fa667c57a4594ef4158405db9a984 Mon Sep 17 00:00:00 2001 From: Angelo Mantellini Date: Tue, 31 Mar 2020 17:50:43 +0200 Subject: [HICN-554] hicn-light refactoring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I36f2d393741d4502ce14d3791158e43e3e9cd4cf Signed-off-by: Jordan Augé --- hicn-light/src/hicn/core/prefix_stats.c | 202 ++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 hicn-light/src/hicn/core/prefix_stats.c (limited to 'hicn-light/src/hicn/core/prefix_stats.c') diff --git a/hicn-light/src/hicn/core/prefix_stats.c b/hicn-light/src/hicn/core/prefix_stats.c new file mode 100644 index 000000000..c32665950 --- /dev/null +++ b/hicn-light/src/hicn/core/prefix_stats.c @@ -0,0 +1,202 @@ +#ifdef WITH_PREFIX_STATS + +// This has to be included first because of _GNU_SOURCE +#include + +#include +#include +#include +#include +#include + +#include "prefix_stats.h" + +#define ALPHA 0.9 +#define STATS_INTERVAL 1000 /* ms */ + +static +void +prefix_stats_mgr_tick(prefix_stats_mgr_t * mgr, int fd, void * data) +{ + + assert(mgr); + assert(!data); + + uint64_t now = ticks_now(); + + /* Loop over FIB entries to compute statistics from counters */ + const fib_t * fib = forwarder_get_fib(mgr->forwarder); + fib_entry_t * entry; + + fib_foreach_entry(fib, entry, { + prefix_stats_update(&entry->prefix_stats, &entry->prefix_counters, now); + }); +} + +int +prefix_stats_mgr_initialize(prefix_stats_mgr_t * mgr, void * forwarder) +{ + mgr->forwarder = forwarder; + mgr->timer_fd = loop_register_timer(MAIN_LOOP, STATS_INTERVAL, mgr, prefix_stats_mgr_tick, NULL); + if (mgr->timer_fd < 0) + return -1; + + return 0; +} + +void +prefix_stats_mgr_finalize(prefix_stats_mgr_t * mgr) +{ + loop_unregister_timer(MAIN_LOOP, mgr->timer_fd); +} + + +void +prefix_stats_on_retransmission(const prefix_stats_mgr_t * mgr, prefix_counters_t * counters, + const nexthops_t * nexthops) +{ + connection_table_t * table = forwarder_get_connection_table(mgr->forwarder); + unsigned nexthop; + nexthops_foreach(nexthops, nexthop, { +#ifdef WITH_POLICY + const connection_t * conn = connection_table_at(table, nexthop); + + if (connection_has_tag(conn, POLICY_TAG_WIRED)) + counters->wired.num_losses++; + if (connection_has_tag(conn, POLICY_TAG_WIFI)) + counters->wifi.num_losses++; + if (connection_has_tag(conn, POLICY_TAG_CELLULAR)) + counters->cellular.num_losses++; +#endif /* WITH_POLICY */ + counters->all.num_losses++; + }); + +} + +#define UPDATE_TAG_STATS(TAG, NAME) \ +do { \ + if (connection_has_tag(conn, TAG)) { \ + counters->NAME.num_packets++; \ + counters->NAME.num_bytes += msg_size; \ + stats->NAME.latency = ALPHA * stats->NAME.latency + \ + (1 - ALPHA) * (double)rtt; \ + counters->NAME.latency_idle = 0; \ + } \ +} while(0) + +/* Update statistic counters upon Data packet reception */ +void +prefix_stats_on_data(const prefix_stats_mgr_t * mgr, prefix_stats_t * stats, + prefix_counters_t * counters, const nexthops_t * nexthops, + const msgbuf_t * msgbuf, Ticks rtt) +{ +#ifdef WITH_POLICY + forwarder_t * forwarder = mgr->forwarder; + connection_table_t * table = forwarder_get_connection_table(forwarder); +#endif /* WITH_POLICY */ + + size_t msg_size = msgbuf_get_len(msgbuf); + + unsigned nexthop; + nexthops_foreach(nexthops, nexthop, { +#ifdef WITH_POLICY + const connection_t * conn = connection_table_at(table, nexthop); + if (!conn) + continue; + + UPDATE_TAG_STATS(POLICY_TAG_WIRED, wired); + UPDATE_TAG_STATS(POLICY_TAG_WIFI, wifi); + UPDATE_TAG_STATS(POLICY_TAG_CELLULAR, cellular); +#endif /* WITH_POLICY */ + }); + + stats->all.latency = ALPHA * stats->all.latency + + (1 - ALPHA) * (double)rtt; + counters->all.latency_idle = 0; + counters->all.num_packets++; + counters->all.num_bytes += msg_size; +} + +void +prefix_stats_on_timeout(const prefix_stats_mgr_t * mgr, prefix_counters_t * counters, + const nexthops_t * nexthops) +{ +#ifdef WITH_POLICY + connection_table_t * table = forwarder_get_connection_table(mgr->forwarder); + + unsigned nexthop; + nexthops_foreach(nexthops, nexthop, { + const connection_t * conn = connection_table_at(table, nexthop); + if (!conn) + continue; + if (connection_has_tag(conn, POLICY_TAG_WIRED)) + counters->wired.num_losses++; + if (connection_has_tag(conn, POLICY_TAG_WIFI)) + counters->wifi.num_losses++; + if (connection_has_tag(conn, POLICY_TAG_CELLULAR)) + counters->cellular.num_losses++; + }); +#endif /* WITH_POLICY */ + + counters->all.num_losses++; +} + +#define UPDATE_TYPE(TYPE) \ +do { \ + /* (a) throughput */ \ + if (counters->TYPE.num_bytes > 0) { \ + throughput = counters->TYPE.num_bytes / \ + (now - counters->last_update) ; \ + throughput = throughput * 8 / 1024; \ + if (throughput < 0) \ + throughput = 0; \ + } else { \ + throughput = 0; \ + } \ + stats->TYPE.throughput = ALPHA * stats->TYPE.throughput + \ + (1-ALPHA) * throughput; \ + \ + /* (b) loss rate */ \ + if ((counters->TYPE.num_losses > 0) && \ + (counters->TYPE.num_packets > 0)) { \ + loss_rate = counters->TYPE.num_losses / \ + counters->TYPE.num_packets; \ + loss_rate *= 100; \ + } else { \ + loss_rate = 0; \ + } \ + stats->TYPE.loss_rate = ALPHA * stats->TYPE.loss_rate + \ + (1-ALPHA) * loss_rate; \ + \ + /* (c) latency */ \ + counters->TYPE.latency_idle++; \ + if (counters->TYPE.latency_idle > 1) \ + stats->TYPE.latency = 0; \ + \ + /* (d) Reset counters */ \ + counters->TYPE.num_bytes = 0; \ + counters->TYPE.num_losses = 0; \ + counters->TYPE.num_packets = 0; \ +} while(0) + +void +prefix_stats_update(prefix_stats_t * stats, prefix_counters_t * counters, uint64_t now) +{ + double throughput; + double loss_rate; + + if (now == counters->last_update) + return; + +#ifdef WITH_POLICY + UPDATE_TYPE(wired); + UPDATE_TYPE(wifi); + UPDATE_TYPE(cellular); +#endif /* WITH_POLICY */ + UPDATE_TYPE(all); + + counters->last_update = now; + +} + +#endif /* WITH_PREFIX_STATS */ -- cgit 1.2.3-korg