From: Michael Tremer Date: Sun, 15 Nov 2020 15:02:28 +0000 (+0000) Subject: Move network lists into an own file X-Git-Tag: 0.9.5~67 X-Git-Url: http://git.ipfire.org/?p=people%2Fms%2Flibloc.git;a=commitdiff_plain;h=e0b9ff5f38beb0d560b16db881647e5a75127df1 Move network lists into an own file Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index a0431a6..f0d8c4c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -96,6 +96,7 @@ pkginclude_HEADERS = \ src/loc/database.h \ src/loc/format.h \ src/loc/network.h \ + src/loc/network-list.h \ src/loc/private.h \ src/loc/stringpool.h \ src/loc/resolv.h \ @@ -110,6 +111,7 @@ src_libloc_la_SOURCES = \ src/country.c \ src/database.c \ src/network.c \ + src/network-list.c \ src/resolv.c \ src/stringpool.c \ src/writer.c diff --git a/src/libloc.sym b/src/libloc.sym index 6139db6..453a1be 100644 --- a/src/libloc.sym +++ b/src/libloc.sym @@ -87,6 +87,7 @@ global: loc_network_format_last_address; loc_network_get_asn; loc_network_get_country_code; + loc_network_gt; loc_network_has_flag; loc_network_is_subnet; loc_network_is_subnet_of; diff --git a/src/loc/network-list.h b/src/loc/network-list.h new file mode 100644 index 0000000..af3b28d --- /dev/null +++ b/src/loc/network-list.h @@ -0,0 +1,37 @@ +/* + libloc - A library to determine the location of someone on the Internet + + Copyright (C) 2020 IPFire Development Team + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. +*/ + +#ifndef LIBLOC_NETWORK_LIST_H +#define LIBLOC_NETWORK_LIST_H + +struct loc_network_list; +int loc_network_list_new(struct loc_ctx* ctx, struct loc_network_list** list); +struct loc_network_list* loc_network_list_ref(struct loc_network_list* list); +struct loc_network_list* loc_network_list_unref(struct loc_network_list* list); +size_t loc_network_list_size(struct loc_network_list* list); +int loc_network_list_empty(struct loc_network_list* list); +void loc_network_list_clear(struct loc_network_list* list); +void loc_network_list_dump(struct loc_network_list* list); +struct loc_network* loc_network_list_get(struct loc_network_list* list, size_t index); +int loc_network_list_push(struct loc_network_list* list, struct loc_network* network); +struct loc_network* loc_network_list_pop(struct loc_network_list* list); +struct loc_network* loc_network_list_pop_first(struct loc_network_list* list); +int loc_network_list_contains(struct loc_network_list* list, struct loc_network* network); +void loc_network_list_sort(struct loc_network_list* list); +void loc_network_list_reverse(struct loc_network_list* list); +int loc_network_list_merge(struct loc_network_list* self, struct loc_network_list* other); + +#endif diff --git a/src/loc/network.h b/src/loc/network.h index 203e61c..d86b685 100644 --- a/src/loc/network.h +++ b/src/loc/network.h @@ -21,6 +21,7 @@ #include #include +#include enum loc_network_flags { LOC_NETWORK_FLAG_ANONYMOUS_PROXY = (1 << 0), // A1 @@ -55,6 +56,7 @@ int loc_network_set_flag(struct loc_network* network, uint32_t flag); int loc_network_match_flag(struct loc_network* network, uint32_t flag); int loc_network_eq(struct loc_network* self, struct loc_network* other); +int loc_network_gt(struct loc_network* self, struct loc_network* other); int loc_network_overlaps(struct loc_network* self, struct loc_network* other); int loc_network_is_subnet(struct loc_network* self, struct loc_network* other); int loc_network_is_subnet_of(struct loc_network* self, struct loc_network* other); @@ -64,24 +66,6 @@ struct loc_network_list* loc_network_exclude( struct loc_network_list* loc_network_exclude_list( struct loc_network* network, struct loc_network_list* list); -// List -struct loc_network_list; -int loc_network_list_new(struct loc_ctx* ctx, struct loc_network_list** list); -struct loc_network_list* loc_network_list_ref(struct loc_network_list* list); -struct loc_network_list* loc_network_list_unref(struct loc_network_list* list); -size_t loc_network_list_size(struct loc_network_list* list); -int loc_network_list_empty(struct loc_network_list* list); -void loc_network_list_clear(struct loc_network_list* list); -void loc_network_list_dump(struct loc_network_list* list); -struct loc_network* loc_network_list_get(struct loc_network_list* list, size_t index); -int loc_network_list_push(struct loc_network_list* list, struct loc_network* network); -struct loc_network* loc_network_list_pop(struct loc_network_list* list); -struct loc_network* loc_network_list_pop_first(struct loc_network_list* list); -int loc_network_list_contains(struct loc_network_list* list, struct loc_network* network); -void loc_network_list_sort(struct loc_network_list* list); -void loc_network_list_reverse(struct loc_network_list* list); -int loc_network_list_merge(struct loc_network_list* self, struct loc_network_list* other); - #ifdef LIBLOC_PRIVATE int loc_network_to_database_v1(struct loc_network* network, struct loc_database_network_v1* dbobj); diff --git a/src/network-list.c b/src/network-list.c new file mode 100644 index 0000000..1f6e80e --- /dev/null +++ b/src/network-list.c @@ -0,0 +1,224 @@ +/* + libloc - A library to determine the location of someone on the Internet + + Copyright (C) 2020 IPFire Development Team + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +struct loc_network_list { + struct loc_ctx* ctx; + int refcount; + + struct loc_network* list[1024]; + size_t size; + size_t max_size; +}; + +LOC_EXPORT int loc_network_list_new(struct loc_ctx* ctx, + struct loc_network_list** list) { + struct loc_network_list* l = calloc(1, sizeof(*l)); + if (!l) + return -ENOMEM; + + l->ctx = loc_ref(ctx); + l->refcount = 1; + + // Do not allow this list to grow larger than this + l->max_size = 1024; + + DEBUG(l->ctx, "Network list allocated at %p\n", l); + *list = l; + return 0; +} + +LOC_EXPORT struct loc_network_list* loc_network_list_ref(struct loc_network_list* list) { + list->refcount++; + + return list; +} + +static void loc_network_list_free(struct loc_network_list* list) { + DEBUG(list->ctx, "Releasing network list at %p\n", list); + + for (unsigned int i = 0; i < list->size; i++) + loc_network_unref(list->list[i]); + + loc_unref(list->ctx); + free(list); +} + +LOC_EXPORT struct loc_network_list* loc_network_list_unref(struct loc_network_list* list) { + if (!list) + return NULL; + + if (--list->refcount > 0) + return list; + + loc_network_list_free(list); + return NULL; +} + +LOC_EXPORT size_t loc_network_list_size(struct loc_network_list* list) { + return list->size; +} + +LOC_EXPORT int loc_network_list_empty(struct loc_network_list* list) { + return list->size == 0; +} + +LOC_EXPORT void loc_network_list_clear(struct loc_network_list* list) { + for (unsigned int i = 0; i < list->size; i++) + loc_network_unref(list->list[i]); + + list->size = 0; +} + +LOC_EXPORT void loc_network_list_dump(struct loc_network_list* list) { + struct loc_network* network; + char* s; + + for (unsigned int i = 0; i < list->size; i++) { + network = list->list[i]; + + s = loc_network_str(network); + + INFO(list->ctx, "%s\n", s); + free(s); + } +} + +LOC_EXPORT struct loc_network* loc_network_list_get(struct loc_network_list* list, size_t index) { + // Check index + if (index >= list->size) + return NULL; + + return loc_network_ref(list->list[index]); +} + +LOC_EXPORT int loc_network_list_push(struct loc_network_list* list, struct loc_network* network) { + // Do not add networks that are already on the list + if (loc_network_list_contains(list, network)) + return 0; + + // Check if we have space left + if (list->size == list->max_size) { + ERROR(list->ctx, "%p: Could not push network onto the stack: Stack full\n", list); + return -ENOMEM; + } + + DEBUG(list->ctx, "%p: Pushing network %p onto stack\n", list, network); + + list->list[list->size++] = loc_network_ref(network); + + return 0; +} + +LOC_EXPORT struct loc_network* loc_network_list_pop(struct loc_network_list* list) { + // Return nothing when empty + if (loc_network_list_empty(list)) { + DEBUG(list->ctx, "%p: Popped empty stack\n", list); + return NULL; + } + + struct loc_network* network = list->list[--list->size]; + + DEBUG(list->ctx, "%p: Popping network %p from stack\n", list, network); + + return network; +} + +LOC_EXPORT struct loc_network* loc_network_list_pop_first(struct loc_network_list* list) { + // Return nothing when empty + if (loc_network_list_empty(list)) { + DEBUG(list->ctx, "%p: Popped empty stack\n", list); + return NULL; + } + + struct loc_network* network = list->list[0]; + + // Move all elements to the top of the stack + for (unsigned int i = 0; i < --list->size; i++) { + list->list[i] = list->list[i+1]; + } + + DEBUG(list->ctx, "%p: Popping network %p from stack\n", list, network); + + return network; +} + +LOC_EXPORT int loc_network_list_contains(struct loc_network_list* list, struct loc_network* network) { + for (unsigned int i = 0; i < list->size; i++) { + if (loc_network_eq(list->list[i], network)) + return 1; + } + + return 0; +} + +static void loc_network_list_swap(struct loc_network_list* list, unsigned int i1, unsigned int i2) { + // Do nothing for invalid indices + if (i1 >= list->size || i2 >= list->size) + return; + + struct loc_network* network1 = list->list[i1]; + struct loc_network* network2 = list->list[i2]; + + list->list[i1] = network2; + list->list[i2] = network1; +} + +LOC_EXPORT void loc_network_list_reverse(struct loc_network_list* list) { + unsigned int i = 0; + unsigned int j = list->size - 1; + + while (i < j) { + loc_network_list_swap(list, i++, j--); + } +} + +LOC_EXPORT void loc_network_list_sort(struct loc_network_list* list) { + unsigned int n = list->size; + int swapped; + + do { + swapped = 0; + + for (unsigned int i = 1; i < n; i++) { + if (loc_network_gt(list->list[i-1], list->list[i]) > 0) { + loc_network_list_swap(list, i-1, i); + swapped = 1; + } + } + + n--; + } while (swapped); +} + +LOC_EXPORT int loc_network_list_merge( + struct loc_network_list* self, struct loc_network_list* other) { + int r; + + for (unsigned int i = 0; i < other->size; i++) { + r = loc_network_list_push(self, other->list[i]); + if (r) + return r; + } + + return 0; +} diff --git a/src/network.c b/src/network.c index d015579..28ca2df 100644 --- a/src/network.c +++ b/src/network.c @@ -29,6 +29,7 @@ #include #include #include +#include #include struct loc_network { @@ -436,7 +437,7 @@ LOC_EXPORT int loc_network_eq(struct loc_network* self, struct loc_network* othe return 1; } -static int loc_network_gt(struct loc_network* self, struct loc_network* other) { +LOC_EXPORT int loc_network_gt(struct loc_network* self, struct loc_network* other) { // Families must match if (self->family != other->family) return -1; @@ -1106,207 +1107,3 @@ int loc_network_tree_node_is_leaf(struct loc_network_tree_node* node) { struct loc_network* loc_network_tree_node_get_network(struct loc_network_tree_node* node) { return loc_network_ref(node->network); } - -// List - -struct loc_network_list { - struct loc_ctx* ctx; - int refcount; - - struct loc_network* list[1024]; - size_t size; - size_t max_size; -}; - -LOC_EXPORT int loc_network_list_new(struct loc_ctx* ctx, - struct loc_network_list** list) { - struct loc_network_list* l = calloc(1, sizeof(*l)); - if (!l) - return -ENOMEM; - - l->ctx = loc_ref(ctx); - l->refcount = 1; - - // Do not allow this list to grow larger than this - l->max_size = 1024; - - DEBUG(l->ctx, "Network list allocated at %p\n", l); - *list = l; - return 0; -} - -LOC_EXPORT struct loc_network_list* loc_network_list_ref(struct loc_network_list* list) { - list->refcount++; - - return list; -} - -static void loc_network_list_free(struct loc_network_list* list) { - DEBUG(list->ctx, "Releasing network list at %p\n", list); - - for (unsigned int i = 0; i < list->size; i++) - loc_network_unref(list->list[i]); - - loc_unref(list->ctx); - free(list); -} - -LOC_EXPORT struct loc_network_list* loc_network_list_unref(struct loc_network_list* list) { - if (!list) - return NULL; - - if (--list->refcount > 0) - return list; - - loc_network_list_free(list); - return NULL; -} - -LOC_EXPORT size_t loc_network_list_size(struct loc_network_list* list) { - return list->size; -} - -LOC_EXPORT int loc_network_list_empty(struct loc_network_list* list) { - return list->size == 0; -} - -LOC_EXPORT void loc_network_list_clear(struct loc_network_list* list) { - for (unsigned int i = 0; i < list->size; i++) - loc_network_unref(list->list[i]); - - list->size = 0; -} - -LOC_EXPORT void loc_network_list_dump(struct loc_network_list* list) { - struct loc_network* network; - char* s; - - for (unsigned int i = 0; i < list->size; i++) { - network = list->list[i]; - - s = loc_network_str(network); - - INFO(list->ctx, "%s\n", s); - free(s); - } -} - -LOC_EXPORT struct loc_network* loc_network_list_get(struct loc_network_list* list, size_t index) { - // Check index - if (index >= list->size) - return NULL; - - return loc_network_ref(list->list[index]); -} - -LOC_EXPORT int loc_network_list_push(struct loc_network_list* list, struct loc_network* network) { - // Do not add networks that are already on the list - if (loc_network_list_contains(list, network)) - return 0; - - // Check if we have space left - if (list->size == list->max_size) { - ERROR(list->ctx, "%p: Could not push network onto the stack: Stack full\n", list); - return -ENOMEM; - } - - DEBUG(list->ctx, "%p: Pushing network %p onto stack\n", list, network); - - list->list[list->size++] = loc_network_ref(network); - - return 0; -} - -LOC_EXPORT struct loc_network* loc_network_list_pop(struct loc_network_list* list) { - // Return nothing when empty - if (loc_network_list_empty(list)) { - DEBUG(list->ctx, "%p: Popped empty stack\n", list); - return NULL; - } - - struct loc_network* network = list->list[--list->size]; - - DEBUG(list->ctx, "%p: Popping network %p from stack\n", list, network); - - return network; -} - -LOC_EXPORT struct loc_network* loc_network_list_pop_first(struct loc_network_list* list) { - // Return nothing when empty - if (loc_network_list_empty(list)) { - DEBUG(list->ctx, "%p: Popped empty stack\n", list); - return NULL; - } - - struct loc_network* network = list->list[0]; - - // Move all elements to the top of the stack - for (unsigned int i = 0; i < --list->size; i++) { - list->list[i] = list->list[i+1]; - } - - DEBUG(list->ctx, "%p: Popping network %p from stack\n", list, network); - - return network; -} - -LOC_EXPORT int loc_network_list_contains(struct loc_network_list* list, struct loc_network* network) { - for (unsigned int i = 0; i < list->size; i++) { - if (loc_network_eq(list->list[i], network)) - return 1; - } - - return 0; -} - -static void loc_network_list_swap(struct loc_network_list* list, unsigned int i1, unsigned int i2) { - // Do nothing for invalid indices - if (i1 >= list->size || i2 >= list->size) - return; - - struct loc_network* network1 = list->list[i1]; - struct loc_network* network2 = list->list[i2]; - - list->list[i1] = network2; - list->list[i2] = network1; -} - -LOC_EXPORT void loc_network_list_reverse(struct loc_network_list* list) { - unsigned int i = 0; - unsigned int j = list->size - 1; - - while (i < j) { - loc_network_list_swap(list, i++, j--); - } -} - -LOC_EXPORT void loc_network_list_sort(struct loc_network_list* list) { - unsigned int n = list->size; - int swapped; - - do { - swapped = 0; - - for (unsigned int i = 1; i < n; i++) { - if (loc_network_gt(list->list[i-1], list->list[i]) > 0) { - loc_network_list_swap(list, i-1, i); - swapped = 1; - } - } - - n--; - } while (swapped); -} - -LOC_EXPORT int loc_network_list_merge( - struct loc_network_list* self, struct loc_network_list* other) { - int r; - - for (unsigned int i = 0; i < other->size; i++) { - r = loc_network_list_push(self, other->list[i]); - if (r) - return r; - } - - return 0; -} diff --git a/src/python/network.c b/src/python/network.c index 11f672b..ed91d65 100644 --- a/src/python/network.c +++ b/src/python/network.c @@ -20,6 +20,7 @@ #include #include +#include #include "locationmodule.h" #include "network.h"