Ports
All packet tx/rx is responsibility of the Port class. The default implementation uses libpcap APIs for packet tx/rx although other technologies can be used by deriving from the abstract class and implementing the same.
PcapPort Design/Implementation Notes
The base PcapPort
has multiple threads viz.
- PortMonitor - Rx
- PortMonitor - Tx
- PortTransmitter/PcapTxThread
- PortTransmitter/PcapTxStats
- PcapTxTtagStats
- PcapRxStats
- PortCapturer
- EmulationTransceiver
This class is designed as a lowest common denominator to work across all platforms without taking advantage of any platform specific features.
The platform specific subclasses override the behaviour where there is an advantage to be utilized
Details of each thread follows alongwith any platform specific notes
PortMonitor - Rx
Responsible for Rx stats - captures each packet only to count stats. Does not care nor look at packet content at all. Directly updates PcapPort::stats_
pointer to which is passed to it in the constructor.
In case directional capture (pcap_setdirection
) is not supported by libpcap on that platform (e.g. Windows) or that API fails for any reason and Drone doesn't have exclusive control of the port (FIXME: why does exclusive control matter here?), Port Notes are set to indicate that Rx Stats will include non Ostinato Tx packets but not Ostinato Tx.
This is because
- Non Ostinato Tx (using PCAP or otherwise) will be received by other PCAP handles
PortTransmitter
usesPortMonitor-Rx
handle for transmitting packets and anything transmitted on that handle will not be received back on the same handle
Linux/BSD/OSX use a separate StatsMonitor class for port stats hence stop this thread and do not use this class.
Windows has its own implementation of this class which uses the WinPCAP only STAT_MODE. Other than Windows, only non-Linux/BSD *nix platforms end up using this (do we have any *nix users?)
PortMonitor - Tx
Responsible for Tx stats - captures each packet only to count stats. Does not care nor look at packet content at all. Directly updates PcapPort::stats_
pointer to which is passed to it in the constructor.
In case directional capture (pcap_setdirection
) is not supported by libpcap on that platform (e.g. Windows) or that API fails for any reason, the transmitter is setup to update txPkts/txBytes of PcapPort::stats_
instead. However, the txPps/txBps are updated by the TxPortMonitor only. Additionally, if Drone doesn't have exclusive control of the port, Port Notes are set to indicate that Tx Stats will include only Ostinato Tx packets but not Tx by others (if we have exclusive control on the port, we are sure that no one else can transmit on that port so PortTx = OstinatoTx).
Linux/BSD/OSX use a separate StatsMonitor class for port stats hence stop this thread and do not use this class.
Windows has its own implementation of this class which uses the WinPCAP only STAT_MODE. Earlier comments about pcap_setdirection() not being supported on Windows and its consequences apply here.
PortTransmitter
Port Transmitter itself is not a thread but an object containing 2 threads - PcapTxThread
and PcapTxStats
PortTransmitter/PcapTxThread
Responsible for transmitting packets for user configured streams. AbstractPort
does the conversion of streams into packets and packet sequences - see Add a new Port Type for more about packet sequences (FIXME: Packet Sequences info should really go into AbstracPort
documentation).
By default, PcapTxThread
will update an internal copy of PortStats
. However, it can be setup to update an external copy of PortStats
if required - see PortMonitor - Tx for use case.
This class/thread also is responsible for tracking Tx Stream stats. Instead of doing this accounting for every packet, the code is optimized to do it after transmit is finished. This saves precious CPU cycles while transmitting, but has the downside that tx stream stats are not available while the transmit is still on - fetching tx stream stats in this state will return 0.
NOTE: The timing related code in this class has platform variants based on #ifdef (FIXME: this was done like this instead of in the platform specific subclass to avoid cost of virtual member functions?)
Timing Accuracy can be set to High (default) or Low. The sources used in each case is -
- High
- Windows - Busy Wait on
QueryPerformanceCounter()
- Linux - Busy Wait on
gettimeofday()
- Others -
QThread::usleep()
- Windows - Busy Wait on
- Low
- All platforms -
QThread::usleep()
- All platforms -
PortTransmitter/PcapTxStats
This thread continously fetches Tx stats from PcapTxThread
and updates the same in the port stats data structure.
PcapTxTtagStats
This thread starts a capture for Tx packets containing signature magic value and TTag TLV. The packets matching these are used to record Tx timing for Ttag packets.
PcapRxStats
This thread starts a capture for Rx packets that contain the signature magic value. For the captured packets, it updates the RX stream stats. If the packet contains the Ttag TLV as well, it records the RX timestamp also for latency/jitter calculation.
PortCapturer
TBD
EmulationTransciever
TBD
Platform specific notes
- Linux/BSD/MacOS do not use the PortMonitor classes. Instead they use a singleton class to fetch stats directly from the OS for all ports in a single stats thread