ostinato/server/pcaptxthread.h
Srivats P c70811eaa4 Fix spurious stream stats drops
The problem happens for bidirectional flows. The sequence of events is
as follows when you start Tx on Ports p1, p2 with the current code -

1. Clear stream stats on p1
2. Start tx on p1
3. Clear stream stats on p2
4. Start tx on p2

By the time #3 is executed, it may have already rx packets from p1 which
are being incorrectly cleared, this will cause these number of packets
to show up as dropped instead - incorrectly.

The fix is to change the order like this -

1. Clear stream stats on p1
2. Clear stream stats on p2
3. Start tx on p1
4. Start tx on p2

Unidirectional flows will not see this problem - as long as startTx is
done only on the Tx port and not the Rx port.

This bug is a regression caused due to the code changes introduced for the
stream stats rates feature implemented in 1.2.0
2023-02-08 16:34:03 +05:30

102 lines
2.6 KiB
C++

/*
Copyright (C) 2010-2016 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef _PCAP_TX_THREAD_H
#define _PCAP_TX_THREAD_H
#include "abstractport.h"
#include "packetsequence.h"
#include "statstuple.h"
#include <QThread>
#include <pcap.h>
class PcapTxThread: public QThread
{
public:
PcapTxThread(const char *device);
~PcapTxThread();
bool setRateAccuracy(AbstractPort::Accuracy accuracy);
bool setStreamStatsTracking(bool enable);
void clearPacketList();
void loopNextPacketSet(qint64 size, qint64 repeats,
long repeatDelaySec, long repeatDelayNsec);
bool appendToPacketList(long sec, long usec, const uchar *packet,
int length);
void setPacketListLoopMode(bool loop, quint64 secDelay, quint64 nsecDelay);
void setHandle(pcap_t *handle);
void setStats(StatsTuple *stats);
const StreamStats& streamStats();
void clearStreamStats();
void run();
void start();
void stop();
bool isRunning();
double lastTxDuration();
private:
enum State
{
kNotStarted,
kRunning,
kFinished
};
static void udelay(unsigned long usec);
int sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, long &overHead,
int sync);
void updateTxStreamStats();
// Intermediate state variables used while building the packet list
PacketSequence *currentPacketSequence_;
int repeatSequenceStart_;
quint64 repeatSize_;
quint64 packetCount_;
QList<PacketSequence*> packetSequenceList_;
quint64 packetListSize_; // count of pkts in packet List including repeats
int returnToQIdx_;
quint64 loopDelay_;
void (*udelayFn_)(unsigned long);
bool usingInternalHandle_;
pcap_t *handle_;
volatile bool stop_;
volatile State state_;
bool trackStreamStats_;
StatsTuple *stats_;
StatsTuple lastStats_;
StreamStats streamStats_;
double lastTxDuration_{0.0}; // in secs
};
#endif