From 548b872ae45485254d6d8a1ef9967e4539f84321 Mon Sep 17 00:00:00 2001 From: Laurent Ghigonis Date: Tue, 4 Dec 2012 00:58:47 +0100 Subject: add libggnet, a helper to keep track of network nodes and connections --- libglouglou/libggnet.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 libglouglou/libggnet.c (limited to 'libglouglou/libggnet.c') diff --git a/libglouglou/libggnet.c b/libglouglou/libggnet.c new file mode 100644 index 0000000..c3a82ea --- /dev/null +++ b/libglouglou/libggnet.c @@ -0,0 +1,154 @@ +#include + +#include "libglouglou.h" +#include "libggnet.h" + +struct ggnet * +ggnet_new(void) +{ + struct ggnet *net; + + net = xcalloc(1, sizeof(struct ggnet)); + return net; +} + +void +ggnet_free(struct ggnet *net) +{ + struct ggnet_conn *c, *ctmp; + struct ggnet_node *n, *ntmp; + + LIST_FOREACH_SAFE(c, &net->conn_list, entry, ctmp) + ggnet_conn_del(net, c); + LIST_FOREACH_SAFE(n, &net->node_list, entry, ntmp) + ggnet_node_del(net, n); + free(net); +} + +struct ggnet_node * +ggnet_node_add(struct ggnet *net, struct in_addr *addr) +{ + struct ggnet_node *n; + + gg_log_debug("user: ggnet_node_add"); + + n = xcalloc(1, sizeof(struct ggnet_node)); + n->addr.s_addr = addr->s_addr; + n->namelen = NODENAME_WAITING; + n->lastseen = net->time; + LIST_INSERT_HEAD(&net->node_list, n, entry); + net->node_count++; + + return n; +} + +void +ggnet_node_del(struct ggnet *net, struct ggnet_node *n) +{ + if (n->used) + gg_log_fatal("user: trying to remove a used node !"); + gg_log_debug("user: ggnet_node_del"); + + LIST_REMOVE(n, entry); + free(n->name); + free(n); + net->node_count--; +} + +struct ggnet_node * +ggnet_node_find(struct ggnet *net, struct in_addr *remote) +{ + struct ggnet_node *n; + + LIST_FOREACH(n, &net->node_list, entry) + if (n->addr.s_addr == remote->s_addr) + return n; + return NULL; +} + +struct ggnet_conn * +ggnet_conn_add(struct ggnet *net, struct in_addr *src, int src_port, + struct in_addr *dst, int dst_port, int proto, int size) +{ + struct ggnet_conn *c; + struct ggnet_node *srcnode; + struct ggnet_node *dstnode; + int id; + + gg_log_debug("user: ggnet_conn_add, %x:%d->%x:%d %d [%d]", + src->s_addr, src_port, dst->s_addr, dst_port, proto, size); + if (net->conn_freeids_ptr == GGNET_CONN_FREEIDS_COUNT) { + gg_log_warn("user: out of connection identifiers !"); + return NULL; + } + + id = net->conn_freeids[net->conn_freeids_ptr]; + net->conn_freeids_ptr++; + + srcnode = ggnet_node_find(net, src); + if (!srcnode) + srcnode = ggnet_node_add(net, src); + srcnode->used++; + dstnode = ggnet_node_find(net, dst); + if (!dstnode) + dstnode = ggnet_node_add(net, dst); + dstnode->used++; + + c = xmalloc(sizeof(struct ggnet_conn)); + c->id = id; + c->state = CONNSTATE_ESTABLISHED; + c->src = srcnode; + c->src_port = src_port; + c->dst = dstnode; + c->dst_port = dst_port; + c->proto = proto; + c->size = size; + c->lastseen = net->time; + LIST_INSERT_HEAD(&net->conn_list, c, entry); + + return c; +} + +void +ggnet_conn_data(struct ggnet *net, struct ggnet_conn *c, int size, int response) +{ + gg_log_debug("user: ggnet_conn_data"); + + c->lastseen = net->time; +} + +void +ggnet_conn_del(struct ggnet *net, struct ggnet_conn *c) +{ + gg_log_debug("user: ggnet_conn_del"); + + if (c->proto == IPPROTO_TCP) { + switch (c->state) { + case CONNSTATE_ESTABLISHED: + c->state = CONNSTATE_TCPFIN; + return; + case CONNSTATE_TCPFIN: + c->state = CONNSTATE_TCPFIN2; + return; + case CONNSTATE_TCPFIN2: + break; + } + } + + if (net->conn_freeids_ptr == 0) + gg_log_fatal("net->conn_freeids_ptr == 0"); + net->conn_freeids_ptr--; + net->conn_freeids[net->conn_freeids_ptr] = c->id; + + c->src->used--; + c->dst->used--; + + LIST_REMOVE(c, entry); + free(c); +} + +void +ggnet_time_update(struct ggnet *net, time_t time) +{ + net->time = time; +} -- cgit v1.2.3-59-g8ed1b