#include #include #include #include #include #include #include #include #include #include #include #include #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); /* * Server */ /* * start a server */ 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)) { struct gg_server *srv; struct sockaddr_in sock_addr; struct event *ev; int s; int sock_on = 1; event_init(); /* XXX needed ? */ srv = xcalloc(1, sizeof(struct gg_server)); srv->ip = ip; srv->port = port; 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)); fd_nonblock(s); bzero(&sock_addr, sizeof(sock_addr)); sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = inet_addr(ip); sock_addr.sin_port = htons(port); if (bind(s, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) goto err; ev = event_new(ev_base, s, EV_READ|EV_PERSIST, cb_srv_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 gg_server_send(struct gg_server *s, int client_id, struct gg_packet *p) { return -1; } void 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_srv_receive(evutil_socket_t fd, short what, void *arg) { printf("srv: Incoming data !\n"); } /* * Client */ /* * connect to a server */ 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)) { struct gg_client *cli; struct sockaddr_in sock_addr; struct event *ev; int s; int sock_on = 1; event_init(); /* XXX needed ? */ cli = xmalloc(sizeof(struct gg_client)); cli->ip = ip; cli->port = port; s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) goto err; cli->sock = s; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &sock_on, sizeof(sock_on)); fd_nonblock(s); bzero(&sock_addr, sizeof(sock_addr)); sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr=inet_addr(ip); sock_addr.sin_port=htons(port); ev = event_new(ev_base, s, EV_READ|EV_PERSIST, cb_cli_receive, cli); event_add(ev, NULL); cli->ev = ev; sendto(s, "", strlen(""), 0, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr)); return cli; err: printf("libglouglou: gg_client_connect: Error ! %s", strerror(errno)); gg_client_disconnect(cli); return NULL; } int gg_client_send(struct gg_client *c, struct gg_packet *p) { return -1; } void gg_client_disconnect(struct gg_client *cli) { if (cli->ev) event_del(cli->ev); if (cli->sock) close(cli->sock); free(cli); } /* * Client - private */ void cb_cli_receive(evutil_socket_t fd, short what, void *arg) { printf("cli: Incoming data !\n"); } /* * 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); }