diff options
author | Laurent Ghigonis <laurent@p1sec.com> | 2012-12-13 15:43:29 +0100 |
---|---|---|
committer | Laurent Ghigonis <laurent@p1sec.com> | 2012-12-13 15:43:29 +0100 |
commit | 4dcf36c3ead23b05e61ad41203c4743d59ccf18a (patch) | |
tree | cd81d3b25d90d5f47dc249452e53be0edcd1faed /libglouglou/libggnet.c | |
parent | more DEBUG backtrace stuff (diff) | |
download | glouglou-4dcf36c3ead23b05e61ad41203c4743d59ccf18a.tar.xz glouglou-4dcf36c3ead23b05e61ad41203c4743d59ccf18a.zip |
introducing node grouping, for now only on address
Diffstat (limited to 'libglouglou/libggnet.c')
-rw-r--r-- | libglouglou/libggnet.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/libglouglou/libggnet.c b/libglouglou/libggnet.c index 9c6314e..480eb22 100644 --- a/libglouglou/libggnet.c +++ b/libglouglou/libggnet.c @@ -4,6 +4,12 @@ #include "libglouglou.h" #include "libggnet.h" +static struct ggnet_nodegroup *nodegroup_add(struct ggnet *, + enum ggnet_grouptype, void *); +static void nodegroup_del(struct ggnet *, struct ggnet_nodegroup *); +static void nodegroup_set(struct ggnet *, struct ggnet_node *); +static void nodegroup_unset(struct ggnet *, struct ggnet_node *); + struct ggnet * ggnet_new(int manage_connid) { @@ -19,16 +25,34 @@ ggnet_new(int manage_connid) return net; } +/** + * Sets grouping option + * + * Note: Must be set before any use of ggnet + */ +void +ggnet_grouping_set(struct ggnet *net, int set, + void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *), + void (*cb_delgroup)(struct ggnet *, struct ggnet_nodegroup *)) +{ + net->use_grouping = set; + net->cb_addgroup = cb_addgroup; + net->cb_delgroup = cb_delgroup; +} + void ggnet_free(struct ggnet *net) { struct ggnet_conn *c, *ctmp; struct ggnet_node *n, *ntmp; + struct ggnet_nodegroup *g, *gtmp; 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); + LIST_FOREACH_SAFE(g, &net->group_list, entry, gtmp) + nodegroup_del(net, g); free(net); } @@ -45,6 +69,8 @@ ggnet_node_add(struct ggnet *net, struct in_addr *addr) n->lastseen = net->time; LIST_INSERT_HEAD(&net->node_list, n, entry); net->node_count++; + if (net->use_grouping) + nodegroup_set(net, n); return n; } @@ -56,6 +82,9 @@ ggnet_node_del(struct ggnet *net, struct ggnet_node *n) gg_log_fatal("ggnet_node_del: trying to remove a used node !"); gg_log_debug("ggnet_node_del: ggnet_node_del"); + if (net->use_grouping) + nodegroup_unset(net, n); + LIST_REMOVE(n, entry); free(n); net->node_count--; @@ -99,6 +128,12 @@ ggnet_node_usrdata_set(struct ggnet_node *n, void *usrdata) n->usrdata = usrdata; } +struct ggnet_nodegroup * +ggnet_node_group_get(struct ggnet_node *n) +{ + return n->group; +} + 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, @@ -168,6 +203,7 @@ ggnet_conn_del(struct ggnet *net, struct ggnet_conn *c) { gg_log_debug("ggnet_conn_del"); + /* UNSUPPORTED if (c->proto == IPPROTO_TCP) { switch (c->state) { case CONNSTATE_ESTABLISHED: @@ -180,6 +216,7 @@ ggnet_conn_del(struct ggnet *net, struct ggnet_conn *c) break; } } + */ if (net->manage_connid) { if (net->conn_freeids_ptr == 0) @@ -269,8 +306,96 @@ ggnet_conn_dst_get(struct ggnet_conn *c) return c->dst; } +void * +ggnet_nodegroup_usrdata_get(struct ggnet_nodegroup *g) +{ + return g->usrdata; +} + +void +ggnet_nodegroup_usrdata_set(struct ggnet_nodegroup *g, void *usrdata) +{ + g->usrdata = usrdata; +} + void ggnet_time_update(struct ggnet *net, time_t time) { net->time = time; } + +static struct ggnet_nodegroup * +nodegroup_add(struct ggnet *net, enum ggnet_grouptype type, void *param) +{ + struct ggnet_nodegroup *group; + + group = xcalloc(1, sizeof(struct ggnet_nodegroup)); + group->type = type; + + switch (type) { + case GROUP_ADDRESS: + group->addr.s_addr = *(u_int *)param; + break; + case GROUP_WHOIS: + case GROUP_DNS: + case GROUP_ROUTE: + /* UNSUPPORTED */ + free(group); + return NULL; + } + + LIST_INSERT_HEAD(&net->group_list, group, entry); + net->cb_addgroup(net, group); + + return group; +} + +static void +nodegroup_del(struct ggnet *net, struct ggnet_nodegroup *group) +{ + net->cb_delgroup(net, group); + LIST_REMOVE(group, entry); + free(group); +} + +static void +nodegroup_set(struct ggnet *net, struct ggnet_node *n) +{ + struct ggnet_nodegroup *group = NULL; + struct ggnet_nodegroup *g; + u_int addr; + + addr = n->addr.s_addr & 0xffff0000; + LIST_FOREACH(g, &net->group_list, entry) { + switch (g->type) { + case GROUP_ADDRESS: + if (g->addr.s_addr == addr) { + group = g; + break; + } + case GROUP_WHOIS: + case GROUP_DNS: + case GROUP_ROUTE: + /* UNSUPPORTED */ + break; + } + } + if (!group) { + group = nodegroup_add(net, GROUP_ADDRESS, &addr); + } + + n->group = group; + group->node_count++; +} + +static void +nodegroup_unset(struct ggnet *net, struct ggnet_node *n) +{ + if (!n->group) + return; + + n->group->node_count--; + if (n->group->node_count == 0) + nodegroup_del(net, n->group); +} + |