From Cristian Constantin:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 6 Feb 2012 17:23:04 +0000 (17:23 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 6 Feb 2012 17:23:04 +0000 (17:23 +0000)
slow voip/sip call flow for large captures.

https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6794

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@40878 f5534014-38df-0310-8fa8-9805f1628bb7

ui/gtk/voip_calls.c
ui/gtk/voip_calls.h
ui/gtk/voip_calls_dlg.c

index 2cdb382..f212b39 100644 (file)
@@ -144,7 +144,7 @@ typedef struct _voip_rtp_stream_info {
 /****************************************************************************/
 /* the one and only global voip_calls_tapinfo_t structure */
 static voip_calls_tapinfo_t the_tapinfo_struct =
-       {0, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+       {0, NULL, {0}, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
 /* the one and only global voip_rtp_tapinfo_t structure */
 static voip_rtp_tapinfo_t the_tapinfo_rtp_struct =
@@ -184,14 +184,20 @@ void voip_calls_reset(voip_calls_tapinfo_t *tapinfo)
                list = g_list_next(list);
        }
        g_list_free(tapinfo->callsinfo_list);
+       /* free the SIP_HASH */
+       if(NULL!=tapinfo->callsinfo_hashtable[SIP_HASH])
+               g_hash_table_remove_all (tapinfo->callsinfo_hashtable[SIP_HASH]);
        tapinfo->callsinfo_list = NULL;
        tapinfo->ncalls = 0;
        tapinfo->npackets = 0;
        tapinfo->start_packets = 0;
        tapinfo->completed_calls = 0;
        tapinfo->rejected_calls = 0;
+       tapinfo->reversed= 0;
 
        /* free the graph data items first */
+       if(NULL!=tapinfo->graph_analysis->ht)
+               g_hash_table_remove_all(tapinfo->graph_analysis->ht);
        list = g_list_first(tapinfo->graph_analysis->list);
        while (list)
        {
@@ -228,6 +234,7 @@ void graph_analysis_data_init(void){
        the_tapinfo_struct.graph_analysis = g_malloc(sizeof(graph_analysis_info_t));
        the_tapinfo_struct.graph_analysis->nconv = 0;
        the_tapinfo_struct.graph_analysis->list = NULL;
+       the_tapinfo_struct.graph_analysis->ht= g_hash_table_new(g_int_hash, g_int_equal);
 }
 
 /****************************************************************************/
@@ -256,7 +263,8 @@ static void add_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo,
        gai->line_style=line_style;
        gai->display=FALSE;
 
-       tapinfo->graph_analysis->list = g_list_append(tapinfo->graph_analysis->list, gai);
+       tapinfo->graph_analysis->list = g_list_prepend(tapinfo->graph_analysis->list, gai);
+       g_hash_table_insert(tapinfo->graph_analysis->ht, &gai->fd->num, gai); 
 
 }
 
@@ -265,35 +273,28 @@ static void add_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo,
 /* return 0 if the frame_num is not in the graph list */
 static int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
 {
-       graph_analysis_item_t *gai;
-       GList *list;
+       graph_analysis_item_t *gai=NULL;
        gchar *frame_label = NULL;
        gchar *comment = NULL;
 
-       list = g_list_first(tapinfo->graph_analysis->list);
-       while (list)
-       {
-               gai = list->data;
-               if (gai->fd->num == frame_num){
-                       frame_label = gai->frame_label;
-                       comment = gai->comment;
+       if(NULL!=tapinfo->graph_analysis->ht)
+               gai=g_hash_table_lookup(tapinfo->graph_analysis->ht, &frame_num);
+       if(gai){
+               frame_label = gai->frame_label;
+               comment = gai->comment;
 
-                       if (new_frame_label != NULL){
-                               gai->frame_label = g_strdup_printf("%s %s", frame_label, new_frame_label);
-                               g_free(frame_label);
-                       }
+               if (new_frame_label != NULL){
+                       gai->frame_label = g_strdup_printf("%s %s", frame_label, new_frame_label);
+                       g_free(frame_label);
+               }
 
-                       if (new_comment != NULL){
-                               gai->comment = g_strdup_printf("%s %s", comment, new_comment);
-                               g_free(comment);
-                       }
-                       break;
+               if (new_comment != NULL){
+                       gai->comment = g_strdup_printf("%s %s", comment, new_comment);
+                       g_free(comment);
                }
-               list = g_list_next(list);
        }
 
-       return list ? 1 : 0;
-
+       return gai? 1 : 0;
 }
 
 /****************************************************************************/
@@ -301,35 +302,28 @@ static int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 fram
 /* return 0 if the frame_num is not in the graph list */
 static int change_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
 {
-       graph_analysis_item_t *gai;
-       GList *list;
+       graph_analysis_item_t *gai=NULL;
        gchar *frame_label = NULL;
        gchar *comment = NULL;
 
-       list = g_list_first(tapinfo->graph_analysis->list);
-       while (list)
-       {
-               gai = list->data;
-               if (gai->fd->num == frame_num){
-                       frame_label = gai->frame_label;
-                       comment = gai->comment;
+       if(NULL!=tapinfo->graph_analysis->ht)
+               gai=g_hash_table_lookup(tapinfo->graph_analysis->ht, &frame_num);
+       if(gai){
+               frame_label = gai->frame_label;
+               comment = gai->comment;
 
-                       if (new_frame_label != NULL){
-                               gai->frame_label = g_strdup(new_frame_label);
-                               g_free(frame_label);
-                       }
+               if (new_frame_label != NULL){
+                       gai->frame_label = g_strdup(new_frame_label);
+                       g_free(frame_label);
+               }
 
-                       if (new_comment != NULL){
-                               gai->comment = g_strdup(new_comment);
-                               g_free(comment);
-                       }
-                       break;
+               if (new_comment != NULL){
+                       gai->comment = g_strdup(new_comment);
+                       g_free(comment);
                }
-               list = g_list_next(list);
        }
 
-       return list ? 1 : 0;
-
+       return gai? 1 : 0;
 }
 
 /****************************************************************************/
@@ -897,13 +891,12 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
        /* we just take note of the ISUP data here; when we receive the MTP3 part everything will
           be compared with existing calls */
 
-       voip_calls_info_t *tmp_listinfo;
        voip_calls_info_t *callsinfo = NULL;
        sip_calls_info_t *tmp_sipinfo = NULL;
-       GList *list;
        address tmp_src, tmp_dst;
        gchar *frame_label = NULL;
        gchar *comment = NULL;
+       gchar *key=NULL;
 
        const sip_info_value_t *pi = SIPinfo;
 
@@ -911,23 +904,19 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
        if (pi->tap_call_id ==NULL){
                return 0;
        }
-
-       /* check whether we already have a call with these parameters in the list */
-       list = g_list_first(tapinfo->callsinfo_list);
-       while (list)
-       {
-               tmp_listinfo=list->data;
-               if (tmp_listinfo->protocol == VOIP_SIP){
-                       tmp_sipinfo = tmp_listinfo->prot_info;
-                       if (strcmp(tmp_sipinfo->call_identifier,pi->tap_call_id)==0){
-                               callsinfo = (voip_calls_info_t*)(list->data);
-                               break;
-                       }
-               }
-               list = g_list_next (list);
-       }
-
-       /* not in the list? then create a new entry if the message is INVITE -i.e. if this session is a call*/
+       key=pi->tap_call_id;
+       /* init the hash table */
+       if(NULL==tapinfo->callsinfo_hashtable[SIP_HASH]) {
+               /* TODO: check how efficient g_str_hash is for sip call ids */
+               tapinfo->callsinfo_hashtable[SIP_HASH]=g_hash_table_new_full(g_str_hash,
+                                                                                                                       g_str_equal,
+                                                                                                                       NULL, /* key_destroy_func */
+                                                               NULL);/* value_destroy_func */
+       }
+       /* search the call information in the SIP_HASH */
+       callsinfo = g_hash_table_lookup(tapinfo->callsinfo_hashtable[SIP_HASH], key);
+               
+       /* not in the hash? then create a new entry if the message is INVITE -i.e. if this session is a call*/
        if ((callsinfo==NULL) &&(pi->request_method!=NULL)){
                if (strcmp(pi->request_method,"INVITE")==0){
                        callsinfo = g_malloc0(sizeof(voip_calls_info_t));
@@ -947,11 +936,15 @@ SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, con
                        tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
                        callsinfo->npackets = 0;
                        callsinfo->call_num = tapinfo->ncalls++;
-                       tapinfo->callsinfo_list = g_list_append(tapinfo->callsinfo_list, callsinfo);
+                       tapinfo->callsinfo_list = g_list_prepend(tapinfo->callsinfo_list, callsinfo);
+                       /* insert the call information in the SIP_HASH */
+                       g_hash_table_insert(tapinfo->callsinfo_hashtable[SIP_HASH], 
+                               tmp_sipinfo->call_identifier, callsinfo);
                }
        }
 
        if (callsinfo!=NULL){
+               tmp_sipinfo = callsinfo->prot_info;
 
                /* let's analyze the call state */
 
index d6ff33c..764c4ce 100644 (file)
@@ -63,6 +63,10 @@ typedef enum _voip_protocol {
                VOIP_COMMON
 } voip_protocol;
 
+typedef enum _hash_indexes {
+               SIP_HASH=0
+} hash_indexes;
+
 extern const char *voip_protocol_name[];
 
 /* defines specific SIP data */
@@ -157,6 +161,7 @@ typedef struct _voip_calls_info {
 typedef struct _voip_calls_tapinfo {
        int     ncalls;       /* number of call */
        GList*  callsinfo_list;   /* list with all calls */
+       GHashTable* callsinfo_hashtable[1]; /* array of hashes per voip protocol; currently only the one for SIP is used */
        int     npackets;       /* total number of packets of all calls */
        voip_calls_info_t* filter_calls_fwd;  /* used as filter in some tap modes */
        guint32 launch_count;   /* number of times the tap has been run */
@@ -164,6 +169,7 @@ typedef struct _voip_calls_tapinfo {
        int completed_calls;
        int rejected_calls;
        graph_analysis_info_t* graph_analysis;
+       gboolean reversed;
        gboolean redraw;
        /* 
         * Now add dummy variables, one for each tap listener.
index 31cfdcb..93340f8 100644 (file)
@@ -325,6 +325,13 @@ on_graph_bt_clicked(GtkButton *button _U_, gpointer user_data _U_)
        GList* listb;
        voip_calls_info_t *listinfo;
 
+       if(!voip_calls_get_info()->reversed) {
+               voip_calls_get_info()->callsinfo_list=
+                       g_list_reverse(voip_calls_get_info()->callsinfo_list);
+               voip_calls_get_info()->graph_analysis->list=
+                       g_list_reverse(voip_calls_get_info()->graph_analysis->list);
+               voip_calls_get_info()->reversed=1;
+       }
        /* reset the "display" parameter in graph analysis */
        listb = g_list_first(voip_calls_get_info()->graph_analysis->list);
        while (listb) {
@@ -756,7 +763,12 @@ voip_calls_dlg_create(void)
 void
 voip_calls_dlg_update(GList *listx)
 {
+       GtkTreeView       *list_view;
+       GtkTreeSortable   *sortable;
        gchar label_text[256];
+
+       list_view = GTK_TREE_VIEW(list);
+       sortable = GTK_TREE_SORTABLE(list_store);
        if (voip_calls_dlg != NULL) {
                calls_nb = 0;
                calls_ns = 0;
@@ -771,7 +783,8 @@ voip_calls_dlg_update(GList *listx)
                gtk_label_set_text(GTK_LABEL(status_label), label_text);
 
                /* Disable the re-ordering */
-               gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(list_store), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
+               gtk_tree_sortable_set_sort_column_id(sortable, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
+
 
                listx = g_list_first(listx);
                while (listx) {
@@ -779,7 +792,8 @@ voip_calls_dlg_update(GList *listx)
                        listx = g_list_next(listx);
                }
                /* Enable the re-ordering */
-               gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(list_store), CALL_COL_START_TIME, GTK_SORT_ASCENDING);
+               gtk_tree_sortable_set_sort_column_id(sortable, CALL_COL_START_TIME, GTK_SORT_ASCENDING);
+
 
                g_snprintf(label_text, sizeof(label_text),
                        "Detected %u VoIP %s. Selected %u %s.",