aboutsummaryrefslogtreecommitdiffstats
path: root/libglouglou/libglouglou.c
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2012-11-29 05:23:38 +0100
committerLaurent Ghigonis <laurent@p1sec.com>2012-11-29 05:23:38 +0100
commitfa31bcce44fd1990c68a68cea963b94faba7b314 (patch)
treecad20cc1b3cf6839e1566a20c149b9f32feafa23 /libglouglou/libglouglou.c
parentbetter naming (diff)
downloadglouglou-fa31bcce44fd1990c68a68cea963b94faba7b314.tar.xz
glouglou-fa31bcce44fd1990c68a68cea963b94faba7b314.zip
correctly handle new users
Diffstat (limited to 'libglouglou/libglouglou.c')
-rw-r--r--libglouglou/libglouglou.c77
1 files changed, 65 insertions, 12 deletions
diff --git a/libglouglou/libglouglou.c b/libglouglou/libglouglou.c
index 27144e4..a0b85ee 100644
--- a/libglouglou/libglouglou.c
+++ b/libglouglou/libglouglou.c
@@ -14,8 +14,10 @@
#include "libglouglou.h"
/* Server - private */
-void cb_srv_receive(evutil_socket_t fd, short what, void *arg);
-void cb_cli_receive(evutil_socket_t fd, short what, void *arg);
+struct gg_user *user_add(struct gg_server *, struct sockaddr_in *);
+struct gg_user *user_find(struct gg_server *, struct sockaddr_in *);
+void cb_srv_receive(evutil_socket_t, short, void *);
+void cb_cli_receive(evutil_socket_t, short, void *);
/*
* Server
@@ -26,8 +28,8 @@ void cb_cli_receive(evutil_socket_t fd, short what, void *arg);
*/
struct gg_server *
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))
+ int (*handle_conn)(struct gg_server *, int, struct sockaddr_in *),
+ int (*handle_packet)(struct gg_server *, struct gg_packet *))
{
struct gg_server *srv;
struct sockaddr_in sock_addr;
@@ -35,7 +37,6 @@ gg_server_start(struct event_base *ev_base, char *ip, int port,
int s;
int sock_on = 1;
- event_init(); /* XXX needed ? */
srv = xcalloc(1, sizeof(struct gg_server));
srv->ip = ip;
srv->port = port;
@@ -91,14 +92,60 @@ gg_server_stop(struct gg_server *srv)
* Server - private
*/
+struct gg_user *
+user_find(struct gg_server *srv, struct sockaddr_in *remote)
+{
+ struct gg_user *usr;
+ struct sockaddr_in *u;
+
+ LIST_FOREACH(usr, &srv->user_list, entry) {
+ u = &usr->addr;
+ if (u->sin_addr.s_addr == remote->sin_addr.s_addr &&
+ u->sin_port == remote->sin_port)
+ return usr;
+ }
+ return NULL;
+}
+
+struct gg_user *
+user_add(struct gg_server *srv, struct sockaddr_in *remote)
+{
+ struct gg_user *usr;
+
+ usr = xcalloc(1, sizeof(struct gg_user));
+ usr->id = srv->user_id_count;
+ srv->user_id_count++;
+ addrcpy(&usr->addr, remote);
+ LIST_INSERT_HEAD(&srv->user_list, usr, entry);
+
+ return usr;
+}
+
void cb_srv_receive(evutil_socket_t fd, short what, void *arg)
{
struct gg_server *srv;
+ struct gg_user *usr;
+ struct sockaddr_in remote;
+ char buf[16384];
+ socklen_t len;
+ int rv;
srv = arg;
- printf("srv: Incoming data !\n");
- if (srv->handle_conn)
- srv->handle_conn(srv, 0, NULL); // XXX IN PROGRESS
+ rv = recvfrom(fd, buf, sizeof(buf), 0,
+ (struct sockaddr *)&remote, &len);
+ if (rv < 0) {
+ printf("libglouglou: cb_srv_receive: recvfrom failed\n");
+ return;
+ }
+ usr = user_find(srv, &remote);
+ if (!usr) {
+ usr = user_add(srv, &remote);
+ if (srv->handle_conn)
+ srv->handle_conn(srv, usr->id, &remote);
+ printf("srv: New user %d !\n", usr->id);
+ } else {
+ printf("srv: Incoming data for existing user !\n");
+ }
}
/*
@@ -110,8 +157,8 @@ void cb_srv_receive(evutil_socket_t fd, short what, void *arg)
*/
struct gg_client *
gg_client_connect(struct event_base *ev_base, 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 (*handle_conn)(struct gg_client *, int),
+ int (*handle_packet)(struct gg_client *, struct gg_packet *))
{
struct gg_client *cli;
struct sockaddr_in sock_addr;
@@ -119,8 +166,7 @@ gg_client_connect(struct event_base *ev_base, char *ip, int port,
int s;
int sock_on = 1;
- event_init(); /* XXX needed ? */
- cli = xmalloc(sizeof(struct gg_client));
+ cli = xcalloc(1, sizeof(struct gg_client));
cli->ip = ip;
cli->port = port;
cli->handle_conn = handle_conn;
@@ -214,3 +260,10 @@ fd_nonblock(int fd)
printf("failed to set fd %i non-blocking", fd);
}
+void
+addrcpy(struct sockaddr_in *dst, struct sockaddr_in *src)
+{
+ dst->sin_addr.s_addr = src->sin_addr.s_addr;
+ dst->sin_port = src->sin_port;
+ dst->sin_family = src->sin_family;
+}