java-topology/defects/wireshark/patch/wireshark-0001-proto-data-wmem-map.patch

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);
}