Importing all of DRL, including ulogd and all of its files.
[distributedratelimiting.git] / drl / drl_state.h
diff --git a/drl/drl_state.h b/drl/drl_state.h
new file mode 100644 (file)
index 0000000..2b1ec5e
--- /dev/null
@@ -0,0 +1,250 @@
+/* See the DRL-LICENSE file for this file's software license. */
+
+#ifndef _DRL_STATE_
+#define _DRL_STATE_
+
+#define _XOPEN_SOURCE 600
+
+/* FILE */
+#include <stdio.h>
+
+/* uint32_t */
+#include <sys/types.h>
+#include <inttypes.h>
+
+/* in_addr_t, in_port_t */
+#include <arpa/inet.h>
+
+/* pthread functions. */
+#include <pthread.h>
+
+/* fd_set */
+#include <sys/select.h>
+
+/* Hash map types/functions. */
+#ifdef STANDALONE
+#include "../util.h"
+#else
+#include "util.h"
+#endif
+
+#define MAX_IDENTS (1024)
+#define MAX_LIMITERS (128)
+
+#define REMOTE_AWOL_THRESHOLD (3)
+
+enum transports { UDP, TCP };
+
+typedef struct gossipval {
+    int gossip_branch;
+    double last_nonzero;
+    double value;
+    double weight;
+} gossip_t;
+
+typedef struct out_neighbor {
+    uint32_t next_seqno;
+    uint32_t first_seqno;
+    double saved_value;
+    double saved_weight;
+} out_neighbor_t;
+
+typedef struct in_neighbor {
+    uint32_t seen_seqno;
+    double saved_value;
+    double saved_weight;
+} in_neighbor_t;
+
+typedef struct remote_node {
+    in_addr_t addr;
+    in_port_t port;
+} remote_node_t;
+
+typedef struct remote_limiter {
+    /** The last known value at the remote limiter. */
+    double rate;
+
+    in_neighbor_t incoming;
+    out_neighbor_t outgoing;
+
+    /* Socket to contact this remote limiter, if using TCP. */
+    int socket;
+
+    in_addr_t addr;
+    in_port_t port;
+
+    /** Flag to keep track of situations in which we read from this node's
+     * value more than once before receiving an update from it.  We use this
+     * value to know when it's safe to begin decaying the remote node's value
+     * (because we assume that it has failed). */
+    int awol;
+
+} remote_limiter_t;
+
+typedef struct comm {
+    /** Communication policy. (COMM_MESH, COMM_GOSSIP) */
+    enum commfabrics comm_fabric;
+
+    /** Transport protocol. */
+    enum transports transport_proto;
+
+    /** Current local value. */
+    double local_rate;
+
+    /** Previous local value. */
+    double last_local_rate;
+
+    double rate_change;
+
+    /** The number of remote nodes in the identity */
+    uint32_t remote_node_count;
+
+    remote_node_t *remote_nodes;
+
+    /** Array containing all known remote limiters in this identity.
+     * Contains the same information as the remote_node_map. */
+    remote_limiter_t *remote_limiters;
+
+    /** Hash map containing all the remote limiters in this identity.
+     * Indexed by the remote_node_t used to create the remote_limiter_t.
+     * Maps to the appropriate element of the remote_limiters array. */
+    map_handle remote_node_map;
+
+    /** A mutex to protect the comm structure. */
+    pthread_mutex_t lock;
+
+    /** Gossip values for our local identity */
+    gossip_t gossip;
+
+    /** Function pointer to send function. */
+    int (*send_function)(struct comm *comm, uint32_t id, int sock);
+
+#if 0
+    /** Thread for handling incoming TCP data. */
+    pthread_t tcp_recv_thread;
+
+    /** Descriptor set for reading TCP messages */
+    fd_set fds;
+#endif
+
+    /** Array of integers specifiying which nodes, if any, have outstanding
+     * unacked data.  When nodes fall in this category, and it's time to send,
+     * these nodes will be chosen first.  This only affects gossip.  A
+     * negative number means there is no retransmit necessary.  Otherwise, the
+     * value is the index into the remote_limiters array of the necessary
+     * retransmit. */
+    int *retrys;
+
+} comm_t;
+
+typedef struct message {
+    uint32_t magic;
+    uint32_t ident_id;
+    uint32_t seqno;
+    uint32_t min_seqno;
+    double value;
+    double weight;
+    uint16_t type;
+} message_t;
+
+typedef struct hello_message {
+    uint32_t magic;
+    uint32_t ident_id;
+    uint16_t port;
+} hello_t;
+
+#if 0
+struct recv_thread_args {
+    comm_ident_t *ident;
+    pthread_rwlock_t *lock;
+    uint16_t port;
+};
+#endif
+
+#if 0
+/**
+ * Initializes the global limiter.
+ *
+ * @param ipaddr The IP address on which the limiter should listen.
+ * INADDR_ANY will suffice.  Should be specified in network byte order.
+ *
+ * @param port The port on which the limiter should listen. Should be specified
+ * in network byte order.
+ */
+void init_limiter(const in_addr_t ipaddr, const in_port_t port);
+
+/**
+ * Deallocates the entire global limiter.
+ */
+void destroy_limiter();
+#endif
+
+/**
+ * Fills in the communication structure of an identity.
+ *
+ * @param comm The communication structure to be created/populated.
+ *
+ * @param config The configuration options for the identity.
+ *
+ * @param nodes An array of remote nodes belonging to this identity.
+ *
+ * @returns 0 on success, ENOMEM if memory cannot be allocated.
+ */
+int new_comm(comm_t *comm, ident_config *config, remote_node_t *nodes);
+
+/**
+ * Frees the memory associated with an identity's communication structure.
+ *
+ * @param comm The communication structure to free.
+ */
+void free_comm(comm_t *comm);
+
+/**
+ * Calculates and reads the current aggregate value for an identity.
+ * This value includes the locally observed value.
+ *
+ * @param comm The comm structure of the identity in question.
+ *
+ * @param aggregate The location at which the aggregate value will
+ * be stored.
+ *
+ * @returns 0 on success, EINVAL on error.
+ */
+int read_comm(comm_t *comm, double *aggregate);
+
+/**
+ * Updates the locally observed value of an identity.
+ *
+ * @param comm The comm structure of the identity to update.
+ *
+ * @param value The new locally observed value.
+ *
+ * @returns 0 on success, EINVAL on error.
+ */
+int write_local_value(comm_t *comm, const double value);
+
+/**
+ * Sends the local state information to one or more peer limiters in the same
+ * identity.  If the identity is configured as a mesh, it will send to all
+ * peers.  If the identity is configured using gossip, it will send to the
+ * number of peers specified by the gossip_branch field of the comm_config_t
+ * that was used to configure the identity.
+ *
+ * @param comm The communication structure of the identity whose value should
+ * be propagated.
+ *
+ * @param id The unique id of the identity that is sending.
+ *
+ * @returns 0 on success, ENOMEM if there was not enough memory, or possibly
+ * other E values as a result of socket-related results.
+ */
+int send_update(comm_t *comm, uint32_t id);
+
+/**
+ * Thread that is responsible for receiving data from other limiters.
+ *
+ * @param limiter The limiter_t that is to be doing the receiving.
+ */
+void *limiter_receive_thread(void *unused);
+
+#endif  /* _DRL_STATE_ */