/* 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 //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_ */