diff options
-rw-r--r-- | libglouglou/libglouglou.c | 114 | ||||
-rw-r--r-- | libglouglou/libglouglou.h | 36 |
2 files changed, 127 insertions, 23 deletions
diff --git a/libglouglou/libglouglou.c b/libglouglou/libglouglou.c index 3882a6c..5c590ba 100644 --- a/libglouglou/libglouglou.c +++ b/libglouglou/libglouglou.c @@ -1,26 +1,66 @@ +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> #include <sys/socket.h> #include <net/if.h> #include <netinet/in.h> +#include <err.h> +#include <errno.h> +#include <netinet/in.h> +#include <event.h> +#include "libglouglou.h" -struct gg_server { -}; +/* Server - private */ +void cb_receive(evutil_socket_t fd, short what, void *arg); -struct gg_packet { -}; +/* + * Server + */ /* * start a server - * totaly unblocking, using libevent */ struct gg_server * -gg_server_start(char *ip, int port, +gg_server_start(struct event_base *ev_base, char *ip, int port, int (*handle_conn)(struct gg_server *s, int client_id, struct sockaddr_in *addr), int (*handle_packet)(struct gg_server *s, struct gg_packet *p)) { - struct gg_server *s; + struct sockaddr_in sock_addr; + struct gg_server *srv; + struct event *ev; + int s; + int sock_on = 1; + + event_init(); /* XXX needed ? */ + srv = xcalloc(1, sizeof(struct gg_server)); + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + goto err; + srv->sock = s; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + &sock_on, sizeof(sock_on)); + memset(&sock_addr, 0, sizeof(sock_addr)); + sock_addr.sin_family = AF_INET; + sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* XXX use ip */ + sock_addr.sin_port = htons(port); + if (bind(s, (struct sockaddr *)&sock_addr, + sizeof(sock_addr)) != 0) + goto err; + fd_nonblock(s); - return s; + ev = event_new(ev_base, s, EV_READ|EV_PERSIST, cb_receive, srv); + event_add(ev, NULL); + srv->ev = ev; + + return srv; + +err: + printf("libglouglou: gg_server_start: Error ! %s", + strerror(errno)); + gg_server_stop(srv); + return NULL; } int @@ -30,14 +70,30 @@ gg_server_send(struct gg_server *s, int client_id, struct gg_packet *p) } void -gg_server_stop(struct gg_server *s) +gg_server_stop(struct gg_server *srv) { + if (srv->ev) + event_del(srv->ev); + if (srv->sock) + close(srv->sock); + free(srv); +} +/* + * Server - private + */ + +void cb_receive(evutil_socket_t fd, short what, void *arg) +{ + printf("Incoming data !\n"); } +/* + * Client + */ + /* * connect to a server - * totaly unblocking, using libevent */ struct gg_client * gg_client_connect(char *ip, int port, @@ -46,6 +102,8 @@ gg_client_connect(char *ip, int port, { struct gg_client *c; + c = xmalloc(sizeof(struct gg_client)); + return c; } @@ -58,5 +116,41 @@ gg_client_send(struct gg_client *c, struct gg_packet *p) void gg_client_disconnect(struct gg_client *c) { + free(c); +} +/* + * Utils + */ + +void * +xmalloc(size_t size) +{ + void *data; + + data = malloc(size); + if (!data) + err(1, "could not malloc %d", (int)size); + return data; +} + +void * +xcalloc(size_t nmemb, size_t size) +{ + void *data; + + data = calloc(nmemb, size); + if (!data) + err(1, "could not calloc %d", (int)size); + return data; } + +void +fd_nonblock(int fd) +{ + int flags = fcntl(fd, F_GETFL, 0); + int rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if (rc == -1) + printf("failed to set fd %i non-blocking", fd); +} + diff --git a/libglouglou/libglouglou.h b/libglouglou/libglouglou.h index 4906bab..c8f1536 100644 --- a/libglouglou/libglouglou.h +++ b/libglouglou/libglouglou.h @@ -1,7 +1,15 @@ #define PACKET_VERSION 1 #define DNSNAME_MAX 20 -struct packet { +struct gg_server { + struct event *ev; + int sock; +}; + +struct gg_client { +}; + +struct gg_packet { u_int8_t ver; u_int8_t type; /* XXX nicer way for _SIZE ... ? */ @@ -48,16 +56,18 @@ struct packet { #define name_fqdn pdat.name.fqdn }; -struct gg_server *gg_server_start(char *ip, int port, - int (*handle_conn)(struct gg_server *s, int client_id, struct sockaddr_in *addr), - int (*handle_packet)(struct gg_server *s, struct gg_packet *p)); -int gg_server_send(struct gg_server *s, int client_id, - struct gg_packet *p); -void gg_server_stop(struct gg_server *s); +struct gg_server *gg_server_start(struct event_base *, char *, int, + int (*handle_conn)(struct gg_server *, int, struct sockaddr_in *), + int (*handle_packet)(struct gg_server *, struct gg_packet *)); +int gg_server_send(struct gg_server *, int, struct gg_packet *); +void gg_server_stop(struct gg_server *); + +struct gg_client *gg_client_connect(char *, int, + int (*handle_conn)(struct gg_client *, int), + int (*handle_packet)(struct gg_client *, struct gg_packet *)); +int gg_client_send(struct gg_client *, struct gg_packet *); +void gg_client_disconnect(struct gg_client *); -struct gg_client *gg_client_connect(char *ip, int port, - int (*handle_conn)(struct gg_client *c, int status), - int (*handle_packet)(struct gg_client *c, - struct gg_packet *p)); -int gg_client_send(struct gg_client *c, struct gg_packet *p); -void gg_client_disconnect(struct gg_client *c); +void *xmalloc(size_t); +void *xcalloc(size_t, size_t); +void fd_nonblock(int); |