voip_calls_dialog/voip_calls: Fix for #16952

The fix solves issue #16952. It reverts commit 88813716 which introduced memory leak which causes the issue. The original issue with duplicating entries is solved too.
Because commit was cherry picked to 3.4.0 (might be in more branches), this patch should be cherry picked too.
This commit is contained in:
j.novak@netsystem.cz 2020-12-30 08:51:00 +00:00 committed by AndersBroman
parent a9d4e70edc
commit 396baef3e5
13 changed files with 194 additions and 10 deletions

View File

@ -192,6 +192,9 @@ static void sequence_analysis_item_free(gpointer data)
g_free(seq_item->comment);
free_address(&seq_item->src_addr);
free_address(&seq_item->dst_addr);
if (seq_item->info_ptr) {
g_free(seq_item->info_ptr);
}
g_free(data);
}

View File

@ -52,6 +52,8 @@ typedef struct _seq_analysis_item {
guint src_node; /**< this is used by graph_analysis.c to identify the node */
guint dst_node; /**< a node is an IP address that will be displayed in columns */
guint16 line_style; /**< the arrow line width in pixels*/
guint32 info_type; /**< type of info for item */
gpointer info_ptr; /**< ptr to info for item */
} seq_analysis_item_t;
/** defines the graph analysis structure */

View File

@ -75,6 +75,8 @@
#include "filter_action.h"
#include "follow_stream_dialog.h"
#include <ui/qt/models/pref_models.h>
#include "rtp_stream_dialog.h"
#include "voip_calls_dialog.h"
class AccordionFrame;
class ByteViewTab;
@ -244,6 +246,11 @@ private:
QWidget* getLayoutWidget(layout_pane_content_e type);
QPointer<RtpStreamDialog> rtp_stream_dialog_; // Singleton pattern used
QPointer<VoipCallsDialog> voip_calls_dialog_; // Singleton pattern used
void interconnectRtpStreamDialogToVoipCallsDialog(RtpStreamDialog *rtp_stream_dialog, VoipCallsDialog *voip_calls_dialog);
void freeze();
void thaw();

View File

@ -3290,14 +3290,29 @@ void MainWindow::on_actionStatisticsHTTP2_triggered()
// Telephony Menu
void MainWindow::interconnectRtpStreamDialogToVoipCallsDialog(RtpStreamDialog *rtp_stream_dialog, VoipCallsDialog *voip_calls_dialog)
{
if (rtp_stream_dialog && voip_calls_dialog) {
// Connect signals between dialogs
connect(voip_calls_dialog, SIGNAL(selectRtpStreamPassOut(rtpstream_id_t *)), rtp_stream_dialog, SLOT(selectRtpStream(rtpstream_id_t *)));
connect(voip_calls_dialog, SIGNAL(deselectRtpStreamPassOut(rtpstream_id_t *)), rtp_stream_dialog, SLOT(deselectRtpStream(rtpstream_id_t *)));
}
}
void MainWindow::openVoipCallsDialog(bool all_flows)
{
VoipCallsDialog *voip_calls_dialog = new VoipCallsDialog(*this, capture_file_, all_flows);
connect(voip_calls_dialog, SIGNAL(goToPacket(int)),
if (!voip_calls_dialog_) {
voip_calls_dialog_ = new VoipCallsDialog(*this, capture_file_, all_flows);
}
connect(voip_calls_dialog_, SIGNAL(goToPacket(int)),
packet_list_, SLOT(goToPacket(int)));
connect(voip_calls_dialog, SIGNAL(updateFilter(QString, bool)),
connect(voip_calls_dialog_, SIGNAL(updateFilter(QString, bool)),
this, SLOT(filterPackets(QString, bool)));
voip_calls_dialog->show();
connect(voip_calls_dialog_, SIGNAL(openRtpStreamDialogPassOut()),
this, SLOT(on_actionTelephonyRTPStreams_triggered()));
interconnectRtpStreamDialogToVoipCallsDialog(rtp_stream_dialog_, voip_calls_dialog_);
voip_calls_dialog_->show();
voip_calls_dialog_->raise();
}
void MainWindow::on_actionTelephonyVoipCalls_triggered()
@ -3389,14 +3404,18 @@ void MainWindow::on_actionTelephonyOsmuxPacketCounter_triggered()
void MainWindow::on_actionTelephonyRTPStreams_triggered()
{
RtpStreamDialog *rtp_stream_dialog = new RtpStreamDialog(*this, capture_file_);
connect(rtp_stream_dialog, SIGNAL(packetsMarked()),
if (!rtp_stream_dialog_) {
rtp_stream_dialog_ = new RtpStreamDialog(*this, capture_file_);
}
connect(rtp_stream_dialog_, SIGNAL(packetsMarked()),
packet_list_, SLOT(redrawVisiblePackets()));
connect(rtp_stream_dialog, SIGNAL(goToPacket(int)),
connect(rtp_stream_dialog_, SIGNAL(goToPacket(int)),
packet_list_, SLOT(goToPacket(int)));
connect(rtp_stream_dialog, SIGNAL(updateFilter(QString, bool)),
connect(rtp_stream_dialog_, SIGNAL(updateFilter(QString, bool)),
this, SLOT(filterPackets(QString, bool)));
rtp_stream_dialog->show();
interconnectRtpStreamDialogToVoipCallsDialog(rtp_stream_dialog_, voip_calls_dialog_);
rtp_stream_dialog_->show();
rtp_stream_dialog_->raise();
}
void MainWindow::on_actionTelephonyRTPStreamAnalysis_triggered()

View File

@ -278,6 +278,31 @@ RtpStreamDialog::~RtpStreamDialog()
remove_tap_listener_rtpstream(&tapinfo_);
}
void RtpStreamDialog::setRtpStreamSelection(rtpstream_id_t *id, bool state)
{
QTreeWidgetItemIterator iter(ui->streamTreeWidget);
while (*iter) {
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(*iter);
rtpstream_info_t *stream_info = rsti->streamInfo();
if (stream_info) {
if (rtpstream_id_equal(id,&stream_info->id,RTPSTREAM_ID_EQUAL_SSRC)) {
(*iter)->setSelected(state);
}
}
++iter;
}
}
void RtpStreamDialog::selectRtpStream(rtpstream_id_t *id)
{
setRtpStreamSelection(id, true);
}
void RtpStreamDialog::deselectRtpStream(rtpstream_id_t *id)
{
setRtpStreamSelection(id, false);
}
bool RtpStreamDialog::eventFilter(QObject *, QEvent *event)
{
if (ui->streamTreeWidget->hasFocus() && event->type() == QEvent::KeyPress) {

View File

@ -38,6 +38,10 @@ signals:
void updateFilter(QString filter, bool force = false);
void goToPacket(int packet_num);
public slots:
void selectRtpStream(rtpstream_id_t *id);
void deselectRtpStream(rtpstream_id_t *id);
protected:
bool eventFilter(QObject *obj, QEvent *event);
@ -61,6 +65,8 @@ private:
void updateWidgets();
void showPlayer();
void setRtpStreamSelection(rtpstream_id_t *id, bool state);
QList<QVariant> streamRowData(int row) const;

View File

@ -27,6 +27,8 @@
#include <ui/qt/utils/variant_pointer.h>
#include <ui/alert_box.h>
#include "ui/qt/widgets/wireshark_file_dialog.h"
#include <ui/voip_calls.h>
#include "rtp_stream_dialog.h"
#include <QDir>
#include <QFontMetrics>
@ -72,6 +74,8 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
packet_num_(0),
sequence_w_(1)
{
QAction *action;
ui->setupUi(this);
QCustomPlot *sp = ui->sequencePlot;
@ -130,7 +134,7 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
ctx_menu_.addAction(ui->actionZoomIn);
ctx_menu_.addAction(ui->actionZoomOut);
QAction * action = ctx_menu_.addAction(tr("Reset Diagram"), this, SLOT(resetView()));
action = ctx_menu_.addAction(tr("Reset Diagram"), this, SLOT(resetView()));
action->setToolTip(tr("Reset the diagram to its initial state."));
ctx_menu_.addSeparator();
ctx_menu_.addAction(ui->actionMoveRight10);
@ -145,6 +149,13 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
ctx_menu_.addAction(ui->actionGoToPacket);
ctx_menu_.addAction(ui->actionGoToNextPacket);
ctx_menu_.addAction(ui->actionGoToPreviousPacket);
ctx_menu_.addSeparator();
action = ui->actionSelectRtpStream;
ctx_menu_.addAction(action);
action->setEnabled(false);
action = ui->actionDeselectRtpStream;
ctx_menu_.addAction(action);
action->setEnabled(false);
set_action_shortcuts_visible_in_context_menu(ctx_menu_.actions());
ui->addressComboBox->setCurrentIndex(0);
@ -269,6 +280,12 @@ void SequenceDialog::keyPressEvent(QKeyEvent *event)
case Qt::Key_P:
on_actionGoToPreviousPacket_triggered();
break;
case Qt::Key_S:
on_actionSelectRtpStream_triggered();
break;
case Qt::Key_D:
on_actionDeselectRtpStream_triggered();
break;
}
QDialog::keyPressEvent(event);
@ -311,6 +328,19 @@ void SequenceDialog::diagramClicked(QMouseEvent *event)
case Qt::RightButton:
// XXX We should find some way to get sequenceDiagram to handle a
// contextMenuEvent instead.
current_rtp_sai_ = NULL;
if (event) {
seq_analysis_item_t *sai = seq_diagram_->itemForPosY(event->pos().y());
ui->actionSelectRtpStream->setEnabled(false);
ui->actionDeselectRtpStream->setEnabled(false);
if (sai) {
if (GA_INFO_TYPE_RTP == sai->info_type) {
ui->actionSelectRtpStream->setEnabled(true);
ui->actionDeselectRtpStream->setEnabled(true);
current_rtp_sai_ = sai;
}
}
}
ctx_menu_.exec(event->globalPos());
break;
default:
@ -320,11 +350,17 @@ void SequenceDialog::diagramClicked(QMouseEvent *event)
void SequenceDialog::mouseMoved(QMouseEvent *event)
{
current_rtp_sai_ = NULL;
packet_num_ = 0;
QString hint;
if (event) {
seq_analysis_item_t *sai = seq_diagram_->itemForPosY(event->pos().y());
if (sai) {
if (GA_INFO_TYPE_RTP == sai->info_type) {
ui->actionSelectRtpStream->setEnabled(true);
ui->actionDeselectRtpStream->setEnabled(true);
current_rtp_sai_ = sai;
}
packet_num_ = sai->frame_number;
QString raw_comment = html_escape(sai->comment);
hint = QString("Packet %1: %2").arg(packet_num_).arg(raw_comment);
@ -686,6 +722,24 @@ void SequenceDialog::on_actionZoomOut_triggered()
zoomXAxis(false);
}
void SequenceDialog::on_actionSelectRtpStream_triggered()
{
if (current_rtp_sai_ && GA_INFO_TYPE_RTP == current_rtp_sai_->info_type) {
emit openRtpStreamDialog();
emit selectRtpStream((rtpstream_id_t *)current_rtp_sai_->info_ptr);
raise();
}
}
void SequenceDialog::on_actionDeselectRtpStream_triggered()
{
if (current_rtp_sai_ && GA_INFO_TYPE_RTP == current_rtp_sai_->info_type) {
emit openRtpStreamDialog();
emit deselectRtpStream((rtpstream_id_t *)current_rtp_sai_->info_ptr);
raise();
}
}
void SequenceDialog::zoomXAxis(bool in)
{
QCustomPlot *sp = ui->sequencePlot;

View File

@ -21,6 +21,7 @@
#include <ui/qt/widgets/qcustomplot.h>
#include "wireshark_dialog.h"
#include "rtp_stream_dialog.h"
#include <QMenu>
@ -56,6 +57,11 @@ protected:
void resizeEvent(QResizeEvent *event);
void keyPressEvent(QKeyEvent *event);
signals:
void selectRtpStream(rtpstream_id_t *id);
void deselectRtpStream(rtpstream_id_t *id);
void openRtpStreamDialog();
private slots:
void updateWidgets();
void hScrollBarChanged(int value);
@ -86,6 +92,8 @@ private slots:
void on_actionMoveDown1_triggered();
void on_actionZoomIn_triggered();
void on_actionZoomOut_triggered();
void on_actionSelectRtpStream_triggered();
void on_actionDeselectRtpStream_triggered();
private:
Ui::SequenceDialog *ui;
@ -98,6 +106,8 @@ private:
QMenu ctx_menu_;
QCPItemText *key_text_;
QCPItemText *comment_text_;
seq_analysis_item_t *current_rtp_sai_; // Used for passing current sai to rtp processing
QPointer<RtpStreamDialog> rtp_stream_dialog_; // Singleton pattern used
void zoomXAxis(bool in);
void panAxes(int x_pixels, int y_pixels);

View File

@ -360,6 +360,28 @@
<string>P</string>
</property>
</action>
<action name="actionSelectRtpStream">
<property name="text">
<string>Select RTP Stream</string>
</property>
<property name="toolTip">
<string>Select RTP stream in RTP Streams dialog</string>
</property>
<property name="shortcut">
<string>S</string>
</property>
</action>
<action name="actionDeselectRtpStream">
<property name="text">
<string>Deselect RTP Stream</string>
</property>
<property name="toolTip">
<string>Deselect RTP stream in RTP Streams dialog</string>
</property>
<property name="shortcut">
<string>D</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@ -16,6 +16,7 @@
#include "epan/dissectors/packet-h225.h"
#include "ui/rtp_stream.h"
#include "ui/rtp_stream_id.h"
#include <ui/qt/utils/qt_ui_utils.h>
#include "rtp_player_dialog.h"
@ -416,6 +417,9 @@ void VoipCallsDialog::showSequence()
}
SequenceDialog *sequence_dialog = new SequenceDialog(parent_, cap_file_, sequence_info_);
connect(sequence_dialog, SIGNAL(selectRtpStream(rtpstream_id_t *)), this, SLOT(selectRtpStreamPassIn(rtpstream_id_t *)));
connect(sequence_dialog, SIGNAL(deselectRtpStream(rtpstream_id_t *)), this, SLOT(deselectRtpStreamPassIn(rtpstream_id_t *)));
connect(sequence_dialog, SIGNAL(openRtpStreamDialog()), this, SLOT(openRtpStreamDialogPassIn()));
sequence_dialog->setAttribute(Qt::WA_DeleteOnClose);
sequence_dialog->show();
}
@ -540,6 +544,22 @@ void VoipCallsDialog::switchTimeOfDay()
ui->callTreeView->resizeColumnToContents(VoipCallsInfoModel::StopTime);
}
void VoipCallsDialog::selectRtpStreamPassIn(rtpstream_id_t *id)
{
emit selectRtpStreamPassOut(id);
}
void VoipCallsDialog::deselectRtpStreamPassIn(rtpstream_id_t *id)
{
emit deselectRtpStreamPassOut(id);
}
void VoipCallsDialog::openRtpStreamDialogPassIn()
{
emit openRtpStreamDialogPassOut();
}
/*
* Editor modelines
*

View File

@ -20,6 +20,7 @@
#include <ui/qt/models/voip_calls_info_model.h>
#include <ui/qt/models/cache_proxy_model.h>
#include "ui/rtp_stream_id.h"
#include "wireshark_dialog.h"
#include <QMenu>
@ -44,6 +45,9 @@ signals:
void updateFilter(QString filter, bool force = false);
void captureFileChanged(capture_file *cf);
void goToPacket(int packet_num);
void selectRtpStreamPassOut(rtpstream_id_t *id);
void deselectRtpStreamPassOut(rtpstream_id_t *id);
void openRtpStreamDialogPassOut();
protected:
void contextMenuEvent(QContextMenuEvent *event);
@ -89,6 +93,9 @@ private slots:
void on_buttonBox_clicked(QAbstractButton *button);
void on_buttonBox_helpRequested();
void updateWidgets();
void selectRtpStreamPassIn(rtpstream_id_t *id);
void deselectRtpStreamPassIn(rtpstream_id_t *id);
void openRtpStreamDialogPassIn();
};
#endif // VOIP_CALLS_DIALOG_H

View File

@ -747,6 +747,9 @@ rtp_draw(void *tap_offset_ptr)
new_gai->comment = g_strdup_printf(comment_fmt,
(rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
duration/1000,(duration%1000), rtp_listinfo->id.ssrc);
new_gai->info_type=GA_INFO_TYPE_RTP;
new_gai->info_ptr=g_new(rtpstream_id_t, 1);
rtpstream_id_copy(&rtp_listinfo->id, (rtpstream_id_t *)new_gai->info_ptr);
new_gai->conv_num = conv_num;
set_fd_time(tapinfo->session, rtp_listinfo->start_fd, time_str);
new_gai->time_str = g_strdup(time_str);

View File

@ -138,6 +138,12 @@ typedef struct _skinny_calls_info {
guint32 callId;
} skinny_calls_info_t;
/** defines info types for graph analysis additional information */
typedef enum _ga_info_type {
GA_INFO_TYPE_NONE=0,
GA_INFO_TYPE_RTP
} ga_info_type;
/** defines a voip call */
typedef struct _voip_calls_info {
voip_call_state call_state;