Qt: Restore ability to display RTT by sequence number
Adds a checkbox to the TCP Stream Dialog's "Round-trip-time" graph tab that allows user to choose sequence number on the x-axis rather than time. Bug: 13740 Change-Id: Iaf881318437c7eecd16cf6c1f8745283ce9b4a7d Reviewed-on: https://code.wireshark.org/review/23376 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
ded1d1089a
commit
f9207b0f6c
|
@ -598,6 +598,11 @@ void TCPStreamDialog::fillGraph(bool reset_axes, bool set_focus)
|
|||
|
||||
void TCPStreamDialog::showWidgetsForGraphType()
|
||||
{
|
||||
if (graph_.type == GRAPH_RTT) {
|
||||
ui->bySeqNumberCheckBox->setVisible(true);
|
||||
} else {
|
||||
ui->bySeqNumberCheckBox->setVisible(false);
|
||||
}
|
||||
if (graph_.type == GRAPH_THROUGHPUT) {
|
||||
#ifdef MA_1_SECOND
|
||||
ui->maWindowSizeLabel->setVisible(true);
|
||||
|
@ -1268,7 +1273,8 @@ void TCPStreamDialog::fillThroughput()
|
|||
// the range from "begin" to "end" are in sequence number order.
|
||||
// (this function would preserve that as an invariant). ]
|
||||
static struct rtt_unack *
|
||||
rtt_selectively_ack_range(QVector<double>& rel_times, QVector<double>& rtt,
|
||||
rtt_selectively_ack_range(QVector<double>& x_vals, bool bySeqNumber,
|
||||
QVector<double>& rtt,
|
||||
struct rtt_unack **list,
|
||||
struct rtt_unack *begin, struct rtt_unack *end,
|
||||
unsigned int left, unsigned int right, double rt_val) {
|
||||
|
@ -1293,7 +1299,11 @@ rtt_selectively_ack_range(QVector<double>& rel_times, QVector<double>& rtt,
|
|||
// (if so, we can delete it and move on)
|
||||
if (left_end_acked && right_end_acked) {
|
||||
// ACK the whole segment
|
||||
rel_times.append(cur->time);
|
||||
if (bySeqNumber) {
|
||||
x_vals.append(cur->seqno);
|
||||
} else {
|
||||
x_vals.append(cur->time);
|
||||
}
|
||||
rtt.append((rt_val - cur->time) * 1000.0);
|
||||
// in this case, we will delete current unack
|
||||
// [ update "begin" if necessary - we will return it to the
|
||||
|
@ -1307,7 +1317,11 @@ rtt_selectively_ack_range(QVector<double>& rel_times, QVector<double>& rtt,
|
|||
// (if so, we can just modify it and move on)
|
||||
if (left_end_acked) { // and right_end_not_acked
|
||||
// ACK the left end
|
||||
rel_times.append(cur->time);
|
||||
if (bySeqNumber) {
|
||||
x_vals.append(cur->seqno);
|
||||
} else {
|
||||
x_vals.append(cur->time);
|
||||
}
|
||||
rtt.append((rt_val - cur->time) * 1000.0);
|
||||
// in this case, "right" marks the start of remaining bytes
|
||||
cur->seqno = right;
|
||||
|
@ -1317,7 +1331,11 @@ rtt_selectively_ack_range(QVector<double>& rel_times, QVector<double>& rtt,
|
|||
// (if so, we can just modify it and move on)
|
||||
if (right_end_acked) { // and left_end_not_acked
|
||||
// ACK the right end
|
||||
rel_times.append(cur->time);
|
||||
if (bySeqNumber) {
|
||||
x_vals.append(left);
|
||||
} else {
|
||||
x_vals.append(cur->time);
|
||||
}
|
||||
rtt.append((rt_val - cur->time) * 1000.0);
|
||||
// in this case, "left" is just beyond the remaining bytes
|
||||
cur->end_seqno = left;
|
||||
|
@ -1329,7 +1347,11 @@ rtt_selectively_ack_range(QVector<double>& rel_times, QVector<double>& rtt,
|
|||
// Therefore, it must intersect the middle, so we must split the unack
|
||||
// into left and right unacked segments:
|
||||
// ACK the SACK block
|
||||
rel_times.append(cur->time);
|
||||
if (bySeqNumber) {
|
||||
x_vals.append(left);
|
||||
} else {
|
||||
x_vals.append(cur->time);
|
||||
}
|
||||
rtt.append((rt_val - cur->time) * 1000.0);
|
||||
// then split cur into two unacked segments
|
||||
// (linking the right-hand unack after the left)
|
||||
|
@ -1347,14 +1369,21 @@ void TCPStreamDialog::fillRoundTripTime()
|
|||
title_->setText(dlg_title);
|
||||
|
||||
QCustomPlot *sp = ui->streamPlot;
|
||||
bool bySeqNumber = ui->bySeqNumberCheckBox->isChecked();
|
||||
|
||||
if (bySeqNumber) {
|
||||
sequence_num_map_.clear();
|
||||
sp->xAxis->setLabel(sequence_number_label_);
|
||||
sp->xAxis->setNumberFormat("f");
|
||||
sp->xAxis->setNumberPrecision(0);
|
||||
}
|
||||
sp->yAxis->setLabel(round_trip_time_ms_label_);
|
||||
sp->yAxis->setNumberFormat("gb");
|
||||
sp->yAxis->setNumberPrecision(3);
|
||||
|
||||
base_graph_->setLineStyle(QCPGraph::lsLine);
|
||||
|
||||
QVector<double> rel_times, rtt;
|
||||
QVector<double> x_vals, rtt;
|
||||
guint32 seq_base = 0;
|
||||
struct rtt_unack *unack_list = NULL, *u = NULL;
|
||||
for (struct segment *seg = graph_.segments; seg != NULL; seg = seg->next) {
|
||||
|
@ -1368,6 +1397,7 @@ void TCPStreamDialog::fillRoundTripTime()
|
|||
guint32 seqno = seg->th_seq - seq_base;
|
||||
if (seg->th_seglen && !rtt_is_retrans(unack_list, seqno)) {
|
||||
double rt_val = seg->rel_secs + seg->rel_usecs / 1000000.0;
|
||||
rt_val -= ts_offset_;
|
||||
u = rtt_get_new_unack(rt_val, seqno, seg->th_seglen);
|
||||
if (!u) {
|
||||
// make sure to free list before returning!
|
||||
|
@ -1379,12 +1409,18 @@ void TCPStreamDialog::fillRoundTripTime()
|
|||
} else {
|
||||
guint32 ack_no = seg->th_ack - seq_base;
|
||||
double rt_val = seg->rel_secs + seg->rel_usecs / 1000000.0;
|
||||
rt_val -= ts_offset_;
|
||||
struct rtt_unack *v;
|
||||
|
||||
for (u = unack_list; u; u = v) {
|
||||
if (tcp_seq_after(ack_no, u->seqno)) {
|
||||
// full or partial ack of seg by ack_no
|
||||
rel_times.append(u->time);
|
||||
if (bySeqNumber) {
|
||||
x_vals.append(u->seqno);
|
||||
sequence_num_map_.insert(u->seqno, seg);
|
||||
} else {
|
||||
x_vals.append(u->time);
|
||||
}
|
||||
rtt.append((rt_val - u->time) * 1000.0);
|
||||
if (tcp_seq_eq_or_after(ack_no, u->end_seqno)) {
|
||||
// fully acked segment - nothing more to see here
|
||||
|
@ -1406,7 +1442,7 @@ void TCPStreamDialog::fillRoundTripTime()
|
|||
for (int i = 0; i < seg->num_sack_ranges; ++i) {
|
||||
guint32 left = seg->sack_left_edge[i] - seq_base;
|
||||
guint32 right = seg->sack_right_edge[i] - seq_base;
|
||||
u = rtt_selectively_ack_range(rel_times, rtt,
|
||||
u = rtt_selectively_ack_range(x_vals, bySeqNumber, rtt,
|
||||
&unack_list, u, v,
|
||||
left, right, rt_val);
|
||||
// if range is empty after selective ack, we can
|
||||
|
@ -1418,7 +1454,7 @@ void TCPStreamDialog::fillRoundTripTime()
|
|||
}
|
||||
// it's possible there's still unacked segs - so be sure to free list!
|
||||
rtt_destroy_unack_list(&unack_list);
|
||||
base_graph_->setData(rel_times, rtt);
|
||||
base_graph_->setData(x_vals, rtt);
|
||||
}
|
||||
|
||||
void TCPStreamDialog::fillWindowScale()
|
||||
|
@ -1643,9 +1679,13 @@ void TCPStreamDialog::mouseMoved(QMouseEvent *event)
|
|||
case GRAPH_TSEQ_TCPTRACE:
|
||||
case GRAPH_THROUGHPUT:
|
||||
case GRAPH_WSCALE:
|
||||
case GRAPH_RTT:
|
||||
packet_seg = time_stamp_map_.value(tr_key, NULL);
|
||||
break;
|
||||
case GRAPH_RTT:
|
||||
if (ui->bySeqNumberCheckBox->isChecked())
|
||||
packet_seg = sequence_num_map_.value(tr_key, NULL);
|
||||
else
|
||||
packet_seg = time_stamp_map_.value(tr_key, NULL);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1843,6 +1883,11 @@ void TCPStreamDialog::on_zoomRadioButton_toggled(bool checked)
|
|||
}
|
||||
}
|
||||
|
||||
void TCPStreamDialog::on_bySeqNumberCheckBox_stateChanged(int /* state */)
|
||||
{
|
||||
fillGraph(/*reset_axes=*/true, /*set_focus=*/false);
|
||||
}
|
||||
|
||||
void TCPStreamDialog::on_showSegLengthCheckBox_stateChanged(int state)
|
||||
{
|
||||
bool visible = (state != 0);
|
||||
|
|
|
@ -69,6 +69,7 @@ private:
|
|||
QMap<double, struct segment *> time_stamp_map_;
|
||||
double ts_offset_;
|
||||
bool ts_origin_conn_;
|
||||
QMap<double, struct segment *> sequence_num_map_;
|
||||
double seq_offset_;
|
||||
bool seq_origin_zero_;
|
||||
struct tcp_graph graph_;
|
||||
|
@ -150,6 +151,7 @@ private slots:
|
|||
void on_otherDirectionButton_clicked();
|
||||
void on_dragRadioButton_toggled(bool checked);
|
||||
void on_zoomRadioButton_toggled(bool checked);
|
||||
void on_bySeqNumberCheckBox_stateChanged(int state);
|
||||
void on_showSegLengthCheckBox_stateChanged(int state);
|
||||
void on_showThroughputCheckBox_stateChanged(int state);
|
||||
void on_showGoodputCheckBox_stateChanged(int state);
|
||||
|
|
|
@ -229,6 +229,19 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="bySeqNumberCheckBox">
|
||||
<property name="toolTip">
|
||||
<string>Display Round Trip Time vs Sequence Number</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RTT By Sequence Number</string>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::TabFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showSegLengthCheckBox">
|
||||
<property name="toolTip">
|
||||
|
|
Loading…
Reference in New Issue