121 lines
3.6 KiB
Diff
121 lines
3.6 KiB
Diff
# UNDF: UNDF-2026-000000341
|
|
--- a/epan/packet_info.h
|
|
+++ b/epan/packet_info.h
|
|
@@ -158,7 +158,7 @@ struct _packet_info {
|
|
gboolean fragmented; /**< TRUE if the protocol is only a fragment */
|
|
gboolean in_error_pkt; /**< TRUE if we're inside an error packet */
|
|
gboolean incomplete_dissector_key;
|
|
- GSList *proto_data; /**< Per-packet protocol data */
|
|
+ wmem_map_t *proto_data; /**< Per-packet protocol data: (proto<<32|key) → data */
|
|
GSList *dependent_frames; /**< A list of frames which this one depends on */
|
|
GSList *frame_end_routines;
|
|
|
|
--- a/epan/proto_data.c
|
|
+++ b/epan/proto_data.c
|
|
@@ -13,7 +13,8 @@
|
|
#include <glib.h>
|
|
|
|
#include <epan/wmem_scopes.h>
|
|
+#include <wsutil/wmem/wmem_map.h>
|
|
#include <epan/packet_info.h>
|
|
#include <epan/proto_data.h>
|
|
#include <epan/proto.h>
|
|
@@ -21,50 +21,41 @@
|
|
-/* Protocol-specific data attached to a frame_data structure - protocol
|
|
- index, key for multiple items with the same protocol index,
|
|
- and opaque pointer. */
|
|
-typedef struct _proto_data {
|
|
- int proto;
|
|
- uint32_t key;
|
|
- void *proto_data;
|
|
-} proto_data_t;
|
|
-
|
|
-static int
|
|
-p_compare(const void *a, const void *b)
|
|
-{
|
|
- const proto_data_t *ap = (const proto_data_t *)a;
|
|
- const proto_data_t *bp = (const proto_data_t *)b;
|
|
-
|
|
- if (ap -> proto > bp -> proto) {
|
|
- return 1;
|
|
- } else if (ap -> proto == bp -> proto) {
|
|
- if (ap->key > bp->key){
|
|
- return 1;
|
|
- } else if (ap -> key == bp -> key) {
|
|
- return 0;
|
|
- }
|
|
- return -1;
|
|
- } else {
|
|
- return -1;
|
|
- }
|
|
-}
|
|
+/* Composite hash key: upper 32 bits = proto index, lower 32 bits = key.
|
|
+ O(1) insert/lookup/remove instead of O(N) GSList scan per operation. */
|
|
+static inline uint64_t
|
|
+p_make_key(int proto, uint32_t key)
|
|
+{
|
|
+ return ((uint64_t)(unsigned)proto << 32) | (uint64_t)key;
|
|
+}
|
|
|
|
void
|
|
p_add_proto_data(wmem_allocator_t *tmp_scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data)
|
|
{
|
|
- proto_data_t *p1;
|
|
- GSList **proto_list;
|
|
- wmem_allocator_t *scope;
|
|
+ wmem_map_t **proto_map;
|
|
+ wmem_allocator_t *scope;
|
|
|
|
if (tmp_scope == pinfo->pool) {
|
|
scope = tmp_scope;
|
|
- proto_list = &pinfo->proto_data;
|
|
+ proto_map = &pinfo->proto_data;
|
|
} else if (tmp_scope == wmem_file_scope()) {
|
|
scope = wmem_file_scope();
|
|
- proto_list = &pinfo->fd->pfd;
|
|
+ proto_map = (wmem_map_t **)&pinfo->fd->pfd;
|
|
} else {
|
|
DISSECTOR_ASSERT(!"invalid wmem scope");
|
|
}
|
|
|
|
- p1 = wmem_new(scope, proto_data_t);
|
|
-
|
|
- p1->proto = proto;
|
|
- p1->key = key;
|
|
- p1->proto_data = proto_data;
|
|
-
|
|
- /* Add it to the GSLIST */
|
|
- *proto_list = g_slist_prepend(*proto_list, p1);
|
|
+ if (*proto_map == NULL)
|
|
+ *proto_map = wmem_map_new(scope, g_int64_hash, g_int64_equal);
|
|
+ uint64_t *map_key = wmem_new(scope, uint64_t);
|
|
+ *map_key = p_make_key(proto, key);
|
|
+ wmem_map_insert(*proto_map, map_key, proto_data);
|
|
}
|
|
|
|
void
|
|
p_set_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data)
|
|
{
|
|
- proto_data_t temp;
|
|
- GSList *item;
|
|
-
|
|
- temp.proto = proto;
|
|
- temp.key = key;
|
|
- temp.proto_data = NULL;
|
|
-
|
|
- if (scope == pinfo->pool) {
|
|
- item = g_slist_find_custom(pinfo->proto_data, &temp, p_compare);
|
|
- } else if (scope == wmem_file_scope()) {
|
|
- item = g_slist_find_custom(pinfo->fd->pfd, &temp, p_compare);
|
|
- } else {
|
|
- DISSECTOR_ASSERT(!"invalid wmem scope");
|
|
- }
|
|
-
|
|
- if (item) {
|
|
- proto_data_t *pd = (proto_data_t *)item->data;
|
|
- pd->proto_data = proto_data;
|
|
- return;
|
|
- }
|
|
-
|
|
p_add_proto_data(scope, pinfo, proto, key, proto_data);
|
|
}
|