#include #include #include #include "queue.h" #define VERSION 0.1 #define BUFMAX 1024 * 10 #define READSIZE 1024 #define WRITESIZE 1024 #define POLL_TIMEOUT 1000 #define POLL_TIMEOUT_ATOMIC 500 #define POLL_ATOMIC_RETRY 3 #define ROUTES_MAX 256 #define LISTENERS_MAX 16 #define LISTENER_CONN_MAX 10 #define POLLER_MAX (ROUTES_MAX + (LISTENERS_MAX + LISTENERS_MAX * LISTENER_CONN_MAX)) #define EXEC_MAX 10 #define MSG_MAGIC "bXl4" struct msg_header { uint8_t version; uint8_t type; uint8_t orig; uint8_t dest; uint8_t arg; /* UNUSED */ uint16_t datalen; }; #define MSG_HEADER_SIZE 7 // XXX change 8 to 13 when we'll use base64 #define MSG_HEADER_SIZE_ENCODED 7 #define MSG_VERSION 1 #define MSG_DATALEN_MAX 1024 * 100 /* keep in sync with pg.c process() cmd */ /* keep in sync with msg.c msg_unpack_header msg_client and msg_server */ /* XXX fix that mess, all in one file */ enum msg_type { MSG_INIT = 0, MSG_INIT_ASYNC = 1, MSG_KILL = 2, MSG_EXEC = 3, MSG_READ = 4, MSG_WRITE = 5, MSG_DATA = 6, MSG_OK = 7, MSG_ERR = 8 }; #define MSG_MAX 8 struct route { char dest; int type; #define ROUTE_PROC 0 #define ROUTE_GW 1 union { struct { char *cmd; char **argv; int pid; int fd[2]; int async; uint8_t *async_sndbuf; int async_sndbuf_size; } proc; struct { char dest; } gw; }; LIST_ENTRY(route) entry; }; struct listener { int sock; int type; #define LISTENER_UNIX 0 #define LISTENER_INET 1 union { struct { char *path; } sock_unix; struct { // XXX TODO //struct addrinfo *res; } sock_inet; }; LIST_HEAD(, conn) conns; int conns_count; LIST_ENTRY(listener) entry; }; enum conn_state { CONN_OPEN = 0, CONN_READY = 1 }; struct conn { struct listener *listener; int orig; int fd; enum conn_state state; int async; struct { char *cmd; char **argv; int pid; int fd[2]; uint8_t *async_writebuf; int async_writebuf_size; } exec; LIST_ENTRY(conn) entry; }; struct conf { char me; int server; char client_dest; }; struct conf conf; LIST_HEAD(, route) routes; int routes_count; LIST_HEAD(, listener) listeners; int listeners_count; /* msg.c */ int msg_send(int, int, char, uint8_t, int, uint8_t *); int msg_send_from_fd(int, int, char, uint8_t, int); uint8_t *msg_pack_header(int, char, char, uint8_t, int); struct msg_header *msg_unpack_header(uint8_t *); int msg_read_data(int, uint8_t **, int); int msg_read_data_to_fd(int, int, int); /* route.c */ int route_add(char, int, char *, int, char *, char); int route_fw(int, struct msg_header *, uint8_t *); struct route *route_find(char); int route_bufferize(struct route *, int); /* listener.c */ int listener_add(int, char *); struct listener *listener_find(int); struct listener *listener_find_orig(char); int listener_conn_add(struct listener *, int); void listener_conn_del(struct conn *); void listener_conn_move(struct conn *, struct conn *); struct conn *listener_conn_find(int); struct conn *listener_conn_find_orig(char); struct conn *listener_conn_find_exec(int); int listener_conn_exec(struct conn *, char *, char **); void listener_conn_exec_kill(struct conn *); int listener_conn_exec_bufferize(struct conn *, int); /* log.c */ void log_init(int, int); void log_tmp(const char *, ...); void log_debug(const char *, ...); void log_info(const char *, ...); void log_warn(const char *, ...); void fatal(const char *, ...); /* util.c */ int send_cmd(char, int, uint8_t, uint8_t *, int); int intab(int *, int, int); char **explode (char *, int, char *, int *); void *xmalloc(size_t); void *xcalloc(size_t, size_t); int setnonblock(int); int execpipe(char *, char **, int *); int readbuf(int, uint8_t **, int); int writebuf(uint8_t *, int, int); int readwrite(int, int, int);