BUG REPORT - MiniSAPserver
Posted: 03 Sep 2008 13:49
As some will be aware, there have recently been a number of SAP storms which appear to be due to a bug in Minisapserver. I've now managed to reproduce this and identify the problem.
This is a serious one - it does not affect minisapserver with the default config, but if you change your config to the values recommended in minisapserver's own documentation, you'll generate a SAP storm (thousands per second). See "How to kill my Cisco router... and those of my neighbours"
miniSAPserver version 0.3.4
on Ubuntu 7.10, gcc 4.1.3
The default config contains:
# Number of seconds between announces. 5 is default. Internet announces better use 30.
sap_delay=5
If you use this default, all is OK. If you add the "-s" flag to the
command, it prints a "." every time it sends out a sap. And as
expected, we get a "." appearing every 5 seconds.
However, if we make the suggested change and increase the value of
sap_delay to 30 (in fact to any value greater than 15!) we get our
SAP storm - thousands of SAPs (and thousands of dots on the screen)
appearing per second.
The problem appears to be an integer overflow in sapserver.cpp
unsigned n = config.Programs.size() ?: 1;
div_t d = div ((1000000000 / n) * config.GetDelay(), 1000000000);
struct timespec delay;
delay.tv_sec = d.quot;
delay.tv_nsec = d.rem;
(snip)
while(!should_exit)
{
for( unsigned int i = 0; i< announces.size() ; i ++ )
{
(snip - send the SAP here)
nanosleep( &delay, NULL );
}
}
So it appears that when config.GetDelay is >15, 1000000000*config.GetDelay
overflows, the arguments to nanosleep are negative.... it doesn't
sleep.... we get a storm.
A quick workaround is to remove the "div" line, and just have
delay.tv_sec = config.GetDelay();
delay.tv_nsec = 0;
I will leave development of a "proper" solution to someone else.
Bruce.
This is a serious one - it does not affect minisapserver with the default config, but if you change your config to the values recommended in minisapserver's own documentation, you'll generate a SAP storm (thousands per second). See "How to kill my Cisco router... and those of my neighbours"
miniSAPserver version 0.3.4
on Ubuntu 7.10, gcc 4.1.3
The default config contains:
# Number of seconds between announces. 5 is default. Internet announces better use 30.
sap_delay=5
If you use this default, all is OK. If you add the "-s" flag to the
command, it prints a "." every time it sends out a sap. And as
expected, we get a "." appearing every 5 seconds.
However, if we make the suggested change and increase the value of
sap_delay to 30 (in fact to any value greater than 15!) we get our
SAP storm - thousands of SAPs (and thousands of dots on the screen)
appearing per second.
The problem appears to be an integer overflow in sapserver.cpp
unsigned n = config.Programs.size() ?: 1;
div_t d = div ((1000000000 / n) * config.GetDelay(), 1000000000);
struct timespec delay;
delay.tv_sec = d.quot;
delay.tv_nsec = d.rem;
(snip)
while(!should_exit)
{
for( unsigned int i = 0; i< announces.size() ; i ++ )
{
(snip - send the SAP here)
nanosleep( &delay, NULL );
}
}
So it appears that when config.GetDelay is >15, 1000000000*config.GetDelay
overflows, the arguments to nanosleep are negative.... it doesn't
sleep.... we get a storm.
A quick workaround is to remove the "div" line, and just have
delay.tv_sec = config.GetDelay();
delay.tv_nsec = 0;
I will leave development of a "proper" solution to someone else.
Bruce.