summaryrefslogtreecommitdiff
path: root/epan/conversation.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2012-02-04 12:23:51 +0000
committerAnders Broman <anders.broman@ericsson.com>2012-02-04 12:23:51 +0000
commit37dec6fcad2db152601d53b618885e8c5f97dfe0 (patch)
tree7cc099a812350ba59c72cba0d71f6a36b4fccf03 /epan/conversation.c
parent5f891470ac4dc871abfdc81807bf7cc66bd54ff4 (diff)
downloadwireshark-37dec6fcad2db152601d53b618885e8c5f97dfe0.tar.gz
From Cristian Constantin:
Slow loading/processing of conversations with over 500k frames. https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6755 svn path=/trunk/; revision=40837
Diffstat (limited to 'epan/conversation.c')
-rw-r--r--epan/conversation.c63
1 files changed, 48 insertions, 15 deletions
diff --git a/epan/conversation.c b/epan/conversation.c
index d40ee7677d..63579f6a4d 100644
--- a/epan/conversation.c
+++ b/epan/conversation.c
@@ -509,10 +509,10 @@ conversation_new(const guint32 setup_frame, const address *addr1, const address
"A conversation template may not be constructed without wildcard options");
*/
GHashTable* hashtable;
- conversation_t *conversation;
- conversation_t *tc;
+ conversation_t *conversation=NULL, *prev=NULL;
conversation_key existing_key;
conversation_key *new_key;
+ guint conv_in_ht=0;
if (options & NO_ADDR2) {
if (options & (NO_PORT2|NO_PORT2_FORCE)) {
@@ -535,7 +535,8 @@ conversation_new(const guint32 setup_frame, const address *addr1, const address
existing_key.port2 = port2;
conversation = g_hash_table_lookup(hashtable, &existing_key);
- tc = conversation; /* Remember if lookup was successful */
+ if(NULL!=conversation)
+ conv_in_ht=1;
new_key = se_alloc(sizeof(struct conversation_key));
new_key->next = conversation_keys;
@@ -547,15 +548,37 @@ conversation_new(const guint32 setup_frame, const address *addr1, const address
new_key->port2 = port2;
if (conversation) {
- for (; conversation->next; conversation = conversation->next)
- ;
- conversation->next = se_alloc(sizeof(conversation_t));
- conversation = conversation->next;
+ /* the list is ordered on setup_frame */
+ if(setup_frame>=conversation->last->setup_frame) {
+ /* add it to the end */
+ conversation->last->next=se_alloc(sizeof(conversation_t));
+ prev=conversation->last->next;
+ prev->next=NULL;
+ conversation->last=prev;
+ conversation = prev;
+ } else {
+ for (prev=NULL; (setup_frame>conversation->setup_frame) && conversation->next; prev=conversation, conversation = conversation->next)
+ ;
+ if(prev) {
+ prev->next = se_alloc(sizeof(conversation_t));
+ prev->next->next = conversation;
+ conversation = prev->next;
+ } else {
+ /* change the head of the list */
+ prev = se_alloc(sizeof(conversation_t));
+ prev->next = conversation;
+ prev->last = conversation->last;
+ conversation->last=NULL;
+ conversation = prev;
+ conv_in_ht=0;
+ }
+ }
} else {
conversation = se_alloc(sizeof(conversation_t));
+ conversation->next = NULL;
+ conversation->last = conversation;
}
- conversation->next = NULL;
conversation->index = new_index;
conversation->setup_frame = setup_frame;
conversation->data_list = NULL;
@@ -571,7 +594,7 @@ conversation_new(const guint32 setup_frame, const address *addr1, const address
/* only insert a hash table entry if this
* is the first conversation with this key */
- if (!tc)
+ if (!conv_in_ht)
g_hash_table_insert(hashtable, new_key, conversation);
return conversation;
@@ -653,9 +676,10 @@ static conversation_t *
conversation_lookup_hashtable(GHashTable *hashtable, const guint32 frame_num, const address *addr1, const address *addr2,
const port_type ptype, const guint32 port1, const guint32 port2)
{
- conversation_t* conversation;
- conversation_t* match;
+ conversation_t* conversation=NULL;
+ conversation_t* match=NULL;
conversation_key key;
+ guint found=0;
/*
* We don't make a copy of the address data, we just copy the
@@ -668,15 +692,24 @@ conversation_lookup_hashtable(GHashTable *hashtable, const guint32 frame_num, co
key.port2 = port2;
match = g_hash_table_lookup(hashtable, &key);
+
+ if (match && (match->setup_frame > frame_num))
+ match = NULL;
if (match) {
+ if(match->last->setup_frame<=frame_num)
+ return match;
for (conversation = match->next; conversation; conversation = conversation->next) {
if ((conversation->setup_frame <= frame_num)
- && (conversation->setup_frame > match->setup_frame))
- match = conversation;
+ && (conversation->setup_frame > match->setup_frame)) {
+ match = conversation;
+ found=1;
+ } else if(conversation->setup_frame>frame_num)
+ /* we are past the frame_num */
+ break;
}
- if (match->setup_frame > frame_num)
- match = NULL;
+ if(!found)
+ match=NULL;
}
return match;