diff --git a/server/pcapport.cpp b/server/pcapport.cpp index 9729960..2768952 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -161,6 +161,14 @@ bool PcapPort::startStreamStatsTracking() goto _tx_fail; if (!rxStatsPoller_->start()) goto _rx_fail; + /* + * If RxPoller receives both IN and OUT packets, packets Tx on this + * port will also be received by it and we consider it to be a Rx (IN) + * packet incorrectly - so adjust Rx stats for this case + * XXX - ideally, RxPoller should do this adjustment, but given our + * design, it is easier to implement in transmitter + */ + transmitter_->adjustRxStreamStats(!rxStatsPoller_->isDirectional()); return true; _rx_fail: diff --git a/server/pcaprxstats.cpp b/server/pcaprxstats.cpp index 6a31d5d..0ba56f2 100644 --- a/server/pcaprxstats.cpp +++ b/server/pcaprxstats.cpp @@ -30,6 +30,7 @@ PcapRxStats::PcapRxStats(const char *device, StreamStats &portStreamStats) device_ = QString::fromAscii(device); stop_ = false; state_ = kNotStarted; + isDirectional_ = true; handle_ = NULL; } @@ -70,10 +71,13 @@ void PcapRxStats::run() // NOTE: WinPcap 4.1.1 and above exports a dummy API that returns -1 // but since we would like to work with previous versions of WinPcap // also, we assume the API does not exist + isDirectional_ = false; #else - if (pcap_setdirection(handle_, PCAP_D_IN) < 0) + if (pcap_setdirection(handle_, PCAP_D_IN) < 0) { qDebug("RxStats: Error setting IN direction %s: %s\n", qPrintable(device_), pcap_geterr(handle_)); + isDirectional_ = false; + } #endif if (pcap_compile(handle_, &bpf, qPrintable(capture_filter), @@ -165,3 +169,8 @@ bool PcapRxStats::isRunning() { return (state_ == kRunning); } + +bool PcapRxStats::isDirectional() +{ + return isDirectional_; +} diff --git a/server/pcaprxstats.h b/server/pcaprxstats.h index f13e516..9d006f9 100644 --- a/server/pcaprxstats.h +++ b/server/pcaprxstats.h @@ -34,6 +34,7 @@ public: bool start(); bool stop(); bool isRunning(); + bool isDirectional(); private: enum State { @@ -47,6 +48,7 @@ private: volatile bool stop_; pcap_t *handle_; volatile State state_; + bool isDirectional_; }; #endif diff --git a/server/pcaptransmitter.cpp b/server/pcaptransmitter.cpp index e6a2c89..e0caef1 100644 --- a/server/pcaptransmitter.cpp +++ b/server/pcaptransmitter.cpp @@ -24,6 +24,7 @@ PcapTransmitter::PcapTransmitter( StreamStats &portStreamStats) : streamStats_(portStreamStats), txThread_(device) { + adjustRxStreamStats_ = false; memset(&stats_, 0, sizeof(stats_)); txStats_.setTxThreadStats(&stats_); txStats_.start(); // TODO: alongwith user transmit start @@ -43,6 +44,11 @@ bool PcapTransmitter::setRateAccuracy( return txThread_.setRateAccuracy(accuracy); } +void PcapTransmitter::adjustRxStreamStats(bool enable) +{ + adjustRxStreamStats_ = enable; +} + bool PcapTransmitter::setStreamStatsTracking(bool enable) { return txThread_.setStreamStatsTracking(enable); @@ -115,6 +121,10 @@ void PcapTransmitter::updateTxThreadStreamStats() streamStats_[guid].tx_pkts += sst.tx_pkts; streamStats_[guid].tx_bytes += sst.tx_bytes; + if (adjustRxStreamStats_) { + streamStats_[guid].rx_pkts -= sst.tx_pkts; + streamStats_[guid].rx_bytes -= sst.tx_bytes; + } } txThread->clearStreamStats(); } diff --git a/server/pcaptransmitter.h b/server/pcaptransmitter.h index a232194..77b9909 100644 --- a/server/pcaptransmitter.h +++ b/server/pcaptransmitter.h @@ -34,6 +34,7 @@ public: bool setRateAccuracy(AbstractPort::Accuracy accuracy); bool setStreamStatsTracking(bool enable); + void adjustRxStreamStats(bool enable); void clearPacketList(); void loopNextPacketSet(qint64 size, qint64 repeats, @@ -55,6 +56,7 @@ private: PcapTxThread txThread_; PcapTxStats txStats_; StatsTuple stats_; + bool adjustRxStreamStats_; }; #endif diff --git a/test/streamstatstest.py b/test/streamstatstest.py index defd3c3..bbd31ff 100644 --- a/test/streamstatstest.py +++ b/test/streamstatstest.py @@ -592,10 +592,8 @@ def test_unidir(drone, ports, dut, dut_ports, dut_ip, emul_ports, dgid_list, # for unidir verify rx on tx port is 0 and vice versa # FIXME: failing currently because tx pkts on tx port seem to be # captured by rxStatsPoller_ on tx port - """ assert ssd.port[ports.x_num].sguid[guid].rx_pkts == 0 assert ssd.port[ports.x_num].sguid[guid].rx_bytes == 0 - """ assert ssd.port[ports.y_num].sguid[guid].tx_pkts == 0 assert ssd.port[ports.y_num].sguid[guid].tx_bytes == 0