diff options
-rw-r--r-- | libglouglou/libggnet.c | 57 | ||||
-rw-r--r-- | libglouglou/libggnet.h | 6 |
2 files changed, 47 insertions, 16 deletions
diff --git a/libglouglou/libggnet.c b/libglouglou/libggnet.c index 480eb22..cfed99e 100644 --- a/libglouglou/libggnet.c +++ b/libglouglou/libggnet.c @@ -5,8 +5,12 @@ #include "libggnet.h" static struct ggnet_nodegroup *nodegroup_add(struct ggnet *, - enum ggnet_grouptype, void *); + enum ggnet_grouptype, void *, + struct ggnet_nodegroup *); static void nodegroup_del(struct ggnet *, struct ggnet_nodegroup *); +static struct ggnet_nodegroup *nodegroup_find(struct ggnet *, + enum ggnet_grouptype type, + void *param); static void nodegroup_set(struct ggnet *, struct ggnet_node *); static void nodegroup_unset(struct ggnet *, struct ggnet_node *); @@ -32,7 +36,7 @@ ggnet_new(int manage_connid) */ void ggnet_grouping_set(struct ggnet *net, int set, - void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *), + void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *, struct ggnet_nodegroup *), void (*cb_delgroup)(struct ggnet *, struct ggnet_nodegroup *)) { net->use_grouping = set; @@ -325,12 +329,17 @@ ggnet_time_update(struct ggnet *net, time_t time) } static struct ggnet_nodegroup * -nodegroup_add(struct ggnet *net, enum ggnet_grouptype type, void *param) +nodegroup_add(struct ggnet *net, enum ggnet_grouptype type, void *param, + struct ggnet_nodegroup *parent) { struct ggnet_nodegroup *group; group = xcalloc(1, sizeof(struct ggnet_nodegroup)); group->type = type; + if (parent) { + group->parent = parent; + parent->child_groups_count++; + } switch (type) { case GROUP_ADDRESS: @@ -345,7 +354,7 @@ nodegroup_add(struct ggnet *net, enum ggnet_grouptype type, void *param) } LIST_INSERT_HEAD(&net->group_list, group, entry); - net->cb_addgroup(net, group); + net->cb_addgroup(net, group, parent); return group; } @@ -354,25 +363,25 @@ static void nodegroup_del(struct ggnet *net, struct ggnet_nodegroup *group) { net->cb_delgroup(net, group); + if (group->parent) { + group->parent->child_groups_count--; + if (group->parent->child_groups_count == 0) + nodegroup_del(net, group->parent); + } LIST_REMOVE(group, entry); free(group); } -static void -nodegroup_set(struct ggnet *net, struct ggnet_node *n) +static struct ggnet_nodegroup * +nodegroup_find(struct ggnet *net, enum ggnet_grouptype type, void *param) { - 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; - } + if (g->addr.s_addr == *(u_int *)param) + return g; case GROUP_WHOIS: case GROUP_DNS: case GROUP_ROUTE: @@ -380,8 +389,28 @@ nodegroup_set(struct ggnet *net, struct ggnet_node *n) break; } } + return NULL; +} + +static void +nodegroup_set(struct ggnet *net, struct ggnet_node *n) +{ + struct ggnet_nodegroup *group, *groot, *gclassb; + u_int addr, addr2; + + addr = n->addr.s_addr & 0xffff0000; + + group = nodegroup_find(net, GROUP_ADDRESS, &addr); if (!group) { - group = nodegroup_add(net, GROUP_ADDRESS, &addr); + addr2 = 0x00000000; + groot = nodegroup_find(net, GROUP_ADDRESS, &addr2); + if (!groot) + groot = nodegroup_add(net, GROUP_ADDRESS, &addr2, NULL); + addr2 = addr & 0xff000000; + gclassb = nodegroup_find(net, GROUP_ADDRESS, &addr2); + if (!gclassb) + gclassb = nodegroup_add(net, GROUP_ADDRESS, &addr2, groot); + group = nodegroup_add(net, GROUP_ADDRESS, &addr, gclassb); } n->group = group; diff --git a/libglouglou/libggnet.h b/libglouglou/libggnet.h index 51d65d4..c705cc5 100644 --- a/libglouglou/libggnet.h +++ b/libglouglou/libggnet.h @@ -27,10 +27,12 @@ enum ggnet_grouptype { struct ggnet_nodegroup { LIST_ENTRY(ggnet_nodegroup) entry; + struct ggnet_nodegroup *parent; enum ggnet_grouptype type; struct in_addr addr; char name[GGNET_DNSNAME_MAX]; int node_count; + int child_groups_count; void *usrdata; }; @@ -78,14 +80,14 @@ struct ggnet { int conn_freeids_ptr; int manage_connid; int use_grouping; - void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *); + void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *, struct ggnet_nodegroup *); void (*cb_delgroup)(struct ggnet *, struct ggnet_nodegroup *); time_t time; }; struct ggnet *ggnet_new(int); void ggnet_grouping_set(struct ggnet *, int, - void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *), + void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *, struct ggnet_nodegroup *), void (*cb_delgroup)(struct ggnet *, struct ggnet_nodegroup *)); void ggnet_free(struct ggnet *); struct ggnet_node *ggnet_node_add(struct ggnet *, struct in_addr *); |