wokhan / WFN

Windows Firewall Notifier extends the default Windows embedded firewall by allowing to handle and notify about outgoing connections, offers real time connections monitoring, connections map, bandwidth usage monitoring and more...
GNU General Public License v3.0
603 stars 95 forks source link

Unhandled negative bps case #161

Open UltimateEvil opened 1 year ago

UltimateEvil commented 1 year ago

Don't ask me how to reproduce this consistently as I ahve no clue, but the error is annoying never the less

        miniYAxis.Labeler = (value) => value == 0 ? "0Bps" : FormatBytes(Math.Pow(10, value), "Bps");

calls FormatBytes(Math.Pow(10, -10),"Bps") Don't ask me how, did not go into debugging that much. This throws an index out of bounds.

Band-aid which should probably be kept in place in some way.

    private static string FormatBytes(double size, string? suffix = null)
    {
        bool neg = size < 0;
        string minus = "";
        if (neg)
        {
            minus = "-";
            size = -size;
        }
        var num = Math.Min(units.Length - 1, (int)Math.Log(size, 1000));
        size = (int)(size / Math.Pow(1000, num) * 100) / 100;
        return $"{minus}{size:#0.##}{units[num]}{suffix}";
    }
wokhan commented 1 year ago

Getting a negative value could come from only one place: in Connection.cs (line 247), to compute the correct bandwidth, one has to subtract the last value from the previous retrieved value. And if the previous was 0... well, you guess what we get. I'll double-check the documentation as I might have wrongly implemented this.

To detect changes over time, you should save the counter values read by a previous call to GetPerTcpConnectionEStats, and subtract them from those read by a subsequent call. (source: https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-setpertcpconnectionestats#remarks)

Update: the code should prevent this, so I guess the negative value comes from the system counter itself?! InboundBandwidth = bandwidth.InboundBandwidth >= _lastInboundReadValue ? bandwidth.InboundBandwidth - _lastInboundReadValue : bandwidth.InboundBandwidth;