From a7ee12c921fcdc1d8f07d89fc537c422b04e1f28 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 2 Apr 2026 14:15:25 +0200 Subject: [PATCH] device: add O(1) lookup by id --- src/util-device.c | 42 ++++++++++++++++++++++++++++++++++++++++-- src/util-device.h | 3 ++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/util-device.c b/src/util-device.c index 2362506208..8e9ab11736 100644 --- a/src/util-device.c +++ b/src/util-device.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2011-2021 Open Information Security Foundation +/* Copyright (C) 2011-2026 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -68,7 +68,7 @@ typedef struct BypassInfo_ { /** if set to 0 when we don't have real devices */ static int live_devices_stats = 1; - +static void LiveDeviceFreeArray(void); static int LiveSafeDeviceName(const char *devname, char *newdevname, size_t destlen); @@ -334,6 +334,7 @@ void LiveDeviceHasNoStats(void) int LiveDeviceListClean(void) { SCEnter(); + LiveDeviceFreeArray(); LiveDevice *pd, *tpd; /* dpdk: need to close all devices before freeing them. */ @@ -437,6 +438,24 @@ TmEcode LiveDeviceIfaceList(json_t *cmd, json_t *answer, void *data) #endif /* BUILD_UNIX_SOCKET */ +static LiveDevice **g_livedev_array = NULL; +static int g_livedev_array_size = 0; + +static void LiveDeviceFreeArray(void) +{ + if (g_livedev_array) + SCFree(g_livedev_array); + g_livedev_array_size = 0; +} + +LiveDevice *LiveDeviceGetById(const int id) +{ + if (g_livedev_array != NULL && id < g_livedev_array_size) { + return g_livedev_array[id]; + } + return NULL; +} + LiveDevice *LiveDeviceForEach(LiveDevice **ldev, LiveDevice **ndev) { if (*ldev == NULL) { @@ -453,6 +472,24 @@ LiveDevice *LiveDeviceForEach(LiveDevice **ldev, LiveDevice **ndev) return NULL; } +static void LiveDeviceFinalizeBuildArray(void) +{ + BUG_ON(g_livedev_array); + int max_id = LiveGetDeviceCount(); + if (max_id <= 0) + return; + + g_livedev_array = SCCalloc(max_id + 1, sizeof(LiveDevice *)); + if (g_livedev_array == NULL) + FatalError("failed to alloc livedev array"); + g_livedev_array_size = max_id + 1; + + LiveDevice *ldev = NULL, *ndev = NULL; + while (LiveDeviceForEach(&ldev, &ndev)) { + g_livedev_array[ldev->id] = ldev; + } +} + /** * Create registered devices * @@ -471,6 +508,7 @@ void LiveDeviceFinalize(void) } SCFree(ld); } + LiveDeviceFinalizeBuildArray(); } static void LiveDevExtensionFree(void *x) diff --git a/src/util-device.h b/src/util-device.h index 8c91c75b3d..bee10c927e 100644 --- a/src/util-device.h +++ b/src/util-device.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2011-2025 Open Information Security Foundation +/* Copyright (C) 2011-2026 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -56,6 +56,7 @@ int LiveGetDeviceCountWithoutAssignedThreading(void); int LiveGetDeviceCount(void); const char *LiveGetDeviceName(int number); LiveDevice *LiveGetDevice(const char *dev); +LiveDevice *LiveDeviceGetById(const int id); const char *LiveGetShortName(const char *dev); int LiveBuildDeviceList(const char *base); void LiveDeviceHasNoStats(void);