Merge with ns-3-dev.
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -6,6 +6,7 @@ Mehdi Benamor (mehdi.benamor@telecom-bretagne.eu)
|
||||
Raj Bhattacharjea (raj.b@gatech.edu)
|
||||
Timo Bingmann (timo.bingmann@student.kit.edu)
|
||||
Pavel Boyko (boyko@iitp.ru)
|
||||
Elena Buchatskaia (borovkovaes@iitp.ru)
|
||||
Gustavo Carneiro (gjc@inescporto.pt, gjcarneiro@gmail.com)
|
||||
Angelos Chatzipapas (chatzipa@ceid.upatras.gr)
|
||||
Luis Cortes (cortes@gatech.edu)
|
||||
|
||||
@@ -59,6 +59,10 @@ event with a context different from the execution context of the caller. This AP
|
||||
by the ns-3 logging system to report the execution context of each log line.
|
||||
<li><b>Object::DoStart</b>: Users who need to complete their object setup at the start of a simulation
|
||||
can override this virtual method, perform their adhoc setup, and then, must chain up to their parent.
|
||||
|
||||
<li><b>Aod hoc On-Demand Distance Vector (AODV)</b> routing model,
|
||||
<a href=http://www.ietf.org/rfc/rfc3561.txt>RFC 3561</a> </li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Changes to existing API:</h2>
|
||||
@@ -122,6 +126,9 @@ sched.SetTypeId ("ns3::ListScheduler");
|
||||
Simulator::SetScheduler (sched);
|
||||
</pre>
|
||||
|
||||
<li> Extensions to IPv4 <b>Ping</b> application: verbose output and the ability to configure different ping
|
||||
sizes and time intervals (via new attributes)</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Changed behavior:</h2>
|
||||
|
||||
@@ -31,10 +31,12 @@ http://www.nsnam.org/wiki/index.php/Installation
|
||||
New user-visible features
|
||||
-------------------------
|
||||
|
||||
* The ns-3 logging macros (NS_LOG_*) now report automatically the node id
|
||||
of the event which called the macro.
|
||||
a) The ns-3 logging macros (NS_LOG_*) now report automatically the node id
|
||||
of the event which called the macro.
|
||||
|
||||
API changes from ns-3.5
|
||||
b) Ad hoc On-Demand Distance Vector (AODV) routing model according to RFC 3561.
|
||||
|
||||
API changes from ns-3.6
|
||||
-----------------------
|
||||
API changes for this release are documented in the file CHANGES.html.
|
||||
|
||||
|
||||
214
examples/routing/aodv.cc
Normal file
214
examples/routing/aodv.cc
Normal file
@@ -0,0 +1,214 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* This is an example script for AODV manet routing protocol.
|
||||
*
|
||||
* Authors: Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#include "ns3/aodv-module.h"
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/common-module.h"
|
||||
#include "ns3/node-module.h"
|
||||
#include "ns3/helper-module.h"
|
||||
#include "ns3/mobility-module.h"
|
||||
#include "ns3/contrib-module.h"
|
||||
#include "ns3/wifi-module.h"
|
||||
#include "ns3/v4ping-helper.h"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
/**
|
||||
* \brief Test script.
|
||||
*
|
||||
* This script creates 1-dimensional grid topology and then ping last node from the first one:
|
||||
*
|
||||
* [10.0.0.1] <-- step --> [10.0.0.2] <-- step --> [10.0.0.3] <-- step --> [10.0.04]
|
||||
*
|
||||
* ping 10.0.0.4
|
||||
*/
|
||||
class AodvExample
|
||||
{
|
||||
public:
|
||||
AodvExample ();
|
||||
/// Configure script parameters, \return true on successful configuration
|
||||
bool Configure (int argc, char **argv);
|
||||
/// Run simulation
|
||||
void Run ();
|
||||
/// Report results
|
||||
void Report (std::ostream & os);
|
||||
|
||||
private:
|
||||
///\name parameters
|
||||
//\{
|
||||
/// Number of nodes
|
||||
uint32_t size;
|
||||
/// Distance between nodes, meters
|
||||
double step;
|
||||
/// Simulation time, seconds
|
||||
double totalTime;
|
||||
/// Write per-device PCAP traces if true
|
||||
bool pcap;
|
||||
//\}
|
||||
|
||||
///\name network
|
||||
//\{
|
||||
NodeContainer nodes;
|
||||
NetDeviceContainer devices;
|
||||
Ipv4InterfaceContainer interfaces;
|
||||
//\}
|
||||
|
||||
private:
|
||||
void CreateNodes ();
|
||||
void CreateDevices ();
|
||||
void InstallInternetStack ();
|
||||
void InstallApplications ();
|
||||
};
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
AodvExample test;
|
||||
if (! test.Configure(argc, argv))
|
||||
NS_FATAL_ERROR ("Configuration failed. Aborted.");
|
||||
|
||||
test.Run ();
|
||||
test.Report (std::cout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
AodvExample::AodvExample () :
|
||||
size (10),
|
||||
step (120),
|
||||
totalTime (10),
|
||||
pcap (true)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
AodvExample::Configure (int argc, char **argv)
|
||||
{
|
||||
// Enable AODV logs by default. Comment this if too noisy
|
||||
// LogComponentEnable("AodvRoutingProtocol", LOG_LEVEL_ALL);
|
||||
|
||||
SeedManager::SetSeed(12345);
|
||||
CommandLine cmd;
|
||||
|
||||
cmd.AddValue ("pcap", "Write PCAP traces.", pcap);
|
||||
cmd.AddValue ("size", "Number of nodes.", size);
|
||||
cmd.AddValue ("time", "Simulation time, s.", totalTime);
|
||||
cmd.AddValue ("step", "Grid step, m", step);
|
||||
|
||||
cmd.Parse (argc, argv);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
AodvExample::Run ()
|
||||
{
|
||||
// Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue (1)); // enable rts cts all the time.
|
||||
CreateNodes ();
|
||||
CreateDevices ();
|
||||
InstallInternetStack ();
|
||||
InstallApplications ();
|
||||
|
||||
std::cout << "Starting simulation for " << totalTime << " s ...\n";
|
||||
|
||||
Simulator::Stop (Seconds (totalTime));
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
|
||||
void
|
||||
AodvExample::Report (std::ostream &)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AodvExample::CreateNodes ()
|
||||
{
|
||||
std::cout << "Creating " << (unsigned)size << " nodes " << step << " m apart.\n";
|
||||
nodes.Create (size);
|
||||
// Name nodes
|
||||
for (uint32_t i = 0; i < size; ++i)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "node-" << i;
|
||||
Names::Add (os.str (), nodes.Get (i));
|
||||
}
|
||||
// Create static grid
|
||||
MobilityHelper mobility;
|
||||
mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
|
||||
"MinX", DoubleValue (0.0),
|
||||
"MinY", DoubleValue (0.0),
|
||||
"DeltaX", DoubleValue (step),
|
||||
"DeltaY", DoubleValue (0),
|
||||
"GridWidth", UintegerValue (size),
|
||||
"LayoutType", StringValue ("RowFirst"));
|
||||
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
|
||||
mobility.Install (nodes);
|
||||
}
|
||||
|
||||
void
|
||||
AodvExample::CreateDevices ()
|
||||
{
|
||||
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
|
||||
wifiMac.SetType ("ns3::AdhocWifiMac");
|
||||
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
|
||||
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
|
||||
wifiPhy.SetChannel (wifiChannel.Create ());
|
||||
WifiHelper wifi = WifiHelper::Default ();
|
||||
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("wifia-6mbs"), "RtsCtsThreshold", UintegerValue (0));
|
||||
devices = wifi.Install (wifiPhy, wifiMac, nodes);
|
||||
|
||||
if (pcap)
|
||||
{
|
||||
wifiPhy.EnablePcapAll (std::string ("aodv"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AodvExample::InstallInternetStack ()
|
||||
{
|
||||
AodvHelper aodv;
|
||||
// you can configure AODV attributes here using aodv.Set(name, value)
|
||||
InternetStackHelper stack;
|
||||
stack.SetRoutingHelper (aodv);
|
||||
stack.Install (nodes);
|
||||
Ipv4AddressHelper address;
|
||||
address.SetBase ("10.0.0.0", "255.0.0.0");
|
||||
interfaces = address.Assign (devices);
|
||||
}
|
||||
|
||||
void
|
||||
AodvExample::InstallApplications ()
|
||||
{
|
||||
V4PingHelper ping (interfaces.GetAddress (size - 1));
|
||||
ping.SetAttribute ("Verbose", BooleanValue (true));
|
||||
|
||||
ApplicationContainer p = ping.Install (nodes.Get (0));
|
||||
p.Start (Seconds (0));
|
||||
p.Stop (Seconds (totalTime));
|
||||
|
||||
// move node away
|
||||
Ptr<Node> node = nodes.Get (size/2);
|
||||
Ptr<MobilityModel> mob = node->GetObject<MobilityModel> ();
|
||||
Simulator::Schedule (Seconds (totalTime/3), &MobilityModel::SetPosition, mob, Vector (1e5, 1e5, 1e5));
|
||||
}
|
||||
|
||||
@@ -44,3 +44,7 @@ def build(bld):
|
||||
obj = bld.create_ns3_program('simple-routing-ping6',
|
||||
['csma', 'internet-stack'])
|
||||
obj.source = 'simple-routing-ping6.cc'
|
||||
|
||||
obj = bld.create_ns3_program('aodv',
|
||||
['wifi', 'internet-stack', 'aodv'])
|
||||
obj.source = 'aodv.cc'
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/inet-socket-address.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/trace-source-accessor.h"
|
||||
#include "ns3/simulator.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -41,6 +41,19 @@ V4Ping::GetTypeId (void)
|
||||
Ipv4AddressValue (),
|
||||
MakeIpv4AddressAccessor (&V4Ping::m_remote),
|
||||
MakeIpv4AddressChecker ())
|
||||
.AddAttribute ("Verbose",
|
||||
"Produce usual output.",
|
||||
BooleanValue (false),
|
||||
MakeBooleanAccessor (&V4Ping::m_verbose),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("Interval", "Wait interval seconds between sending each packet.",
|
||||
TimeValue (Seconds (1)),
|
||||
MakeTimeAccessor (&V4Ping::m_interval),
|
||||
MakeTimeChecker ())
|
||||
.AddAttribute ("Size", "The number of data bytes to be sent, real packet will be 8 (ICMP) + 20 (IP) bytes longer.",
|
||||
UintegerValue (56),
|
||||
MakeUintegerAccessor (&V4Ping::m_size),
|
||||
MakeUintegerChecker<uint32_t> (16))
|
||||
.AddTraceSource ("Rtt",
|
||||
"The rtt calculated by the ping.",
|
||||
MakeTraceSourceAccessor (&V4Ping::m_traceRtt));
|
||||
@@ -49,9 +62,14 @@ V4Ping::GetTypeId (void)
|
||||
}
|
||||
|
||||
V4Ping::V4Ping ()
|
||||
: m_socket (0),
|
||||
m_seq (0)
|
||||
{}
|
||||
: m_interval (Seconds (1)),
|
||||
m_size (56),
|
||||
m_socket (0),
|
||||
m_seq (0),
|
||||
m_verbose (false),
|
||||
m_recv (0)
|
||||
{
|
||||
}
|
||||
V4Ping::~V4Ping ()
|
||||
{}
|
||||
|
||||
@@ -92,6 +110,7 @@ V4Ping::Receive (Ptr<Socket> socket)
|
||||
NS_ASSERT (realFrom.GetPort () == 1); // protocol should be icmp.
|
||||
Ipv4Header ipv4;
|
||||
p->RemoveHeader (ipv4);
|
||||
uint32_t recvSize = p->GetSize ();
|
||||
NS_ASSERT (ipv4.GetProtocol () == 1); // protocol should be icmp.
|
||||
Icmpv4Header icmp;
|
||||
p->RemoveHeader (icmp);
|
||||
@@ -99,10 +118,11 @@ V4Ping::Receive (Ptr<Socket> socket)
|
||||
{
|
||||
Icmpv4Echo echo;
|
||||
p->RemoveHeader (echo);
|
||||
if (echo.GetSequenceNumber () == (m_seq - 1) &&
|
||||
echo.GetIdentifier () == 0)
|
||||
std::map<uint16_t, Time>::iterator i = m_sent.find(echo.GetSequenceNumber());
|
||||
|
||||
if (i != m_sent.end () && echo.GetIdentifier () == 0)
|
||||
{
|
||||
uint32_t buf[4];
|
||||
uint32_t buf[m_size / 4];
|
||||
uint32_t dataSize = echo.GetDataSize ();
|
||||
if (dataSize == sizeof(buf))
|
||||
{
|
||||
@@ -111,13 +131,22 @@ V4Ping::Receive (Ptr<Socket> socket)
|
||||
if (buf[0] == GetNode ()->GetId () &&
|
||||
buf[1] == GetApplicationId ())
|
||||
{
|
||||
int64_t ts = buf[3];
|
||||
ts <<= 32;
|
||||
ts |= buf[2];
|
||||
Time sendTime = TimeStep (ts);
|
||||
Time sendTime = i->second;
|
||||
NS_ASSERT (Simulator::Now () > sendTime);
|
||||
Time delta = Simulator::Now () - sendTime;
|
||||
|
||||
m_sent.erase (i);
|
||||
m_avgRtt.Update (delta.GetMilliSeconds());
|
||||
m_recv++;
|
||||
m_traceRtt (delta);
|
||||
|
||||
if (m_verbose)
|
||||
{
|
||||
std::cout << recvSize << " bytes from " << realFrom.GetIpv4() << ":"
|
||||
<< " icmp_seq=" << echo.GetSequenceNumber ()
|
||||
<< " ttl=" << (unsigned)ipv4.GetTtl ()
|
||||
<< " time=" << delta.GetMilliSeconds() << " ms\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,20 +164,8 @@ V4Ping::Write32 (uint8_t *buffer, uint32_t data)
|
||||
}
|
||||
|
||||
void
|
||||
V4Ping::StartApplication (void)
|
||||
V4Ping::Send ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_socket = Socket::CreateSocket (GetNode (), TypeId::LookupByName ("ns3::Ipv4RawSocketFactory"));
|
||||
NS_ASSERT (m_socket != 0);
|
||||
m_socket->SetAttribute ("Protocol", UintegerValue (1)); // icmp
|
||||
m_socket->SetRecvCallback (MakeCallback (&V4Ping::Receive, this));
|
||||
InetSocketAddress src = InetSocketAddress (Ipv4Address::GetAny (), 0);
|
||||
int status;
|
||||
status = m_socket->Bind (src);
|
||||
NS_ASSERT (status != -1);
|
||||
InetSocketAddress dst = InetSocketAddress (m_remote, 0);
|
||||
status = m_socket->Connect (dst);
|
||||
NS_ASSERT (status != -1);
|
||||
Ptr<Packet> p = Create<Packet> ();
|
||||
Icmpv4Echo echo;
|
||||
echo.SetSequenceNumber (m_seq);
|
||||
@@ -161,22 +178,17 @@ V4Ping::StartApplication (void)
|
||||
// (where any difference would show up anyway) and borrow that code. Don't
|
||||
// be too surprised when you see that this is a little endian convention.
|
||||
//
|
||||
uint8_t data[4 * sizeof(uint32_t)];
|
||||
uint8_t data[m_size];
|
||||
for (uint32_t i = 0; i < m_size; ++i) data[i] = 0;
|
||||
NS_ASSERT (m_size >= 16);
|
||||
|
||||
uint32_t tmp = GetNode ()->GetId ();
|
||||
Write32 (&data[0 * sizeof(uint32_t)], tmp);
|
||||
|
||||
tmp = GetApplicationId ();
|
||||
Write32 (&data[1 * sizeof(uint32_t)], tmp);
|
||||
|
||||
int64_t now = Simulator::Now ().GetTimeStep ();
|
||||
tmp = now & 0xffffffff;
|
||||
Write32 (&data[2 * sizeof(uint32_t)], tmp);
|
||||
|
||||
now >>= 32;
|
||||
tmp = now & 0xffffffff;
|
||||
Write32 (&data[3 * sizeof(uint32_t)], tmp);
|
||||
|
||||
Ptr<Packet> dataPacket = Create<Packet> ((uint8_t *) &data, 16);
|
||||
Ptr<Packet> dataPacket = Create<Packet> ((uint8_t *) &data, m_size);
|
||||
echo.SetData (dataPacket);
|
||||
p->AddHeader (echo);
|
||||
Icmpv4Header header;
|
||||
@@ -184,13 +196,57 @@ V4Ping::StartApplication (void)
|
||||
header.SetCode (0);
|
||||
p->AddHeader (header);
|
||||
m_socket->Send (p, 0);
|
||||
m_sent.insert (std::make_pair (m_seq - 1, Simulator::Now()));
|
||||
m_next = Simulator::Schedule (m_interval, & V4Ping::Send, this);
|
||||
}
|
||||
|
||||
void
|
||||
V4Ping::StartApplication (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
m_started = Simulator::Now ();
|
||||
if (m_verbose)
|
||||
{
|
||||
std::cout << "PING " << m_remote << " 56(84) bytes of data.\n";
|
||||
}
|
||||
|
||||
m_socket = Socket::CreateSocket (GetNode (), TypeId::LookupByName ("ns3::Ipv4RawSocketFactory"));
|
||||
NS_ASSERT (m_socket != 0);
|
||||
m_socket->SetAttribute ("Protocol", UintegerValue (1)); // icmp
|
||||
m_socket->SetRecvCallback (MakeCallback (&V4Ping::Receive, this));
|
||||
InetSocketAddress src = InetSocketAddress (Ipv4Address::GetAny (), 0);
|
||||
int status;
|
||||
status = m_socket->Bind (src);
|
||||
NS_ASSERT (status != -1);
|
||||
InetSocketAddress dst = InetSocketAddress (m_remote, 0);
|
||||
status = m_socket->Connect (dst);
|
||||
NS_ASSERT (status != -1);
|
||||
|
||||
Send ();
|
||||
}
|
||||
void
|
||||
V4Ping::StopApplication (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_next.Cancel();
|
||||
m_socket->Close ();
|
||||
|
||||
if (m_verbose)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.precision (4);
|
||||
os << "--- " << m_remote << " ping statistics ---\n"
|
||||
<< m_seq << " packets transmitted, " << m_recv << " received, "
|
||||
<< ((m_seq - m_recv) * 100 / m_seq) << "% packet loss, "
|
||||
<< "time " << (Simulator::Now () - m_started).GetMilliSeconds () << "ms\n";
|
||||
|
||||
if (m_avgRtt.Count () > 0)
|
||||
os << "rtt min/avg/max/mdev = " << m_avgRtt.Min() << "/" << m_avgRtt.Avg() << "/"
|
||||
<< m_avgRtt.Max() << "/" << m_avgRtt.Err()
|
||||
<< " ms\n";
|
||||
std::cout << os.str();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,27 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef V4PING_H
|
||||
#define V4PING_H
|
||||
|
||||
#include "ns3/application.h"
|
||||
#include "ns3/traced-callback.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/average.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include <map>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -35,11 +53,32 @@ private:
|
||||
virtual void DoDispose (void);
|
||||
uint32_t GetApplicationId (void) const;
|
||||
void Receive (Ptr<Socket> socket);
|
||||
void Send ();
|
||||
|
||||
/// Remote address
|
||||
Ipv4Address m_remote;
|
||||
/// Wait interval seconds between sending each packet
|
||||
Time m_interval;
|
||||
/**
|
||||
* Specifies the number of data bytes to be sent.
|
||||
* The default is 56, which translates into 64 ICMP data bytes when combined with the 8 bytes of ICMP header data.
|
||||
*/
|
||||
uint32_t m_size;
|
||||
Ptr<Socket> m_socket;
|
||||
uint16_t m_seq;
|
||||
TracedCallback<Time> m_traceRtt;
|
||||
/// produce ping-style output if true
|
||||
bool m_verbose;
|
||||
/// received packets counter
|
||||
uint32_t m_recv;
|
||||
/// Start time to report total ping time
|
||||
Time m_started;
|
||||
/// Average rtt is ms
|
||||
Average<double> m_avgRtt;
|
||||
/// Next packet will be sent
|
||||
EventId m_next;
|
||||
/// All sent but not answered packets. Map icmp seqno -> when sent
|
||||
std::map<uint16_t, Time> m_sent;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
82
src/contrib/average.h
Normal file
82
src/contrib/average.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#ifndef AVERAGE_H
|
||||
#define AVERAGE_H
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
/// Simple average, min, max and std. deviation calculator
|
||||
template <typename T = double>
|
||||
class Average
|
||||
{
|
||||
public:
|
||||
Average () :
|
||||
size (0), min (std::numeric_limits<T>::max ()), max (0), avg (0), avg2 (0)
|
||||
{
|
||||
}
|
||||
|
||||
/// Add new value
|
||||
void Update (T const & x)
|
||||
{
|
||||
min = std::min (x, min);
|
||||
max = std::max (x, max);
|
||||
avg = (size * avg + x) / (size + 1);
|
||||
avg2 = (size * avg2 + x * x) / (size + 1);
|
||||
size++;
|
||||
}
|
||||
/// Reset statistics
|
||||
void Reset ()
|
||||
{
|
||||
size = 0;
|
||||
min = std::numeric_limits<T>::max ();
|
||||
max = 0;
|
||||
avg = 0;
|
||||
avg2 = 0;
|
||||
}
|
||||
|
||||
///\name Access results
|
||||
//\{
|
||||
uint32_t Count () const { return size; }
|
||||
T Min () const { return min; }
|
||||
T Max () const { return max; }
|
||||
double Avg () const { return avg; }
|
||||
double Err () const { return sqrt ((avg2 - avg*avg)/(size - 1)); }
|
||||
//\}
|
||||
|
||||
private:
|
||||
uint32_t size;
|
||||
T min, max;
|
||||
double avg, avg2;
|
||||
};
|
||||
|
||||
/// Print avg (err) [min, max]
|
||||
template <typename T>
|
||||
std::ostream & operator<< (std::ostream & os, Average<T> const & x)
|
||||
{
|
||||
if (x.Count () != 0)
|
||||
os << x.Avg () << " (" << x.Err () << ") [" << x.Min () << ", " << x.Max () << "]";
|
||||
else
|
||||
os << "NA"; // not avaliable
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif /* AVERAGE_H */
|
||||
@@ -43,6 +43,7 @@ def build(bld):
|
||||
'file-config.h',
|
||||
'config-store.h',
|
||||
'flow-id-tag.h',
|
||||
'average.h',
|
||||
]
|
||||
|
||||
if bld.env['ENABLE_GTK_CONFIG_STORE']:
|
||||
|
||||
@@ -56,7 +56,20 @@ PppHeader::GetInstanceTypeId (void) const
|
||||
void
|
||||
PppHeader::Print (std::ostream &os) const
|
||||
{
|
||||
os << "Point-to-Point Protocol: " << m_protocol;
|
||||
std::string proto;
|
||||
|
||||
switch(m_protocol)
|
||||
{
|
||||
case 0x0021: /* IPv4 */
|
||||
proto = "IP (0x0021)";
|
||||
break;
|
||||
case 0x0057: /* IPv6 */
|
||||
proto = "IPv6 (0x0057)";
|
||||
break;
|
||||
default:
|
||||
NS_ASSERT_MSG(false, "PPP Protocol number not defined!");
|
||||
}
|
||||
os << "Point-to-Point Protocol: " << proto;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "ns3/pointer.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/trace-source-accessor.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("AdhocWifiMac");
|
||||
|
||||
@@ -48,6 +49,16 @@ AdhocWifiMac::GetTypeId (void)
|
||||
PointerValue (),
|
||||
MakePointerAccessor (&AdhocWifiMac::GetDcaTxop),
|
||||
MakePointerChecker<DcaTxop> ())
|
||||
.AddTraceSource ( "TxOkHeader",
|
||||
"The header of successfully transmitted packet",
|
||||
MakeTraceSourceAccessor (
|
||||
&AdhocWifiMac::m_txOkCallback)
|
||||
)
|
||||
.AddTraceSource ( "TxErrHeader",
|
||||
"The header of unsuccessfully transmitted packet",
|
||||
MakeTraceSourceAccessor (
|
||||
&AdhocWifiMac::m_txErrCallback)
|
||||
)
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
@@ -67,6 +78,7 @@ AdhocWifiMac::AdhocWifiMac ()
|
||||
m_dca = CreateObject<DcaTxop> ();
|
||||
m_dca->SetLow (m_low);
|
||||
m_dca->SetManager (m_dcfManager);
|
||||
m_dca->SetTxFailedCallback (MakeCallback (&AdhocWifiMac::TxFailed, this));
|
||||
}
|
||||
AdhocWifiMac::~AdhocWifiMac ()
|
||||
{}
|
||||
@@ -276,6 +288,14 @@ AdhocWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AdhocWifiMac::TxOk (const WifiMacHeader &hdr)
|
||||
{
|
||||
m_txOkCallback (hdr);
|
||||
}
|
||||
void
|
||||
AdhocWifiMac::TxFailed (const WifiMacHeader &hdr)
|
||||
{
|
||||
m_txErrCallback (hdr);
|
||||
}
|
||||
} // namespace ns3
|
||||
|
||||
@@ -87,8 +87,9 @@ private:
|
||||
AdhocWifiMac (const AdhocWifiMac & ctor_arg);
|
||||
AdhocWifiMac &operator = (const AdhocWifiMac &o);
|
||||
Ptr<DcaTxop> GetDcaTxop(void) const;
|
||||
void TxOk (WifiMacHeader const &hdr);
|
||||
void TxFailed (WifiMacHeader const &hdr);
|
||||
virtual void FinishConfigureStandard (enum WifiPhyStandard standard);
|
||||
|
||||
Ptr<DcaTxop> m_dca;
|
||||
Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> m_upCallback;
|
||||
Ptr<WifiRemoteStationManager> m_stationManager;
|
||||
@@ -97,6 +98,8 @@ private:
|
||||
MacRxMiddle *m_rxMiddle;
|
||||
Ptr<MacLow> m_low;
|
||||
Ssid m_ssid;
|
||||
TracedCallback<WifiMacHeader const &> m_txOkCallback;
|
||||
TracedCallback<WifiMacHeader const &> m_txErrCallback;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -91,6 +91,15 @@ WifiNetDevice::DoDispose (void)
|
||||
NetDevice::DoDispose ();
|
||||
}
|
||||
|
||||
void
|
||||
WifiNetDevice::DoStart (void)
|
||||
{
|
||||
m_phy->Start ();
|
||||
m_mac->Start ();
|
||||
m_stationManager->Start ();
|
||||
NetDevice::DoStart ();
|
||||
}
|
||||
|
||||
void
|
||||
WifiNetDevice::CompleteConfig (void)
|
||||
{
|
||||
|
||||
@@ -104,6 +104,7 @@ public:
|
||||
|
||||
private:
|
||||
virtual void DoDispose (void);
|
||||
virtual void DoStart (void);
|
||||
void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
|
||||
void LinkUp (void);
|
||||
void LinkDown (void);
|
||||
|
||||
55
src/helper/aodv-helper.cc
Normal file
55
src/helper/aodv-helper.cc
Normal file
@@ -0,0 +1,55 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Pavel Boyko <boyko@iitp.ru>, written after OlsrHelper by Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "aodv-helper.h"
|
||||
#include "ns3/aodv-routing-protocol.h"
|
||||
#include "ns3/node-list.h"
|
||||
#include "ns3/names.h"
|
||||
#include "ns3/ipv4-list-routing.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
AodvHelper::AodvHelper() :
|
||||
Ipv4RoutingHelper ()
|
||||
{
|
||||
m_agentFactory.SetTypeId ("ns3::aodv::RoutingProtocol");
|
||||
}
|
||||
|
||||
AodvHelper*
|
||||
AodvHelper::Copy (void) const
|
||||
{
|
||||
return new AodvHelper (*this);
|
||||
}
|
||||
|
||||
Ptr<Ipv4RoutingProtocol>
|
||||
AodvHelper::Create (Ptr<Node> node) const
|
||||
{
|
||||
Ptr<aodv::RoutingProtocol> agent = m_agentFactory.Create<aodv::RoutingProtocol> ();
|
||||
node->AggregateObject (agent);
|
||||
return agent;
|
||||
}
|
||||
|
||||
void
|
||||
AodvHelper::Set (std::string name, const AttributeValue &value)
|
||||
{
|
||||
m_agentFactory.Set (name, value);
|
||||
}
|
||||
|
||||
}
|
||||
70
src/helper/aodv-helper.h
Normal file
70
src/helper/aodv-helper.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Pavel Boyko <boyko@iitp.ru>, written after OlsrHelper by Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef AODVHELPER_H_
|
||||
#define AODVHELPER_H_
|
||||
|
||||
#include "ns3/object-factory.h"
|
||||
#include "ns3/node.h"
|
||||
#include "node-container.h"
|
||||
#include "ipv4-routing-helper.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief Helper class that adds AODV routing to nodes.
|
||||
*/
|
||||
class AodvHelper : public Ipv4RoutingHelper
|
||||
{
|
||||
public:
|
||||
AodvHelper();
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* \returns pointer to clone of this OlsrHelper
|
||||
*
|
||||
* This method is mainly for internal use by the other helpers;
|
||||
* clients are expected to free the dynamic memory allocated by this method
|
||||
*/
|
||||
AodvHelper* Copy (void) const;
|
||||
|
||||
/**
|
||||
* \param node the node on which the routing protocol will run
|
||||
* \returns a newly-created routing protocol
|
||||
*
|
||||
* This method will be called by ns3::InternetStackHelper::Install
|
||||
*
|
||||
* TODO: support installing AODV on the subset of all available IP interfaces
|
||||
*/
|
||||
virtual Ptr<Ipv4RoutingProtocol> Create (Ptr<Node> node) const;
|
||||
/**
|
||||
* \param name the name of the attribute to set
|
||||
* \param value the value of the attribute to set.
|
||||
*
|
||||
* This method controls the attributes of ns3::aodv::RoutingProtocol
|
||||
*/
|
||||
void Set (std::string name, const AttributeValue &value);
|
||||
|
||||
private:
|
||||
ObjectFactory m_agentFactory;
|
||||
};
|
||||
|
||||
}
|
||||
#endif /* AODVHELPER_H_ */
|
||||
@@ -30,6 +30,12 @@ V4PingHelper::V4PingHelper (Ipv4Address remote)
|
||||
m_factory.Set ("Remote", Ipv4AddressValue (remote));
|
||||
}
|
||||
|
||||
void
|
||||
V4PingHelper::SetAttribute (std::string name, const AttributeValue &value)
|
||||
{
|
||||
m_factory.Set (name, value);
|
||||
}
|
||||
|
||||
ApplicationContainer
|
||||
V4PingHelper::Install (Ptr<Node> node) const
|
||||
{
|
||||
|
||||
@@ -55,6 +55,12 @@ public:
|
||||
*/
|
||||
ApplicationContainer Install (std::string nodeName) const;
|
||||
|
||||
/**
|
||||
* \brief Configure ping applications attribute
|
||||
* \param name attribute's name
|
||||
* \param value attribute's value
|
||||
*/
|
||||
void SetAttribute (std::string name, const AttributeValue &value);
|
||||
private:
|
||||
/**
|
||||
* \internal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
helper = bld.create_ns3_module('helper', ['internet-stack', 'wifi', 'point-to-point', 'csma', 'olsr', 'nix-vector-routing', 'global-routing', 'onoff', 'packet-sink', 'udp-echo'])
|
||||
helper = bld.create_ns3_module('helper', ['internet-stack', 'wifi', 'point-to-point', 'csma', 'olsr', 'global-routing', 'onoff', 'packet-sink', 'udp-echo'])
|
||||
helper.source = [
|
||||
'node-container.cc',
|
||||
'net-device-container.cc',
|
||||
@@ -29,6 +29,7 @@ def build(bld):
|
||||
'ipv4-global-routing-helper.cc',
|
||||
'ipv4-list-routing-helper.cc',
|
||||
'ipv4-routing-helper.cc',
|
||||
'aodv-helper.cc',
|
||||
'mesh-helper.cc',
|
||||
'dot11s-installer.cc',
|
||||
'flame-installer.cc',
|
||||
@@ -68,9 +69,10 @@ def build(bld):
|
||||
'nqos-wifi-mac-helper.h',
|
||||
'qos-wifi-mac-helper.h',
|
||||
'ipv4-nix-vector-helper.h',
|
||||
'ipv4-global-routing-helper.h',
|
||||
'ipv4-global-routing-helper.h',
|
||||
'ipv4-list-routing-helper.h',
|
||||
'ipv4-routing-helper.h',
|
||||
'aodv-helper.h',
|
||||
'mesh-helper.h',
|
||||
'mesh-stack-installer.h',
|
||||
'dot11s-installer.h',
|
||||
|
||||
@@ -86,6 +86,7 @@ Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address dest, uint8_t typ
|
||||
NS_ASSERT (ipv4 != 0 && ipv4->GetRoutingProtocol () != 0);
|
||||
Ipv4Header header;
|
||||
header.SetDestination (dest);
|
||||
header.SetProtocol (PROT_NUMBER);
|
||||
Socket::SocketErrno errno_;
|
||||
Ptr<Ipv4Route> route;
|
||||
uint32_t oif = 0; //specify non-zero if bound to a source address
|
||||
|
||||
@@ -42,7 +42,8 @@ Ipv4Interface::GetTypeId (void)
|
||||
.AddAttribute ("ArpCache",
|
||||
"The arp cache for this ipv4 interface",
|
||||
PointerValue (0),
|
||||
MakePointerAccessor (&Ipv4Interface::m_cache),
|
||||
MakePointerAccessor (&Ipv4Interface::SetArpCache,
|
||||
&Ipv4Interface::GetArpCache),
|
||||
MakePointerChecker<ArpCache> ())
|
||||
;
|
||||
;
|
||||
@@ -128,6 +129,18 @@ Ipv4Interface::GetMetric (void) const
|
||||
return m_metric;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Interface::SetArpCache (Ptr<ArpCache> a)
|
||||
{
|
||||
m_cache = a;
|
||||
}
|
||||
|
||||
Ptr<ArpCache>
|
||||
Ipv4Interface::GetArpCache () const
|
||||
{
|
||||
return m_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* These are IP interface states and may be distinct from
|
||||
* NetDevice states, such as found in real implementations
|
||||
|
||||
@@ -56,12 +56,17 @@ public:
|
||||
|
||||
void SetNode (Ptr<Node> node);
|
||||
void SetDevice (Ptr<NetDevice> device);
|
||||
void SetArpCache (Ptr<ArpCache>);
|
||||
|
||||
/**
|
||||
* \returns the underlying NetDevice. This method cannot return zero.
|
||||
*/
|
||||
Ptr<NetDevice> GetDevice (void) const;
|
||||
|
||||
/**
|
||||
* \return ARP cache used by this interface
|
||||
*/
|
||||
Ptr<ArpCache> GetArpCache () const;
|
||||
|
||||
/**
|
||||
* \param metric configured routing metric (cost) of this interface
|
||||
*
|
||||
|
||||
@@ -241,7 +241,6 @@ private:
|
||||
bool m_ipForward;
|
||||
L4List_t m_protocols;
|
||||
Ipv4InterfaceList m_interfaces;
|
||||
uint32_t m_nInterfaces;
|
||||
uint8_t m_defaultTtl;
|
||||
uint16_t m_identification;
|
||||
Ptr<Node> m_node;
|
||||
|
||||
@@ -174,6 +174,7 @@ Ipv4RawSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags,
|
||||
{
|
||||
Ipv4Header header;
|
||||
header.SetDestination (dst);
|
||||
header.SetProtocol (m_protocol);
|
||||
SocketErrno errno_ = ERROR_NOTERROR;//do not use errno as it is the standard C last error number
|
||||
Ptr<Ipv4Route> route;
|
||||
uint32_t oif = 0; //specify non-zero if bound to a source address
|
||||
@@ -247,6 +248,7 @@ Ipv4RawSocketImpl::ForwardUp (Ptr<const Packet> p, Ipv4Header ipHeader, Ptr<NetD
|
||||
{
|
||||
return false;
|
||||
}
|
||||
NS_LOG_LOGIC ("src = " << m_src << " dst = " << m_dst);
|
||||
if ((m_src == Ipv4Address::GetAny () || ipHeader.GetDestination () == m_src) &&
|
||||
(m_dst == Ipv4Address::GetAny () || ipHeader.GetSource () == m_dst) &&
|
||||
ipHeader.GetProtocol () == m_protocol)
|
||||
|
||||
@@ -576,6 +576,7 @@ TcpL4Protocol::Send (Ptr<Packet> packet,
|
||||
// should be cached.
|
||||
Ipv4Header header;
|
||||
header.SetDestination (daddr);
|
||||
header.SetProtocol (PROT_NUMBER);
|
||||
Socket::SocketErrno errno_;
|
||||
Ptr<Ipv4Route> route;
|
||||
uint32_t oif = 0; //specify non-zero if bound to a source address
|
||||
@@ -615,6 +616,7 @@ TcpL4Protocol::SendPacket (Ptr<Packet> packet, const TcpHeader &outgoing,
|
||||
// should be cached.
|
||||
Ipv4Header header;
|
||||
header.SetDestination (daddr);
|
||||
header.SetProtocol (PROT_NUMBER);
|
||||
Socket::SocketErrno errno_;
|
||||
Ptr<Ipv4Route> route;
|
||||
uint32_t oif = 0; //specify non-zero if bound to a source address
|
||||
|
||||
@@ -373,6 +373,8 @@ UdpSocketImpl::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
|
||||
// Get the primary address
|
||||
Ipv4InterfaceAddress iaddr = ipv4->GetAddress (i, 0);
|
||||
Ipv4Address addri = iaddr.GetLocal ();
|
||||
if (addri == Ipv4Address ("127.0.0.1"))
|
||||
continue;
|
||||
Ipv4Mask maski = iaddr.GetMask ();
|
||||
if (maski == Ipv4Mask::GetOnes ())
|
||||
{
|
||||
@@ -403,6 +405,7 @@ UdpSocketImpl::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
|
||||
{
|
||||
Ipv4Header header;
|
||||
header.SetDestination (dest);
|
||||
header.SetProtocol (UdpL4Protocol::PROT_NUMBER);
|
||||
Socket::SocketErrno errno_;
|
||||
Ptr<Ipv4Route> route;
|
||||
uint32_t oif = 0; //specify non-zero if bound to a source address
|
||||
|
||||
@@ -127,6 +127,8 @@ def build(bld):
|
||||
'sequence-number.h',
|
||||
'icmpv4.h',
|
||||
'icmpv6-header.h',
|
||||
# used by routing
|
||||
'ipv4-interface.h',
|
||||
'ipv4-l3-protocol.h',
|
||||
'ipv6-l3-protocol.h',
|
||||
'ipv6-extension-header.h',
|
||||
|
||||
@@ -45,7 +45,9 @@ Ptr<Socket>
|
||||
Socket::CreateSocket (Ptr<Node> node, TypeId tid)
|
||||
{
|
||||
Ptr<Socket> s;
|
||||
NS_ASSERT (node != 0);
|
||||
Ptr<SocketFactory> socketFactory = node->GetObject<SocketFactory> (tid);
|
||||
NS_ASSERT (socketFactory != 0);
|
||||
s = socketFactory->CreateSocket ();
|
||||
NS_ASSERT (s != 0);
|
||||
return s;
|
||||
|
||||
173
src/routing/manet/aodv/aodv-neighbor.cc
Normal file
173
src/routing/manet/aodv/aodv-neighbor.cc
Normal file
@@ -0,0 +1,173 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#include "aodv-neighbor.h"
|
||||
#include "ns3/log.h"
|
||||
#include <algorithm>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("AodvNeighbors");
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace aodv
|
||||
{
|
||||
Neighbors::Neighbors (Time delay) :
|
||||
m_ntimer (Timer::CANCEL_ON_DESTROY)
|
||||
{
|
||||
m_ntimer.SetDelay(delay);
|
||||
m_ntimer.SetFunction(&Neighbors::Purge, this);
|
||||
m_txErrorCallback = MakeCallback (& Neighbors::ProcessTxError, this);
|
||||
}
|
||||
|
||||
bool
|
||||
Neighbors::IsNeighbor (Ipv4Address addr)
|
||||
{
|
||||
Purge ();
|
||||
for (std::vector<Neighbor>::const_iterator i = m_nb.begin ();
|
||||
i != m_nb.end (); ++i)
|
||||
{
|
||||
if (i->m_neighborAddress == addr)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Time
|
||||
Neighbors::GetExpireTime (Ipv4Address addr)
|
||||
{
|
||||
Purge ();
|
||||
for (std::vector<Neighbor>::const_iterator i = m_nb.begin (); i
|
||||
!= m_nb.end (); ++i)
|
||||
{
|
||||
if (i->m_neighborAddress == addr)
|
||||
return (i->m_expireTime - Simulator::Now ());
|
||||
}
|
||||
return Seconds (0);
|
||||
}
|
||||
|
||||
void
|
||||
Neighbors::Update (Ipv4Address addr, Time expire)
|
||||
{
|
||||
for (std::vector<Neighbor>::iterator i = m_nb.begin (); i != m_nb.end (); ++i)
|
||||
if (i->m_neighborAddress == addr)
|
||||
{
|
||||
i->m_expireTime
|
||||
= std::max (expire + Simulator::Now (), i->m_expireTime);
|
||||
if (i->m_hardwareAddress == Mac48Address ())
|
||||
i->m_hardwareAddress = LookupMacAddress (i->m_neighborAddress);
|
||||
return;
|
||||
}
|
||||
|
||||
NS_LOG_LOGIC ("Open link to " << addr);
|
||||
Neighbor neighbor (addr, LookupMacAddress (addr), expire + Simulator::Now ());
|
||||
m_nb.push_back (neighbor);
|
||||
Purge ();
|
||||
}
|
||||
|
||||
struct CloseNeighbor
|
||||
{
|
||||
bool operator() (const Neighbors::Neighbor & nb) const
|
||||
{
|
||||
return ((nb.m_expireTime < Simulator::Now ()) || nb.close);
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
Neighbors::Purge ()
|
||||
{
|
||||
if (m_nb.empty ())
|
||||
return;
|
||||
|
||||
CloseNeighbor pred;
|
||||
if (!m_handleLinkFailure.IsNull ())
|
||||
{
|
||||
for (std::vector<Neighbor>::iterator j = m_nb.begin (); j != m_nb.end (); ++j)
|
||||
{
|
||||
if (pred (*j))
|
||||
{
|
||||
NS_LOG_LOGIC ("Close link to " << j->m_neighborAddress);
|
||||
m_handleLinkFailure (j->m_neighborAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_nb.erase (std::remove_if (m_nb.begin (), m_nb.end (), pred), m_nb.end ());
|
||||
m_ntimer.Cancel ();
|
||||
m_ntimer.Schedule ();
|
||||
}
|
||||
|
||||
void
|
||||
Neighbors::ScheduleTimer ()
|
||||
{
|
||||
m_ntimer.Cancel ();
|
||||
m_ntimer.Schedule ();
|
||||
}
|
||||
|
||||
void
|
||||
Neighbors::AddArpCache (Ptr<ArpCache> a)
|
||||
{
|
||||
m_arp.push_back (a);
|
||||
}
|
||||
|
||||
void
|
||||
Neighbors::DelArpCache (Ptr<ArpCache> a)
|
||||
{
|
||||
m_arp.erase (std::remove (m_arp.begin (), m_arp.end (), a), m_arp.end ());
|
||||
}
|
||||
|
||||
Mac48Address
|
||||
Neighbors::LookupMacAddress (Ipv4Address addr)
|
||||
{
|
||||
Mac48Address hwaddr;
|
||||
for (std::vector<Ptr<ArpCache> >::const_iterator i = m_arp.begin ();
|
||||
i != m_arp.end (); ++i)
|
||||
{
|
||||
ArpCache::Entry * entry = (*i)->Lookup (addr);
|
||||
if (entry != 0 && entry->IsAlive () && !entry->IsExpired ())
|
||||
{
|
||||
hwaddr = Mac48Address::ConvertFrom (entry->GetMacAddress ());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return hwaddr;
|
||||
}
|
||||
|
||||
void
|
||||
Neighbors::ProcessTxError (WifiMacHeader const & hdr)
|
||||
{
|
||||
Mac48Address addr = hdr.GetAddr1 ();
|
||||
|
||||
for (std::vector<Neighbor>::iterator i = m_nb.begin (); i != m_nb.end (); ++i)
|
||||
{
|
||||
if (i->m_hardwareAddress == addr)
|
||||
i->close = true;
|
||||
}
|
||||
Purge ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
114
src/routing/manet/aodv/aodv-neighbor.h
Normal file
114
src/routing/manet/aodv/aodv-neighbor.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#ifndef AODVNEIGHBOR_H
|
||||
#define AODVNEIGHBOR_H
|
||||
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/timer.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/wifi-mac-header.h"
|
||||
#include "ns3/arp-cache.h"
|
||||
#include <vector>
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace aodv
|
||||
{
|
||||
class RoutingProtocol;
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief maintain list of active neighbors
|
||||
*/
|
||||
class Neighbors
|
||||
{
|
||||
public:
|
||||
/// c-tor
|
||||
Neighbors (Time delay);
|
||||
/// Neighbor description
|
||||
struct Neighbor
|
||||
{
|
||||
Ipv4Address m_neighborAddress;
|
||||
Mac48Address m_hardwareAddress;
|
||||
Time m_expireTime;
|
||||
bool close;
|
||||
|
||||
Neighbor (Ipv4Address ip, Mac48Address mac, Time t) :
|
||||
m_neighborAddress (ip), m_hardwareAddress (mac), m_expireTime (t),
|
||||
close (false)
|
||||
{
|
||||
}
|
||||
};
|
||||
/// Return expire time for neighbor node with address addr, if exists, else return 0.
|
||||
Time GetExpireTime (Ipv4Address addr);
|
||||
/// Check that node with address addr is neighbor
|
||||
bool IsNeighbor (Ipv4Address addr);
|
||||
/// Update expire time for entry with address addr, if it exists, else add new entry
|
||||
void Update (Ipv4Address addr, Time expire);
|
||||
/// Remove all expired entries
|
||||
void Purge ();
|
||||
/// Schedule m_ntimer.
|
||||
void ScheduleTimer ();
|
||||
/// Remove all entries
|
||||
void Clear () { m_nb.clear (); }
|
||||
|
||||
/// Add ARP cache to be used to allow layer 2 notifications processing
|
||||
void AddArpCache (Ptr<ArpCache>);
|
||||
/// Don't use given ARP cache any more (interface is down)
|
||||
void DelArpCache (Ptr<ArpCache>);
|
||||
/// Get callback to ProcessTxError
|
||||
Callback<void, WifiMacHeader const &> GetTxErrorCallback () const { return m_txErrorCallback; }
|
||||
|
||||
///\name Handle link failure callback
|
||||
//\{
|
||||
void SetCallback (Callback<void, Ipv4Address> cb) { m_handleLinkFailure = cb;}
|
||||
Callback<void, Ipv4Address> GetCallback () const { return m_handleLinkFailure; }
|
||||
//\}
|
||||
private:
|
||||
/// link failure callback
|
||||
Callback<void, Ipv4Address> m_handleLinkFailure;
|
||||
/// TX error callback
|
||||
Callback<void, WifiMacHeader const &> m_txErrorCallback;
|
||||
/// Timer for neighbor's list. Schedule Purge().
|
||||
Timer m_ntimer;
|
||||
/// vector of entries
|
||||
std::vector<Neighbor> m_nb;
|
||||
/// list of ARP cached to be used for layer 2 notifications processing
|
||||
std::vector<Ptr<ArpCache> > m_arp;
|
||||
|
||||
/// Find MAC address by IP using list of ARP caches
|
||||
Mac48Address LookupMacAddress (Ipv4Address);
|
||||
/// Process layer 2 TX error notification
|
||||
void ProcessTxError (WifiMacHeader const &);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* AODVNEIGHBOR_H */
|
||||
580
src/routing/manet/aodv/aodv-packet.cc
Normal file
580
src/routing/manet/aodv/aodv-packet.cc
Normal file
@@ -0,0 +1,580 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
#include "aodv-packet.h"
|
||||
#include "ns3/address-utils.h"
|
||||
#include "ns3/packet.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace aodv
|
||||
{
|
||||
|
||||
TypeHeader::TypeHeader (MessageType t) :
|
||||
m_type (t), m_valid (true)
|
||||
{
|
||||
}
|
||||
|
||||
TypeId
|
||||
TypeHeader::GetInstanceTypeId () const
|
||||
{
|
||||
return TypeId ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
TypeHeader::GetSerializedSize () const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
TypeHeader::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteU8 ((uint8_t) m_type);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
TypeHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
uint8_t type = i.ReadU8 ();
|
||||
m_valid = true;
|
||||
switch (type)
|
||||
{
|
||||
case AODVTYPE_RREQ:
|
||||
case AODVTYPE_RREP:
|
||||
case AODVTYPE_RERR:
|
||||
case AODVTYPE_RREP_ACK:
|
||||
{
|
||||
m_type = (MessageType) type;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
m_valid = false;
|
||||
}
|
||||
uint32_t dist = i.GetDistanceFrom (start);
|
||||
NS_ASSERT (dist == GetSerializedSize ());
|
||||
return dist;
|
||||
}
|
||||
|
||||
void
|
||||
TypeHeader::Print (std::ostream &os) const
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case AODVTYPE_RREQ:
|
||||
{
|
||||
os << "RREQ" << "\n";
|
||||
break;
|
||||
}
|
||||
case AODVTYPE_RREP:
|
||||
{
|
||||
os << "RREP" << "\n";
|
||||
break;
|
||||
}
|
||||
case AODVTYPE_RERR:
|
||||
{
|
||||
os << "RERR" << "\n";
|
||||
break;
|
||||
}
|
||||
case AODVTYPE_RREP_ACK:
|
||||
{
|
||||
os << "RREP_ACK" << "\n";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
os << "UNKNOWN_TYPE";
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TypeHeader::operator== (TypeHeader const & o) const
|
||||
{
|
||||
return (m_type == o.m_type && m_valid == o.m_valid);
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator<< (std::ostream & os, TypeHeader const & h)
|
||||
{
|
||||
h.Print (os);
|
||||
return os;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RREQ
|
||||
//-----------------------------------------------------------------------------
|
||||
RreqHeader::RreqHeader (uint8_t flags, uint8_t reserved, uint8_t hopCount, uint32_t requestID, Ipv4Address dst,
|
||||
uint32_t dstSeqNo, Ipv4Address origin, uint32_t originSeqNo) :
|
||||
m_flags (flags), m_reserved (reserved), m_hopCount (hopCount), m_requestID (requestID), m_dst(dst),
|
||||
m_dstSeqNo (dstSeqNo), m_origin(origin), m_originSeqNo (originSeqNo)
|
||||
{
|
||||
}
|
||||
|
||||
TypeId
|
||||
RreqHeader::GetInstanceTypeId () const
|
||||
{
|
||||
return TypeId ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RreqHeader::GetSerializedSize () const
|
||||
{
|
||||
return 23;
|
||||
}
|
||||
|
||||
void
|
||||
RreqHeader::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteU8 (m_flags);
|
||||
i.WriteU8 (m_reserved);
|
||||
i.WriteU8 (m_hopCount);
|
||||
i.WriteHtonU32 (m_requestID);
|
||||
WriteTo (i, m_dst);
|
||||
i.WriteHtonU32 (m_dstSeqNo);
|
||||
WriteTo (i, m_origin);
|
||||
i.WriteHtonU32 (m_originSeqNo);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RreqHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
m_flags = i.ReadU8 ();
|
||||
m_reserved = i.ReadU8 ();
|
||||
m_hopCount = i.ReadU8 ();
|
||||
m_requestID = i.ReadNtohU32 ();
|
||||
ReadFrom (i, m_dst);
|
||||
m_dstSeqNo = i.ReadNtohU32 ();
|
||||
ReadFrom (i, m_origin);
|
||||
m_originSeqNo = i.ReadNtohU32 ();
|
||||
|
||||
uint32_t dist = i.GetDistanceFrom (start);
|
||||
NS_ASSERT (dist == GetSerializedSize ());
|
||||
return dist;
|
||||
}
|
||||
|
||||
void
|
||||
RreqHeader::Print (std::ostream &os) const
|
||||
{
|
||||
os << "RREQ ID " << m_requestID << "\n" << "destination: ipv4 " << m_dst
|
||||
<< " " << "sequence number " << m_dstSeqNo << "\n" << "source: ipv4 "
|
||||
<< m_origin << " " << "sequence number " << m_originSeqNo << "\n"
|
||||
<< "flags:\n" << "Gratuitous RREP " << (*this).GetGratiousRrep () << "\n"
|
||||
<< "Destination only " << (*this).GetDestinationOnly () << "\n"
|
||||
<< "Unknown sequence number " << (*this).GetUnknownSeqno () << "\n";
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator<< (std::ostream & os, RreqHeader const & h)
|
||||
{
|
||||
h.Print (os);
|
||||
return os;
|
||||
}
|
||||
|
||||
void
|
||||
RreqHeader::SetGratiousRrep (bool f)
|
||||
{
|
||||
if (f)
|
||||
m_flags |= (1 << 5);
|
||||
else
|
||||
m_flags &= ~(1 << 5);
|
||||
}
|
||||
|
||||
bool
|
||||
RreqHeader::GetGratiousRrep () const
|
||||
{
|
||||
return (m_flags & (1 << 5));
|
||||
}
|
||||
|
||||
void
|
||||
RreqHeader::SetDestinationOnly (bool f)
|
||||
{
|
||||
if (f)
|
||||
m_flags |= (1 << 4);
|
||||
else
|
||||
m_flags &= ~(1 << 4);
|
||||
}
|
||||
|
||||
bool
|
||||
RreqHeader::GetDestinationOnly () const
|
||||
{
|
||||
return (m_flags & (1 << 4));
|
||||
}
|
||||
|
||||
void
|
||||
RreqHeader::SetUnknownSeqno (bool f)
|
||||
{
|
||||
if (f)
|
||||
m_flags |= (1 << 3);
|
||||
else
|
||||
m_flags &= ~(1 << 3);
|
||||
}
|
||||
|
||||
bool
|
||||
RreqHeader::GetUnknownSeqno () const
|
||||
{
|
||||
return (m_flags & (1 << 3));
|
||||
}
|
||||
|
||||
bool
|
||||
RreqHeader::operator== (RreqHeader const & o) const
|
||||
{
|
||||
return (m_flags == o.m_flags && m_reserved == o.m_reserved &&
|
||||
m_hopCount == o.m_hopCount && m_requestID == o.m_requestID &&
|
||||
m_dst == o.m_dst && m_dstSeqNo == o.m_dstSeqNo &&
|
||||
m_origin == o.m_origin && m_originSeqNo == o.m_originSeqNo);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RREP
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
RrepHeader::RrepHeader (uint8_t prefixSize, uint8_t hopCount, Ipv4Address dst,
|
||||
uint32_t dstSeqNo, Ipv4Address origin, Time lifeTime) :
|
||||
m_flags (0), m_prefixSize (prefixSize), m_hopCount (hopCount),
|
||||
m_dst (dst), m_dstSeqNo (dstSeqNo), m_origin (origin)
|
||||
{
|
||||
m_lifeTime = uint32_t (lifeTime.GetMilliSeconds ());
|
||||
}
|
||||
|
||||
TypeId
|
||||
RrepHeader::GetInstanceTypeId () const
|
||||
{
|
||||
return TypeId ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RrepHeader::GetSerializedSize () const
|
||||
{
|
||||
return 19;
|
||||
}
|
||||
|
||||
void
|
||||
RrepHeader::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteU8 (m_flags);
|
||||
i.WriteU8 (m_prefixSize);
|
||||
i.WriteU8 (m_hopCount);
|
||||
WriteTo (i, m_dst);
|
||||
i.WriteHtonU32 (m_dstSeqNo);
|
||||
WriteTo (i, m_origin);
|
||||
i.WriteHtonU32 (m_lifeTime);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RrepHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
m_flags = i.ReadU8 ();
|
||||
m_prefixSize = i.ReadU8 ();
|
||||
m_hopCount = i.ReadU8 ();
|
||||
ReadFrom (i, m_dst);
|
||||
m_dstSeqNo = i.ReadNtohU32 ();
|
||||
ReadFrom (i, m_origin);
|
||||
m_lifeTime = i.ReadNtohU32 ();
|
||||
|
||||
uint32_t dist = i.GetDistanceFrom (start);
|
||||
NS_ASSERT (dist == GetSerializedSize ());
|
||||
return dist;
|
||||
}
|
||||
|
||||
void
|
||||
RrepHeader::Print (std::ostream &os) const
|
||||
{
|
||||
os << "destination: ipv4 " << m_dst << "sequence number " << m_dstSeqNo;
|
||||
if (m_prefixSize != 0)
|
||||
os << "prefix size " << m_prefixSize << "\n";
|
||||
else
|
||||
os << "\n";
|
||||
os << "source ipv4 " << m_origin << "\n" << "life time " << m_lifeTime
|
||||
<< "\n" << "acknowledgment required flag " << (*this).GetAckRequired ()
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
void
|
||||
RrepHeader::SetLifeTime (Time t)
|
||||
{
|
||||
m_lifeTime = t.GetMilliSeconds ();
|
||||
}
|
||||
|
||||
Time
|
||||
RrepHeader::GetLifeTime () const
|
||||
{
|
||||
Time t (MilliSeconds (m_lifeTime));
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
RrepHeader::SetAckRequired (bool f)
|
||||
{
|
||||
if (f)
|
||||
m_flags |= (1 << 6);
|
||||
else
|
||||
m_flags &= ~(1 << 6);
|
||||
}
|
||||
|
||||
bool
|
||||
RrepHeader::GetAckRequired () const
|
||||
{
|
||||
return (m_flags & (1 << 6));
|
||||
}
|
||||
|
||||
void
|
||||
RrepHeader::SetPrefixSize (uint8_t sz)
|
||||
{
|
||||
m_prefixSize = sz;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
RrepHeader::GetPrefixSize () const
|
||||
{
|
||||
return m_prefixSize;
|
||||
}
|
||||
|
||||
bool
|
||||
RrepHeader::operator== (RrepHeader const & o) const
|
||||
{
|
||||
return (m_flags == o.m_flags && m_prefixSize == o.m_prefixSize &&
|
||||
m_hopCount == o.m_hopCount && m_dst == o.m_dst && m_dstSeqNo == o.m_dstSeqNo &&
|
||||
m_origin == o.m_origin && m_lifeTime == o.m_lifeTime);
|
||||
}
|
||||
|
||||
void
|
||||
RrepHeader::SetHello (Ipv4Address origin, uint32_t srcSeqNo, Time lifetime)
|
||||
{
|
||||
m_flags = 0;
|
||||
m_prefixSize = 0;
|
||||
m_hopCount = 0;
|
||||
m_dst = origin;
|
||||
m_dstSeqNo = srcSeqNo;
|
||||
m_origin = origin;
|
||||
m_lifeTime = lifetime.GetMilliSeconds ();
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator<< (std::ostream & os, RrepHeader const & h)
|
||||
{
|
||||
h.Print (os);
|
||||
return os;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RREP-ACK
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
RrepAckHeader::RrepAckHeader () :
|
||||
m_reserved (0)
|
||||
{
|
||||
}
|
||||
|
||||
TypeId
|
||||
RrepAckHeader::GetInstanceTypeId () const
|
||||
{
|
||||
return TypeId ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RrepAckHeader::GetSerializedSize () const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
RrepAckHeader::Serialize (Buffer::Iterator i ) const
|
||||
{
|
||||
i.WriteU8 (m_reserved);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RrepAckHeader::Deserialize (Buffer::Iterator start )
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
m_reserved = i.ReadU8 ();
|
||||
uint32_t dist = i.GetDistanceFrom (start);
|
||||
NS_ASSERT (dist == GetSerializedSize ());
|
||||
return dist;
|
||||
}
|
||||
|
||||
void
|
||||
RrepAckHeader::Print (std::ostream &os ) const
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
RrepAckHeader::operator== (RrepAckHeader const & o ) const
|
||||
{
|
||||
return m_reserved == o.m_reserved;
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator<< (std::ostream & os, RrepAckHeader const & h )
|
||||
{
|
||||
h.Print (os);
|
||||
return os;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RERR
|
||||
//-----------------------------------------------------------------------------
|
||||
RerrHeader::RerrHeader () :
|
||||
m_flag (0), m_reserved (0)
|
||||
{
|
||||
}
|
||||
|
||||
TypeId
|
||||
RerrHeader::GetInstanceTypeId () const
|
||||
{
|
||||
return TypeId ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RerrHeader::GetSerializedSize () const
|
||||
{
|
||||
return (3 + 8 * GetDestCount ());
|
||||
}
|
||||
|
||||
void
|
||||
RerrHeader::Serialize (Buffer::Iterator i ) const
|
||||
{
|
||||
i.WriteU8 (m_flag);
|
||||
i.WriteU8 (m_reserved);
|
||||
i.WriteU8 (GetDestCount ());
|
||||
std::map<Ipv4Address, uint32_t>::const_iterator j;
|
||||
for (j = m_unreachableDstSeqNo.begin (); j != m_unreachableDstSeqNo.end (); ++j)
|
||||
{
|
||||
WriteTo (i, (*j).first);
|
||||
i.WriteHtonU32 ((*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RerrHeader::Deserialize (Buffer::Iterator start )
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
m_flag = i.ReadU8 ();
|
||||
m_reserved = i.ReadU8 ();
|
||||
uint8_t dest = i.ReadU8 ();
|
||||
m_unreachableDstSeqNo.clear ();
|
||||
Ipv4Address address;
|
||||
uint32_t seqNo;
|
||||
for (uint8_t k = 0; k < dest; ++k)
|
||||
{
|
||||
ReadFrom (i, address);
|
||||
seqNo = i.ReadNtohU32 ();
|
||||
m_unreachableDstSeqNo.insert (std::make_pair (address, seqNo));
|
||||
}
|
||||
|
||||
uint32_t dist = i.GetDistanceFrom (start);
|
||||
NS_ASSERT (dist == GetSerializedSize ());
|
||||
return dist;
|
||||
}
|
||||
|
||||
void
|
||||
RerrHeader::Print (std::ostream &os ) const
|
||||
{
|
||||
os << "Unreachable destination (ipv4 address, seq. number):\n";
|
||||
std::map<Ipv4Address, uint32_t>::const_iterator j;
|
||||
for (j = m_unreachableDstSeqNo.begin (); j != m_unreachableDstSeqNo.end (); ++j)
|
||||
{
|
||||
os << (*j).first << ", " << (*j).second << "\n";
|
||||
}
|
||||
os << "No delete flag " << (*this).GetNoDelete () << "\n";
|
||||
}
|
||||
|
||||
void
|
||||
RerrHeader::SetNoDelete (bool f )
|
||||
{
|
||||
if (f)
|
||||
m_flag |= (1 << 0);
|
||||
else
|
||||
m_flag &= ~(1 << 0);
|
||||
}
|
||||
|
||||
bool
|
||||
RerrHeader::GetNoDelete () const
|
||||
{
|
||||
return (m_flag & (1 << 0));
|
||||
}
|
||||
|
||||
bool
|
||||
RerrHeader::AddUnDestination (Ipv4Address dst, uint32_t seqNo )
|
||||
{
|
||||
if (m_unreachableDstSeqNo.find (dst) != m_unreachableDstSeqNo.end ())
|
||||
return true;
|
||||
|
||||
NS_ASSERT (GetDestCount() < 255); // can't support more than 255 destinations in single RERR
|
||||
m_unreachableDstSeqNo.insert (std::make_pair (dst, seqNo));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RerrHeader::RemoveUnDestination (std::pair<Ipv4Address, uint32_t> & un )
|
||||
{
|
||||
if (m_unreachableDstSeqNo.empty ())
|
||||
return false;
|
||||
std::map<Ipv4Address, uint32_t>::iterator i = m_unreachableDstSeqNo.begin ();
|
||||
un = *i;
|
||||
m_unreachableDstSeqNo.erase (i);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RerrHeader::Clear ()
|
||||
{
|
||||
m_unreachableDstSeqNo.clear ();
|
||||
m_flag = 0;
|
||||
m_reserved = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
RerrHeader::operator== (RerrHeader const & o ) const
|
||||
{
|
||||
if (m_flag != o.m_flag || m_reserved != o.m_reserved || GetDestCount () != o.GetDestCount ())
|
||||
return false;
|
||||
|
||||
std::map<Ipv4Address, uint32_t>::const_iterator j = m_unreachableDstSeqNo.begin ();
|
||||
std::map<Ipv4Address, uint32_t>::const_iterator k = o.m_unreachableDstSeqNo.begin ();
|
||||
for (uint8_t i = 0; i < GetDestCount (); ++i)
|
||||
{
|
||||
if ((j->first != k->first) || (j->second != k->second))
|
||||
return false;
|
||||
|
||||
j++;
|
||||
k++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator<< (std::ostream & os, RerrHeader const & h )
|
||||
{
|
||||
h.Print (os);
|
||||
return os;
|
||||
}
|
||||
}
|
||||
}
|
||||
330
src/routing/manet/aodv/aodv-packet.h
Normal file
330
src/routing/manet/aodv/aodv-packet.h
Normal file
@@ -0,0 +1,330 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
#ifndef AODVPACKET_H
|
||||
#define AODVPACKET_H
|
||||
|
||||
#include <iostream>
|
||||
#include "ns3/header.h"
|
||||
#include "ns3/enum.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include <map>
|
||||
#include "ns3/nstime.h"
|
||||
|
||||
namespace ns3 {
|
||||
namespace aodv {
|
||||
|
||||
enum MessageType
|
||||
{
|
||||
AODVTYPE_RREQ = 1, //!< AODVTYPE_RREQ
|
||||
AODVTYPE_RREP = 2, //!< AODVTYPE_RREP
|
||||
AODVTYPE_RERR = 3, //!< AODVTYPE_RERR
|
||||
AODVTYPE_RREP_ACK = 4 //!< AODVTYPE_RREP_ACK
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief AODV types
|
||||
*/
|
||||
class TypeHeader : public Header
|
||||
{
|
||||
public:
|
||||
/// c-tor
|
||||
TypeHeader (MessageType t);
|
||||
|
||||
///\name Header serialization/deserialization
|
||||
//\{
|
||||
TypeId GetInstanceTypeId () const;
|
||||
uint32_t GetSerializedSize () const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
void Print (std::ostream &os) const;
|
||||
//\}
|
||||
|
||||
/// Return type
|
||||
MessageType Get () const { return m_type; }
|
||||
/// Check that type if valid
|
||||
bool IsValid () const { return m_valid; }
|
||||
bool operator== (TypeHeader const & o) const;
|
||||
private:
|
||||
MessageType m_type;
|
||||
bool m_valid;
|
||||
};
|
||||
|
||||
std::ostream & operator<< (std::ostream & os, TypeHeader const & h);
|
||||
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief Route Request (RREQ) Message Format
|
||||
\verbatim
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Type |J|R|G|D|U| Reserved | Hop Count |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| RREQ ID |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Destination IP Address |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Destination Sequence Number |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Originator IP Address |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Originator Sequence Number |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
\endverbatim
|
||||
*/
|
||||
class RreqHeader : public Header
|
||||
{
|
||||
public:
|
||||
/// c-tor
|
||||
RreqHeader (uint8_t flags = 0, uint8_t reserved = 0, uint8_t hopCount = 0,
|
||||
uint32_t requestID = 0, Ipv4Address dst = Ipv4Address (),
|
||||
uint32_t dstSeqNo = 0, Ipv4Address origin = Ipv4Address (),
|
||||
uint32_t originSeqNo = 0);
|
||||
|
||||
///\name Header serialization/deserialization
|
||||
//\{
|
||||
TypeId GetInstanceTypeId () const;
|
||||
uint32_t GetSerializedSize () const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
void Print (std::ostream &os) const;
|
||||
//\}
|
||||
|
||||
///\name Fields
|
||||
//\{
|
||||
void SetHopCount (uint8_t count) { m_hopCount = count; }
|
||||
uint8_t GetHopCount () const { return m_hopCount; }
|
||||
void SetId (uint32_t id) { m_requestID = id; }
|
||||
uint8_t GetId () const { return m_requestID; }
|
||||
void SetDst (Ipv4Address a) { m_dst = a; }
|
||||
Ipv4Address GetDst () const { return m_dst; }
|
||||
void SetDstSeqno (uint32_t s) { m_dstSeqNo = s; }
|
||||
uint32_t GetDstSeqno () const { return m_dstSeqNo; }
|
||||
void SetOrigin (Ipv4Address a) { m_origin = a; }
|
||||
Ipv4Address GetOrigin () const { return m_origin; }
|
||||
void SetOriginSeqno (uint32_t s) { m_originSeqNo = s; }
|
||||
uint32_t GetOriginSeqno () const { return m_originSeqNo; }
|
||||
//\}
|
||||
|
||||
///\name Flags
|
||||
//\{
|
||||
void SetGratiousRrep (bool f);
|
||||
bool GetGratiousRrep () const;
|
||||
void SetDestinationOnly (bool f);
|
||||
bool GetDestinationOnly () const;
|
||||
void SetUnknownSeqno (bool f);
|
||||
bool GetUnknownSeqno () const;
|
||||
//\}
|
||||
|
||||
bool operator== (RreqHeader const & o) const;
|
||||
private:
|
||||
uint8_t m_flags; ///< |J|R|G|D|U| bit flags, see RFC
|
||||
uint8_t m_reserved; ///< Not used
|
||||
uint8_t m_hopCount; ///< Hop Count
|
||||
uint32_t m_requestID; ///< RREQ ID
|
||||
Ipv4Address m_dst; ///< Destination IP Address
|
||||
uint32_t m_dstSeqNo; ///< Destination Sequence Number
|
||||
Ipv4Address m_origin; ///< Originator IP Address
|
||||
uint32_t m_originSeqNo; ///< Source Sequence Number
|
||||
};
|
||||
|
||||
std::ostream & operator<< (std::ostream & os, RreqHeader const &);
|
||||
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief Route Reply (RREP) Message Format
|
||||
\verbatim
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Type |R|A| Reserved |Prefix Sz| Hop Count |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Destination IP address |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Destination Sequence Number |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Originator IP address |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Lifetime |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
\endverbatim
|
||||
*/
|
||||
class RrepHeader : public Header
|
||||
{
|
||||
public:
|
||||
/// c-tor
|
||||
RrepHeader (uint8_t prefixSize = 0, uint8_t hopCount = 0, Ipv4Address dst =
|
||||
Ipv4Address (), uint32_t dstSeqNo = 0, Ipv4Address origin =
|
||||
Ipv4Address (), Time lifetime = MilliSeconds (0));
|
||||
///\name Header serialization/deserialization
|
||||
//\{
|
||||
TypeId GetInstanceTypeId () const;
|
||||
uint32_t GetSerializedSize () const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
void Print (std::ostream &os) const;
|
||||
//\}
|
||||
|
||||
///\name Fields
|
||||
//\{
|
||||
void SetHopCount (uint8_t count) { m_hopCount = count; }
|
||||
uint8_t GetHopCount () const { return m_hopCount; }
|
||||
void SetDst (Ipv4Address a) { m_dst = a; }
|
||||
Ipv4Address GetDst () const { return m_dst; }
|
||||
void SetDstSeqno (uint32_t s) { m_dstSeqNo = s; }
|
||||
uint32_t GetDstSeqno () const { return m_dstSeqNo; }
|
||||
void SetOrigin (Ipv4Address a) { m_origin = a; }
|
||||
Ipv4Address GetOrigin () const { return m_origin; }
|
||||
void SetLifeTime (Time t);
|
||||
Time GetLifeTime () const;
|
||||
//\}
|
||||
|
||||
///\name Flags
|
||||
//\{
|
||||
void SetAckRequired (bool f);
|
||||
bool GetAckRequired () const;
|
||||
void SetPrefixSize (uint8_t sz);
|
||||
uint8_t GetPrefixSize () const;
|
||||
//\}
|
||||
|
||||
/// Configure RREP to be a Hello message
|
||||
void SetHello (Ipv4Address src, uint32_t srcSeqNo, Time lifetime);
|
||||
|
||||
bool operator== (RrepHeader const & o) const;
|
||||
private:
|
||||
uint8_t m_flags; ///< A - acknowledgment required flag
|
||||
uint8_t m_prefixSize; ///< Prefix Size
|
||||
uint8_t m_hopCount; ///< Hop Count
|
||||
Ipv4Address m_dst; ///< Destination IP Address
|
||||
uint32_t m_dstSeqNo; ///< Destination Sequence Number
|
||||
Ipv4Address m_origin; ///< Source IP Address
|
||||
uint32_t m_lifeTime; ///< Lifetime (in milliseconds)
|
||||
};
|
||||
|
||||
std::ostream & operator<< (std::ostream & os, RrepHeader const &);
|
||||
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief Route Reply Acknowledgment (RREP-ACK) Message Format
|
||||
\verbatim
|
||||
0 1
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Type | Reserved |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
\endverbatim
|
||||
*/
|
||||
class RrepAckHeader : public Header
|
||||
{
|
||||
public:
|
||||
/// c-tor
|
||||
RrepAckHeader ();
|
||||
|
||||
///\name Header serialization/deserialization
|
||||
//\{
|
||||
TypeId GetInstanceTypeId () const;
|
||||
uint32_t GetSerializedSize () const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
void Print (std::ostream &os) const;
|
||||
//\}
|
||||
|
||||
bool operator== (RrepAckHeader const & o) const;
|
||||
private:
|
||||
uint8_t m_reserved;
|
||||
};
|
||||
std::ostream & operator<< (std::ostream & os, RrepAckHeader const &);
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief Route Error (RERR) Message Format
|
||||
\verbatim
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Type |N| Reserved | DestCount |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Unreachable Destination IP Address (1) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Unreachable Destination Sequence Number (1) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
|
||||
| Additional Unreachable Destination IP Addresses (if needed) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|Additional Unreachable Destination Sequence Numbers (if needed)|
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
\endverbatim
|
||||
*/
|
||||
class RerrHeader : public Header
|
||||
{
|
||||
public:
|
||||
/// c-tor
|
||||
RerrHeader ();
|
||||
|
||||
///\name Header serialization/deserialization
|
||||
//\{
|
||||
TypeId GetInstanceTypeId () const;
|
||||
uint32_t GetSerializedSize () const;
|
||||
void Serialize (Buffer::Iterator i) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
void Print (std::ostream &os) const;
|
||||
//\}
|
||||
|
||||
///\name No delete flag
|
||||
//\{
|
||||
void SetNoDelete (bool f);
|
||||
bool GetNoDelete () const;
|
||||
//\}
|
||||
|
||||
/**
|
||||
* Add unreachable node address and its sequence number in RERR header
|
||||
*\return false if we already added maximum possible number of unreachable destinations
|
||||
*/
|
||||
bool AddUnDestination (Ipv4Address dst, uint32_t seqNo);
|
||||
/** Delete pair (address + sequence number) from REER header, if the number of unreachable destinations > 0
|
||||
* \return true on success
|
||||
*/
|
||||
bool RemoveUnDestination (std::pair<Ipv4Address, uint32_t> & un);
|
||||
/// Clear header
|
||||
void Clear();
|
||||
/// Return number of unreachable destinations in RERR message
|
||||
uint8_t GetDestCount () const { return (uint8_t)m_unreachableDstSeqNo.size(); }
|
||||
bool operator== (RerrHeader const & o) const;
|
||||
private:
|
||||
uint8_t m_flag; ///< No delete flag
|
||||
uint8_t m_reserved; ///< Not used
|
||||
|
||||
/// List of Unreachable destination: IP addresses and sequence numbers
|
||||
std::map<Ipv4Address, uint32_t> m_unreachableDstSeqNo;
|
||||
};
|
||||
|
||||
std::ostream & operator<< (std::ostream & os, RerrHeader const &);
|
||||
}
|
||||
}
|
||||
#endif /* AODVPACKET_H */
|
||||
1498
src/routing/manet/aodv/aodv-routing-protocol.cc
Normal file
1498
src/routing/manet/aodv/aodv-routing-protocol.cc
Normal file
File diff suppressed because it is too large
Load Diff
254
src/routing/manet/aodv/aodv-routing-protocol.h
Normal file
254
src/routing/manet/aodv/aodv-routing-protocol.h
Normal file
@@ -0,0 +1,254 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
#ifndef AODVROUTINGPROTOCOL_H
|
||||
#define AODVROUTINGPROTOCOL_H
|
||||
|
||||
#include "aodv-rtable.h"
|
||||
#include "aodv-rqueue.h"
|
||||
#include "aodv-packet.h"
|
||||
#include "aodv-neighbor.h"
|
||||
|
||||
#include "ns3/dpd.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/ipv4-routing-protocol.h"
|
||||
#include "ns3/ipv4-interface.h"
|
||||
#include "ns3/ipv4-l3-protocol.h"
|
||||
#include <map>
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace aodv
|
||||
{
|
||||
/**
|
||||
* \ingroup aodv
|
||||
*
|
||||
* \brief AODV routing protocol
|
||||
*/
|
||||
class RoutingProtocol : public Ipv4RoutingProtocol
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
static const uint32_t AODV_PORT;
|
||||
|
||||
/// c-tor
|
||||
RoutingProtocol ();
|
||||
virtual ~RoutingProtocol();
|
||||
virtual void DoDispose ();
|
||||
|
||||
///\name From Ipv4RoutingProtocol
|
||||
//\{
|
||||
Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, uint32_t oif, Socket::SocketErrno &sockerr);
|
||||
bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
|
||||
UnicastForwardCallback ucb, MulticastForwardCallback mcb,
|
||||
LocalDeliverCallback lcb, ErrorCallback ecb);
|
||||
virtual void NotifyInterfaceUp (uint32_t interface);
|
||||
virtual void NotifyInterfaceDown (uint32_t interface);
|
||||
virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
|
||||
virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
|
||||
virtual void SetIpv4 (Ptr<Ipv4> ipv4);
|
||||
//\}
|
||||
|
||||
///\name Handle protocol parameters
|
||||
//\{
|
||||
bool GetDesinationOnlyFlag () const { return DestinationOnly; }
|
||||
void SetDesinationOnlyFlag (bool f) { DestinationOnly = f; }
|
||||
bool GetGratuitousReplyFlag () const { return GratuitousReply; }
|
||||
void SetGratuitousReplyFlag (bool f) { GratuitousReply = f; }
|
||||
void SetHelloEnable (bool f) { EnableHello = f; }
|
||||
bool GetHelloEnable () const { return EnableHello; }
|
||||
void SetBroadcastEnable (bool f) { EnableBroadcast = f; }
|
||||
bool GetBroadcastEnable () const { return EnableBroadcast; }
|
||||
//\}
|
||||
private:
|
||||
///\name Protocol parameters.
|
||||
//\{
|
||||
uint32_t RreqRetries; ///< Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route
|
||||
uint16_t RreqRateLimit; ///< Maximum number of RREQ per second.
|
||||
Time ActiveRouteTimeout; ///< Period of time during which the route is considered to be valid.
|
||||
uint32_t NetDiameter; ///< Net diameter measures the maximum possible number of hops between two nodes in the network
|
||||
/**
|
||||
* NodeTraversalTime is a conservative estimate of the average one hop traversal time for packets
|
||||
* and should include queuing delays, interrupt processing times and transfer times.
|
||||
*/
|
||||
Time NodeTraversalTime;
|
||||
Time NetTraversalTime; ///< Estimate of the average net traversal time.
|
||||
Time PathDiscoveryTime; ///< Estimate of maximum time needed to find route in network.
|
||||
Time MyRouteTimeout; ///< Value of lifetime field in RREP generating by this node.
|
||||
/**
|
||||
* Every HelloInterval the node checks whether it has sent a broadcast within the last HelloInterval.
|
||||
* If it has not, it MAY broadcast a Hello message
|
||||
*/
|
||||
Time HelloInterval;
|
||||
uint32_t AllowedHelloLoss; ///< Number of hello messages which may be loss for valid link
|
||||
/**
|
||||
* DeletePeriod is intended to provide an upper bound on the time for which an upstream node A
|
||||
* can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D.
|
||||
*/
|
||||
Time DeletePeriod;
|
||||
Time NextHopWait; ///< Period of our waiting for the neighbour's RREP_ACK
|
||||
/**
|
||||
* The TimeoutBuffer is configurable. Its purpose is to provide a buffer for the timeout so that if the RREP is delayed
|
||||
* due to congestion, a timeout is less likely to occur while the RREP is still en route back to the source.
|
||||
*/
|
||||
uint16_t TimeoutBuffer;
|
||||
Time BlackListTimeout; ///< Time for which the node is put into the blacklist
|
||||
uint32_t MaxQueueLen; ///< The maximum number of packets that we allow a routing protocol to buffer.
|
||||
Time MaxQueueTime; ///< The maximum period of time that a routing protocol is allowed to buffer a packet for.
|
||||
bool DestinationOnly; ///< Indicates only the destination may respond to this RREQ.
|
||||
bool GratuitousReply; ///< Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.
|
||||
bool EnableHello; ///< Indicates whether a hello messages enable
|
||||
bool EnableBroadcast; ///< Indicates whether a a broadcast data packets forwarding enable
|
||||
//\}
|
||||
|
||||
/// IP protocol
|
||||
Ptr<Ipv4> m_ipv4;
|
||||
/// Raw socket per each IP interface, map socket -> iface address (IP + mask)
|
||||
std::map< Ptr<Socket>, Ipv4InterfaceAddress > m_socketAddresses;
|
||||
|
||||
/// Routing table
|
||||
RoutingTable m_routingTable;
|
||||
/// A "drop-front" queue used by the routing layer to buffer packets to which it does not have a route.
|
||||
RequestQueue m_queue;
|
||||
/// Broadcast ID
|
||||
uint32_t m_requestId;
|
||||
/// Request sequence number
|
||||
uint32_t m_seqNo;
|
||||
/// Handle duplicated RREQ
|
||||
dpd::IdCache m_rreqIdCache;
|
||||
/// Handle duplicated broadcast/multicast packets
|
||||
dpd::DuplicatePacketDetection m_dpd;
|
||||
/// Handle neighbors
|
||||
Neighbors m_nb;
|
||||
/// Number of RREQs used for RREQ rate control
|
||||
uint16_t m_rreqCount;
|
||||
|
||||
/// Unicast callback for own packets
|
||||
UnicastForwardCallback m_scb;
|
||||
/// Error callback for own packets
|
||||
ErrorCallback m_ecb;
|
||||
|
||||
private:
|
||||
/// Start protocol operation
|
||||
void Start ();
|
||||
/// If route exists and valid, forward packet.
|
||||
bool Forwarding (Ptr<const Packet> p, const Ipv4Header & header, UnicastForwardCallback ucb, ErrorCallback ecb);
|
||||
/**
|
||||
* To reduce congestion in a network, repeated attempts by a source node at route discovery
|
||||
* for a single destination MUST utilize a binary exponential backoff.
|
||||
*/
|
||||
void ScheduleRreqRetry (Ipv4Address dst);
|
||||
/**
|
||||
* Set lifetime field in routing table entry to the maximum of existing lifetime and lt, if the entry exists
|
||||
* \param addr - destination address
|
||||
* \param lt - proposed time for lifetime field in routing table entry for destination with address addr.
|
||||
* \return true if route to destination address addr exist
|
||||
*/
|
||||
bool UpdateRouteLifeTime (Ipv4Address addr, Time lt);
|
||||
/**
|
||||
* Update neighbor record.
|
||||
* \param receiver is supposed to be my interface
|
||||
* \param sender is supposed to be IP address of my neighbor.
|
||||
*/
|
||||
void UpdateRouteToNeighbor (Ipv4Address sender, Ipv4Address receiver);
|
||||
/// Check that packet is send from own interface
|
||||
bool IsMyOwnAddress (Ipv4Address src);
|
||||
/// Find socket with local interface address iface
|
||||
Ptr<Socket> FindSocketWithInterfaceAddress (Ipv4InterfaceAddress iface) const;
|
||||
/// Process hello message
|
||||
void ProcessHello (RrepHeader const & rrepHeader, Ipv4Address receiverIfaceAddr);
|
||||
|
||||
///\name Receive control packets
|
||||
//\{
|
||||
/// Receive and process control packet
|
||||
void RecvAodv (Ptr<Socket> socket);
|
||||
/// Receive RREQ
|
||||
void RecvRequest (Ptr<Packet> p, Ipv4Address receiver, Ipv4Address src);
|
||||
/// Receive RREP
|
||||
void RecvReply (Ptr<Packet> p, Ipv4Address my ,Ipv4Address src);
|
||||
/// Receive RREP_ACK
|
||||
void RecvReplyAck (Ipv4Address neighbor);
|
||||
/// Receive RERR from node with address src
|
||||
void RecvError (Ptr<Packet> p, Ipv4Address src);
|
||||
//\}
|
||||
|
||||
///\name Send
|
||||
//\{
|
||||
/// Forward packet from route request queue
|
||||
void SendPacketFromQueue (Ipv4Address dst, Ptr<Ipv4Route> route);
|
||||
/// Aux. send helper
|
||||
void Send (Ptr<Ipv4Route>, Ptr<const Packet>, const Ipv4Header &);
|
||||
/// Send hello
|
||||
void SendHello ();
|
||||
/// Send RREQ
|
||||
void SendRequest (Ipv4Address dst);
|
||||
/// Send RREP
|
||||
void SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin);
|
||||
/** Send RREP by intermediate node
|
||||
* \param toDst routing table entry to destination
|
||||
* \param toOrigin routing table entry to originator
|
||||
* \param gratRep indicates whether a gratuitous RREP should be unicast to destination
|
||||
*/
|
||||
void SendReplyByIntermediateNode (RoutingTableEntry & toDst, RoutingTableEntry & toOrigin, bool gratRep);
|
||||
/// Send RREP_ACK
|
||||
void SendReplyAck (Ipv4Address neighbor);
|
||||
/// Initiate RERR
|
||||
void SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop);
|
||||
/// Forward RERR
|
||||
void SendRerrMessage(Ptr<Packet> packet, std::vector<Ipv4Address> precursors);
|
||||
/**
|
||||
* Send RERR message when no route to forward input packet. Unicast if there is reverse route to originating node, broadcast otherwise.
|
||||
* \param dst - destination node IP address
|
||||
* \param dstSeqNo - destination node sequence number
|
||||
* \param origin - originating node IP address
|
||||
*/
|
||||
void SendRerrWhenNoRouteToForward (Ipv4Address dst, uint32_t dstSeqNo, Ipv4Address origin);
|
||||
//\}
|
||||
|
||||
/// Notify that packet is dropped for some reason
|
||||
void Drop(Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno);
|
||||
|
||||
/// Hello timer
|
||||
Timer m_htimer;
|
||||
/// Schedule next send of hello message
|
||||
void HelloTimerExpire ();
|
||||
/// RREQ rate limit timer
|
||||
Timer m_rreqRateLimitTimer;
|
||||
/// Reset RREQ count and schedule RREQ rate limit timer with delay 1 sec.
|
||||
void RreqRateLimitTimerExpire ();
|
||||
/// Map IP address + RREQ timer.
|
||||
std::map<Ipv4Address, Timer> m_addressReqTimer;
|
||||
/// Handle route discovery process
|
||||
void RouteRequestTimerExpire (Ipv4Address dst);
|
||||
/// Mark link to neighbor node as unidirectional for blacklistTimeout
|
||||
void AckTimerExpire (Ipv4Address neighbor, Time blacklistTimeout);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* AODVROUTINGPROTOCOL_H */
|
||||
151
src/routing/manet/aodv/aodv-rqueue.cc
Normal file
151
src/routing/manet/aodv/aodv-rqueue.cc
Normal file
@@ -0,0 +1,151 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
#include "aodv-rqueue.h"
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include "ns3/ipv4-route.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("AodvRequestQueue");
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace aodv
|
||||
{
|
||||
uint32_t
|
||||
RequestQueue::GetSize ()
|
||||
{
|
||||
Purge ();
|
||||
return m_queue.size ();
|
||||
}
|
||||
|
||||
bool
|
||||
RequestQueue::Enqueue (QueueEntry & entry)
|
||||
{
|
||||
Purge ();
|
||||
for (std::vector<QueueEntry>::const_iterator i = m_queue.begin (); i
|
||||
!= m_queue.end (); ++i)
|
||||
{
|
||||
if ((i->GetPacket ()->GetUid () == entry.GetPacket ()->GetUid ())
|
||||
&& (i->GetIpv4Header ().GetDestination ()
|
||||
== entry.GetIpv4Header ().GetDestination ()))
|
||||
return false;
|
||||
}
|
||||
entry.SetExpireTime (m_queueTimeout);
|
||||
if (m_queue.size () == m_maxLen)
|
||||
{
|
||||
Drop (m_queue.front (), "Drop the most aged packet"); // Drop the most aged packet
|
||||
m_queue.erase (m_queue.begin ());
|
||||
}
|
||||
m_queue.push_back (entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RequestQueue::DropPacketWithDst (Ipv4Address dst)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst);
|
||||
Purge ();
|
||||
const Ipv4Address addr = dst;
|
||||
for (std::vector<QueueEntry>::iterator i = m_queue.begin (); i
|
||||
!= m_queue.end (); ++i)
|
||||
{
|
||||
if (IsEqual (*i, dst))
|
||||
{
|
||||
Drop (*i, "DropPacketWithDst ");
|
||||
}
|
||||
}
|
||||
m_queue.erase (std::remove_if (m_queue.begin (), m_queue.end (),
|
||||
std::bind2nd (std::ptr_fun (RequestQueue::IsEqual), dst)), m_queue.end ());
|
||||
}
|
||||
|
||||
bool
|
||||
RequestQueue::Dequeue (Ipv4Address dst, QueueEntry & entry)
|
||||
{
|
||||
Purge ();
|
||||
for (std::vector<QueueEntry>::iterator i = m_queue.begin (); i != m_queue.end (); ++i)
|
||||
{
|
||||
if (i->GetIpv4Header ().GetDestination () == dst)
|
||||
{
|
||||
entry = *i;
|
||||
m_queue.erase (i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RequestQueue::Find (Ipv4Address dst)
|
||||
{
|
||||
for (std::vector<QueueEntry>::const_iterator i = m_queue.begin (); i
|
||||
!= m_queue.end (); ++i)
|
||||
{
|
||||
if (i->GetIpv4Header ().GetDestination () == dst)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct IsExpired
|
||||
{
|
||||
bool
|
||||
operator() (QueueEntry const & e) const
|
||||
{
|
||||
return (e.GetExpireTime () < Seconds (0));
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
RequestQueue::Purge ()
|
||||
{
|
||||
IsExpired pred;
|
||||
for (std::vector<QueueEntry>::iterator i = m_queue.begin (); i
|
||||
!= m_queue.end (); ++i)
|
||||
{
|
||||
if (pred (*i))
|
||||
{
|
||||
Drop (*i, "Drop outdated packet ");
|
||||
}
|
||||
}
|
||||
m_queue.erase (std::remove_if (m_queue.begin (), m_queue.end (), pred),
|
||||
m_queue.end ());
|
||||
}
|
||||
|
||||
void
|
||||
RequestQueue::Drop (QueueEntry en, std::string reason)
|
||||
{
|
||||
NS_LOG_LOGIC (reason << en.GetPacket ()->GetUid () << " " << en.GetIpv4Header ().GetDestination ());
|
||||
en.GetErrorCallback () (en.GetPacket (), en.GetIpv4Header (),
|
||||
Socket::ERROR_NOROUTETOHOST);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
137
src/routing/manet/aodv/aodv-rqueue.h
Normal file
137
src/routing/manet/aodv/aodv-rqueue.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
#ifndef AODV_RQUEUE_H
|
||||
#define AODV_RQUEUE_H
|
||||
|
||||
#include <vector>
|
||||
#include "ns3/ipv4-routing-protocol.h"
|
||||
#include "ns3/simulator.h"
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
namespace aodv {
|
||||
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief AODV Queue Entry
|
||||
*/
|
||||
class QueueEntry
|
||||
{
|
||||
public:
|
||||
typedef Ipv4RoutingProtocol::UnicastForwardCallback UnicastForwardCallback;
|
||||
typedef Ipv4RoutingProtocol::ErrorCallback ErrorCallback;
|
||||
/// c-tor
|
||||
QueueEntry (Ptr<const Packet> pa = 0, Ipv4Header const & h = Ipv4Header (),
|
||||
UnicastForwardCallback ucb = UnicastForwardCallback (),
|
||||
ErrorCallback ecb = ErrorCallback (), Time exp = Simulator::Now ()) :
|
||||
m_packet (pa), m_header (h), m_ucb (ucb), m_ecb (ecb),
|
||||
m_expire (exp + Simulator::Now ())
|
||||
{}
|
||||
|
||||
/**
|
||||
* Compare queue entries
|
||||
* \return true if equal
|
||||
*/
|
||||
bool operator== (QueueEntry const & o) const
|
||||
{
|
||||
return ((m_packet == o.m_packet) && (m_header.GetDestination () == o.m_header.GetDestination ()) && (m_expire == o.m_expire));
|
||||
}
|
||||
///\name Fields
|
||||
//\{
|
||||
UnicastForwardCallback GetUnicastForwardCallback () const { return m_ucb; }
|
||||
void SetUnicastForwardCallback (UnicastForwardCallback ucb) { m_ucb = ucb; }
|
||||
ErrorCallback GetErrorCallback () const { return m_ecb; }
|
||||
void SetErrorCallback (ErrorCallback ecb) { m_ecb = ecb; }
|
||||
Ptr<const Packet> GetPacket () const { return m_packet; }
|
||||
void SetPacket (Ptr<const Packet> p) { m_packet = p; }
|
||||
Ipv4Header GetIpv4Header() const { return m_header; }
|
||||
void SetIpv4Header (Ipv4Header h) { m_header = h; }
|
||||
void SetExpireTime (Time exp) { m_expire = exp + Simulator::Now(); }
|
||||
Time GetExpireTime () const { return m_expire - Simulator::Now(); }
|
||||
//\}
|
||||
private:
|
||||
/// Data packet
|
||||
Ptr<const Packet> m_packet;
|
||||
/// IP header
|
||||
Ipv4Header m_header;
|
||||
/// Unicast forward callback
|
||||
UnicastForwardCallback m_ucb;
|
||||
/// Error callback
|
||||
ErrorCallback m_ecb;
|
||||
/// Expire time for queue entry
|
||||
Time m_expire;
|
||||
};
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief AODV route request queue
|
||||
*
|
||||
* Since AODV is an on demand routing we queue requests while looking for route.
|
||||
*/
|
||||
class RequestQueue
|
||||
{
|
||||
public:
|
||||
/// Default c-tor
|
||||
RequestQueue (uint32_t maxLen, Time routeToQueueTimeout) :
|
||||
m_maxLen (maxLen), m_queueTimeout (routeToQueueTimeout)
|
||||
{
|
||||
}
|
||||
/// Push entry in queue, if there is no entry with the same packet and destination address in queue.
|
||||
bool Enqueue (QueueEntry & entry);
|
||||
/// Return first found (the earliest) entry for given destination
|
||||
bool Dequeue (Ipv4Address dst, QueueEntry & entry);
|
||||
/// Remove all packets with destination IP address dst
|
||||
void DropPacketWithDst (Ipv4Address dst);
|
||||
/// Finds whether a packet with destination dst exists in the queue
|
||||
bool Find (Ipv4Address dst);
|
||||
/// Number of entries
|
||||
uint32_t GetSize ();
|
||||
///\name Fields
|
||||
//\{
|
||||
uint32_t GetMaxQueueLen () const { return m_maxLen; }
|
||||
void SetMaxQueueLen (uint32_t len) { m_maxLen = len; }
|
||||
Time GetQueueTimeout () const { return m_queueTimeout; }
|
||||
void SetQueueTimeout (Time t) { m_queueTimeout = t; }
|
||||
//\}
|
||||
|
||||
private:
|
||||
std::vector<QueueEntry> m_queue;
|
||||
/// Remove all expired entries
|
||||
void Purge ();
|
||||
/// Notify that packet is dropped from queue by timeout
|
||||
void Drop (QueueEntry en, std::string reason);
|
||||
/// The maximum number of packets that we allow a routing protocol to buffer.
|
||||
uint32_t m_maxLen;
|
||||
/// The maximum period of time that a routing protocol is allowed to buffer a packet for, seconds.
|
||||
Time m_queueTimeout;
|
||||
static bool IsEqual (QueueEntry en, const Ipv4Address dst) { return (en.GetIpv4Header ().GetDestination () == dst); }
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif /* AODV_RQUEUE_H */
|
||||
344
src/routing/manet/aodv/aodv-rtable.cc
Normal file
344
src/routing/manet/aodv/aodv-rtable.cc
Normal file
@@ -0,0 +1,344 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
#include "aodv-rtable.h"
|
||||
#include <algorithm>
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("AodvRoutingTable");
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace aodv
|
||||
{
|
||||
|
||||
/*
|
||||
The Routing Table
|
||||
*/
|
||||
|
||||
RoutingTableEntry::RoutingTableEntry (Ptr<NetDevice> dev, Ipv4Address dst, bool vSeqNo, u_int32_t seqNo,
|
||||
Ipv4InterfaceAddress iface, u_int16_t hops, Ipv4Address nextHop, Time lifetime) :
|
||||
m_ackTimer (Timer::CANCEL_ON_DESTROY),
|
||||
m_validSeqNo (vSeqNo), m_seqNo (seqNo), m_hops (hops),
|
||||
m_lifeTime (lifetime + Simulator::Now ()), m_iface (iface), m_flag (VALID),
|
||||
m_reqCount (0), m_blackListState (false), m_blackListTimeout (Simulator::Now ())
|
||||
{
|
||||
m_ipv4Route = Create<Ipv4Route> ();
|
||||
m_ipv4Route->SetDestination (dst);
|
||||
m_ipv4Route->SetGateway (nextHop);
|
||||
m_ipv4Route->SetSource (m_iface.GetLocal ());
|
||||
m_ipv4Route->SetOutputDevice (dev);
|
||||
}
|
||||
|
||||
RoutingTableEntry::~RoutingTableEntry ()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
RoutingTableEntry::InsertPrecursor (Ipv4Address id)
|
||||
{
|
||||
if (!LookupPrecursor (id))
|
||||
{
|
||||
m_precursorList.push_back (id);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RoutingTableEntry::LookupPrecursor (Ipv4Address id)
|
||||
{
|
||||
for (std::vector<Ipv4Address>::const_iterator i = m_precursorList.begin (); i
|
||||
!= m_precursorList.end (); ++i)
|
||||
{
|
||||
if (*i == id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RoutingTableEntry::DeletePrecursor (Ipv4Address id)
|
||||
{
|
||||
std::vector<Ipv4Address>::iterator i = std::remove (m_precursorList.begin (),
|
||||
m_precursorList.end (), id);
|
||||
if (i == m_precursorList.end ())
|
||||
return false;
|
||||
else
|
||||
m_precursorList.erase (i, m_precursorList.end ());
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RoutingTableEntry::DeleteAllPrecursors ()
|
||||
{
|
||||
m_precursorList.clear ();
|
||||
}
|
||||
|
||||
bool
|
||||
RoutingTableEntry::IsPrecursorListEmpty () const
|
||||
{
|
||||
return m_precursorList.empty ();
|
||||
}
|
||||
|
||||
void
|
||||
RoutingTableEntry::GetPrecursors (std::vector<Ipv4Address> & prec) const
|
||||
{
|
||||
if (IsPrecursorListEmpty ())
|
||||
return;
|
||||
for (std::vector<Ipv4Address>::const_iterator i = m_precursorList.begin (); i
|
||||
!= m_precursorList.end (); ++i)
|
||||
{
|
||||
bool result = true;
|
||||
for (std::vector<Ipv4Address>::const_iterator j = prec.begin (); j
|
||||
!= prec.end (); ++j)
|
||||
{
|
||||
if (*j == *i)
|
||||
result = false;
|
||||
}
|
||||
if (result)
|
||||
prec.push_back (*i);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoutingTableEntry::Invalidate (Time badLinkLifetime)
|
||||
{
|
||||
if (m_flag == INVALID)
|
||||
return;
|
||||
m_flag = INVALID;
|
||||
m_reqCount = 0;
|
||||
m_lifeTime = badLinkLifetime + Simulator::Now ();
|
||||
}
|
||||
|
||||
void
|
||||
RoutingTableEntry::Print (std::ostream & os) const
|
||||
{
|
||||
os << m_ipv4Route->GetDestination () << "\t" << m_ipv4Route->GetGateway ()
|
||||
<< "\t" << m_iface.GetLocal () << "\t";
|
||||
switch (m_flag)
|
||||
{
|
||||
case VALID:
|
||||
{
|
||||
os << "UP";
|
||||
break;
|
||||
}
|
||||
case INVALID:
|
||||
{
|
||||
os << "DOWN";
|
||||
break;
|
||||
}
|
||||
case IN_SEARCH:
|
||||
{
|
||||
os << "IN_SEARCH";
|
||||
break;
|
||||
}
|
||||
}
|
||||
os << "\t" << (m_lifeTime - Simulator::Now ()).GetSeconds () << "\t"
|
||||
<< m_hops << "\n";
|
||||
}
|
||||
|
||||
/*
|
||||
The Routing Table
|
||||
*/
|
||||
|
||||
RoutingTable::RoutingTable (Time t) :
|
||||
m_badLinkLifetime (t)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
RoutingTable::LookupRoute (Ipv4Address id, RoutingTableEntry & rt)
|
||||
{
|
||||
Purge ();
|
||||
if (m_ipv4AddressEntry.empty ())
|
||||
return false;
|
||||
std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
|
||||
m_ipv4AddressEntry.find (id);
|
||||
if (i == m_ipv4AddressEntry.end ())
|
||||
return false;
|
||||
rt = i->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RoutingTable::DeleteRoute (Ipv4Address dst)
|
||||
{
|
||||
Purge ();
|
||||
if (m_ipv4AddressEntry.erase (dst) != 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RoutingTable::AddRoute (RoutingTableEntry & rt)
|
||||
{
|
||||
if (rt.GetFlag () != IN_SEARCH)
|
||||
rt.SetRreqCnt (0);
|
||||
std::pair<std::map<Ipv4Address, RoutingTableEntry>::iterator, bool> result =
|
||||
m_ipv4AddressEntry.insert (std::make_pair (rt.GetDestination (), rt));
|
||||
return result.second;
|
||||
}
|
||||
|
||||
bool
|
||||
RoutingTable::Update (RoutingTableEntry & rt)
|
||||
{
|
||||
std::map<Ipv4Address, RoutingTableEntry>::iterator i =
|
||||
m_ipv4AddressEntry.find (rt.GetDestination ());
|
||||
if (i == m_ipv4AddressEntry.end ())
|
||||
return false;
|
||||
i->second = rt;
|
||||
if (i->second.GetFlag () != IN_SEARCH)
|
||||
i->second.SetRreqCnt (0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RoutingTable::SetEntryState (Ipv4Address id, RouteFlags state)
|
||||
{
|
||||
std::map<Ipv4Address, RoutingTableEntry>::iterator i =
|
||||
m_ipv4AddressEntry.find (id);
|
||||
if (i == m_ipv4AddressEntry.end ())
|
||||
return false;
|
||||
i->second.SetFlag (state);
|
||||
i->second.SetRreqCnt (0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RoutingTable::GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable )
|
||||
{
|
||||
Purge ();
|
||||
unreachable.clear ();
|
||||
for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
|
||||
m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
|
||||
{
|
||||
if (i->second.GetNextHop () == nextHop)
|
||||
{
|
||||
unreachable.insert (std::make_pair (i->first, i->second.GetSeqNo ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoutingTable::InvalidateRoutesWithDst (const std::map<Ipv4Address, uint32_t> & unreachable)
|
||||
{
|
||||
Purge ();
|
||||
for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
|
||||
m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
|
||||
{
|
||||
for (std::map<Ipv4Address, uint32_t>::const_iterator j =
|
||||
unreachable.begin (); j != unreachable.end (); ++j)
|
||||
{
|
||||
if ((i->first == j->first) && (i->second.GetFlag () == VALID))
|
||||
{
|
||||
NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
|
||||
i->second.Invalidate (m_badLinkLifetime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoutingTable::DeleteAllRoutesFromInterface (Ipv4InterfaceAddress iface)
|
||||
{
|
||||
if (m_ipv4AddressEntry.empty ())
|
||||
return;
|
||||
for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
|
||||
m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end ();)
|
||||
{
|
||||
if (i->second.GetInterface () == iface)
|
||||
{
|
||||
std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
|
||||
++i;
|
||||
m_ipv4AddressEntry.erase (tmp);
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoutingTable::Purge ()
|
||||
{
|
||||
if (m_ipv4AddressEntry.empty ())
|
||||
return;
|
||||
for (std::map<Ipv4Address, RoutingTableEntry>::iterator i =
|
||||
m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end ();)
|
||||
{
|
||||
if (i->second.GetLifeTime () < Seconds (0))
|
||||
{
|
||||
if (i->second.GetFlag () == INVALID)
|
||||
{
|
||||
std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
|
||||
++i;
|
||||
m_ipv4AddressEntry.erase (tmp);
|
||||
}
|
||||
else if (i->second.GetFlag () == VALID)
|
||||
{
|
||||
NS_LOG_LOGIC ("Invalidate route with destination address " << i->first);
|
||||
i->second.Invalidate (m_badLinkLifetime);
|
||||
++i;
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
RoutingTable::MarkLinkAsUnidirectional (Ipv4Address neighbor, Time blacklistTimeout)
|
||||
{
|
||||
std::map<Ipv4Address, RoutingTableEntry>::iterator i =
|
||||
m_ipv4AddressEntry.find (neighbor);
|
||||
if (i == m_ipv4AddressEntry.end ())
|
||||
return false;
|
||||
i->second.SetUnidirectional (true);
|
||||
i->second.SetBalcklistTimeout (blacklistTimeout);
|
||||
i->second.SetRreqCnt (0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RoutingTable::Print (std::ostream &os)
|
||||
{
|
||||
Purge ();
|
||||
os << "\nAODV Routing table\n"
|
||||
<< "Destination\tGateway\t\tInterface\tFlag\tExpire\tHops\n";
|
||||
for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i =
|
||||
m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
|
||||
{
|
||||
i->second.Print (os);
|
||||
}
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
252
src/routing/manet/aodv/aodv-rtable.h
Normal file
252
src/routing/manet/aodv/aodv-rtable.h
Normal file
@@ -0,0 +1,252 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
#ifndef AODV_RTABLE_H
|
||||
#define AODV_RTABLE_H
|
||||
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <sys/types.h>
|
||||
#include "ns3/ipv4.h"
|
||||
#include "ns3/ipv4-route.h"
|
||||
#include "ns3/timer.h"
|
||||
#include "ns3/net-device.h"
|
||||
|
||||
namespace ns3 {
|
||||
namespace aodv {
|
||||
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief Route record states
|
||||
*/
|
||||
enum RouteFlags
|
||||
{
|
||||
VALID = 0, //!< VALID
|
||||
INVALID = 1, //!< INVALID
|
||||
IN_SEARCH = 2, //!< IN_SEARCH
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief Routing table entry
|
||||
*/
|
||||
class RoutingTableEntry
|
||||
{
|
||||
public:
|
||||
/// c-to
|
||||
RoutingTableEntry (Ptr<NetDevice> dev = 0,Ipv4Address dst = Ipv4Address(), bool vSeqNo = false, u_int32_t m_seqNo = 0,
|
||||
Ipv4InterfaceAddress iface = Ipv4InterfaceAddress(), u_int16_t hops = 0,
|
||||
Ipv4Address nextHop = Ipv4Address(), Time lifetime = Simulator::Now());
|
||||
|
||||
~RoutingTableEntry ();
|
||||
|
||||
///\name Precursors management
|
||||
//\{
|
||||
/**
|
||||
* Insert precursor in precursor list if it doesn't yet exist in the list
|
||||
* \param id precursor address
|
||||
* \return true on success
|
||||
*/
|
||||
bool InsertPrecursor (Ipv4Address id);
|
||||
/**
|
||||
* Lookup precursor by address
|
||||
* \param id precursor address
|
||||
* \return true on success
|
||||
*/
|
||||
bool LookupPrecursor (Ipv4Address id);
|
||||
/**
|
||||
* \brief Delete precursor
|
||||
* \param id precursor address
|
||||
* \return true on success
|
||||
*/
|
||||
bool DeletePrecursor (Ipv4Address id);
|
||||
/// Delete all precursors
|
||||
void DeleteAllPrecursors ();
|
||||
/**
|
||||
* Check that precursor list empty
|
||||
* \return true if precursor list empty
|
||||
*/
|
||||
bool IsPrecursorListEmpty () const;
|
||||
/**
|
||||
* Inserts precursors in vector prec if they does not yet exist in vector
|
||||
*/
|
||||
void GetPrecursors (std::vector<Ipv4Address> & prec) const;
|
||||
//\}
|
||||
|
||||
/// Mark entry as "down" (i.e. disable it)
|
||||
void Invalidate (Time badLinkLifetime);
|
||||
///\name Fields
|
||||
//\{
|
||||
Ipv4Address GetDestination () const { return m_ipv4Route->GetDestination(); }
|
||||
Ptr<Ipv4Route> GetRoute () const { return m_ipv4Route; }
|
||||
void SetRoute (Ptr<Ipv4Route> r) { m_ipv4Route = r; }
|
||||
void SetNextHop (Ipv4Address nextHop) { m_ipv4Route->SetGateway(nextHop); }
|
||||
Ipv4Address GetNextHop () const { return m_ipv4Route->GetGateway(); }
|
||||
void SetOutputDevice (Ptr<NetDevice> dev) { m_ipv4Route->SetOutputDevice(dev); }
|
||||
Ptr<NetDevice> GetOutputDevice () const { return m_ipv4Route->GetOutputDevice(); }
|
||||
Ipv4InterfaceAddress GetInterface () const { return m_iface;}
|
||||
void SetInterface (Ipv4InterfaceAddress iface) { m_iface = iface; }
|
||||
void SetValidSeqNo (bool s) { m_validSeqNo = s; }
|
||||
bool GetValidSeqNo () const { return m_validSeqNo; }
|
||||
void SetSeqNo (uint32_t sn) { m_seqNo = sn; }
|
||||
uint32_t GetSeqNo () const { return m_seqNo; }
|
||||
void SetHop (uint16_t hop) { m_hops = hop; }
|
||||
uint16_t GetHop () const {return m_hops; }
|
||||
void SetLifeTime (Time lt) { m_lifeTime = lt + Simulator::Now(); }
|
||||
Time GetLifeTime () const { return m_lifeTime - Simulator::Now(); }
|
||||
void SetFlag (RouteFlags flag) { m_flag = flag; }
|
||||
RouteFlags GetFlag () const { return m_flag; }
|
||||
void SetRreqCnt (uint8_t n) { m_reqCount = n; }
|
||||
uint8_t GetRreqCnt () const { return m_reqCount; }
|
||||
void IncrementRreqCnt () { m_reqCount++; }
|
||||
void SetUnidirectional (bool u) { m_blackListState = u; }
|
||||
bool IsUnidirectional () const { return m_blackListState; }
|
||||
void SetBalcklistTimeout (Time t) { m_blackListTimeout = t; }
|
||||
Time GetBlacklistTimeout () const { return m_blackListTimeout; }
|
||||
/// RREP_ACK timer
|
||||
Timer m_ackTimer;
|
||||
//\}
|
||||
|
||||
/**
|
||||
* \brief Compare destination address
|
||||
* \return true if equal
|
||||
*/
|
||||
bool operator== (Ipv4Address const dst) const
|
||||
{
|
||||
return (m_ipv4Route->GetDestination () == dst);
|
||||
}
|
||||
void Print(std::ostream & os) const;
|
||||
|
||||
private:
|
||||
/// Valid Destination Sequence Number flag
|
||||
bool m_validSeqNo;
|
||||
/// Destination Sequence Number, if m_validSeqNo = true
|
||||
uint32_t m_seqNo;
|
||||
/// Hop Count (number of hops needed to reach destination)
|
||||
uint16_t m_hops;
|
||||
/**
|
||||
* \brief Expiration or deletion time of the route
|
||||
* Lifetime field in the routing table plays dual role --
|
||||
* for an active route it is the expiration time, and for an invalid route
|
||||
* it is the deletion time.
|
||||
*/
|
||||
Time m_lifeTime;
|
||||
/** Ip route, include
|
||||
* - destination address
|
||||
* - source address
|
||||
* - next hop address (gateway)
|
||||
* - output device
|
||||
*/
|
||||
Ptr<Ipv4Route> m_ipv4Route;
|
||||
/// Output interface address
|
||||
Ipv4InterfaceAddress m_iface;
|
||||
/// Routing flags: valid, invalid or in search
|
||||
RouteFlags m_flag;
|
||||
|
||||
/// List of precursors
|
||||
std::vector<Ipv4Address> m_precursorList;
|
||||
/// When I can send another request
|
||||
Time m_routeRequestTimout;
|
||||
/// Number of route requests
|
||||
uint8_t m_reqCount;
|
||||
/// Indicate if this entry is in "blacklist"
|
||||
bool m_blackListState;
|
||||
/// Time for which the node is put into the blacklist
|
||||
Time m_blackListTimeout;
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup aodv
|
||||
* \brief The Routing table used by AODV protocol
|
||||
*/
|
||||
class RoutingTable
|
||||
{
|
||||
public:
|
||||
/// c-tor
|
||||
RoutingTable (Time t);
|
||||
///\name Handle life time of invalid route
|
||||
//\{
|
||||
Time GetBadLinkLifetime () const { return m_badLinkLifetime; }
|
||||
void SetBadLinkLifetime (Time t) { m_badLinkLifetime = t; }
|
||||
//\}
|
||||
/**
|
||||
* Add routing table entry if it doesn't yet exist in routing table
|
||||
* \param r routing table entry
|
||||
* \return true in success
|
||||
*/
|
||||
bool AddRoute (RoutingTableEntry & r);
|
||||
/**
|
||||
* Delete routing table entry with destination address dst, if it exists.
|
||||
* \param dst destination address
|
||||
* \return true on success
|
||||
*/
|
||||
bool DeleteRoute (Ipv4Address dst);
|
||||
/**
|
||||
* Lookup routing table entry with destination address dst
|
||||
* \param dst destination address
|
||||
* \param rt entry with destination address dst, if exists
|
||||
* \return true on success
|
||||
*/
|
||||
bool LookupRoute (Ipv4Address dst, RoutingTableEntry & rt);
|
||||
/// Update routing table
|
||||
bool Update (RoutingTableEntry & rt);
|
||||
/// Set routing table entry flags
|
||||
bool SetEntryState (Ipv4Address dst, RouteFlags state);
|
||||
/// Lookup routing entries with next hop Address dst and not empty list of precursors.
|
||||
void GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable);
|
||||
/**
|
||||
* Update routing entries with this destinations as follows:
|
||||
* 1. The destination sequence number of this routing entry, if it
|
||||
* exists and is valid, is incremented.
|
||||
* 2. The entry is invalidated by marking the route entry as invalid
|
||||
* 3. The Lifetime field is updated to current time plus DELETE_PERIOD.
|
||||
*/
|
||||
void InvalidateRoutesWithDst (std::map<Ipv4Address, uint32_t> const & unreachable);
|
||||
/// Delete all route from interface with address iface
|
||||
void DeleteAllRoutesFromInterface (Ipv4InterfaceAddress iface);
|
||||
/// Delete all entries from routing table
|
||||
void Clear () { m_ipv4AddressEntry.clear (); }
|
||||
/// Delete all outdated entries and invalidate valid entry if Lifetime is expired
|
||||
void Purge ();
|
||||
/** Mark entry as unidirectional (e.g. add this neighbor to "blacklist" for blacklistTimeout period)
|
||||
* \param neighbor - neighbor address link to which assumed to be unidirectional
|
||||
* \param blacklistTimeout - time for which the neighboring node is put into the blacklist
|
||||
* \return true on success
|
||||
*/
|
||||
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout);
|
||||
/// Print routing table
|
||||
void Print(std::ostream &os);
|
||||
|
||||
private:
|
||||
std::map<Ipv4Address, RoutingTableEntry> m_ipv4AddressEntry;
|
||||
/// Deletion time for invalid routes
|
||||
Time m_badLinkLifetime;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* AODV_RTABLE_H */
|
||||
554
src/routing/manet/aodv/aodv-test-suite.cc
Normal file
554
src/routing/manet/aodv/aodv-test-suite.cc
Normal file
@@ -0,0 +1,554 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
#include "ns3/test.h"
|
||||
#include "aodv-neighbor.h"
|
||||
#include "aodv-packet.h"
|
||||
#include "aodv-rqueue.h"
|
||||
#include "aodv-rtable.h"
|
||||
#include "ns3/ipv4-route.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace aodv
|
||||
{
|
||||
|
||||
/// Unit test for neighbors
|
||||
struct NeighborTest : public TestCase
|
||||
{
|
||||
NeighborTest () : TestCase ("Neighbor"), neighbor (0) { }
|
||||
virtual bool DoRun ();
|
||||
void Handler (Ipv4Address addr);
|
||||
void CheckTimeout1 ();
|
||||
void CheckTimeout2 ();
|
||||
void CheckTimeout3 ();
|
||||
Neighbors * neighbor;
|
||||
};
|
||||
|
||||
void
|
||||
NeighborTest::Handler (Ipv4Address addr)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NeighborTest::CheckTimeout1 ()
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), true, "Neighbor exists");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.1.1.1")), true, "Neighbor exists");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("2.2.2.2")), true, "Neighbor exists");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("3.3.3.3")), true, "Neighbor exists");
|
||||
}
|
||||
void
|
||||
NeighborTest::CheckTimeout2 ()
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), false, "Neighbor doesn't exist");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.1.1.1")), false, "Neighbor doesn't exist");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("2.2.2.2")), false, "Neighbor doesn't exist");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("3.3.3.3")), true, "Neighbor exists");
|
||||
}
|
||||
void
|
||||
NeighborTest::CheckTimeout3 ()
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), false, "Neighbor doesn't exist");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.1.1.1")), false, "Neighbor doesn't exist");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("2.2.2.2")), false, "Neighbor doesn't exist");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("3.3.3.3")), false, "Neighbor doesn't exist");
|
||||
}
|
||||
|
||||
bool
|
||||
NeighborTest::DoRun ()
|
||||
{
|
||||
Neighbors nb (Seconds (1));
|
||||
neighbor = &nb;
|
||||
neighbor->SetCallback (MakeCallback (&NeighborTest::Handler, this));
|
||||
neighbor->Update (Ipv4Address ("1.2.3.4"), Seconds (1));
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), true, "Neighbor exists");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("4.3.2.1")), false, "Neighbor doesn't exist");
|
||||
neighbor->Update (Ipv4Address ("1.2.3.4"), Seconds (10));
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->IsNeighbor (Ipv4Address ("1.2.3.4")), true, "Neighbor exists");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->GetExpireTime (Ipv4Address ("1.2.3.4")), Seconds (10), "Known expire time");
|
||||
NS_TEST_EXPECT_MSG_EQ (neighbor->GetExpireTime (Ipv4Address ("4.3.2.1")), Seconds (0), "Known expire time");
|
||||
neighbor->Update (Ipv4Address ("1.1.1.1"), Seconds (5));
|
||||
neighbor->Update (Ipv4Address ("2.2.2.2"), Seconds (10));
|
||||
neighbor->Update (Ipv4Address ("3.3.3.3"), Seconds (20));
|
||||
|
||||
Simulator::Schedule (Seconds (2), &NeighborTest::CheckTimeout1, this);
|
||||
Simulator::Schedule (Seconds (15), &NeighborTest::CheckTimeout2, this);
|
||||
Simulator::Schedule (Seconds (30), &NeighborTest::CheckTimeout3, this);
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
struct TypeHeaderTest : public TestCase
|
||||
{
|
||||
TypeHeaderTest () : TestCase ("AODV TypeHeader")
|
||||
{
|
||||
}
|
||||
virtual bool DoRun ()
|
||||
{
|
||||
TypeHeader h (AODVTYPE_RREQ);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.IsValid (), true, "Default header is valid");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.Get (), AODVTYPE_RREQ, "Default header is RREQ");
|
||||
|
||||
Ptr<Packet> p = Create<Packet> ();
|
||||
p->AddHeader (h);
|
||||
TypeHeader h2 (AODVTYPE_RREP);
|
||||
uint32_t bytes = p->RemoveHeader (h2);
|
||||
NS_TEST_EXPECT_MSG_EQ (bytes, 1, "Type header is 1 byte long");
|
||||
NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Unit test for RREQ
|
||||
struct RreqHeaderTest : public TestCase
|
||||
{
|
||||
RreqHeaderTest () : TestCase ("AODV RREQ")
|
||||
{
|
||||
}
|
||||
virtual bool DoRun ()
|
||||
{
|
||||
RreqHeader h (/*flags*/0, /*reserved*/0, /*hopCount*/6, /*requestID*/1, /*dst*/Ipv4Address ("1.2.3.4"),
|
||||
/*dstSeqNo*/40, /*origin*/Ipv4Address ("4.3.2.1"), /*originSeqNo*/10);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetGratiousRrep (), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDestinationOnly (), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 6, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetId (), 1, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.2.3.4"), "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 40, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.3.2.1"), "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetOriginSeqno (), 10, "trivial");
|
||||
|
||||
h.SetGratiousRrep (true);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetGratiousRrep (), true, "trivial");
|
||||
h.SetDestinationOnly (true);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDestinationOnly (), true, "trivial");
|
||||
h.SetUnknownSeqno (true);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetUnknownSeqno (), true, "trivial");
|
||||
h.SetDst (Ipv4Address ("1.1.1.1"));
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.1.1.1"), "trivial");
|
||||
h.SetDstSeqno (5);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 5, "trivial");
|
||||
h.SetHopCount (7);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 7, "trivial");
|
||||
h.SetId (55);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetId (), 55, "trivial");
|
||||
h.SetOrigin (Ipv4Address ("4.4.4.4"));
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.4.4.4"), "trivial");
|
||||
h.SetOriginSeqno (23);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetOriginSeqno (), 23, "trivial");
|
||||
|
||||
Ptr<Packet> p = Create<Packet> ();
|
||||
p->AddHeader (h);
|
||||
RreqHeader h2;
|
||||
uint32_t bytes = p->RemoveHeader (h2);
|
||||
NS_TEST_EXPECT_MSG_EQ (bytes, 23, "RREP is 23 bytes long");
|
||||
NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Unit test for RREP
|
||||
struct RrepHeaderTest : public TestCase
|
||||
{
|
||||
RrepHeaderTest () : TestCase ("AODV RREP") {}
|
||||
virtual bool DoRun ()
|
||||
{
|
||||
RrepHeader h (/*prefixSize*/0, /*hopCount*/12, /*dst*/Ipv4Address ("1.2.3.4"), /*dstSeqNo*/2,
|
||||
/*origin*/Ipv4Address ("4.3.2.1"), /*lifetime*/Seconds (3));
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetPrefixSize (), 0, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 12, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.2.3.4"), "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 2, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.3.2.1"), "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetLifeTime (), Seconds (3), "trivial");
|
||||
h.SetDst (Ipv4Address ("1.1.1.1"));
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDst (), Ipv4Address ("1.1.1.1"), "trivial");
|
||||
h.SetDstSeqno (123);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 123, "trivial");
|
||||
h.SetOrigin (Ipv4Address ("4.4.4.4"));
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetOrigin (), Ipv4Address ("4.4.4.4"), "trivial");
|
||||
h.SetLifeTime (MilliSeconds (1200));
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetLifeTime (), MilliSeconds (1200), "trivial");
|
||||
h.SetAckRequired (true);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetAckRequired (), true, "trivial");
|
||||
h.SetAckRequired (false);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetAckRequired (), false, "trivial");
|
||||
h.SetPrefixSize (2);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetPrefixSize (), 2, "trivial");
|
||||
h.SetHopCount (15);
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetHopCount (), 15, "trivial");
|
||||
|
||||
h.SetHello (Ipv4Address ("10.0.0.2"), 9, Seconds (15));
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDst (), h.GetOrigin (), "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDstSeqno (), 9, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetLifeTime (), Seconds (15), "trivial");
|
||||
|
||||
Ptr<Packet> p = Create<Packet> ();
|
||||
p->AddHeader (h);
|
||||
RrepHeader h2;
|
||||
uint32_t bytes = p->RemoveHeader (h2);
|
||||
NS_TEST_EXPECT_MSG_EQ (bytes, 19, "RREP is 19 bytes long");
|
||||
NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Unit test for RREP-ACK
|
||||
struct RrepAckHeaderTest : public TestCase
|
||||
{
|
||||
RrepAckHeaderTest () : TestCase ("AODV RREP-ACK")
|
||||
{
|
||||
}
|
||||
virtual bool DoRun()
|
||||
{
|
||||
RrepAckHeader h;
|
||||
Ptr<Packet> p = Create<Packet> ();
|
||||
p->AddHeader (h);
|
||||
RrepAckHeader h2;
|
||||
uint32_t bytes = p->RemoveHeader(h2);
|
||||
NS_TEST_EXPECT_MSG_EQ (bytes, 1, "ACK is 1 byte long");
|
||||
NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Unit test for RERR
|
||||
struct RerrHeaderTest : public TestCase
|
||||
{
|
||||
RerrHeaderTest () : TestCase ("AODV RERR")
|
||||
{
|
||||
}
|
||||
virtual bool DoRun()
|
||||
{
|
||||
RerrHeader h;
|
||||
h.SetNoDelete(true);
|
||||
NS_TEST_EXPECT_MSG_EQ(h.GetNoDelete(), true, "trivial");
|
||||
Ipv4Address dst = Ipv4Address("1.2.3.4");
|
||||
NS_TEST_EXPECT_MSG_EQ(h.AddUnDestination(dst, 12), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ(h.GetDestCount(), 1, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ(h.AddUnDestination(dst, 13), true, "trivial");
|
||||
Ipv4Address dst2 = Ipv4Address("4.3.2.1");
|
||||
NS_TEST_EXPECT_MSG_EQ(h.AddUnDestination(dst2, 12), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ(h.GetDestCount(), 2, "trivial");
|
||||
|
||||
Ptr<Packet> p = Create<Packet> ();
|
||||
p->AddHeader (h);
|
||||
RerrHeader h2;
|
||||
uint32_t bytes = p->RemoveHeader(h2);
|
||||
NS_TEST_EXPECT_MSG_EQ (bytes, h.GetSerializedSize(), "(De)Serialized size match");
|
||||
NS_TEST_EXPECT_MSG_EQ (h, h2, "Round trip serialization works");
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Unit test for AODV routing table entry
|
||||
struct QueueEntryTest : public TestCase
|
||||
{
|
||||
QueueEntryTest () : TestCase ("QueueEntry") {}
|
||||
void Unicast (Ptr<Ipv4Route> route, Ptr<const Packet> packet, const Ipv4Header & header) {}
|
||||
void Error (Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno) {}
|
||||
void Unicast2 (Ptr<Ipv4Route> route, Ptr<const Packet> packet, const Ipv4Header & header) {}
|
||||
void Error2 (Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno) {}
|
||||
virtual bool DoRun()
|
||||
{
|
||||
Ptr<const Packet> packet = Create<Packet> ();
|
||||
Ipv4Header h;
|
||||
h.SetDestination (Ipv4Address ("1.2.3.4"));
|
||||
h.SetSource (Ipv4Address ("4.3.2.1"));
|
||||
Ipv4RoutingProtocol::UnicastForwardCallback ucb = MakeCallback (&QueueEntryTest::Unicast, this);
|
||||
Ipv4RoutingProtocol::ErrorCallback ecb = MakeCallback (&QueueEntryTest::Error, this);
|
||||
QueueEntry entry (packet, h, ucb, ecb, Seconds (1));
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetDestination (), entry.GetIpv4Header ().GetDestination (), "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (h.GetSource (), entry.GetIpv4Header ().GetSource (), "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (ucb.IsEqual(entry.GetUnicastForwardCallback ()), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (ecb.IsEqual(entry.GetErrorCallback ()), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (entry.GetExpireTime (), Seconds (1), "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (entry.GetPacket (), packet, "trivial");
|
||||
entry.SetExpireTime (Seconds (3));
|
||||
NS_TEST_EXPECT_MSG_EQ (entry.GetExpireTime (), Seconds (3), "trivial");
|
||||
Ipv4Header h2;
|
||||
h2.SetDestination(Ipv4Address ("1.1.1.1"));
|
||||
entry.SetIpv4Header (h2);
|
||||
NS_TEST_EXPECT_MSG_EQ (entry.GetIpv4Header ().GetDestination (), Ipv4Address ("1.1.1.1"), "trivial");
|
||||
Ipv4RoutingProtocol::UnicastForwardCallback ucb2 = MakeCallback (&QueueEntryTest::Unicast2, this);
|
||||
Ipv4RoutingProtocol::ErrorCallback ecb2 = MakeCallback (&QueueEntryTest::Error2, this);
|
||||
entry.SetErrorCallback (ecb2);
|
||||
NS_TEST_EXPECT_MSG_EQ (ecb2.IsEqual (entry.GetErrorCallback ()), true, "trivial");
|
||||
entry.SetUnicastForwardCallback (ucb2);
|
||||
NS_TEST_EXPECT_MSG_EQ (ucb2.IsEqual (entry.GetUnicastForwardCallback ()), true, "trivial");
|
||||
|
||||
return GetErrorStatus();
|
||||
}
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Unit test for RequestQueue
|
||||
struct AodvRqueueTest : public TestCase
|
||||
{
|
||||
AodvRqueueTest () : TestCase ("Rqueue"), q (64, Seconds (30)) {}
|
||||
virtual bool DoRun ();
|
||||
void Unicast (Ptr<Ipv4Route> route, Ptr<const Packet> packet, const Ipv4Header & header) {}
|
||||
void Error (Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno) {}
|
||||
void CheckSizeLimit ();
|
||||
void CheckTimeout ();
|
||||
|
||||
RequestQueue q;
|
||||
};
|
||||
|
||||
bool
|
||||
AodvRqueueTest::DoRun ()
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetMaxQueueLen (), 64, "trivial");
|
||||
q.SetMaxQueueLen (32);
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetMaxQueueLen (), 32, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetQueueTimeout (), Seconds (30), "trivial");
|
||||
q.SetQueueTimeout (Seconds(10));
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetQueueTimeout (), Seconds (10), "trivial");
|
||||
|
||||
Ptr<const Packet> packet = Create<Packet> ();
|
||||
Ipv4Header h;
|
||||
h.SetDestination (Ipv4Address ("1.2.3.4"));
|
||||
h.SetSource (Ipv4Address ("4.3.2.1"));
|
||||
Ipv4RoutingProtocol::UnicastForwardCallback ucb = MakeCallback (&AodvRqueueTest::Unicast, this);
|
||||
Ipv4RoutingProtocol::ErrorCallback ecb = MakeCallback (&AodvRqueueTest::Error, this);
|
||||
QueueEntry e1 (packet, h, ucb, ecb, Seconds (1));
|
||||
q.Enqueue (e1);
|
||||
q.Enqueue (e1);
|
||||
q.Enqueue (e1);
|
||||
NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("1.2.3.4")), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("1.1.1.1")), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 1, "trivial");
|
||||
q.DropPacketWithDst (Ipv4Address ("1.2.3.4"));
|
||||
NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("1.2.3.4")), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 0, "trivial");
|
||||
|
||||
h.SetDestination (Ipv4Address ("2.2.2.2"));
|
||||
QueueEntry e2 (packet, h, ucb, ecb, Seconds (1));
|
||||
q.Enqueue (e1);
|
||||
q.Enqueue (e2);
|
||||
Ptr<Packet> packet2 = Create<Packet> ();
|
||||
QueueEntry e3 (packet2, h, ucb, ecb, Seconds (1));
|
||||
NS_TEST_EXPECT_MSG_EQ (q.Dequeue (Ipv4Address("3.3.3.3"), e3), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (q.Dequeue (Ipv4Address ("2.2.2.2"), e3), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (q.Find (Ipv4Address ("2.2.2.2")), false, "trivial");
|
||||
q.Enqueue (e2);
|
||||
q.Enqueue (e3);
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 2, "trivial");
|
||||
Ptr<Packet> packet4 = Create<Packet> ();
|
||||
h.SetDestination (Ipv4Address ("1.2.3.4"));
|
||||
QueueEntry e4 (packet4, h, ucb, ecb, Seconds (20));
|
||||
q.Enqueue (e4);
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 3, "trivial");
|
||||
q.DropPacketWithDst (Ipv4Address ("1.2.3.4"));
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetSize(), 1, "trivial");
|
||||
|
||||
CheckSizeLimit ();
|
||||
|
||||
Ipv4Header header2;
|
||||
Ipv4Address dst2 ("1.2.3.4");
|
||||
header2.SetDestination (dst2);
|
||||
|
||||
Simulator::Schedule (q.GetQueueTimeout () + Seconds (1), &AodvRqueueTest::CheckTimeout, this);
|
||||
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
void
|
||||
AodvRqueueTest::CheckSizeLimit ()
|
||||
{
|
||||
Ptr<Packet> packet = Create<Packet> ();
|
||||
Ipv4Header header;
|
||||
Ipv4RoutingProtocol::UnicastForwardCallback ucb = MakeCallback (&AodvRqueueTest::Unicast, this);
|
||||
Ipv4RoutingProtocol::ErrorCallback ecb = MakeCallback (&AodvRqueueTest::Error, this);
|
||||
QueueEntry e1 (packet, header, ucb, ecb, Seconds (1));
|
||||
|
||||
for (uint32_t i = 0; i < q.GetMaxQueueLen (); ++i)
|
||||
q.Enqueue (e1);
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 2, "trivial");
|
||||
|
||||
for (uint32_t i = 0; i < q.GetMaxQueueLen (); ++i)
|
||||
q.Enqueue (e1);
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 2, "trivial");
|
||||
}
|
||||
|
||||
void
|
||||
AodvRqueueTest::CheckTimeout ()
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ (q.GetSize (), 0, "Must be empty now");
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Unit test for AODV routing table entry
|
||||
struct AodvRtableEntryTest : public TestCase
|
||||
{
|
||||
AodvRtableEntryTest () : TestCase ("RtableEntry") {}
|
||||
virtual bool DoRun()
|
||||
{
|
||||
Ptr<NetDevice> dev;
|
||||
Ipv4InterfaceAddress iface;
|
||||
RoutingTableEntry rt (/*output device*/dev, /*dst*/Ipv4Address("1.2.3.4"), /*validSeqNo*/true, /*seqNo*/10,
|
||||
/*interface*/iface, /*hop*/5, /*next hop*/Ipv4Address("3.3.3.3"), /*lifetime*/Seconds(10));
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetOutputDevice (), dev, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetDestination (), Ipv4Address ("1.2.3.4"), "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetValidSeqNo (), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetSeqNo (), 10, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetInterface (), iface, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetHop (), 5, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetNextHop (), Ipv4Address ("3.3.3.3"), "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), Seconds (10), "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), VALID, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetRreqCnt (), 0, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.IsPrecursorListEmpty (), true, "trivial");
|
||||
|
||||
Ptr<NetDevice> dev2;
|
||||
Ipv4InterfaceAddress iface2;
|
||||
rt.SetOutputDevice (dev2);
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetOutputDevice (), dev2, "trivial");
|
||||
rt.SetInterface (iface2);
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetInterface (), iface2, "trivial");
|
||||
rt.SetValidSeqNo (false);
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetValidSeqNo (), false, "trivial");
|
||||
rt.SetFlag (INVALID);
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), INVALID, "trivial");
|
||||
rt.SetFlag (IN_SEARCH);
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), IN_SEARCH, "trivial");
|
||||
rt.SetHop (12);
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetHop (), 12, "trivial");
|
||||
rt.SetLifeTime (Seconds (1));
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), Seconds (1), "trivial");
|
||||
rt.SetNextHop (Ipv4Address ("1.1.1.1"));
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetNextHop (), Ipv4Address ("1.1.1.1"), "trivial");
|
||||
rt.SetUnidirectional (true);
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.IsUnidirectional (), true, "trivial");
|
||||
rt.SetBalcklistTimeout (Seconds (7));
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetBlacklistTimeout (), Seconds (7), "trivial");
|
||||
rt.SetRreqCnt (2);
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetRreqCnt (), 2, "trivial");
|
||||
rt.IncrementRreqCnt ();
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetRreqCnt (), 3, "trivial");
|
||||
rt.Invalidate (Seconds (13));
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), INVALID, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), Seconds (13), "trivial");
|
||||
rt.SetLifeTime (Seconds (0.1));
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetLifeTime (), Seconds (0.1), "trivial");
|
||||
Ptr<Ipv4Route> route = rt.GetRoute ();
|
||||
NS_TEST_EXPECT_MSG_EQ (route->GetDestination (), Ipv4Address ("1.2.3.4"), "trivial");
|
||||
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.1")), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.IsPrecursorListEmpty (), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.2")), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.2")), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.LookupPrecursor (Ipv4Address ("10.0.0.3")), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.LookupPrecursor (Ipv4Address ("10.0.0.1")), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.DeletePrecursor (Ipv4Address ("10.0.0.2")), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.LookupPrecursor (Ipv4Address ("10.0.0.2")), false, "trivial");
|
||||
std::vector<Ipv4Address> prec;
|
||||
rt.GetPrecursors (prec);
|
||||
NS_TEST_EXPECT_MSG_EQ (prec.size (), 1, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.InsertPrecursor (Ipv4Address ("10.0.0.4")), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.DeletePrecursor (Ipv4Address ("10.0.0.5")), false, "trivial");
|
||||
rt.GetPrecursors (prec);
|
||||
NS_TEST_EXPECT_MSG_EQ (prec.size (), 2, "trivial");
|
||||
rt.DeleteAllPrecursors ();
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.IsPrecursorListEmpty (), true, "trivial");
|
||||
rt.GetPrecursors (prec);
|
||||
NS_TEST_EXPECT_MSG_EQ (prec.size (), 2, "trivial");
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Unit test for AODV routing table
|
||||
struct AodvRtableTest : public TestCase
|
||||
{
|
||||
AodvRtableTest () : TestCase ("Rtable") {}
|
||||
virtual bool DoRun()
|
||||
{
|
||||
RoutingTable rtable (Seconds (2));
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.GetBadLinkLifetime (), Seconds (2), "trivial");
|
||||
rtable.SetBadLinkLifetime (Seconds (1));
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.GetBadLinkLifetime (), Seconds (1), "trivial");
|
||||
Ptr<NetDevice> dev;
|
||||
Ipv4InterfaceAddress iface;
|
||||
RoutingTableEntry rt (/*output device*/dev, /*dst*/Ipv4Address("1.2.3.4"), /*validSeqNo*/true, /*seqNo*/10,
|
||||
/*interface*/iface, /*hop*/5, /*next hop*/Ipv4Address("1.1.1.1"), /*lifetime*/Seconds(10));
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt), false, "trivial");
|
||||
RoutingTableEntry rt2 (/*output device*/dev, /*dst*/Ipv4Address("4.3.2.1"), /*validSeqNo*/false, /*seqNo*/0,
|
||||
/*interface*/iface, /*hop*/15, /*next hop*/Ipv4Address("1.1.1.1"), /*lifetime*/Seconds(1));
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt2), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (rt2.GetDestination (), rt), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt2.GetDestination (), rt.GetDestination (), "trivial");
|
||||
rt.SetHop (20);
|
||||
rt.InsertPrecursor (Ipv4Address ("10.0.0.3"));
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.Update (rt), true, "trivial");
|
||||
RoutingTableEntry rt3;
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("10.0.0.1"), rt), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.Update (rt3), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.SetEntryState (Ipv4Address ("10.0.0.1"), INVALID), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.SetEntryState (Ipv4Address ("1.2.3.4"), IN_SEARCH), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.DeleteRoute (Ipv4Address ("5.5.5.5")), false, "trivial");
|
||||
RoutingTableEntry rt4 (/*output device*/dev, /*dst*/Ipv4Address ("5.5.5.5"), /*validSeqNo*/false, /*seqNo*/0,
|
||||
/*interface*/iface, /*hop*/15, /*next hop*/Ipv4Address ("1.1.1.1"), /*lifetime*/Seconds (-10));
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.AddRoute (rt4), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.SetEntryState (Ipv4Address ("5.5.5.5"), INVALID), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("5.5.5.5"), rt), false, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.MarkLinkAsUnidirectional (Ipv4Address ("1.2.3.4"), Seconds (2)), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("1.2.3.4"), rt), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.IsUnidirectional (), true, "trivial");
|
||||
rt.SetLifeTime (Seconds (-5));
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.Update (rt), true, "trivial");
|
||||
std::map<Ipv4Address, uint32_t> unreachable;
|
||||
rtable.GetListOfDestinationWithNextHop (Ipv4Address ("1.1.1.1"), unreachable);
|
||||
NS_TEST_EXPECT_MSG_EQ (unreachable.size (), 2, "trivial");
|
||||
unreachable.insert (std::make_pair (Ipv4Address ("4.3.2.1"), 3));
|
||||
rtable.InvalidateRoutesWithDst (unreachable);
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.LookupRoute (Ipv4Address ("4.3.2.1"), rt), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), INVALID, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.DeleteRoute (Ipv4Address ("1.2.3.4")), true, "trivial");
|
||||
NS_TEST_EXPECT_MSG_EQ (rtable.DeleteRoute (Ipv4Address ("1.2.3.4")), false, "trivial");
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
class AodvTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
AodvTestSuite () : TestSuite ("routing-aodv", UNIT)
|
||||
{
|
||||
AddTestCase (new NeighborTest);
|
||||
AddTestCase (new TypeHeaderTest);
|
||||
AddTestCase (new RreqHeaderTest);
|
||||
AddTestCase (new RrepHeaderTest);
|
||||
AddTestCase (new RrepAckHeaderTest);
|
||||
AddTestCase (new RerrHeaderTest);
|
||||
AddTestCase (new QueueEntryTest);
|
||||
AddTestCase (new AodvRqueueTest);
|
||||
AddTestCase (new AodvRtableEntryTest);
|
||||
AddTestCase (new AodvRtableTest);
|
||||
}
|
||||
} g_aodvTestSuite;
|
||||
|
||||
}}
|
||||
86
src/routing/manet/aodv/aodv.h
Normal file
86
src/routing/manet/aodv/aodv.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#ifndef AODV_H
|
||||
#define AODV_H
|
||||
|
||||
/**
|
||||
* \ingroup routing
|
||||
* \defgroup aodv AODV
|
||||
*
|
||||
* This model implements the base specification of the Ad hoc on demand distance vector (AODV)
|
||||
* protocol. Implementation is based on RFC3561.
|
||||
*
|
||||
* Class aodv::RoutingProtocol implements all functionality of service packet exchange and inherits Ipv4RoutingProtocol.
|
||||
* Base class defines two virtual functions for packet routing and forwarding. The first one,
|
||||
* RouteOutput(), is used for locally originated packets, and the second one, RouteInput(), is used for forwarding
|
||||
* and/or delivering received packets.
|
||||
*
|
||||
* Protocol operation depends on the many adjustable parameters. Parameters for this functionality are attributes of
|
||||
* aodv::RoutingProtocol. We support parameters, with their default values, from RFC and parameters that enable/disable
|
||||
* protocol features, such as broadcasting HELLO messages, broadcasting data packets and so on.
|
||||
*
|
||||
* AODV discovers routes on demand. Therefore, our AODV model buffer all packets, while a route request packet (RREQ)
|
||||
* is disseminated. We implement a packet queue in aodv-rqueue.cc. Smart pointer to packet, Ipv4RoutingProtocol::ErrorCallback,
|
||||
* Ipv4RoutingProtocol::UnicastForwardCallback and IP header are stored in this queue. The packet queue implements garbage collection of old
|
||||
* packets and a queue size limit.
|
||||
*
|
||||
* Routing table implementation support garbage collection of old entries and state machine, defined in standard.
|
||||
* It implements as a STL map container. The key is a destination IP address.
|
||||
*
|
||||
* Some moments of protocol operation aren't described in RFC. This moments generally concern cooperation of different OSI model layers.
|
||||
* We use following heuristics:
|
||||
*
|
||||
* 1) This AODV implementation can detect the presence of unidirectional links and avoid them if necessary.
|
||||
* If the node we received a RREQ for is a neighbor we are probably facing a unidirectional link...
|
||||
* This heuristic is taken from AODV-UU implementation and can be disabled.
|
||||
*
|
||||
* 2) Protocol operation strongly depends on broken link detection mechanism. We implements two such heuristics.
|
||||
* First, this implementation support HELLO messages. However HELLO messages are not a good way to do neighbor sensing
|
||||
* in a wireless environment (at least not over 802.11). Therefore, you may experience bad performance when running over wireless.
|
||||
* There are several reasons for this:
|
||||
* -# HELLO messages are broadcasted. In 802.11, broadcasting is done at a lower bit rate than unicasting,
|
||||
* thus HELLO messages travel further than data.
|
||||
* -# HELLO messages are small, thus less prone to bit errors than data transmissions.
|
||||
* -# Broadcast transmissions are not guaranteed to be bidirectional, unlike unicast transmissions.
|
||||
* Second, we use layer 2 feedback when possible. Link considered to be broken, if frame transmission results in a transmission
|
||||
* failure for all retries. This mechanism meant for active links and work much more faster, than first method.
|
||||
* Layer 2 feedback implementation relies on TxErrHeader trace source, currently it is supported in AdhocWifiMac only.
|
||||
*
|
||||
* 3) Duplicate packet detection. We use special class dpd::DuplicatePacketDetection for this purpose.
|
||||
*
|
||||
* Following optional protocol optimizations aren't implemented:
|
||||
* - Expanding ring search.
|
||||
* - Local link repair.
|
||||
* - RREP, RREQ and HELLO message extensions.
|
||||
* This techniques require direct access to IP header, which contradict assertion from AODV RFC that AODV works over UDP. Our model use UDP
|
||||
* for simplicity, but this disable us to implement protocol optimizations. We don't use low layer raw socket, because they are not portable.
|
||||
*
|
||||
*/
|
||||
|
||||
#endif /* AODV_H */
|
||||
BIN
src/routing/manet/aodv/test/aodv-chain-regression-test-0-0.pcap
Normal file
BIN
src/routing/manet/aodv/test/aodv-chain-regression-test-0-0.pcap
Normal file
Binary file not shown.
BIN
src/routing/manet/aodv/test/aodv-chain-regression-test-1-0.pcap
Normal file
BIN
src/routing/manet/aodv/test/aodv-chain-regression-test-1-0.pcap
Normal file
Binary file not shown.
BIN
src/routing/manet/aodv/test/aodv-chain-regression-test-2-0.pcap
Normal file
BIN
src/routing/manet/aodv/test/aodv-chain-regression-test-2-0.pcap
Normal file
Binary file not shown.
BIN
src/routing/manet/aodv/test/aodv-chain-regression-test-3-0.pcap
Normal file
BIN
src/routing/manet/aodv/test/aodv-chain-regression-test-3-0.pcap
Normal file
Binary file not shown.
BIN
src/routing/manet/aodv/test/aodv-chain-regression-test-4-0.pcap
Normal file
BIN
src/routing/manet/aodv/test/aodv-chain-regression-test-4-0.pcap
Normal file
Binary file not shown.
171
src/routing/manet/aodv/test/aodv-regression.cc
Normal file
171
src/routing/manet/aodv/test/aodv-regression.cc
Normal file
@@ -0,0 +1,171 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#include "aodv-regression.h"
|
||||
|
||||
#include "ns3/mesh-helper.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/random-variable.h"
|
||||
#include "ns3/mobility-helper.h"
|
||||
#include "ns3/double.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/string.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/yans-wifi-helper.h"
|
||||
#include "ns3/internet-stack-helper.h"
|
||||
#include "ns3/ipv4-address-helper.h"
|
||||
#include "ns3/abort.h"
|
||||
#include "ns3/udp-echo-helper.h"
|
||||
#include "ns3/mobility-model.h"
|
||||
#include "ns3/pcap-file.h"
|
||||
#include "ns3/aodv-helper.h"
|
||||
#include "ns3/v4ping-helper.h"
|
||||
#include "ns3/nqos-wifi-mac-helper.h"
|
||||
#include <sstream>
|
||||
|
||||
/// Set to true to rewrite reference traces, leave false to run regression tests
|
||||
const bool WRITE_VECTORS = false;
|
||||
|
||||
namespace ns3 {
|
||||
namespace aodv {
|
||||
//-----------------------------------------------------------------------------
|
||||
// Test suite
|
||||
//-----------------------------------------------------------------------------
|
||||
class AodvRegressionTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
AodvRegressionTestSuite () : TestSuite ("routing-aodv-regression", SYSTEM)
|
||||
{
|
||||
AddTestCase (new ChainRegressionTest);
|
||||
}
|
||||
} g_aodvRegressionTestSuite;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ChainRegressionTest
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Unique PCAP files prefix for this test
|
||||
const char * const ChainRegressionTest::PREFIX = "aodv-chain-regression-test";
|
||||
|
||||
ChainRegressionTest::ChainRegressionTest () : TestCase ("AODV chain regression test"),
|
||||
m_nodes (0),
|
||||
m_time (Seconds (10)),
|
||||
m_size (5),
|
||||
m_step (120)
|
||||
{
|
||||
}
|
||||
|
||||
ChainRegressionTest::~ChainRegressionTest ()
|
||||
{
|
||||
delete m_nodes;
|
||||
}
|
||||
|
||||
bool
|
||||
ChainRegressionTest::DoRun ()
|
||||
{
|
||||
SeedManager::SetSeed(12345);
|
||||
CreateNodes ();
|
||||
CreateDevices ();
|
||||
|
||||
// At m_time / 3 move central node away and see what will happen
|
||||
Ptr<Node> node = m_nodes->Get (m_size / 2);
|
||||
Ptr<MobilityModel> mob = node->GetObject<MobilityModel> ();
|
||||
Simulator::Schedule (m_time / Scalar(3.0), &MobilityModel::SetPosition, mob, Vector (1e5, 1e5, 1e5));
|
||||
|
||||
Simulator::Stop (m_time);
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
if (!WRITE_VECTORS) CheckResults ();
|
||||
|
||||
delete m_nodes, m_nodes = 0;
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
void
|
||||
ChainRegressionTest::CreateNodes ()
|
||||
{
|
||||
m_nodes = new NodeContainer;
|
||||
m_nodes->Create (m_size);
|
||||
MobilityHelper mobility;
|
||||
mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
|
||||
"MinX", DoubleValue (0.0),
|
||||
"MinY", DoubleValue (0.0),
|
||||
"DeltaX", DoubleValue (m_step),
|
||||
"DeltaY", DoubleValue (0),
|
||||
"GridWidth", UintegerValue (m_size),
|
||||
"LayoutType", StringValue ("RowFirst"));
|
||||
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
|
||||
mobility.Install (*m_nodes);
|
||||
}
|
||||
|
||||
void
|
||||
ChainRegressionTest::CreateDevices ()
|
||||
{
|
||||
// 1. Setup WiFi
|
||||
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
|
||||
wifiMac.SetType ("ns3::AdhocWifiMac");
|
||||
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
|
||||
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
|
||||
wifiPhy.SetChannel (wifiChannel.Create ());
|
||||
WifiHelper wifi = WifiHelper::Default ();
|
||||
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("wifia-6mbs"), "RtsCtsThreshold", StringValue ("2200"));
|
||||
NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, *m_nodes);
|
||||
|
||||
// 2. Setup TCP/IP & AODV
|
||||
AodvHelper aodv; // Use default parameters here
|
||||
InternetStackHelper internetStack;
|
||||
internetStack.SetRoutingHelper (aodv);
|
||||
internetStack.Install (*m_nodes);
|
||||
Ipv4AddressHelper address;
|
||||
address.SetBase ("10.1.1.0", "255.255.255.0");
|
||||
Ipv4InterfaceContainer interfaces = address.Assign (devices);
|
||||
|
||||
// 3. Setup ping
|
||||
V4PingHelper ping (interfaces.GetAddress (m_size - 1));
|
||||
ping.SetAttribute ("Verbose", BooleanValue (false)); // don't need verbose ping in regression test
|
||||
ApplicationContainer p = ping.Install (m_nodes->Get (0));
|
||||
p.Start (Seconds (0));
|
||||
p.Stop (m_time);
|
||||
|
||||
// 4. write PCAP
|
||||
std::string prefix = (WRITE_VECTORS ? NS_TEST_SOURCEDIR : GetTempDir ()) + PREFIX;
|
||||
wifiPhy.EnablePcapAll (prefix);
|
||||
}
|
||||
|
||||
void
|
||||
ChainRegressionTest::CheckResults ()
|
||||
{
|
||||
for (uint32_t i = 0; i < m_size; ++i)
|
||||
{
|
||||
std::ostringstream os1, os2;
|
||||
// File naming conventions are hard-coded here.
|
||||
os1 << NS_TEST_SOURCEDIR << PREFIX << "-" << i << "-0.pcap";
|
||||
os2 << GetTempDir () << PREFIX << "-" << i << "-0.pcap";
|
||||
|
||||
uint32_t sec(0), usec(0);
|
||||
bool diff = PcapFile::Diff (os1.str(), os2.str(), sec, usec);
|
||||
NS_TEST_EXPECT_MSG_EQ (diff, false, "PCAP traces " << os1.str() << " and " << os2.str()
|
||||
<< " differ starting from " << sec << " s " << usec << " us");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
184
src/routing/manet/aodv/test/aodv-regression.h
Normal file
184
src/routing/manet/aodv/test/aodv-regression.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#ifndef AODVREGRESSION_H_
|
||||
#define AODVREGRESSION_H_
|
||||
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/node-container.h"
|
||||
|
||||
namespace ns3 {
|
||||
namespace aodv {
|
||||
|
||||
/**
|
||||
* \ingroup aodv
|
||||
*
|
||||
* \brief AODV chain regression test
|
||||
*
|
||||
* This script creates 1-dimensional grid topology and then ping last node from the first one:
|
||||
*
|
||||
* [10.1.1.1] <-- step --> [10.1.1.2] <-- step --> [10.1.1.3] <-- step --> [10.1.1.4] <-- step --> [10.1.1.5]
|
||||
*
|
||||
* Each node can hear only his right and his left neighbor, if they exist. When one third of total time expired,
|
||||
* central node moves away. After this, node 3 doesn't hear any packets from other nodes and nobody hears his packets.
|
||||
* We want to demonstrate in this script
|
||||
* 1) route establishing
|
||||
* 2) broken link detection both from layer 2 information and hello messages.
|
||||
*
|
||||
* \verbatim
|
||||
Expected packets time diagram.
|
||||
1 2 3 4 5
|
||||
<------|------>| | | | RREQ (orig 10.1.1.1, dst 10.1.1.5, G=1, U=1, hop=0, ID=1, org_seqno=1) src = 10.1.1.1
|
||||
|<------|------>| | | RREQ (orig 10.1.1.1, dst 10.1.1.5, G=1, U=1, hop=1, ID=1, org_seqno=1) src = 10.1.1.2
|
||||
| |<------|------>| | RREQ (orig 10.1.1.1, dst 10.1.1.5, G=1, U=1, hop=2, ID=1, org_seqno=1) src = 10.1.1.3
|
||||
| | |<------|------>| RREQ (orig 10.1.1.1, dst 10.1.1.5, G=1, U=1, hop=3, ID=1, org_seqno=1) src = 10.1.1.4
|
||||
| | | |<------|------> ARP request. Who has 10.1.1.4? Tell 10.1.1.5
|
||||
| | | |======>| ARP reply
|
||||
| | | |<======| RREP (orig 10.1.1.1, dst 10.1.1.5, hop=0, dst_seqno=0) src=10.1.1.5
|
||||
| | |<------|------>| ARP request. Who has 10.1.1.3? Tell 10.1.1.4
|
||||
| | |======>| | ARP reply
|
||||
| | |<======| | RREP (orig 10.1.1.1, dst 10.1.1.5, hop=1, dst_seqno=0) src=10.1.1.4
|
||||
| |<------|------>| | ARP request. Who has 10.1.1.2? Tell 10.1.1.3
|
||||
| |======>| | | ARP reply
|
||||
| |<======| | | RREP (orig 10.1.1.1, dst 10.1.1.5, hop=2, dst_seqno=0) src=10.1.1.3
|
||||
|<------|------>| | | ARP request. Who has 10.1.1.1? Tell 10.1.1.2
|
||||
|======>| | | | ARP reply
|
||||
|<======| | | | RREP (orig 10.1.1.1, dst 10.1.1.5, hop=3, dst_seqno=0) src=10.1.1.2
|
||||
<-------|------>| | | | ARP request. Who has 10.1.1.2? Tell 10.1.1.1
|
||||
|<======| | | |
|
||||
|======>| | | | ICMP (ping) request 0 from 10.1.1.1 to 10.1.1.5; src=10.1.1.1 next_hop=10.1.1.2
|
||||
|<------|------>| | | ARP request. Who has 10.1.1.3? Tell 10.1.1.2
|
||||
| |<======| | | ARP reply
|
||||
| |======>| | | ICMP (ping) request 0 from 10.1.1.1 to 10.1.1.5; src=10.1.1.2 next_hop=10.1.1.3
|
||||
| |<------|------>| | ARP request. Who has 10.1.1.4? Tell 10.1.1.3
|
||||
| | |<======| | ARP reply
|
||||
| | |======>| | ICMP (ping) request 0 from 10.1.1.1 to 10.1.1.5; src=10.1.1.3 next_hop=10.1.1.4
|
||||
| | |<------|------>| ARP request. Who has 10.1.1.5? Tell 10.1.1.4
|
||||
| | | |<======| ARP reply
|
||||
| | | |======>| ICMP (ping) request 0; src=10.1.1.4 next_hop=10.1.1.5
|
||||
| | | |<======| ICMP (ping) reply 0; src=10.1.1.5 next_hop=10.1.1.4
|
||||
| | |<======| | ICMP (ping) reply 0; src=10.1.1.4 next_hop=10.1.1.3
|
||||
| |<======| | | ICMP (ping) reply 0; src=10.1.1.3 next_hop=10.1.1.2
|
||||
|<======| | | | ICMP (ping) reply 0; src=10.1.1.2 next_hop=10.1.1.1
|
||||
| | | |<------|------> Hello
|
||||
|<------|------>| | | Hello
|
||||
<------|------>| | | | Hello
|
||||
| |<------|------>| | Hello
|
||||
|======>| | | | ICMP (ping) request 1; src=10.1.1.1 next_hop=10.1.1.2
|
||||
| | |<------|------>| Hello
|
||||
| |======>| | | ICMP (ping) request 1; src=10.1.1.2 next_hop=10.1.1.3
|
||||
| | |======>| | ICMP (ping) request 1; src=10.1.1.3 next_hop=10.1.1.4
|
||||
| | | |======>| ICMP (ping) request 1; src=10.1.1.4 next_hop=10.1.1.5
|
||||
| | | |<======| ICMP (ping) reply 1; src=10.1.1.5 next_hop=10.1.1.4
|
||||
| | |<======| | ICMP (ping) reply 1; src=10.1.1.4 next_hop=10.1.1.3
|
||||
| |<======| | | ICMP (ping) reply 11; src=10.1.1.3 next_hop=10.1.1.2
|
||||
|<======| | | | ICMP (ping) reply 1; src=10.1.1.2 next_hop=10.1.1.1
|
||||
| | | |<------|------> Hello
|
||||
|<------|------>| | | Hello
|
||||
<------|------>| | | | Hello
|
||||
| | |<------|------>| Hello
|
||||
| |<------|------>| | Hello
|
||||
|======>| | | | ICMP (ping) request 2; src=10.1.1.1 next_hop=10.1.1.2
|
||||
| |======>| | | ICMP (ping) request 2; src=10.1.1.2 next_hop=10.1.1.3
|
||||
| | |======>| | ICMP (ping) request 2; src=10.1.1.3 next_hop=10.1.1.4
|
||||
| | | |======>| ICMP (ping) request 2; src=10.1.1.4 next_hop=10.1.1.5
|
||||
| | | |<======| ICMP (ping) reply 2; src=10.1.1.5 next_hop=10.1.1.4
|
||||
| | |<======| | ICMP (ping) reply 2; src=10.1.1.4 next_hop=10.1.1.3
|
||||
| |<======| | | ICMP (ping) reply 2; src=10.1.1.3 next_hop=10.1.1.2
|
||||
|<======| | | | ICMP (ping) reply 2; src=10.1.1.2 next_hop=10.1.1.1
|
||||
| | | |<------|------> Hello
|
||||
<------|------>| | | | Hello
|
||||
| |<------|------>| | Hello
|
||||
|<------|------>| | | Hello
|
||||
| | |<------|------>| Hello
|
||||
|======>| | | | ICMP (ping) request 3; src=10.1.1.1 next_hop=10.1.1.2
|
||||
| |======>| | | ICMP (ping) request 3; src=10.1.1.2 next_hop=10.1.1.3
|
||||
| | |======>| | ICMP (ping) request 3; src=10.1.1.3 next_hop=10.1.1.4
|
||||
| | | |======>| ICMP (ping) request 3; src=10.1.1.4 next_hop=10.1.1.5
|
||||
| | | |<======| ICMP (ping) reply 3; src=10.1.1.5 next_hop=10.1.1.4
|
||||
| | |<======| | ICMP (ping) reply 3; src=10.1.1.4 next_hop=10.1.1.3
|
||||
| |<======| | | ICMP (ping) reply 3; src=10.1.1.3 next_hop=10.1.1.2
|
||||
|<======| | | | ICMP (ping) reply 3; src=10.1.1.2 next_hop=10.1.1.1
|
||||
| | | |<------|------> Hello
|
||||
<------|------>| | | | Hello
|
||||
|<------|--> | | | Hello |
|
||||
| | <--|--> | | Hello |Node 3 move away => nobody hear his packets and node 3 doesn't hear anything !
|
||||
| | | <--|------>| Hello |
|
||||
|======>| | | | ICMP (ping) request 4; src=10.1.1.1 next_hop=10.1.1.2
|
||||
| |==> | | | ICMP (ping) request 4; src=10.1.1.2 next_hop=10.1.1.3. 7 retries.
|
||||
|<======| | | | RERR (unreachable dst 10.1.1.3 & 10.1.1.5) src=10.1.1.2
|
||||
| | | |<------|------> Hello
|
||||
<------|------>| | | | Hello
|
||||
|<------|--> | | | Hello
|
||||
| | <--|--> | | Hello
|
||||
| | | <--|------>| Hello
|
||||
<------|------>| | | | RREQ (orig 10.1.1.1, dst 10.1.1.5, G=1, hop=0, ID=2, org_seqno=2) src = 10.1.1.1
|
||||
|<------|--> | | | RREQ (orig 10.1.1.1, dst 10.1.1.5, G=1, hop=1, ID=2, org_seqno=1) src = 10.1.1.2
|
||||
| | | |<------|------> Hello
|
||||
| | | <--|------>| Hello
|
||||
| | <--|--> | | Hello
|
||||
<------|------>| | | | Hello
|
||||
<------|------>| | | | RREQ (orig 10.1.1.1, dst 10.1.1.5, G=1, hop=0, ID=3, org_seqno=3) src = 10.1.1.1
|
||||
|<------|--> | | | Hello
|
||||
|<------|--> | | | RREQ (orig 10.1.1.1, dst 10.1.1.5, G=1, hop=1, ID=3, org_seqno=3) src = 10.1.1.2
|
||||
| | | |======>| RERR (unreachable dst 10.1.1.1 & 10.1.1.3) src=10.1.1.4
|
||||
| | | |<------|------> Hello
|
||||
| | | <--|------>| Hello
|
||||
| | <--|--> | | Hello
|
||||
|<------|--> | | | Hello
|
||||
<------|------>| | | | Hello
|
||||
<------|------>| | | | RREQ (orig 10.1.1.1, dst 10.1.1.5, G=1, hop=0, ID=4, org_seqno=4) src = 10.1.1.1
|
||||
|<------|--> | | | RREQ (orig 10.1.1.1, dst 10.1.1.5, G=1, hop=1, ID=4, org_seqno=4) src = 10.1.1.2
|
||||
|
||||
..................................................................
|
||||
* \endverbatim
|
||||
*/
|
||||
class ChainRegressionTest : public TestCase
|
||||
{
|
||||
public:
|
||||
ChainRegressionTest ();
|
||||
~ChainRegressionTest ();
|
||||
private:
|
||||
/// Unique PCAP files prefix for this test
|
||||
static const char * const PREFIX;
|
||||
/// XXX It is important to have pointers here
|
||||
NodeContainer * m_nodes;
|
||||
|
||||
/// Total simulation time
|
||||
const Time m_time;
|
||||
/// Chain size
|
||||
const uint32_t m_size;
|
||||
/// Chain step, meters
|
||||
const double m_step;
|
||||
|
||||
/// Create test topology
|
||||
void CreateNodes ();
|
||||
/// Create devices, install TCP/IP stack and applications
|
||||
void CreateDevices ();
|
||||
/// Compare traces with reference ones
|
||||
void CheckResults ();
|
||||
/// Go
|
||||
bool DoRun ();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* AODVREGRESSION_H_ */
|
||||
1
src/routing/manet/aodv/waf
vendored
Executable file
1
src/routing/manet/aodv/waf
vendored
Executable file
@@ -0,0 +1 @@
|
||||
exec "`dirname "$0"`"/../../../../waf "$@"
|
||||
25
src/routing/manet/aodv/wscript
Normal file
25
src/routing/manet/aodv/wscript
Normal file
@@ -0,0 +1,25 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
module = bld.create_ns3_module('aodv', ['internet-stack', 'contrib'])
|
||||
module.includes = '.'
|
||||
module.source = [
|
||||
'aodv-rtable.cc',
|
||||
'aodv-rqueue.cc',
|
||||
'aodv-packet.cc',
|
||||
'aodv-neighbor.cc',
|
||||
'aodv-routing-protocol.cc',
|
||||
'aodv-test-suite.cc',
|
||||
'test/aodv-regression.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers.module = 'aodv'
|
||||
headers.source = [
|
||||
'aodv-rtable.h',
|
||||
'aodv-rqueue.h',
|
||||
'aodv-packet.h',
|
||||
'aodv-neighbor.h',
|
||||
'aodv-routing-protocol.h',
|
||||
]
|
||||
|
||||
50
src/routing/manet/dpd/dpd.cc
Normal file
50
src/routing/manet/dpd/dpd.cc
Normal file
@@ -0,0 +1,50 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#include "dpd.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace dpd
|
||||
{
|
||||
|
||||
bool
|
||||
DuplicatePacketDetection::IsDuplicate (Ptr<const Packet> p, const Ipv4Header & header)
|
||||
{
|
||||
return m_idCache.IsDuplicate (header.GetSource (), p->GetUid() );
|
||||
}
|
||||
void
|
||||
DuplicatePacketDetection::SetLifetime (Time lifetime)
|
||||
{
|
||||
m_idCache.SetLifetime(lifetime);
|
||||
}
|
||||
|
||||
Time
|
||||
DuplicatePacketDetection::GetLifetime () const
|
||||
{
|
||||
return m_idCache.GetLifeTime();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
59
src/routing/manet/dpd/dpd.h
Normal file
59
src/routing/manet/dpd/dpd.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#ifndef DUPLICATEPACKETDETECTION_H_
|
||||
#define DUPLICATEPACKETDETECTION_H_
|
||||
|
||||
#include "id-cache.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/ipv4-header.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace dpd
|
||||
{
|
||||
/**
|
||||
* \ingroup dpd
|
||||
*
|
||||
* \brief Helper class used to remember already seen packets and detect duplicates.
|
||||
*/
|
||||
class DuplicatePacketDetection
|
||||
{
|
||||
public:
|
||||
/// C-tor
|
||||
DuplicatePacketDetection (Time lifetime) : m_idCache(lifetime) {}
|
||||
/// Check that the packet is duplicated. If not, save information about this packet.
|
||||
bool IsDuplicate (Ptr<const Packet> p, const Ipv4Header & header);
|
||||
/// Set duplicate records lifetimes
|
||||
void SetLifetime (Time lifetime);
|
||||
/// Get duplicate records lifetimes
|
||||
Time GetLifetime () const;
|
||||
private:
|
||||
/// Impl
|
||||
IdCache m_idCache;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
131
src/routing/manet/dpd/id-cache.cc
Normal file
131
src/routing/manet/dpd/id-cache.cc
Normal file
@@ -0,0 +1,131 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
#include "id-cache.h"
|
||||
#include "ns3/test.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace dpd
|
||||
{
|
||||
bool
|
||||
IdCache::IsDuplicate (Ipv4Address addr, uint32_t id)
|
||||
{
|
||||
Purge ();
|
||||
for (std::vector<UniqueId>::const_iterator i = m_idCache.begin ();
|
||||
i != m_idCache.end (); ++i)
|
||||
if (i->m_context == addr && i->m_id == id)
|
||||
return true;
|
||||
struct UniqueId uniqueId =
|
||||
{ addr, id, m_lifetime + Simulator::Now () };
|
||||
m_idCache.push_back (uniqueId);
|
||||
return false;
|
||||
}
|
||||
void
|
||||
IdCache::Purge ()
|
||||
{
|
||||
m_idCache.erase (remove_if (m_idCache.begin (), m_idCache.end (),
|
||||
IsExpired ()), m_idCache.end ());
|
||||
}
|
||||
|
||||
uint32_t
|
||||
IdCache::GetSize ()
|
||||
{
|
||||
Purge ();
|
||||
return m_idCache.size ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Tests
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Unit test for id cache
|
||||
struct IdCacheTest : public TestCase
|
||||
{
|
||||
IdCacheTest () : TestCase ("Id Cache"), cache (Seconds(10))
|
||||
{}
|
||||
virtual bool DoRun();
|
||||
void CheckTimeout1 ();
|
||||
void CheckTimeout2 ();
|
||||
void CheckTimeout3 ();
|
||||
|
||||
IdCache cache;
|
||||
};
|
||||
|
||||
bool
|
||||
IdCacheTest::DoRun ()
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ (cache.GetLifeTime(), Seconds(10), "Lifetime");
|
||||
NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("1.2.3.4"), 3), false, "Unknown ID & address");
|
||||
NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("1.2.3.4"), 4), false, "Unknown ID");
|
||||
NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("4.3.2.1"), 3), false, "Unknown address");
|
||||
NS_TEST_EXPECT_MSG_EQ (cache.IsDuplicate (Ipv4Address ("1.2.3.4"), 3), true, "Known address & ID");
|
||||
cache.SetLifetime(Seconds(15));
|
||||
NS_TEST_EXPECT_MSG_EQ (cache.GetLifeTime(), Seconds(15), "New lifetime");
|
||||
cache.IsDuplicate (Ipv4Address ("1.1.1.1"), 4);
|
||||
cache.IsDuplicate (Ipv4Address ("1.1.1.1"), 4);
|
||||
cache.IsDuplicate (Ipv4Address ("2.2.2.2"), 5);
|
||||
cache.IsDuplicate (Ipv4Address ("3.3.3.3"), 6);
|
||||
NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 6, "trivial");
|
||||
|
||||
Simulator::Schedule (Seconds(5), &IdCacheTest::CheckTimeout1, this);
|
||||
Simulator::Schedule (Seconds(11), &IdCacheTest::CheckTimeout2, this);
|
||||
Simulator::Schedule (Seconds(30), &IdCacheTest::CheckTimeout3, this);
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
void
|
||||
IdCacheTest::CheckTimeout1 ()
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 6, "Nothing expire");
|
||||
}
|
||||
|
||||
void
|
||||
IdCacheTest::CheckTimeout2 ()
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 3, "3 records left");
|
||||
}
|
||||
|
||||
void
|
||||
IdCacheTest::CheckTimeout3 ()
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ (cache.GetSize (), 0, "All records expire");
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
class IdCacheTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
IdCacheTestSuite () : TestSuite ("routing-id-cache", UNIT)
|
||||
{
|
||||
AddTestCase (new IdCacheTest);
|
||||
}
|
||||
} g_idCacheTestSuite;
|
||||
|
||||
}}
|
||||
86
src/routing/manet/dpd/id-cache.h
Normal file
86
src/routing/manet/dpd/id-cache.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Based on
|
||||
* NS-2 AODV model developed by the CMU/MONARCH group and optimized and
|
||||
* tuned by Samir Das and Mahesh Marina, University of Cincinnati;
|
||||
*
|
||||
* AODV-UU implementation by Erik Nordström of Uppsala University
|
||||
* http://core.it.uu.se/core/index.php/AODV-UU
|
||||
*
|
||||
* Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#ifndef IDCACHE_H_
|
||||
#define IDCACHE_H_
|
||||
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include <vector>
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace dpd
|
||||
{
|
||||
/**
|
||||
* \ingroup dpd
|
||||
*
|
||||
* \brief Unique packets identification cache used for simple duplicate detection.
|
||||
*/
|
||||
class IdCache
|
||||
{
|
||||
public:
|
||||
/// c-tor
|
||||
IdCache (Time lifetime): m_lifetime (lifetime) {}
|
||||
/// Check that entry (addr, id) exists in cache. Add entry, if it doesn't exist.
|
||||
bool IsDuplicate (Ipv4Address addr, uint32_t id);
|
||||
/// Remove all expired entries
|
||||
void Purge ();
|
||||
/// Return number of entries in cache
|
||||
uint32_t GetSize ();
|
||||
/// Set lifetime for future added entries.
|
||||
void SetLifetime (Time lifetime) { m_lifetime = lifetime; }
|
||||
/// Return lifetime for existing entries in cache
|
||||
Time GetLifeTime () const { return m_lifetime; }
|
||||
private:
|
||||
/// Unique packet ID
|
||||
struct UniqueId
|
||||
{
|
||||
/// ID is supposed to be unique in single address context (e.g. sender address)
|
||||
Ipv4Address m_context;
|
||||
/// The id
|
||||
uint32_t m_id;
|
||||
/// When record will expire
|
||||
Time m_expire;
|
||||
};
|
||||
struct IsExpired
|
||||
{
|
||||
bool operator() (const struct UniqueId & u) const
|
||||
{
|
||||
return (u.m_expire < Simulator::Now ());
|
||||
}
|
||||
};
|
||||
/// Already seen IDs
|
||||
std::vector<UniqueId> m_idCache;
|
||||
/// Default lifetime for ID records
|
||||
Time m_lifetime;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* IDCACHE_H_ */
|
||||
1
src/routing/manet/dpd/waf
vendored
Executable file
1
src/routing/manet/dpd/waf
vendored
Executable file
@@ -0,0 +1 @@
|
||||
exec "`dirname "$0"`"/../../../../waf "$@"
|
||||
17
src/routing/manet/dpd/wscript
Normal file
17
src/routing/manet/dpd/wscript
Normal file
@@ -0,0 +1,17 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
module = bld.create_ns3_module('dpd', ['contrib'])
|
||||
module.includes = '.'
|
||||
module.source = [
|
||||
'id-cache.cc',
|
||||
'dpd.cc'
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers.module = 'dpd'
|
||||
headers.source = [
|
||||
'dpd.h',
|
||||
'id-cache.h',
|
||||
]
|
||||
|
||||
@@ -32,6 +32,8 @@ all_modules = (
|
||||
'routing/global-routing',
|
||||
'routing/static-routing',
|
||||
'routing/list-routing',
|
||||
'routing/manet/aodv',
|
||||
'routing/manet/dpd',
|
||||
'mobility',
|
||||
'devices/wifi',
|
||||
'helper',
|
||||
|
||||
Reference in New Issue
Block a user