From 5d3eea14a376d402594ae290ed9292fe57a680b5 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Mon, 4 May 2020 21:26:59 +0200 Subject: [PATCH] ConversationDialog: fix a TCP graph race condition When the user opens the conversation dialog, selects a tcp conversation and presses the Graph button, the ConversationDialog kicks off these two actions 1.) apply a display filter "tcp.stream eq X" (where X is the number of the stream) 2.) open the tcp stream graph Both actions are asynchronous and, at least on my machines, the graph is opened before the filter is applied. The graph requires that the current packet be part of the selected tcp conversation. If it's not (because the filter isn't applied yet), we get the "Selected packet isn't a TCP segment or is truncated" error message and the graph is not shown. Fix this by enforcing the correct order for the two actions. MainWindow sends the displayFilterSuccess signal when a display filter was applied. Listen to this signal in ConversationDialog and launch the tcp graph when the filter was applied successfully. Change-Id: I63debe2125ba8f0a737ff4882a9fca0a7bcdb0f5 Reviewed-on: https://code.wireshark.org/review/37130 Reviewed-by: Martin Kaiser Petri-Dish: Martin Kaiser Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman --- ui/qt/conversation_dialog.cpp | 24 ++++++++++++++++++++---- ui/qt/conversation_dialog.h | 3 +++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/ui/qt/conversation_dialog.cpp b/ui/qt/conversation_dialog.cpp index b1bde96a16..8dfe9d1385 100644 --- a/ui/qt/conversation_dialog.cpp +++ b/ui/qt/conversation_dialog.cpp @@ -53,7 +53,8 @@ static const QString table_name_ = QObject::tr("Conversation"); ConversationDialog::ConversationDialog(QWidget &parent, CaptureFile &cf, int cli_proto_id, const char *filter) : - TrafficTableDialog(parent, cf, filter, table_name_) + TrafficTableDialog(parent, cf, filter, table_name_), + tcp_graph_requested_(false) { follow_bt_ = buttonBox()->addButton(tr("Follow Stream" UTF8_HORIZONTAL_ELLIPSIS), QDialogButtonBox::ActionRole); follow_bt_->setToolTip(tr("Follow a TCP or UDP stream.")); @@ -63,6 +64,9 @@ ConversationDialog::ConversationDialog(QWidget &parent, CaptureFile &cf, int cli graph_bt_->setToolTip(tr("Graph a TCP conversation.")); connect(graph_bt_, SIGNAL(clicked()), this, SLOT(graphTcp())); + connect(wsApp->mainWindow(), SIGNAL(displayFilterSuccess(bool)), + this, SLOT(displayFilterSuccess(bool))); + absoluteTimeCheckBox()->show(); addProgressFrame(&parent); @@ -236,10 +240,10 @@ void ConversationDialog::graphTcp() return; } - // Apply the filter for this conversation. + tcp_graph_requested_ = true; + // Apply the filter for this conversation. When the filter is active, we + // can draw the TCP graph. emit filterAction(filter, FilterAction::ActionApply, FilterAction::ActionTypePlain); - // This action will now find a packet from the intended conversation/stream. - openTcpStreamGraph(GRAPH_TSEQ_TCPTRACE); } void ConversationDialog::currentTabChanged() @@ -300,6 +304,18 @@ void ConversationDialog::on_buttonBox_helpRequested() wsApp->helpTopicAction(HELP_STATS_CONVERSATIONS_DIALOG); } +void ConversationDialog::displayFilterSuccess(bool success) +{ + if (tcp_graph_requested_) { + if (success) { + // The display filter was applied successfully, i.e. the current + // packet is now part of our selected tcp conversation. + openTcpStreamGraph(GRAPH_TSEQ_TCPTRACE); + } + tcp_graph_requested_ = false; + } +} + void init_conversation_table(struct register_ct* ct, const char *filter) { wsApp->emitStatCommandSignal("Conversations", filter, GINT_TO_POINTER(get_conversation_proto_id(ct))); diff --git a/ui/qt/conversation_dialog.h b/ui/qt/conversation_dialog.h index b6b86422b6..95f42e4726 100644 --- a/ui/qt/conversation_dialog.h +++ b/ui/qt/conversation_dialog.h @@ -67,6 +67,8 @@ private: bool addTrafficTable(register_ct_t* table); conv_item_t *currentConversation(); + bool tcp_graph_requested_; + private slots: void currentTabChanged(); void conversationSelectionChanged(); @@ -74,6 +76,7 @@ private slots: void followStream(); void graphTcp(); void on_buttonBox_helpRequested(); + void displayFilterSuccess(bool success); }; void init_conversation_table(struct register_ct* ct, const char *filter);