aboutsummaryrefslogtreecommitdiffstats
path: root/libglouglou/libggnet.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglouglou/libggnet.c')
-rw-r--r--libglouglou/libggnet.c154
1 files changed, 154 insertions, 0 deletions
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 <stdlib.h>
+
+#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;
+}