vortex-5 / ddwrt-bwmon

An Individual Bandwidth Monitor For DD-WRT
171 stars 37 forks source link

Variable Overflow? #52

Closed SyntaxUnknown closed 7 years ago

SyntaxUnknown commented 7 years ago

Hey there!

I've been using this a while now and one of the machines on my network has recently fallen off the list (my son's machine who is a HEAVY user). I was looking at usage.js and it looks like he's used so much bandwidth that he's overflowed a variable. Here's the data:

[mac address],-2081241637,226664542,-2081241637,226664542,2017-04-27 19:00

Does that look like a possibility? Last time I saw his machine on the list, he was over 2 TB of usage.

vortex-5 commented 7 years ago

it is possible that you run into the maximum javascript limit I never did a test to see what the maximum bandwidth count could be. The idea is that most people would run bwmon/clean.sh to clear the stats back to zero so they would never encounter it.

vortex-5 commented 7 years ago

it's suspicious that the variable has gone negative there are libraries that are very slow that calculate the variables but keep them as strings but they are specialized mathematical libraries not something I'm familiar with using.

According to firefox the max safe integer is: Number.MAX_SAFE_INTEGER 9007199254740991

However keep in mind the line that you're looking at is actually generated by the bash script and I honestly don't know what the limits are there when you do a add / subtract.

vortex-5 commented 7 years ago

Ok so I'm looking into this a bit more it looks like people say the max int limits in sh shell are non portable meaning they won't stay the same from os to os so they may differ depending on the CPU that is doing the adding.

in general it looks like the value is can be given by a header value I don't have access to:

https://unix.stackexchange.com/questions/325206/bitwise-shift-and-the-largest-integer-in-bash

the last representable value seems to be: 4611686018427387904

after which you hit a wrap around.

See how this is a sh script addition limitation there's not a whole lot I can do around this unless the preferred solution is to clear the bandwidth stats once someone hits a maximum. Alternatively one an negative bandwidth value is encountered the UI can just display an error like (HIGH) but there's not many good work around for processing large integer additions in sh without high performance penalties I bet.

Maybe someone that knows a bit more from scientific computing could help out in this area.

J3n50m4t commented 7 years ago

I'm a heavy user as well but I reset every month. But I was over 20 TB with no problem but as my internet is pretty fast I will start a test.

vortex-5 commented 7 years ago

Hmm... not too sure then 20TB seems to be within my normal assumptions of the command line integer adds should be big enough.

Maybe in a few years 20TB a month would be the norm but right now I would consider one devices swallowing 20TB to be pretty high and reasonably high enough for me to consider that a pass for a big enough maximum.

J3n50m4t commented 7 years ago

the last representable value seems to be: 4611686018427387904

Because downloading that much would need ages (even with Gigabit), I adjusted the value in the usage file.

Rebooting the router gave me the correct gigabit number.

Now comes the weird one: As soon as I started my download again the machine disappeared like the one of @SyntaxUnknown, but came back with ne next refresh and cleaned download.

So I would guess overflowing this value will reset the data.

I still think it isn't the problem. Even if the son is using it heavily, it would need (if I'm right) nearly 501461 TB to reach the limitation

SyntaxUnknown commented 7 years ago

I'm thinking that the limit is probably different from router to router. For example, on my router, I get this result:

root@DD-WRT:~# echo $((1<<62)) 1073741824

root@DD-WRT:~# echo $(((1<<63)-1)) 2147483647

root@DD-WRT:~# echo $((1<<30)) 1073741824

root@DD-WRT:~# echo $(((1<<31)-1)) 2147483647

I'm guessing you'd probably get higher numbers on other routers.

Is there anyway to push the actual math off to the AngularJS side as opposed to doing it in the router? If not, maybe some way to reset the numbers from the UI would be handy as well.

J3n50m4t commented 7 years ago

On mine I get the same numbers:

root@J3n50m4t:~# echo $((1<<62))
1073741824
root@J3n50m4t:~# echo $(((1<<63)-1))
2147483647
root@J3n50m4t:~# echo $((1<<30))
1073741824
root@J3n50m4t:~# echo $(((1<<31)-1))
2147483647

Reset Button was discussed here #31

vortex-5 commented 7 years ago

There isn't a way to push the addition off to angular js the reason is the router has keep track of how much was downloaded the angular js script is not long lived the data is gone when you leave the page.

other solutions won't work without some loss of functionality for example if you reset very large values when you encounter them then you might have an effective activity meter but you won't be able to see an accurate breakdown of how much each device used.

a much more complicated solution might be to break down the integer into several blocks and add them separately respecting the carry but that's pretty complicated not sure there won't be a measurable performance impact doing it this way not to mention bugs.