aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoshe Kaplan <me@moshekaplan.com>2018-02-07 12:35:32 -0500
committerAnders Broman <a.broman58@gmail.com>2018-02-08 05:36:28 +0000
commit58d5baf3c081b5d6aa795cd9e05d547927d89001 (patch)
tree2ba97ca07568576e84b53231620faaad726a833f
parent0f721985f1d8e75a7db419402436bcf0637b23e6 (diff)
Cleanup HTTP Referer tracking code and use less memory
Change-Id: I7d9d8a1ab6ed9f180511281348d6b679b5fba1fb Reviewed-on: https://code.wireshark.org/review/25665 Reviewed-by: Peter Wu <peter@lekensteyn.nl> Petri-Dish: Peter Wu <peter@lekensteyn.nl> Reviewed-by: Moshe Kaplan <me@moshekaplan.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--epan/dissectors/packet-http.c152
1 files changed, 86 insertions, 66 deletions
diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c
index 7a39d18fc3..096bcad316 100644
--- a/epan/dissectors/packet-http.c
+++ b/epan/dissectors/packet-http.c
@@ -692,19 +692,83 @@ static wmem_map_t* refstats_node_id_to_parent_node_id_hash = NULL;
static void
http_ref_stats_tree_init(stats_tree* st)
{
- int *parent_node_id_p = NULL;
+ gint root_node_id = 0;
+ gpointer root_node_id_p = GINT_TO_POINTER(root_node_id);
+ gpointer node_id_p = NULL;
+ gchar *uri = NULL;
- refstats_node_id_to_parent_node_id_hash = wmem_map_new(wmem_file_scope(), g_int_hash, g_int_equal);
- refstats_node_id_to_uri_hash = wmem_map_new(wmem_file_scope(), g_int_hash, g_int_equal);
+ refstats_node_id_to_parent_node_id_hash = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
+ refstats_node_id_to_uri_hash = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
refstats_uri_to_node_id_hash = wmem_map_new(wmem_file_scope(), wmem_str_hash, g_str_equal);
+
/* Add the root node and its mappings */
- parent_node_id_p = wmem_new(wmem_file_scope(), int);
- *parent_node_id_p = 0;
- st_node_requests_by_referer = stats_tree_create_node(st, st_str_requests_by_referer, *parent_node_id_p, TRUE);
+ st_node_requests_by_referer = stats_tree_create_node(st, st_str_requests_by_referer, root_node_id, TRUE);
+ node_id_p = GINT_TO_POINTER(st_node_requests_by_referer);
+ uri = wmem_strdup(wmem_file_scope(), st_str_requests_by_referer);
+
+ wmem_map_insert(refstats_uri_to_node_id_hash, uri, node_id_p);
+ wmem_map_insert(refstats_node_id_to_uri_hash, node_id_p, uri);
+ wmem_map_insert(refstats_node_id_to_parent_node_id_hash, node_id_p, root_node_id_p);
+}
+
+static gint
+http_ref_stats_tick_referer(stats_tree* st, const http_info_value_t* v)
+{
+ gint root_node_id = st_node_requests_by_referer;
+ gpointer root_node_id_p = GINT_TO_POINTER(st_node_requests_by_referer);
+ gint referer_node_id;
+ gpointer referer_node_id_p;
+ gint referer_parent_node_id;
+ gpointer referer_parent_node_id_p;
+ gchar *referer_uri;
+
+ /* Tick the referer's URI */
+ /* Does the node exist? */
+ if (!wmem_map_lookup_extended(refstats_uri_to_node_id_hash, v->referer_uri, NULL, &referer_node_id_p)) {
+ /* The node for the referer didn't already exist, create the mappings */
+ referer_node_id = tick_stat_node(st, v->referer_uri, root_node_id, TRUE);
+ referer_node_id_p = GINT_TO_POINTER(referer_node_id);
+ referer_parent_node_id_p = root_node_id_p;
+
+ referer_uri = wmem_strdup(wmem_file_scope(), v->referer_uri);
+ wmem_map_insert(refstats_uri_to_node_id_hash, referer_uri, referer_node_id_p);
+ wmem_map_insert(refstats_node_id_to_uri_hash, referer_node_id_p, referer_uri);
+ wmem_map_insert(refstats_node_id_to_parent_node_id_hash, referer_node_id_p, referer_parent_node_id_p);
+ } else {
+ /* The node for the referer already exists, tick it */
+ referer_parent_node_id_p = wmem_map_lookup(refstats_node_id_to_parent_node_id_hash, referer_node_id_p);
+ referer_parent_node_id = GPOINTER_TO_INT(referer_parent_node_id_p);
+ referer_node_id = tick_stat_node(st, v->referer_uri, referer_parent_node_id, TRUE);
+ }
+ return referer_node_id;
+}
+
+static void
+http_ref_stats_tick_request(stats_tree* st, const http_info_value_t* v, gint referer_node_id)
+{
+ gpointer referer_node_id_p = GINT_TO_POINTER(referer_node_id);
+ gint node_id;
+ gpointer node_id_p;
+ gchar *uri;
+
+ node_id = tick_stat_node(st, v->full_uri, referer_node_id, TRUE);
+ node_id_p = GINT_TO_POINTER(node_id);
- wmem_map_insert(refstats_uri_to_node_id_hash, st_str_requests_by_referer, parent_node_id_p);
- wmem_map_insert(refstats_node_id_to_uri_hash, &st_node_requests_by_referer, wmem_strdup(wmem_file_scope(), st_str_requests_by_referer));
- wmem_map_insert(refstats_node_id_to_parent_node_id_hash, &st_node_requests_by_referer, parent_node_id_p);
+ /* Update the mappings. Even if the URI was already seen, the URI->node mapping may need to be updated */
+
+ /* Is this a new node? */
+ uri = (gchar *) wmem_map_lookup(refstats_node_id_to_uri_hash, node_id_p);
+ if (!uri) {
+ /* node not found, add mappings for the node and uri */
+ uri = wmem_strdup(wmem_file_scope(), v->full_uri);
+
+ wmem_map_insert(refstats_uri_to_node_id_hash, uri, node_id_p);
+ wmem_map_insert(refstats_node_id_to_uri_hash, node_id_p, uri);
+ wmem_map_insert(refstats_node_id_to_parent_node_id_hash, node_id_p, referer_node_id_p);
+ } else {
+ /* We've seen the node id before. Update the URI mapping refer to this node id*/
+ wmem_map_insert(refstats_uri_to_node_id_hash, uri, node_id_p);
+ }
}
/* HTTP/Referers stats packet function */
@@ -712,72 +776,28 @@ static int
http_ref_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* p)
{
const http_info_value_t* v = (const http_info_value_t*)p;
- int *referer_node_id_p = NULL;
- int uri_node_id;
- int *uri_node_id_p = NULL;
- int *parent_node_id_p = NULL;
- int *current_node_id_p = NULL;
+
+ gint referer_node_id;
+
+ gint parent_node_id;
+ gpointer parent_node_id_p;
+ gpointer current_node_id_p;
+
gchar *uri = NULL;
- gchar *referer_uri = NULL;
- wmem_list_t *node_ids_list = NULL;
- wmem_list_frame_t *node_ids_list_pos = NULL;
if (v->request_method && v->referer_uri && v->full_uri) {
/* Tick the referer's URI */
- /* If the node for the referer didn't already exist, create the mappings */
- referer_node_id_p = (int *) wmem_map_lookup(refstats_uri_to_node_id_hash, v->referer_uri);
- if (!referer_node_id_p) {
- referer_uri = wmem_strdup(wmem_file_scope(), v->referer_uri);
- referer_node_id_p = wmem_new(wmem_file_scope(), int);
- *referer_node_id_p = tick_stat_node(st, v->referer_uri, st_node_requests_by_referer, TRUE);
-
- wmem_map_insert(refstats_uri_to_node_id_hash, referer_uri, referer_node_id_p);
- wmem_map_insert(refstats_node_id_to_uri_hash, referer_node_id_p, referer_uri);
- wmem_map_insert(refstats_node_id_to_parent_node_id_hash, referer_node_id_p, &st_node_requests_by_referer);
- } else {
- parent_node_id_p = (int *) wmem_map_lookup(refstats_node_id_to_parent_node_id_hash, referer_node_id_p);
- *referer_node_id_p = tick_stat_node(st, v->referer_uri, *parent_node_id_p, TRUE);
- }
+ referer_node_id = http_ref_stats_tick_referer(st, v);
/* Tick the request's URI */
- /* Even if the URI was seen, the mapping needs to be updated to refer to the correct node */
- uri_node_id = tick_stat_node(st, v->full_uri, *referer_node_id_p, TRUE);
-
- /* Have we seen this node id before? */
- uri = (gchar *) wmem_map_lookup(refstats_node_id_to_uri_hash, &uri_node_id);
- if (!uri) {
- /* URI node not found, add mappings for the uri (under the referer node) */
- uri = wmem_strdup(wmem_file_scope(), v->full_uri);
- uri_node_id_p = wmem_new(wmem_file_scope(), int);
- *uri_node_id_p = uri_node_id;
-
- wmem_map_insert(refstats_uri_to_node_id_hash, uri, uri_node_id_p);
- wmem_map_insert(refstats_node_id_to_uri_hash, uri_node_id_p, uri);
- wmem_map_insert(refstats_node_id_to_parent_node_id_hash, uri_node_id_p, referer_node_id_p);
- } else {
- /* We've seen the node id before. Does the URI mapping refer to this node id?*/
- if ( *((int *) wmem_map_lookup(refstats_uri_to_node_id_hash, uri)) != uri_node_id) {
- /* Reuse the existing pointer containing uri_node_id, to avoid leaking memory */
- node_ids_list = wmem_map_get_keys(wmem_file_scope(), refstats_node_id_to_uri_hash);
- node_ids_list_pos = wmem_list_head(node_ids_list);
- while (node_ids_list_pos != NULL) {
- uri_node_id_p = (int *) wmem_list_frame_data(node_ids_list_pos);
- if( *uri_node_id_p == uri_node_id) {
- wmem_map_insert(refstats_uri_to_node_id_hash, uri, uri_node_id_p);
- break;
- }
- node_ids_list_pos = wmem_list_frame_next(node_ids_list_pos);
- }
- wmem_destroy_list(node_ids_list);
- }
- }
+ http_ref_stats_tick_request(st, v, referer_node_id);
/* Tick all stats nodes above the referer */
- current_node_id_p = (int *) wmem_map_lookup(refstats_node_id_to_parent_node_id_hash, referer_node_id_p);
- while (current_node_id_p && *current_node_id_p) {
- parent_node_id_p = (int *) wmem_map_lookup(refstats_node_id_to_parent_node_id_hash, current_node_id_p);
+ current_node_id_p = GINT_TO_POINTER(referer_node_id);
+ while (wmem_map_lookup_extended(refstats_node_id_to_parent_node_id_hash, current_node_id_p, NULL, &parent_node_id_p)) {
+ parent_node_id = GPOINTER_TO_INT(parent_node_id_p);
uri = (gchar *) wmem_map_lookup(refstats_node_id_to_uri_hash, current_node_id_p);
- tick_stat_node(st, uri, *parent_node_id_p, TRUE);
+ tick_stat_node(st, uri, parent_node_id, TRUE);
current_node_id_p = parent_node_id_p;
}
}