#ifndef CONN_ENGINE_CORE_H
#define CONN_ENGINE_CORE_H
#include <Conn_config.h>
#define _GNU_SOURCE
#include <stdarg.h>
#include <resolv.h>
#include <errno.h>
#include <signal.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <ctype.h>
/* type */
enum CONN_TYPE {
CONN_TYPE_UNK = 0,
CONN_TYPE_MASTER,
CONN_TYPE_P2P
};
/* state */
enum CONN_STATE {
CONN_STATE_FREE = 0,
CONN_STATE_EMPTY,
CONN_STATE_OPEN,
CONN_STATE_LISTEN,
CONN_STATE_CONNECT_0,
CONN_STATE_CONNECT_a,
CONN_STATE_CONNECT_b,
CONN_STATE_ERROR
};
/* error kind */
enum CONN_ERROR {
CONN_ERROR_NO_ERROR = 0,
CONN_ERROR_USERREQ, /* user requested the close */
CONN_ERROR_POLL,
CONN_ERROR_RECV,
CONN_ERROR_SEND,
CONN_ERROR_SOCKET,
CONN_ERROR_HANGUP,
CONN_ERROR_GETADDRINFO,
CONN_ERROR_EXPIRED,
CONN_ERROR_ACCEPT, /* This is free. TODO: check! */
CONN_ERROR_MEM,
CONN_ERROR_CONNECT,
CONN_ERROR_READ_TIMEOUT,
CONN_ERROR_CONN_TIMEOUT,
CONN_ERROR_INTERNAL
};
/* FLAGS */
#define CONN_FLAGS_AUTO_RECONNECT 0x01 << 0
#define CONN_FLAGS_CLOSE_AFTER_SEND 0x01 << 1
/* Parameters */
enum CONN_PARA {
CONN_PARA_AUTO_RECONNECT = 0,
CONN_PARA_RECONNECT_DELAY,
CONN_PARA_IDLE_TIME,
CONN_PARA_READ_TIMEOUT,
CONN_PARA_CONN_TIMEOUT,
CONN_PARA_TRIGGER,
CONN_PARA_IBUF,
CONN_PARA_OBUF
};
/* Callbacks */
enum CONN_CB {
CONN_CB_ACCEPT = 0,
CONN_CB_RECV,
CONN_CB_SEND,
CONN_CB_DATA,
CONN_CB_CLOSE,
CONN_CB_TRIGGER,
CONN_CB_ERROR,
CONN_CB_CONNECTED,
CONN_CB_ACCEPT_ERROR
};
/* Engine type */
enum CONN_ENGINE {
CONN_ENGINE_POLL = 1,
CONN_ENGINE_EPOLL
};
extern unsigned int CONN_POLLIN;
extern unsigned int CONN_POLLOUT;
extern unsigned int CONN_POLLPRI;
extern unsigned int CONN_POLLERR;
extern unsigned int CONN_POLLHUP;
extern unsigned int CONN_POLLNVAL;
extern unsigned int CONN_POLLRDNORM;
extern unsigned int CONN_POLLRDBAND;
struct Conn
{
int fd;
unsigned int events, revents; /* I/O events */
unsigned char type;
unsigned char state;
unsigned char error_state;
unsigned int slot;
char *ibuf;
unsigned int ibuf_size, ibuf_head, ibuf_tail;
char *obuf;
unsigned int obuf_size, obuf_head, obuf_tail;
struct timeval trecv, tsend; /* last time we saw an receive/send */
time_t idle; /* idle time allowed */
unsigned int read_timeout; /* Max timeout for receiving an answer (milliseconds) */
struct timeval conn_syn; /* Time when a connection was initiated */
unsigned int conn_timeout; /* Timeout for connection (milliseconds) */
time_t last_trigger; /* last trigger was at */
time_t trigger; /* Frequency of wakeup a connection */
int sock_domain;
int sock_type;
int sock_protocol;
char addr[64], bind_addr[64];
int port, bind_port;
unsigned long long via; /* "via" is the connection id via a client was accepted */
unsigned long long bi, bo;
void *private; /* private use by user */
/* reconnect stuff */
unsigned int retries;
unsigned int delay; /* delay between reconnects */
time_t tryat; /* when we go to CONNECT_a state */
int xerrno;
time_t start;
unsigned int flags;
/* bandwidth stuff */
struct timeval band_lasttime; /* last time tokens were added */
unsigned int band_tokens; /* 1 token -> 1000 bytes */
unsigned int band_factor; /* tokens cannot go past f * w */
unsigned int band_width; /* in 1000b increments */
unsigned long long id; /* the id of a connection */
/* Specific callbacks */
void (*cb_accept)(struct Conn *C);
void (*cb_recv)(struct Conn *C);
void (*cb_send)(struct Conn *C);
void (*cb_data)(struct Conn *C);
void (*cb_close)(struct Conn *C);
void (*cb_trigger)(struct Conn *C);
void (*cb_error)(struct Conn *C);
void (*cb_connected)(struct Conn *C);
void (*cb_accept_error)(struct Conn *C);
struct timeval time_open; /* When a connect succeded */
};
struct Conn_queue_entry
{
unsigned int slot;
struct Conn_queue_entry *next;
};
struct Conn_queue
{
struct Conn_queue_entry *head, *tail;
};
/* For parsing */
struct Conn_split_cell
{
struct Conn_split_cell *next;
char *left;
char *right;
unsigned int right_len;
};
struct Conn_split
{
struct Conn_split_cell *head, *tail;
char *line;
};
/* Variables */
extern void (*Conn_accept_cb)(struct Conn *C);
extern void (*Conn_recv_cb)(struct Conn *C);
extern void (*Conn_send_cb)(struct Conn *C);
extern void (*Conn_data_cb)(struct Conn *C);
extern void (*Conn_close_cb)(struct Conn *C);
extern void (*Conn_trigger_cb)(struct Conn *C);
extern void (*Conn_error_cb)(struct Conn *C);
extern void (*Conn_connected_cb)(struct Conn *C);
extern void (*Conn_accept_error_cb)(struct Conn *C);
extern char *(*Conn_status_slot_html_cb)(const struct Conn *C);
extern char *(*Conn_status_cb)(void);
extern unsigned int Conn_max_reached;
extern unsigned int Conn_default_ibuf;
extern unsigned int Conn_default_obuf;
extern unsigned int Conn_max_ibuf;
extern unsigned int Conn_max_obuf;
extern unsigned int Conn_no;
extern unsigned int Conn_work_to_do;
extern unsigned int Conn_max;
extern unsigned long Conn_total;
extern unsigned int Conn_start;
extern unsigned int Conn_pending;
extern struct timeval Conn_now;
extern unsigned int Conn_max_send;
extern unsigned int Conn_max_recv;
extern unsigned short Conn_level;
extern unsigned int Conn_accept_is_allowed;
extern unsigned int Conn_accept_is_allowed_last;
extern struct Conn *Conns;
extern unsigned int Conn_inited;
extern unsigned int Conn_allocated;
extern unsigned long long Conn_id;
extern unsigned int Conn_must_stop;
extern char Conn_error[512];
extern FILE *Conn_Log;
extern int debug_band;
/* queues */
extern struct Conn_queue Conn_queue_free;
/* Functions */
extern char *Conn_strerror(void);
extern void Log(const unsigned short level, char *format, ...);
extern char *Conn_errno(const struct Conn *C);
extern char *Conn_status_slot(const unsigned int slot);
extern char *Conn_status(const unsigned int flags);
extern int Conn_try_expand_buf(const unsigned int slot, const int what,
const unsigned int needed);
extern char *Conn_state(const struct Conn *C);
extern long long Conn_time_diff(const struct timeval *t1,
const struct timeval *t2);
extern void Conn_last_time(const struct Conn *C, struct timeval *tv);
extern int Conn_setnonblock(const int fd);
extern char *Conn_dump(const char *buf_src, const int len_src);
extern char *Conn_dumphex(const char *buf_src, const int len_src);
extern void Conn_debug(FILE *f, const unsigned short debug);
extern void Conn_close(struct Conn *C);
extern int Conn_ignore(const unsigned int slot);
extern void Conn_expire(const unsigned int slot);
extern int Conn_set_cb(struct Conn *C, const unsigned int cb_type,
void (*f)(struct Conn *));
extern char *Conn_get_line(struct Conn *C);
extern void Conn_for_every_line(struct Conn *C,
int (*cb)(struct Conn *C, char *line));
extern void Conn_eat(struct Conn *C, const unsigned int bytes);
extern void Conn_eatall(struct Conn *C);
extern unsigned int Conn_qlen(const struct Conn *C);
extern void Conn_set(struct Conn *C, const unsigned int var,
const int val);
extern int Conn_get_fd(const struct Conn *C);
extern unsigned long long Conn_getid(const struct Conn *C);
extern struct Conn *Conn_get(const unsigned long long id);
extern char *Conn_ibuf(const struct Conn *C);
extern char *Conn_obuf(const struct Conn *C);
extern char *Conn_domain(const struct Conn *C);
extern char *Conn_type(const struct Conn *C);
extern char *Conn_get_socket_protocol(const struct Conn *C);
extern int Conn_addr_family(const char *addr);
extern void Conn_error_raise(const unsigned int slot, const int err);
extern void Conn_stop(void);
extern int Conn_set_address(struct Conn *C, const int flags);
/* queue stuff */
extern void Conn_queue_init(struct Conn_queue *q);
extern int Conn_queue_add(struct Conn_queue *q,
const unsigned int slot);
extern void Conn_queue_destroy(struct Conn_queue *q);
/* String stuff */
extern char *Conn_strstr(struct Conn *C, const char *str);
extern char *Conn_strcasestr(struct Conn *C, const char *str);
/* splitting stuff */
extern void Conn_rtrim(char *s, const char *chars);
extern struct Conn_split *Conn_split(const char *line);
extern char *Conn_split_get_size(const struct Conn_split *s,
const char *l, unsigned int *len);
extern char *Conn_split_get_e(const struct Conn_split *s,
const char *l);
extern char *Conn_split_get(const struct Conn_split *s,
const char *l);
extern unsigned long Conn_split_get_ul(const struct Conn_split *s,
const char *l, unsigned int base);
extern unsigned long long Conn_split_get_ull(const struct Conn_split *s,
const char *l, unsigned int base);
extern double Conn_split_get_d(const struct Conn_split *s,
const char *l);
extern void Conn_split_free(struct Conn_split **s);
/* Misc stuff */
extern int Conn_alphanum(const char *s);
#endif