#include #include /* XXX for now lets use the default sys/queue.h * maybe in the future it will become a pain on linux because they ship * an old version of it, and i'll need to ship the BSD version * #include "contrib/queue.h" */ #include #define PACKET_VERSION 1 #define PACKET_BUFFER_SIZE 16384 #define DNSNAME_MAX 20 struct gg_packet { #define PACKET_HEADER_SIZE 2 u_int8_t ver; u_int8_t type; /* XXX nicer way for _SIZE ... ? */ #define PACKET_TYPE_MIN 0 #define PACKET_TYPE_MAX 3 #define PACKET_NEWCONN 0 #define PACKET_NEWCONN_SIZE (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.newconn) #define PACKET_DELCONN 1 #define PACKET_DELCONN_SIZE (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.delconn) #define PACKET_DATA 2 #define PACKET_DATA_SIZE (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.data) #define PACKET_NAME 3 #define PACKET_NAME_SIZE ((PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.name) - DNSNAME_MAX) union { struct newconn { u_int16_t id; u_int32_t src; u_int32_t dst; u_int8_t proto; u_int8_t size; } newconn; struct delconn { u_int16_t id; } delconn; struct data { u_int16_t connid; u_int8_t size; } data; struct name { u_int32_t addr; u_int8_t len; u_char fqdn[DNSNAME_MAX]; } name; } pdat; #define newconn_id pdat.newconn.id #define newconn_src pdat.newconn.src #define newconn_dst pdat.newconn.dst #define newconn_proto pdat.newconn.proto #define newconn_size pdat.newconn.size #define delconn_id pdat.delconn.id #define data_connid pdat.data.connid #define data_size pdat.data.size #define name_addr pdat.name.addr #define name_len pdat.name.len #define name_fqdn pdat.name.fqdn }; struct gg_user { LIST_ENTRY(gg_user) entry; int id; struct sockaddr_in addr; char *buf[16384]; }; struct gg_server { const char *ip; int port; struct sockaddr_in addr; struct event *ev; int sock; int (*handle_conn)(struct gg_server *, struct gg_user *); int (*handle_packet)(struct gg_server *, struct gg_user *, struct gg_packet *); void *usrdata; LIST_HEAD(, gg_user) user_list; int user_id_count; }; struct gg_client { const char *ip; int port; struct sockaddr_in addr; struct event *ev; int sock; int status; #define GG_CLIENT_STATUS_DISCONNECTED 0 #define GG_CLIENT_STATUS_CONNECTED 1 int (*handle_conn)(struct gg_client *); int (*handle_packet)(struct gg_client *, struct gg_packet *); void *usrdata; }; struct gg_server *gg_server_start(struct event_base *, char *, int, int (*handle_conn)(struct gg_server *, struct gg_user *), int (*handle_packet)(struct gg_server *, struct gg_user *, struct gg_packet *), void *); int gg_server_send(struct gg_server *, struct gg_packet *, int, struct gg_user *); void gg_server_stop(struct gg_server *); struct gg_client *gg_client_connect(struct event_base *, char *, int, int (*handle_conn)(struct gg_client *), int (*handle_packet)(struct gg_client *, struct gg_packet *), void *); int gg_client_send(struct gg_client *, struct gg_packet *, int); void gg_client_disconnect(struct gg_client *); void *xmalloc(size_t); void *xcalloc(size_t, size_t); void fd_nonblock(int); void addrcpy(struct sockaddr_in *, struct sockaddr_in *);