Looking at the code, and then after a bit of a play and analysis with ANTS profilers found that PCapDevice could do with a couple of changes. The attribute LinkType gets called on every packet, which then calls ThrowIfNotOpen which then calls Opened() which does the compare PcapHandle != IntPtr.Zero, which will always be the same providing PcapHandle is not modified. So why not set a private bool m_device_open when PCapHandle is set which will return when Opened() gets called. You can then apply the same logic for linkType.
So the code for PcapHandle will look like this.
public virtual bool Opened
{
get { return m_device_open; } // (PcapHandle != IntPtr.Zero); }
}
/// <summary>
/// The underlying pcap device handle
/// </summary>
internal virtual IntPtr PcapHandle
{
get { return m_pcapAdapterHandle; }
set { m_pcapAdapterHandle = value;
m_device_open = (m_pcapAdapterHandle!= IntPtr.Zero);
if (m_device_open == true)
{
m_LinkType = (PacketDotNet.LinkLayers)LibPcapSafeNativeMethods.pcap_datalink(m_pcapAdapterHandle);
}
else
{
m_LinkType = PacketDotNet.LinkLayers.Null;
}
}
}
///
These small changes showed a worthwhile performace improvment loking at the percentage stats in ANT profiles.
This is a small change, but it may be also worth considering in PacketNet not to copy all the payload byes all the time. Why not pass the input packet through the system, allowing the offset to be modified by each protocol parser. You will need to carry out length checks more often, but you do not need to keep creating ByteArraySegments at every processing level. This should provide good performace improvements in terms of system through put, and better memory footprints, you should then get 100Mb, I currently am seeing about 80Mb currently It would mean you would have to modify the order of things so that you extract the header meta data before you pas the packet on to the next protocol.
Anonymous
Hello.
Can we converse via email? chmorgan@gmail.com is my email address.
To respond to your first comment I'm not entirely sure what you are suggesting. When would we set the cached open flag? When the device was opened?
With regards to your second comment, most of the parsers avoid parsing any data until the values are requested. The previous version of SharpPcap used to pass around the byte array and offset but this was prone to errors. In addition this approach made it difficult to alter portions of the packet as the parent packets were using and relying on the same byte array. You might want to look at the older versions of SharpPcap. I'd also be interested in how the single array with offset would work in terms of enabling packets to be modified?
Sent you some mail. Interested in testing after the improvements thus far? I'm seeing a 2% improvement but that's likely well within the measurement error although it seems faster than before, eg. no results from the new performance benchmark are lower than the ones with the old benchmark so it is likely there is some improvement.
Still not sure how to improve the ByteArraySegment issue. I'd like to not have to create those instances but is there any other way? We can't really use offsets, you can look in the architecture document in packet.net or look at older versions of sharppcap to see how the old implementation worked. It was unsustainable and doesn't work if you want to replace parts of a packet or say insert options at one datagram level that would shift the byte array for the rest of the nested datagrams.
Chris