aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglouglou/libglouglou.c114
-rw-r--r--libglouglou/libglouglou.h36
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);