Make win32 specific changes for per-stream latency
There are 2 changes - 1. Encode txPort in ttag packets and use it at TxTtagStats and RxPcapStats to identify Tx and Rx packets respectively 2. Don't use pcap_sendqueue_transmit() if stream timing is in use - since we can't modify TTAG packets inside that API
This commit is contained in:
parent
e138fa0d3d
commit
bafdd948f8
@ -19,6 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
#include "sign.h"
|
||||
|
||||
#include "../common/streambase.h"
|
||||
|
||||
SignProtocol::SignProtocol(StreamBase *stream, AbstractProtocol *parent)
|
||||
: AbstractProtocol(stream, parent)
|
||||
{
|
||||
@ -76,6 +78,7 @@ AbstractProtocol::FieldFlags SignProtocol::fieldFlags(int index) const
|
||||
switch (index)
|
||||
{
|
||||
case sign_magic:
|
||||
case sign_tlv_tx_port:
|
||||
case sign_tlv_guid:
|
||||
case sign_tlv_ttag:
|
||||
case sign_tlv_end:
|
||||
@ -140,6 +143,29 @@ QVariant SignProtocol::fieldData(int index, FieldAttrib attrib,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case sign_tlv_tx_port:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldName:
|
||||
return QString("TxPort");
|
||||
case FieldValue:
|
||||
return mpStream->portId();
|
||||
case FieldTextValue:
|
||||
return QString("%1").arg(mpStream->portId());
|
||||
case FieldFrameValue:
|
||||
{
|
||||
QByteArray fv;
|
||||
fv.resize(2);
|
||||
fv[0] = mpStream->portId() & 0xFF;
|
||||
fv[1] = kTypeLenTxPort;
|
||||
return fv;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case sign_tlv_guid:
|
||||
{
|
||||
quint32 guid = data.stream_guid() & 0xFFFFFF;
|
||||
@ -258,6 +284,8 @@ bool SignProtocol::packetTtagId(const uchar *pkt, int pktLen, uint *ttagId, uint
|
||||
ret = true;
|
||||
} else if (*p == kTypeLenGuid) {
|
||||
*guid = qFromBigEndian<quint32>(p - 3) >> 8;
|
||||
} else if (*p == kTypeLenTxPort) {
|
||||
*ttagId |= uint(*(p - 1)) << 8;
|
||||
}
|
||||
p -= 1 + (*p >> 5); // move to next TLV
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ TLVs are encoded as
|
||||
Type = 1, Len = 3 (0x61): Stream GUID
|
||||
Type = 2, Len = 1 (0x22): T-Tag Placeholder (0 value)
|
||||
Type = 3, Len = 1 (0x23): T-Tag with actual value
|
||||
Type = 4, Len = 1 (0x24): Tx Port Id
|
||||
*/
|
||||
|
||||
class SignProtocol : public AbstractProtocol
|
||||
@ -55,6 +56,7 @@ public:
|
||||
{
|
||||
// Frame Fields
|
||||
sign_tlv_end = 0,
|
||||
sign_tlv_tx_port,
|
||||
sign_tlv_guid,
|
||||
sign_tlv_ttag,
|
||||
sign_magic,
|
||||
@ -100,6 +102,7 @@ private:
|
||||
static const quint32 kSignMagic = 0x1d10c0da; // coda! (unicode - 0x1d10c)
|
||||
static const quint8 kTypeLenEnd = 0x00;
|
||||
static const quint8 kTypeLenGuid = 0x61;
|
||||
static const quint8 kTypeLenTxPort = 0x24;
|
||||
OstProto::Sign data;
|
||||
};
|
||||
|
||||
|
@ -75,9 +75,8 @@ public:
|
||||
quint32 id() const;
|
||||
bool setId(quint32 id);
|
||||
|
||||
quint32 portId() { return portId_;}
|
||||
#if 0 // FIXME(HI): needed?
|
||||
quint32 portId()
|
||||
{ return mCore->port_id();}
|
||||
bool setPortId(quint32 id)
|
||||
{ mCore->set_port_id(id); return true;}
|
||||
#endif
|
||||
|
@ -123,11 +123,27 @@ _skip_filter:
|
||||
switch (ret) {
|
||||
case 1: {
|
||||
uint ttagId, guid;
|
||||
#ifdef Q_OS_WIN32
|
||||
// Npcap (Windows) doesn't support direction, so packets
|
||||
// Tx by PcapTxThread are received back by us here - use
|
||||
// TxPort to filter out. TxPort is returned as byte 1 of
|
||||
// ttagId (byte 0 is ttagId).
|
||||
// If TxPort is us ==> Tx Packet, so skip
|
||||
// FIXME: remove once npcap supports pcap direction
|
||||
if (SignProtocol::packetTtagId(data, hdr->caplen, &ttagId, &guid)
|
||||
&& (ttagId >> 8 != uint(portId_))) {
|
||||
ttagId &= 0xFF;
|
||||
timing_->recordRxTime(portId_, guid, ttagId, hdr->ts);
|
||||
timingDebug("[%d RX] %ld:%ld ttag %u guid %u", portId_,
|
||||
hdr->ts.tv_sec, long(hdr->ts.tv_usec), ttagId, guid);
|
||||
}
|
||||
#else
|
||||
if (SignProtocol::packetTtagId(data, hdr->caplen, &ttagId, &guid)) {
|
||||
timing_->recordRxTime(portId_, guid, ttagId, hdr->ts);
|
||||
timingDebug("[%d RX] %ld:%ld ttag %u guid %u", portId_,
|
||||
hdr->ts.tv_sec, long(hdr->ts.tv_usec), ttagId, guid);
|
||||
}
|
||||
#endif
|
||||
if (guid != SignProtocol::kInvalidGuid) {
|
||||
streamStats_[guid].rx_pkts++;
|
||||
streamStats_[guid].rx_bytes += hdr->caplen;
|
||||
|
@ -329,7 +329,9 @@ _restart:
|
||||
#ifdef Q_OS_WIN32
|
||||
TimeStamp ovrStart, ovrEnd;
|
||||
|
||||
if (seq->usecDuration_ <= long(1e6)) { // 1s
|
||||
// Use Windows-only pcap_sendqueue_transmit() if duration < 1s
|
||||
// and no stream timing is configured
|
||||
if (seq->usecDuration_ <= long(1e6) && firstTtagPkt_ < 0) {
|
||||
getTimeStamp(&ovrStart);
|
||||
ret = pcap_sendqueue_transmit(handle_,
|
||||
seq->sendQueue_, kSyncTransmit);
|
||||
|
@ -107,6 +107,13 @@ _skip_filter:
|
||||
uint guid;
|
||||
if (SignProtocol::packetTtagId(data, hdr->caplen,
|
||||
&ttagId, &guid)) {
|
||||
#ifdef Q_OS_WIN32
|
||||
// TxPort is NOT us ==> Rx Packet, so skip
|
||||
// See similar check in PcapRxStats for details
|
||||
if (ttagId >> 8 != uint(portId_))
|
||||
break;
|
||||
ttagId &= 0xFF;
|
||||
#endif
|
||||
timing_->recordTxTime(portId_, guid, ttagId, hdr->ts);
|
||||
timingDebug("[%d TX] %ld:%ld ttag %u guid %u", portId_,
|
||||
hdr->ts.tv_sec, long(hdr->ts.tv_usec), ttagId, guid);
|
||||
|
Loading…
Reference in New Issue
Block a user