Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use WinDivertRecvEx #304

Merged
merged 2 commits into from
Sep 6, 2021
Merged

Use WinDivertRecvEx #304

merged 2 commits into from
Sep 6, 2021

Conversation

kayoub5
Copy link
Collaborator

@kayoub5 kayoub5 commented Sep 2, 2021

Pending reply on basil00/Divert#282 to finish implementation

Partially resolves #273

@kayoub5 kayoub5 changed the title WIP: Use WinDivertRecvEx Use WinDivertRecvEx Sep 4, 2021
@kayoub5
Copy link
Collaborator Author

kayoub5 commented Sep 4, 2021

@trudyhood I believe you have an application/setup to test WinDivert performance since you reported #273, could you check this PR?
I had to add a call to WinDivertHelperParsePacket so I am not 100% confident on the performance improvement

@codecov-commenter
Copy link

codecov-commenter commented Sep 4, 2021

Codecov Report

Merging #304 (cec885e) into master (166872c) will increase coverage by 0.26%.
The diff coverage is 90.90%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #304      +/-   ##
==========================================
+ Coverage   79.86%   80.12%   +0.26%     
==========================================
  Files          35       35              
  Lines        2155     2194      +39     
  Branches      241      244       +3     
==========================================
+ Hits         1721     1758      +37     
- Misses        339      340       +1     
- Partials       95       96       +1     
Flag Coverage Δ
linux 0.00% <0.00%> (ø)
macos 63.85% <0.00%> (-1.16%) ⬇️
windows_2016_vs2017_npcap 71.78% <90.90%> (+0.46%) ⬆️
windows_2019_vs2019_npcap 71.74% <90.90%> (+0.41%) ⬆️
windows_2019_vs2019_winpcap 69.69% <90.90%> (+1.19%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
SharpPcap/WinDivert/WinDivertDevice.cs 74.60% <90.90%> (+3.64%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 166872c...cec885e. Read the comment docs.

@trudyhood
Copy link

@kayoub5
Thank you for the improvement you have done but unfortunately the result is disappointing,
The new SharpPcap speed, is still close to "passthru.exe true 1 1", it looks there is no noticeable improvement, as you see "passthru.exe true 1 10" cab boost its own performance more than 2X.
here is the results:

No Filter

   Speedtest by Ookla

     Server: NETGEAR Inc. - San Jose, CA (id = 43447)
        ISP: Amazon.com
    Latency:     0.25 ms   (0.03 ms jitter)
   Download:   963.65 Mbps (data used: 449.4 MB)
     Upload:   608.07 Mbps (data used: 717.7 MB)
Packet Loss: Not available.
 Result URL: https://www.speedtest.net/result/c/779c63f1-1830-482a-a35a-3dafe55fe27b

Old SharpPcap

   Speedtest by Ookla

     Server: NETGEAR Inc. - San Jose, CA (id = 43447)
        ISP: Amazon.com
    Latency:     0.37 ms   (0.02 ms jitter)
   Download:   140.88 Mbps (data used: 257.7 MB)
     Upload:   163.18 Mbps (data used: 279.5 MB)
Packet Loss: Not available.
 Result URL: https://www.speedtest.net/result/c/0d5117ad-cda1-496d-ad2f-8a4598ffa634

New SharpPcap with batch

   Speedtest by Ookla

     Server: NETGEAR Inc. - San Jose, CA (id = 43447)
        ISP: Amazon.com
    Latency:     0.53 ms   (0.02 ms jitter)
   Download:   160.86 Mbps (data used: 277.0 MB)
     Upload:   158.79 Mbps (data used: 213.9 MB)
https://www.speedtest.net/result/c/cbf5253e-6b61-4981-9d6b-de0959379f99

Original WinDivert Batch 1 : passthru.exe true 1 1

     Speedtest by Ookla

     Server: NETGEAR Inc. - San Jose, CA (id = 43447)
        ISP: Amazon.com
    Latency:     0.38 ms   (0.03 ms jitter)
   Download:   217.66 Mbps (data used: 340.4 MB)
     Upload:   203.27 Mbps (data used: 272.8 MB)
Packet Loss: Not available.
 Result URL: https://www.speedtest.net/result/c/6e8c7dfd-6778-4235-8ebe-45a6cf39a0df

Original WinDivert Batch 10 : passthru.exe true 1 10

Speedtest by Ookla

     Server: NETGEAR Inc. - San Jose, CA (id = 43447)
        ISP: Amazon.com
    Latency:     0.32 ms   (0.03 ms jitter)
   Download:   490.18 Mbps (data used: 866.2 MB)
     Upload:   335.49 Mbps (data used: 580.5 MB)
Packet Loss: Not available.
 Result URL: https://www.speedtest.net/result/c/d3176b31-b8bb-4c58-90fb-17bfe5fd3c35

I used the following code:

using PacketDotNet;
using SharpPcap.WinDivert;
using System;
using System.Threading;

namespace SimpleFilter
{
    class Program
    {
        static readonly WinDivertDevice WinDivert = new();
        private static long _length;
        private static long _lastLength;

        static void Main()
        {

            WinDivert.Layer = WinDivertLayer.Network;
            WinDivert.Filter = "ip";
            WinDivert.Flags = 0;
            WinDivert.Open(new SharpPcap.DeviceConfiguration());
            WinDivert.OnPacketArrival += WinDivert_OnPacketArrival;

            Console.WriteLine("Working...");
            WinDivert.StartCapture();
            Thread.Sleep(-1);
        }

        private static void WinDivert_OnPacketArrival(object sender, SharpPcap.PacketCapture e)
        {
            var rawPacket = e.GetPacket();
            var packet = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data);
            var lastCaptureHeader = (WinDivertHeader)e.Header;
            var ipPacket = packet.Extract<IPv4Packet>();

            WinDivert.SendPacket(ipPacket.Bytes, lastCaptureHeader);

            _length += packet.TotalPacketLength;
            if (_length > _lastLength + 1000000)
            {
                _lastLength = _length;
                Console.WriteLine(_lastLength);
            }
        }
    }
}

@kayoub5
Copy link
Collaborator Author

kayoub5 commented Sep 4, 2021

@trudyhood I only implemented WinDivertRecvEx, sending is still being done packet per packet
that could be the bottleneck in your case

@trudyhood
Copy link

@kayoub5
I am not sure the issue is rooted in .NET overhead, but as we see, SharpPcap performance is close to "passthru.exe true 1 1."
I looked at your code; you capture packets in batch, but to be compatible with SharpPacp, you needed to send them one by one, so eventually, we couldn't pass the packets in batch using WinDivertSendEx. As I used tcp connection for speed so decreasing send speed lead to decrease in receive speed too.

I wish SharpPcap.PacketCapture contains an array of packets instead of a single packet but I think it would be big change!
Can you test and create a .NET passthru using WinDivertRecvEx, WinDivertSendEx. so we can check the feasibility!

@trudyhood
Copy link

@trudyhood I only implemented WinDivertRecvEx, sending is still being done packet per packet
that could be the bottleneck in your case

Ya, I saw your message after sending my own.

@kayoub5
Copy link
Collaborator Author

kayoub5 commented Sep 4, 2021

@trudyhood could you profile your application and upload the results, my ISP is not fast enough to test 200Mbps 😞
The report would help identify the bottleneck, so we don't have to speculate

See https://docs.microsoft.com/en-us/visualstudio/profiling/cpu-usage?view=vs-2019

Instrumentation, CPU usage and .NET Object Allocation Tracking are the interesting reports in this case

@trudyhood
Copy link

@trudyhood could you profile your application and upload the results, my ISP is not fast enough to test 200Mbps 😞
The report would help identify the bottleneck, so we don't have to speculate

See https://docs.microsoft.com/en-us/visualstudio/profiling/cpu-usage?view=vs-2019

Instrumentation, CPU usage and .NET Object Allocation Tracking are the interesting reports in this case

@kayoub5 My ISP is not that fast; I compiled it on my machine and ran it on an Amazon EC2 server with 1Gbit speed. Unfortunately, it just has 1GB of memory which is not enough to install visual studio.

@kayoub5
Copy link
Collaborator Author

kayoub5 commented Sep 4, 2021

Just checked with profiler with 40Mbps traffic, most of the CPU time goes to either WinDivertRecvEx or WinDivertSend, WinDivertHelperParsePacket is fast and consume almost no CPU time.

So the good news is that this PR introduce no regression performance, and should allow faster reception of packets.

The not so good news is that we need some kind of API for WinDivertSendEx

Copy link
Collaborator

@chmorgan chmorgan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This improves performance when capturing using windivert? I saw the messages on the ticket but didn't read them in depth to confirm this was the case.

@kayoub5
Copy link
Collaborator Author

kayoub5 commented Sep 6, 2021

This improves performance when capturing using windivert? I saw the messages on the ticket but didn't read them in depth to confirm this was the case.

Yes.

@trudyhood
Copy link

This improves performance when capturing using windivert? I saw the messages on the ticket but didn't read them in depth to confirm this was the case.

I believe it is much more to be done, the improvement is not noticeable yet.

@kayoub5 kayoub5 merged commit 57045a7 into master Sep 6, 2021
@kayoub5 kayoub5 deleted the feature/windivert_recv_ex branch September 6, 2021 06:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improving WinDivert perfomance by using BatchMode offered in WinDivertRecvEx
4 participants