Lots of changes. In no particular order:
[distributedratelimiting.git] / drl / multipleinterval.h
diff --git a/drl/multipleinterval.h b/drl/multipleinterval.h
new file mode 100644 (file)
index 0000000..3fc007e
--- /dev/null
@@ -0,0 +1,174 @@
+/* See the DRL-LICENSE file for this file's software license. */
+
+/*
+ * Defines the multiple-interval "perfect" flow accounting table.
+ *
+ */
+
+#ifndef _MULTIPLE_ACCOUNTING_H_
+#define _MULTIPLE_ACCOUNTING_H_
+
+#include <inttypes.h>
+
+//FIXME: Update comments on structure variables
+
+/** The number of hash buckets in the table. */
+#define MUL_FLOW_HASH_SIZE 1024
+
+/** The number of seconds after which a flow is considered to be inactive.
+ * Inactive flows will be removed from the table during the next call to the
+ * cleanup function. */
+#define MUL_FLOW_IDLE_TIME 15
+
+#define MUL_INTERVAL_COUNT 10
+
+typedef struct mul_interval {
+    /** The number of bytes this flow has sent since the last update to this
+     * interval structure. */
+    uint32_t bytes_since;
+
+    /** The time at which this interval was last updated. */
+    struct timeval last_update;
+
+    /** The time at which the most recent packet in this flow was received
+     * in this interval. */
+    time_t last_packet;
+
+    uint32_t valid;
+
+    struct mul_interval *next;
+} interval;
+
+/** Representation of a flow in a multiple-interval table. */
+typedef struct mul_flow {
+    /* Flow information. */
+
+    /** The rate of the flow in the current estimate interval. */
+    uint32_t rate;
+
+    /** The rate of the flow in the previous estimate interval. */
+    uint32_t last_rate;
+
+    time_t last_packet;
+
+    interval *current_interval;
+
+    interval *intervals;
+
+    /* Identification information. */
+
+    /** The flow's source IP address. */
+    uint32_t source_ip;
+
+    /** The flow's destination IP address. */
+    uint32_t dest_ip;
+
+    /** The flow's source port. */
+    uint16_t source_port;
+
+    /** The flow's destination port. */
+    uint16_t dest_port;
+
+    /** The flow's protocol.  This corresponds to the protocol field of the IP
+     * header. */
+    uint8_t protocol;
+
+    /* Table state. */
+
+    /** Pointer to the next flow in the hash list. */
+    struct mul_flow *nexth;
+
+    /** Pointers to the next flow in the linked list. */
+    struct mul_flow *next;
+
+    /** Pointers to the previous flow in the linked list. */
+    struct mul_flow *prev;
+
+} multiple_flow;
+
+/**
+ * The "table" that stores the flows.  It's constructed of two main pieces.
+ *
+ * The first is an array of hash buckets.  Flows are classified into buckets
+ * by hashing the flow's values (key flow) using the table's hash function.
+ * Flows are chained together as a list in each bucket to deal with collisions.
+ *
+ * The second is a simple doubly linked list containing every flow in the table.
+ */
+struct mul_flow_table {
+
+    /** Pointer to the common flow information for the identity that owns this
+     * sampled flow table.  This is updated with aggregate information. */
+    common_accounting_t *common;
+
+    uint32_t interval_count;
+
+    interval *current_interval;
+
+    interval *intervals;
+
+    /* Table structures. */
+
+    /** Hash buckets - each is a list of flows. */
+    struct mul_flow *flows[MUL_FLOW_HASH_SIZE];
+
+    /** The head of the linked list of flows. */
+    struct mul_flow *flows_head;
+    
+    /** The tail of the linked list of flows. */
+    struct mul_flow *flows_tail;
+
+    /** Function pointer to the function that will yield the hash of a
+     * key_flow.
+     */
+    uint32_t (*hash_function)(const key_flow *key);
+
+};
+
+/** The type multiple_flow_table is really a pointer to a struct
+ * mul_flow_table. */
+typedef struct mul_flow_table *multiple_flow_table;
+
+/**
+ * Creates a new table that will use the specified hash function.
+ *
+ * Returns the new table or NULL on failure.
+ */
+multiple_flow_table multiple_table_create(uint32_t (*hash_function)(const key_flow *key), uint32_t interval_count, common_accounting_t *common);
+
+/**
+ * Destroys the specified table.
+ */
+void multiple_table_destroy(multiple_flow_table table);
+
+/**
+ * Looks for a flow that matches the given key in the specified table.  If a
+ * matching flow is not found, this function will allocate a new flow for the
+ * key.
+ *
+ * Returns a pointer to the flow that matches the key or NULL if there is no
+ * matching flow and a new flow couldn't be allocated.
+ */
+multiple_flow *multiple_table_lookup(multiple_flow_table table, const key_flow *key);
+
+/**
+ * Updates the state of the table given a newly acquired packet.
+ *
+ * Returns 1 if the flow is in the table.  0 otherwise (indicating that memory
+ * could not be allocated to add a new flow to the table for the given key.
+ */
+int multiple_table_sample(multiple_flow_table table, const key_flow *key);
+
+/**
+ * Cleans the table by removing flow entires for any flow that hasn't seen a
+ * new packet in the interval specified by MUL_FLOW_IDLE_TIME seconds.
+ */
+int multiple_table_cleanup(multiple_flow_table table);
+
+/**
+ * Updates the rate information for all flows in the table according to the
+ * specified current time and EWMA weight.
+ */
+void multiple_table_update_flows(multiple_flow_table table, struct timeval now, double ewma_weight);
+
+#endif  /* _MULTIPLE_ACCOUNTING_H_ */