/* See the DRL-LICENSE file for this file's software license. */
+#include <arpa/inet.h>
#include <inttypes.h>
+#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
+#include <sys/types.h>
#include <time.h>
#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)
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));
if (lookup == NULL) {
/* Table is full!?! */
- printf("Full table!\n");
+ printlog(LOG_WARN, "samplehold.c: Table full!\n");
return 0;
}
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);
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];
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;
}