rough framework
[lemu] / connections.h
diff --git a/connections.h b/connections.h
new file mode 100644 (file)
index 0000000..5c0a3f8
--- /dev/null
@@ -0,0 +1,109 @@
+#ifndef CONNECTIONS_H
+#define CONNECTIONS_H
+
+#include <event2/bufferevent.h>
+#include <event2/buffer.h>
+#include <event2/dns.h>
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <arpa/inet.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+
+#include <ossp/uuid.h>
+
+#include "bsd_queue.h"
+#include "workqueue.h"
+
+enum connection_state_enum {
+       CONNECTION_STATE_INIT = 0,
+       CONNECTION_STATE_CONNECTED,
+       CONNECTION_STATE_AUTHENTICATED,
+       CONNECTION_STATE_WANT_CLOSE,
+       CONNECTION_STATE_CLOSED
+};
+
+typedef uint_fast8_t connection_flags_t;
+enum connection_flags {
+       CONN_TYPE_SSL = (1<<0),
+};
+
+struct connection {
+       pthread_mutex_t rc_mutex;               /* mutex for ref count */
+       size_t reference_count;                 /* */
+
+       struct server *server;
+
+       enum connection_state_enum state;
+       connection_flags_t flags;
+
+       struct bufferevent *bev;
+       uuid_t *uuid;                           /* uuid */
+       
+       char name[256];                         /* temporary auto-generated unique name */
+
+#ifdef DARWIN
+       struct timeval connect_time;            /* time of instantiation of this connection entity */
+       struct timeval last_received_time;      /* time of last data received from connection */
+#else
+       struct timespec connect_timespec;       /* time this connection entity was initialized */
+       struct timespec last_received_timespec; /* time of last data received from connection */
+#endif /* DARWIN */
+
+       size_t total_read;                      /* a tally of number of bytes read from connection */
+       struct timeval utime;                   /* accounting: rusage usertime accumulation */
+       struct timeval stime;                   /* accounting: rusage systime accumulation */
+
+       char *client_address;
+       struct sockaddr *sa;
+       int sa_len;
+       struct evdns_request *evdns_request;    /* the request for looking up the reverse of sa */
+       struct event *dns_retry_ev;             /* timeout event for retrying failed dns */
+       size_t dns_retries;
+
+       pthread_mutex_t commands_mutex;
+       STAILQ_HEAD(commands_stailq_head, command) commands_head;
+       volatile struct thread_struct *owner;   /* set if command queue is currently being consumed */
+
+       TAILQ_ENTRY(connection) tailq_entry;
+};
+
+struct connections {
+       pthread_mutex_t mutex;
+
+       TAILQ_HEAD(connection_tailq_head, connection) head;
+       size_t count;
+};
+
+
+
+int connections_init(struct connections *cs);
+void connections_fini(struct connections *cs);
+
+void connections_append(struct connection *c);
+void connections_remove(struct connection *c);
+
+struct connection ** connections_all_as_array(struct connections *cs, struct connection *c_exclude);
+
+int connection_init(struct server *s, struct connection *c, struct bufferevent *bev, struct sockaddr *sock, int socklen, connection_flags_t flags);
+void connection_inc_ref(struct connection *c);
+void connection_free(struct connection *c);
+
+int connection_command_enqueue(struct connection *c, struct command *command);
+
+void connection_accounting_increment(struct connection *c, struct rusage *ru_start, struct rusage *ru_end);
+
+void connection_lock_output(struct connection *c);
+void connection_unlock_output(struct connection *c);
+
+int connection_printf(struct connection *c, const char *fmt, ...);
+int connection_vprintf(struct connection *c, const char *fmt, va_list ap);
+int connection_printf_broadcast(struct connection *sender, bool exclude_sender, const char *fmt, ...);
+
+int connection_multi_send(struct connection **clist, char *data, size_t len);
+
+void connection_resolve_hostname(struct connection *c);
+
+
+#endif /* CONNECTIONS_H */