diff options
author | Laurent Ghigonis <laurent@p1sec.com> | 2013-10-13 18:52:16 +0200 |
---|---|---|
committer | Laurent Ghigonis <laurent@p1sec.com> | 2013-10-13 18:52:16 +0200 |
commit | a6eb95307d495b66e6a869a21cc46d564daa7524 (patch) | |
tree | 6b34d1979ad6a08c8e4a2a193cad272ca7de63dd | |
parent | add doc ressource (diff) | |
download | glouglou-a6eb95307d495b66e6a869a21cc46d564daa7524.tar.xz glouglou-a6eb95307d495b66e6a869a21cc46d564daa7524.zip |
WIP glougloud server / packets
-rw-r--r-- | v3/glougloud/Makefile | 2 | ||||
-rw-r--r-- | v3/glougloud/glougloud_mod_0_internal/glougloud_mod_0_internal.c | 4 | ||||
-rw-r--r-- | v3/libglouglou/Makefile | 4 | ||||
-rw-r--r-- | v3/libglouglou/client.c | 13 | ||||
-rw-r--r-- | v3/libglouglou/libglouglou.h | 66 | ||||
-rw-r--r-- | v3/libglouglou/packet.c | 36 | ||||
-rw-r--r-- | v3/libglouglou/server.c | 81 |
7 files changed, 180 insertions, 26 deletions
diff --git a/v3/glougloud/Makefile b/v3/glougloud/Makefile index 1e3e71d..7a36f34 100644 --- a/v3/glougloud/Makefile +++ b/v3/glougloud/Makefile @@ -41,7 +41,9 @@ install: $(PROG) mkdir -p $(INCLUDEDIR) install -m 0755 $(PROG) $(BINDIR) install -m 0644 $(HEADERS) $(INCLUDEDIR) + make -C glougloud_mod_0_internal_headers/ install make -C glougloud_mod_0_internal/ install + make -C glougloud_mod_1_net_headers/ install make -C glougloud_mod_1_net/ install clean: diff --git a/v3/glougloud/glougloud_mod_0_internal/glougloud_mod_0_internal.c b/v3/glougloud/glougloud_mod_0_internal/glougloud_mod_0_internal.c index 01931b6..4b6ab4e 100644 --- a/v3/glougloud/glougloud_mod_0_internal/glougloud_mod_0_internal.c +++ b/v3/glougloud/glougloud_mod_0_internal/glougloud_mod_0_internal.c @@ -1,6 +1,6 @@ #include <glougloud.h> - #include <libglouglou.h> +#include <libglouglou/modules/libglouglou_mod_0_internal.h> struct ggdmodviz_conf * ggdmodviz_init(struct glougloud *ggd) @@ -10,7 +10,7 @@ ggdmodviz_init(struct glougloud *ggd) log_debug("glougloud_mod_internal: viz init"); mod = xcalloc(1, sizeof(struct ggdmodviz_conf)); - mod->id = 0; + mod->id = GLOUGLOUD_MOD_0_INTERNAL_ID; mod->api_version = 1; return mod; diff --git a/v3/libglouglou/Makefile b/v3/libglouglou/Makefile index 0b61a9e..a35fc5f 100644 --- a/v3/libglouglou/Makefile +++ b/v3/libglouglou/Makefile @@ -7,8 +7,8 @@ LIBDIR=$(PREFIX)/lib LIBNAME=libglouglou TARGET = ${LIBNAME}.so -SOURCES = log.c client.c packet.c server.c utils.c -HEADERS = libglouglou.h +SOURCES = log.c client.c packet.c server.c utils.c libglouglou_mod_0_internal/libglouglou_mod_0_internal.c +HEADERS = libglouglou.h libglouglou_mod_0_internal.h OBJECTS = $(SOURCES:.c=.o) all: $(TARGET) diff --git a/v3/libglouglou/client.c b/v3/libglouglou/client.c index e69de29..1e2c585 100644 --- a/v3/libglouglou/client.c +++ b/v3/libglouglou/client.c @@ -0,0 +1,13 @@ +#include "libglouglou.h" + +int +gg_client_send(struct gg_client *cli, int module_id, struct ggpkt *pkt) +{ + if (!pkt) { + log_warn("gg_client_send called with NULL pkt !"); + return -1; + } + + // XXX + return -1; +} diff --git a/v3/libglouglou/libglouglou.h b/v3/libglouglou/libglouglou.h index 7677a2f..ab5ff8c 100644 --- a/v3/libglouglou/libglouglou.h +++ b/v3/libglouglou/libglouglou.h @@ -16,22 +16,34 @@ /* packet.c */ -#define PACKET_VERSION 0x03 -#define PACKET_HEADER_SIZE 2 -#define PACKET_BUFFER_SIZE 16384 -#define PACKET_SNDBUF_MAX 500 -#define PACKET_ARG_MAX 60 - -struct __attribute__((packed)) gg_packet { - u_int8_t ver; - u_int8_t module; +#define GGPKT_ARG_MAX 60 +#define GGPKT_BUF_SIZE 16384 + +/* included in packets from libglouglou modules */ +struct ggpkt_header { + u_int8_t module_id; + u_int8_t module_version; + u_int16_t len; }; +struct ggpkt { + void *body; /* packet created in libglouglou modules */ + int (*body_len)(struct ggpkt *); /* implemented in libglouglou modules */ +}; + +struct ggpkt *ggpkt_new(int module_id, int module_version, + void *body, int (*fn_body_len)(struct ggpkt *)); +int ggpkt_header_encode(struct ggpkt_header *header, + int module_id, int module_version); +int ggpkt_header_decode(struct ggpkt_header *header, + int *module_id, int *module_version); + /* client.c */ -enum client_status { - GG_CLIENT_STATUS_CONNECTING = 0, - GG_CLIENT_STATUS_CONNECTED = 1 +enum gg_client_status { + GG_CLIENT_STATUS_CONNECTED = 0, + GG_CLIENT_STATUS_AUTHENTICATED = 1, + GG_CLIENT_STATUS_OK = 2 }; struct gg_client { @@ -42,27 +54,37 @@ struct gg_client { struct event *ev; struct event *ev_timer; int sock; - enum client_status status; + enum gg_client_status status; int (*handle_conn)(struct gg_client *); - int (*handle_packet)(struct gg_client *, struct gg_packet *); + int (*handle_packet)(struct gg_client *, struct ggpkt *); void *usrdata; struct sendbuf *sbuf; }; struct gg_client *gg_client_connect(struct event_base *, - struct addr *ip, int port, - int (*handle_conn)(struct gg_client *prb), - int (*handle_pkt)(struct gg_client *prb, struct gg_packet *pkt)); -void gg_client_disconnect(struct gg_client *); -int gg_client_send(struct gg_client *, struct gg_packet *); + struct addr *ip, int port, + int *register_module_ids, + int (*handle_conn)(struct gg_client *prb), + int (*handle_pkt)(struct gg_client *prb, + struct ggpkt *pkt)); +void gg_client_disconnect(struct gg_client *); +int gg_client_send(struct gg_client *, + int module_id, struct ggpkt *); /* server.c */ +enum gg_user_status { + GG_USER_STATUS_CONNECTED = 0, + GG_USER_STATUS_AUTHENTICATED = 1, + GG_USER_STATUS_OK = 2 +}; + struct gg_user { LIST_ENTRY(gg_user) entry; int id; int sock; + enum gg_user_status status; struct sockaddr_in addr; struct sendbuf *sbuf; }; @@ -74,9 +96,10 @@ struct gg_server { struct sockaddr_in addr; struct event *ev; int sock; + int *module_ids; int (*handle_conn)(struct gg_server *, struct gg_user *); int (*handle_packet)(struct gg_server *, - struct gg_user *, struct gg_packet *); + struct gg_user *, struct ggpkt *); void *usrdata; LIST_HEAD(, gg_user) user_list; int user_count; @@ -85,8 +108,9 @@ struct gg_server { struct gg_server *gg_server_start(struct event_base *, struct addr *ip, int port, + int *register_module_ids, int (*handle_conn)(struct gg_server *srv, struct gg_user *usr), - int (*handle_pkt)(struct gg_server *srv, struct gg_user *usr, struct gg_packet *pkt), void *); + int (*handle_pkt)(struct gg_server *srv, struct gg_user *usr, struct ggpkt *pkt), void *); void gg_server_stop(struct gg_server *srv); /* log.c */ diff --git a/v3/libglouglou/packet.c b/v3/libglouglou/packet.c index e69de29..e5f275f 100644 --- a/v3/libglouglou/packet.c +++ b/v3/libglouglou/packet.c @@ -0,0 +1,36 @@ +#include <stdarg.h> +#include <stdlib.h> + +#include "libglouglou.h" + +struct ggpkt *ggpkt_new(int module_id, int module_version, + void *body, int (*fn_body_len)(struct ggpkt *)) +{ + struct ggpkt *pkt; + pkt = xcalloc(1, sizeof(struct ggpkt)); + pkt->body = body; + pkt->body_len = fn_body_len; + ggpkt_header_encode((struct ggpkt_header *)body, + module_id, module_version); + + return pkt; +} + +int +ggpkt_header_encode(struct ggpkt_header *header, + int module_id, int module_version) +{ + header->module_id = module_id; + header->module_version = module_version; + return 0; +} + +int +ggpkt_header_decode(struct ggpkt_header *header, + int *module_id, int *module_version) +{ + *module_id = header->module_id; + *module_version = header->module_version; + return 0; +} + diff --git a/v3/libglouglou/server.c b/v3/libglouglou/server.c index d3870fe..88e8d76 100644 --- a/v3/libglouglou/server.c +++ b/v3/libglouglou/server.c @@ -6,10 +6,59 @@ #include <libsendbuf.h> #include "libglouglou.h" +/* we include libglouglou_mod_0_internal header and link against it, wich + * is not the case for other libglouglou module which are normaly independent */ +#include "libglouglou_mod_0_internal/libglouglou_mod_0_internal.h" + void cb_srv_receive(evutil_socket_t fd, short what, void *arg) { + struct gg_server *srv; + struct ggpkt *pkt; + struct sockaddr_in remote; + socklen_t remote_len; + char buf[PACKET_BUFFER_SIZE]; + + // XXX IN PROGRESS + srv = (struct gg_server *)arg; + remote_len = sizeof(struct sockaddr_in); + len = recvfrom(fd, buf, sizeof(buf), 0, + (struct sockaddr *)&remote, &remote_len); + if (len < 0) { + error("recvfrom failed"); + return; + } + pkt = ggpkt_receive_header(fd, &len, &remote, &remote_len); + + usr = user_find(srv, &remote); + if (!usr) { + + usr = user_add(srv, &remote); + // XXX delay until AUTH if (srv->handle_conn) + // srv->handle_conn(srv, usr); + + user_send(usr, "", 0); + } else { + debug("Incoming data from existing user !"); + if (len == 0) { + user_del(srv, usr); + return; + } + if (srv->handle_packet) { + buf_p = buf; + buf_len = len; + while (buf_len > 0 && (pkt = pkt_decode(&buf_p, &buf_len))) + srv->handle_packet(srv, usr, pkt); + if (buf_len > 0) { + /* XXX store incomplete packet for next recv */ + error("incomplete packet, dropped %d bytes !", buf_len); + } + } + } + + pkt = ggpkt_mod_0_internal_hello_res(); + gg_server_send(srv, pkt); } int @@ -24,6 +73,34 @@ user_send(struct gg_user *usr, void *data, int size) return sent; } +struct gg_user * +user_add(struct gg_server *srv, struct sockaddr_in *remote) +{ + struct gg_user *usr; + struct sendbuf *sbuf; + + usr = xcalloc(1, sizeof(struct gg_user)); + usr->id = srv->user_id_count; + srv->user_id_count++; + srv->user_count++; + usr->sock = srv->sock; + addrcpy(&usr->addr, remote); + + sbuf = sendbuf_new(srv->ev_base, PACKET_SNDBUF_MAX, 200, cb_usr_send, usr); + if (!sbuf) + goto err; + usr->sbuf = sbuf; + + LIST_INSERT_HEAD(&srv->user_list, usr, entry); + verbose("Add user %d !", usr->id); + + return usr; + +err: + user_del(srv, usr); + return NULL; +} + void user_del(struct gg_server *srv, struct gg_user *usr) { @@ -39,8 +116,9 @@ user_del(struct gg_server *srv, struct gg_user *usr) struct gg_server *gg_server_start(struct event_base *evb, struct addr *ip, int port, + int *register_module_ids, int (*handle_conn)(struct gg_server *srv, struct gg_user *usr), - int (*handle_packet)(struct gg_server *srv, struct gg_user *usr, struct gg_packet *pkt), void *usrdata) + int (*handle_packet)(struct gg_server *srv, struct gg_user *usr, struct ggpkt *pkt), void *usrdata) { struct gg_server *srv; @@ -48,6 +126,7 @@ struct gg_server *gg_server_start(struct event_base *evb, srv->evb = evb; srv->ip = ip; srv->port = port; + srv->module_ids = register_module_ids; srv->handle_conn = handle_conn; srv->handle_packet = handle_packet; srv->usrdata = usrdata; |