Bug 1982

Summary: AODV and mesh use random variables before seed can be set
Product: ns-3 Reporter: Tom Henderson <tomh>
Component: aodvAssignee: Tom Henderson <tomh>
Status: RESOLVED FIXED    
Severity: normal CC: ns-bugs, tomh
Priority: P5    
Version: pre-release   
Hardware: PC   
OS: Linux   
Attachments: aodv patch to fix
mesh patch to fix
probe test patch
tcp test patch
AODV test for bug772 not setting all streams

Description Tom Henderson 2014-09-11 13:22:02 UTC
When AODV is installed by InternetStackHelper, SetIpv4() is eventually called as part of the Install() process.  It contains:

void
RoutingProtocol::SetIpv4 (Ptr<Ipv4> ipv4)
{
  NS_ASSERT (ipv4 != 0);
  NS_ASSERT (m_ipv4 == 0);

  if (EnableHello)
    {
      m_htimer.SetFunction (&RoutingProtocol::HelloTimerExpire, this);
      m_htimer.Schedule (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 100)));
    }

Later, the users (such as the AODV regression test suite) tries to assign fixed streams.  However, the value has been used already.

There doesn't seem to be another opportunity (in the present implementation) to defer this start until after simulation construction time (which would give us opportunity to fix the seed before usage).

This issue can be deferred until after ns-3.21 and is part of object start/stop discussion which will be discussed after 3.21.
Comment 1 Tom Henderson 2014-10-10 14:43:58 UTC
A similar problem exists in the mesh module.

HwmpProactiveRegressionTest::CreateDevices ()

has this code:

  // 2. setup mesh
  MeshHelper mesh = MeshHelper::Default ();
  mesh.SetStackInstaller ("ns3::Dot11sStack", "Root", Mac48AddressValue (Mac48Address ("00:00:00:00:00:0d")));
  mesh.SetMacType ("RandomStart", TimeValue (Seconds (0.1)));
  mesh.SetNumberOfInterfaces (1);
  NetDeviceContainer meshDevices = mesh.Install (wifiPhy, *m_nodes);
 // Five devices, 9 streams per device 
  streamsUsed += mesh.AssignStreams (meshDevices, streamsUsed);

The mesh installer in this case is the Dot11s stack, which has this code in the Dot11sStack::InstallStack (Ptr<MeshPointDevice> mp): 

  if (mp->GetAddress () == m_root)
    {
      hwmp->SetRoot ();
    }

This method uses a random variable before the call to AssignStreams can be made.

//Proactive PREQ routines:
void
HwmpProtocol::SetRoot ()
{
  Time randomStart = Seconds (m_coefficient->GetValue ());
  m_proactivePreqTimer = Simulator::Schedule (randomStart, &HwmpProtocol::SendProactivePreq, this);
  NS_LOG_DEBUG ("ROOT IS: " << m_address);
  m_isRoot = true;
}

Starting this timer probably could be deferred to DoInitialize().

Until this is fixed, perturbations in the static random variables in use throughout the simulator will cause the devices-mesh-dot11s-regression test to fail.
Comment 2 Tom Henderson 2015-03-26 13:56:45 UTC
Created attachment 2002 [details]
aodv patch to fix

Defers usage of AODV random variables until after SetStream()
Comment 3 Tom Henderson 2015-03-26 13:57:29 UTC
Created attachment 2003 [details]
mesh patch to fix

defers mesh random variable usage until after SetStream ()
Comment 4 Tom Henderson 2015-03-26 13:58:16 UTC
Created attachment 2004 [details]
probe test patch

defers usage of random variables for probe test suite until run time
Comment 5 Tom Henderson 2015-03-26 13:58:52 UTC
Created attachment 2005 [details]
tcp test patch

defers usage of random variables in TCP test suite until run time
Comment 6 Tom Henderson 2015-03-26 13:59:31 UTC
Created attachment 2006 [details]
AODV test for bug772 not setting all streams

minor fix to an AODV test
Comment 7 Tom Henderson 2015-03-26 14:00:55 UTC
I've posted 5 patches that I intend to commit shortly to resolve this bug.  The first two patches are the fixes, and the bug772 test patch is also needed.  The probe and tcp test patches are nice to have because they make future debugging of issues like this easier.
Comment 8 Tom Henderson 2015-03-27 16:27:57 UTC
fixed in changesets 06390d19e6f9 and 73dd242bbaed