size_t size;
};
-static int loc_network_list_grow(struct loc_network_list* list, size_t size) {
+static int loc_network_list_grow(struct loc_network_list* list) {
+ size_t size = list->elements_size * 2;
+ if (size < 1024)
+ size = 1024;
+
DEBUG(list->ctx, "Growing network list %p by %zu to %zu\n",
list, size, list->elements_size + size);
struct loc_network** elements = reallocarray(list->elements,
list->elements_size + size, sizeof(*list->elements));
if (!elements)
- return -errno;
+ return 1;
list->elements = elements;
list->elements_size += size;
}
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_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->elements[i];
- s = loc_network_str(network);
-
- INFO(list->ctx, "%4d: %s\n", i, s);
- free(s);
+ INFO(list->ctx, "%4d: %s\n",
+ i, loc_network_str(network));
}
}
// Check if we have space left
if (list->size >= list->elements_size) {
- int r = loc_network_list_grow(list, 64);
+ int r = loc_network_list_grow(list);
if (r)
return r;
}
return network;
}
+int loc_network_list_remove(struct loc_network_list* list, struct loc_network* network) {
+ int found = 0;
+
+ // Find the network on the list
+ off_t index = loc_network_list_find(list, network, &found);
+
+ // Nothing to do if the network wasn't found
+ if (!found)
+ return 0;
+
+ // Dereference the network at the position
+ loc_network_unref(list->elements[index]);
+
+ // Move all other elements back
+ for (unsigned int i = index; i < list->size - 1; i++)
+ list->elements[i] = list->elements[i+1];
+
+ // The list is shorter now
+ --list->size;
+
+ return 0;
+}
+
LOC_EXPORT int loc_network_list_contains(struct loc_network_list* list, struct loc_network* network) {
int found = 0;
return 1;
}
+ DEBUG(ctx, "Summarizing %s - %s\n", loc_address_str(first), loc_address_str(last));
+
const int family1 = loc_address_family(first);
const int family2 = loc_address_family(last);
if (r)
return r;
-#ifdef ENABLE_DEBUG
- char* n = loc_network_str(network);
- if (n) {
- DEBUG(ctx, "Found network %s\n", n);
- free(n);
- }
-#endif
+ DEBUG(ctx, "Found network %s\n", loc_network_str(network));
// Push network on the list
r = loc_network_list_push(*list, network);
// The next network starts right after this one
start = *loc_network_get_last_address(network);
+
+ // If we have reached the end of possible IP addresses, we stop
+ if (loc_address_all_ones(&start))
+ break;
+
loc_address_increment(&start);
}
return 0;
}
+
+void loc_network_list_remove_with_prefix_smaller_than(
+ struct loc_network_list* list, const unsigned int prefix) {
+ unsigned int p = 0;
+
+ // Count how many networks were removed
+ unsigned int removed = 0;
+
+ for (unsigned int i = 0; i < list->size; i++) {
+ // Fetch the prefix
+ p = loc_network_prefix(list->elements[i]);
+
+ if (p > prefix) {
+ // Drop this network
+ loc_network_unref(list->elements[i]);
+
+ // Increment counter
+ removed++;
+
+ continue;
+ }
+
+ // Move pointers backwards to keep the list filled
+ list->elements[i - removed] = list->elements[i];
+ }
+
+ // Adjust size
+ list->size -= removed;
+
+ return;
+}