X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drl%2Fsamplehold.c;h=9a309955629cfa71ae8d6801962f45e0414f3c26;hb=845a86c2059f50aef544fffde2534064d4048ed4;hp=4b79f3eec59e7e9a402251d2bacb18e043ce1994;hpb=0be9704d6b24d09ebd55beedec52758cb88c570b;p=distributedratelimiting.git diff --git a/drl/samplehold.c b/drl/samplehold.c index 4b79f3e..9a30995 100644 --- a/drl/samplehold.c +++ b/drl/samplehold.c @@ -1,14 +1,18 @@ /* See the DRL-LICENSE file for this file's software license. */ +#include #include +#include #include #include #include #include +#include #include #include "common_accounting.h" #include "samplehold.h" +#include "logging.h" static int match(const key_flow *key, const sampled_flow *flow) { if (flow->state != FLOW_USED) @@ -73,21 +77,23 @@ sampled_flow_table sampled_table_create(uint32_t (*hash_function)(const key_flow return NULL; } - table->capacity = (uint32_t) ((base_size * oversampling_factor) * 1.03); + table->capacity = (uint32_t) (base_size * oversampling_factor); table->size = 0; table->hash_function = hash_function; table->sample_prob = (double) (((double) table->capacity / (double) max_bytes) * (double) RANDOM_GRANULARITY); table->threshold = (double) ((double) flow_percentage / 100) * max_bytes; + + /* Allocate the backing and give it a little bit extra to deal with variance. */ table->largest = NULL; - table->backing = malloc(sizeof(sampled_flow) * table->capacity); + table->backing = malloc(sizeof(sampled_flow) * table->capacity * SAMPLEHOLD_BONUS_FACTOR); if (table->backing == NULL) { free(table); return NULL; } - memset(table->backing, 0, sizeof(sampled_flow) * table->capacity); + memset(table->backing, 0, sizeof(sampled_flow) * table->capacity * SAMPLEHOLD_BONUS_FACTOR); srand(time(NULL)); @@ -167,7 +173,7 @@ int sampled_table_sample(sampled_flow_table table, const key_flow *key) { if (lookup == NULL) { /* Table is full!?! */ - printf("Full table!\n"); + printlog(LOG_WARN, "samplehold.c: Table full!\n"); return 0; } @@ -270,6 +276,17 @@ void sampled_table_update_flows(sampled_flow_table table, struct timeval now, do uint32_t rate_delta = 0; double time_delta = 0; double unweighted_rate = 0; + struct in_addr src, dst; + char sip[22], dip[22]; + + /* Reset statistics. */ + table->common->num_flows = 0; + table->common->num_flows_5k = 0; + table->common->num_flows_10k = 0; + table->common->num_flows_20k = 0; + table->common->num_flows_50k = 0; + table->common->avg_rate = 0; + /* End statistics. */ /* Update common aggregate information. */ time_delta = timeval_subtract(now, table->common->last_update); @@ -294,8 +311,11 @@ void sampled_table_update_flows(sampled_flow_table table, struct timeval now, do unweighted_rate * (1 - ewma_weight); } + printlog(LOG_DEBUG, "table->common->rate is now %u\n", table->common->rate); + table->common->bytes_since = 0; table->common->last_update = now; + table->common->num_flows = 0; /* Update per-flow information. */ table->largest = &table->backing[i]; @@ -328,9 +348,41 @@ void sampled_table_update_flows(sampled_flow_table table, struct timeval now, do largest_rate = table->backing[i].rate; table->largest = &table->backing[i]; } + + if (table->backing[i].rate > 51200) { + table->common->num_flows_50k += 1; + table->common->num_flows_20k += 1; + table->common->num_flows_10k += 1; + table->common->num_flows_5k += 1; + } else if (table->backing[i].rate > 20480) { + table->common->num_flows_20k += 1; + table->common->num_flows_10k += 1; + table->common->num_flows_5k += 1; + } else if (table->backing[i].rate > 10240) { + table->common->num_flows_10k += 1; + table->common->num_flows_5k += 1; + } else if (table->backing[i].rate > 5120) { + table->common->num_flows_5k += 1; + } + + table->common->num_flows += 1; + + /* Print debugging info. */ + src.s_addr = ntohl(table->backing[i].source_ip); + dst.s_addr = ntohl(table->backing[i].dest_ip); + strcpy(sip, inet_ntoa(src)); + strcpy(dip, inet_ntoa(dst)); + printlog(LOG_DEBUG, "FLOW: (%p) %s:%d -> %s:%d at %d\n", &table->backing[i], + sip, table->backing[i].source_port, + dip, table->backing[i].dest_port, + table->backing[i].rate); } } + if (table->common->num_flows > 0) { + table->common->avg_rate = table->common->rate / table->common->num_flows; + } + table->common->max_flow_rate = largest_rate; }