From d3ec8f8791f7b7f4ee60e7dc57b60702050a95c7 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 26 Jul 2007 12:05:31 +0100 Subject: [PATCH 01/61] EvenId const fixes. --- src/simulator/event-id.cc | 4 ++-- src/simulator/event-id.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/simulator/event-id.cc b/src/simulator/event-id.cc index 18f875935..1c2915037 100644 --- a/src/simulator/event-id.cc +++ b/src/simulator/event-id.cc @@ -45,12 +45,12 @@ EventId::Cancel (void) } } bool -EventId::IsExpired (void) +EventId::IsExpired (void) const { return Simulator::IsExpired (*this); } bool -EventId::IsRunning (void) +EventId::IsRunning (void) const { return !IsExpired (); } diff --git a/src/simulator/event-id.h b/src/simulator/event-id.h index 4350c9bbe..52371faa1 100644 --- a/src/simulator/event-id.h +++ b/src/simulator/event-id.h @@ -44,8 +44,8 @@ public: * method. * \returns true if the event has expired, false otherwise. */ - bool IsExpired (void); - bool IsRunning (void); + bool IsExpired (void) const; + bool IsRunning (void) const; public: /* The following methods are semi-private * they are supposed to be invoked only by From ccd6240e232338e46bd805a04fb731c53fb1deb2 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 26 Jul 2007 12:08:22 +0100 Subject: [PATCH 02/61] Add a Timer class (bug #46) --- src/simulator/timer.cc | 81 +++++++++++++++ src/simulator/timer.h | 223 +++++++++++++++++++++++++++++++++++++++++ src/simulator/wscript | 2 + 3 files changed, 306 insertions(+) create mode 100644 src/simulator/timer.cc create mode 100644 src/simulator/timer.h diff --git a/src/simulator/timer.cc b/src/simulator/timer.cc new file mode 100644 index 000000000..823efb65b --- /dev/null +++ b/src/simulator/timer.cc @@ -0,0 +1,81 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo Carneiro + */ + +#include "timer.h" + +#ifdef RUN_SELF_TESTS + +#include "ns3/test.h" + +namespace ns3 { + +class TimerTests : public Test +{ + int m_counter; +public: + TimerTests (); + virtual ~TimerTests (); + virtual bool RunTests (void); + + void TimerCallback (int x); +}; + +TimerTests::TimerTests () + : Test ("Timer"), m_counter (0) +{} +TimerTests::~TimerTests () +{} + +void +TimerTests::TimerCallback (int x) +{ + m_counter += x; +} + +bool TimerTests::RunTests (void) +{ + bool result = true; + + Timer timer1 (MilliSeconds (1), MakeCallback (&TimerTests::TimerCallback, this)); + + // Check if it works in the common case + timer1.Schedule (1); + Simulator::Run (); + NS_TEST_ASSERT_EQUAL (m_counter, 1); + + // Check that it does not repeat itself + Simulator::Run (); + NS_TEST_ASSERT_EQUAL (m_counter, 1); + + // Check cancellation + timer1.Schedule (1); + timer1.Cancel (); + Simulator::Run (); + NS_TEST_ASSERT_EQUAL (m_counter, 1); + + return result; +} + +static TimerTests g_timerTests; + +}; + +#endif /* RUN_SELF_TESTS */ diff --git a/src/simulator/timer.h b/src/simulator/timer.h new file mode 100644 index 000000000..6be706fa6 --- /dev/null +++ b/src/simulator/timer.h @@ -0,0 +1,223 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo Carneiro + */ +#ifndef TIMER_H +#define TIMER_H + +#include "simulator.h" +#include "ns3/callback.h" +#include "nstime.h" + +namespace ns3 { + +template +class Timer +{ +public: + typedef Callback CallbackType; + +protected: + Time m_interval; + CallbackType m_callback; + EventId m_eventId; + T1 m_t1; + T2 m_t2; + T3 m_t3; + T4 m_t4; + T5 m_t5; + + +public: + + /** + * \brief create a new timer object + * + * Constructs a new timer object with the given interval and callback. + * The timer will not actually start until Schedule() is called. + * + * \param interval The time interval after which the timer will expire + * \param callback The callback object that will be invoked when the + * timer expires + * + */ + Timer (Time const &interval, CallbackType callback) + : m_interval (interval), m_callback (callback) + { + } + + Timer (CallbackType callback) + : m_callback (callback) + { + } + + bool IsRunning () const + { + return m_eventId.IsRunning (); + } + + /** + * \brief start the timer + * + * Calling Schedule() on a timer essentially starts running + * it. After the configured interval, the timer will expire and the + * registered callback will be invoked. + */ + void Schedule () + { + if (m_eventId.IsRunning ()) + Simulator::Cancel (m_eventId); + m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this); + } + void Schedule (T1 v1) + { + if (m_eventId.IsRunning ()) + Simulator::Cancel (m_eventId); + m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this, + v1); + } + void Schedule (T1 v1, T2 v2) + { + if (m_eventId.IsRunning ()) + Simulator::Cancel (m_eventId); + m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this, + v1, v2); + } + void Schedule (T1 v1, T2 v2, T3 v3) + { + if (m_eventId.IsRunning ()) + Simulator::Cancel (m_eventId); + m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this, + v1, v2, v3); + } + void Schedule (T1 v1, T2 v2, T3 v3, T4 v4) + { + if (m_eventId.IsRunning ()) + Simulator::Cancel (m_eventId); + m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this, + v1, v2, v3, v4); + } + void Schedule (T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) + { + if (m_eventId.IsRunning ()) + Simulator::Cancel (m_eventId); + m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this, + v1, v2, v3, v4, v5); + } + + /** + * \brief changes the time interval for future Schedule() calls + * + * \param interval The time interval after which the timer will expire + */ + void SetInterval (Time const &interval) + { + m_interval = interval; + } + + /** + * \brief cancel the timer + * + * Cancels the timer; after calling Cancel () the registered + * callback will no longer be invoked, unless Schedule() is called + * again. May be called even if the timer is not running. + */ + void Cancel () + { + if (m_eventId.IsRunning ()) + Simulator::Cancel (m_eventId); + } + + ~Timer () + { + Cancel (); + } + + /** + * \brief artificially expire the timer + * + * Expires the timer at the current time. This will result in the + * registered callback to be invoked and the previously schedule + * timeout, if any, to be cancelled. + */ + void Expire () + { + Cancel (); + Expired (); + } + void Expire (T1 v1) + { + Cancel (); + Expired (v1); + } + void Expire (T1 v1, T2 v2) + { + Cancel (); + Expired (v1, v2); + } + void Expire (T1 v1, T2 v2, T3 v3) + { + Cancel (); + Expired (v1, v2, v3); + } + void Expire (T1 v1, T2 v2, T3 v3, T4 v4) + { + Cancel (); + Expired (v1, v2, v3, v4); + } + void Expire (T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) + { + Cancel (); + Expired (v1, v2, v3, v4, v5); + } + +private: + void Expired () + { + m_callback (); + } + void Expired (T1 v1) + { + m_callback (v1); + } + void Expired (T1 v1, T2 v2) + { + m_callback (v1, v2); + } + void Expired (T1 v1, T2 v2, T3 v3) + { + m_callback (v1, v2, v3); + } + void Expired (T1 v1, T2 v2, T3 v3, T4 v4) + { + m_callback (v1, v2, v3, v4); + } + void Expired (T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) + { + m_callback (v1, v2, v3, v4, v5); + } + +}; + + +}; // namespace ns3 + +#endif /* TIMER_H */ diff --git a/src/simulator/wscript b/src/simulator/wscript index c9f14bd67..f043d65b6 100644 --- a/src/simulator/wscript +++ b/src/simulator/wscript @@ -55,6 +55,7 @@ def build(bld): sim.source = [ 'high-precision.cc', 'time.cc', + 'timer.cc', 'event-id.cc', 'scheduler.cc', 'scheduler-factory.cc', @@ -71,6 +72,7 @@ def build(bld): headers.source = [ 'high-precision.h', 'nstime.h', + 'timer.h', 'event-id.h', 'event-impl.h', 'simulator.h', From 48cf146a6f5541f153e6be67137df7d56843d775 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 26 Jul 2007 12:11:37 +0100 Subject: [PATCH 03/61] Add Ipv4Address::CombineMask, and implement Ipv4Address::IsBroadcast. --- src/node/ipv4-address.cc | 12 ++++++++++++ src/node/ipv4-address.h | 15 ++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/node/ipv4-address.cc b/src/node/ipv4-address.cc index f8ff9f7a6..5e68720e3 100644 --- a/src/node/ipv4-address.cc +++ b/src/node/ipv4-address.cc @@ -145,6 +145,18 @@ Ipv4Address::IsEqual (Ipv4Address other) const } } +bool +Ipv4Address::IsBroadcast (void) const +{ + return (m_address == 0xffffffffU); +} + +Ipv4Address +Ipv4Address::CombineMask (Ipv4Mask const &mask) const +{ + return Ipv4Address (GetHostOrder () & mask.GetHostOrder ()); +} + bool Ipv4Address::IsMulticast (void) { diff --git a/src/node/ipv4-address.h b/src/node/ipv4-address.h index dc834052a..0fe400af5 100644 --- a/src/node/ipv4-address.h +++ b/src/node/ipv4-address.h @@ -27,6 +27,8 @@ namespace ns3 { +class Ipv4Mask; + /** Ipv4 addresses are stored in host order in * this class. */ @@ -80,8 +82,19 @@ public: */ void Print (std::ostream &os) const; - bool IsBroadcast (void); + bool IsBroadcast (void) const; bool IsMulticast (void); + + /** + * \brief Combine this address with a network mask + * + * This method returns an IPv4 address that is this address combined + * (bitwise and) with a network mask, yielding an IPv4 network + * address. + * + * \param a network mask + */ + Ipv4Address CombineMask (Ipv4Mask const &mask) const; static Ipv4Address GetZero (void); static Ipv4Address GetAny (void); From e45d934cb62cef68024813eaa59fe6bba5dd7911 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 26 Jul 2007 12:12:51 +0100 Subject: [PATCH 04/61] Allow ARP resolution to work with broadcast IPv4 (dest=255.255.255.255) packets; Partially fixes bug #36. --- src/internet-node/arp-cache.cc | 2 ++ src/internet-node/arp-ipv4-interface.cc | 15 ++++++++++++++- src/internet-node/arp-l3-protocol.cc | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/internet-node/arp-cache.cc b/src/internet-node/arp-cache.cc index e9f48561d..92cb13af4 100644 --- a/src/internet-node/arp-cache.cc +++ b/src/internet-node/arp-cache.cc @@ -109,6 +109,8 @@ ArpCache::Lookup (Ipv4Address to) ArpCache::Entry * ArpCache::Add (Ipv4Address to) { + NS_ASSERT (m_arpCache.find (to) == m_arpCache.end ()); + ArpCache::Entry *entry = new ArpCache::Entry (this); m_arpCache[to] = entry; return entry; diff --git a/src/internet-node/arp-ipv4-interface.cc b/src/internet-node/arp-ipv4-interface.cc index 42d6af238..4ca7ebbb3 100644 --- a/src/internet-node/arp-ipv4-interface.cc +++ b/src/internet-node/arp-ipv4-interface.cc @@ -21,6 +21,7 @@ */ #include "ns3/packet.h" +#include "ns3/debug.h" #include "ns3/composite-trace-resolver.h" #include "ns3/node.h" #include "ns3/net-device.h" @@ -60,7 +61,19 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest) { Ptr arp = m_node->QueryInterface (ArpPrivate::iid); MacAddress hardwareDestination; - bool found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination); + bool found; + + if (dest.IsBroadcast ()) + { + hardwareDestination = GetDevice ()->GetBroadcast (); + found = true; + } + else + { + Ptr arp = m_node->QueryInterface (ArpPrivate::iid); + found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination); + } + if (found) { GetDevice ()->Send (p, hardwareDestination, Ipv4L3Protocol::PROT_NUMBER); diff --git a/src/internet-node/arp-l3-protocol.cc b/src/internet-node/arp-l3-protocol.cc index f04a6aa25..b68995be3 100644 --- a/src/internet-node/arp-l3-protocol.cc +++ b/src/internet-node/arp-l3-protocol.cc @@ -87,6 +87,13 @@ ArpL3Protocol::Receive(Packet& packet, Ptr device) ArpCache *cache = FindCache (device); ArpHeader arp; packet.RemoveHeader (arp); + + NS_DEBUG ("ARP: received "<< (arp.IsRequest ()? "request" : "reply") << + " node="<GetId ()<<", got request from " << + arp.GetSourceIpv4Address () << " for address " << + arp.GetDestinationIpv4Address () << "; we have address " << + cache->GetInterface ()->GetAddress ()); + if (arp.IsRequest () && arp.GetDestinationIpv4Address () == cache->GetInterface ()->GetAddress ()) { @@ -128,6 +135,12 @@ ArpL3Protocol::Receive(Packet& packet, Ptr device) // XXX report packet as dropped. } } + else + { + NS_DEBUG ("node="<GetId ()<<", got request from " << + arp.GetSourceIpv4Address () << " for unknown address " << + arp.GetDestinationIpv4Address () << " -- drop"); + } } bool ArpL3Protocol::Lookup (Packet &packet, Ipv4Address destination, @@ -203,6 +216,11 @@ void ArpL3Protocol::SendArpRequest (ArpCache const *cache, Ipv4Address to) { ArpHeader arp; + NS_DEBUG ("ARP: sending request from node "<GetId ()<< + " || src: " << cache->GetDevice ()->GetAddress () << + " / " << cache->GetInterface ()->GetAddress () << + " || dst: " << cache->GetDevice ()->GetBroadcast () << + " / " << to); arp.SetRequest (cache->GetDevice ()->GetAddress (), cache->GetInterface ()->GetAddress (), cache->GetDevice ()->GetBroadcast (), @@ -216,6 +234,10 @@ void ArpL3Protocol::SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac) { ArpHeader arp; + NS_DEBUG ("ARP: sending reply from node "<GetId ()<< + "|| src: " << cache->GetDevice ()->GetAddress () << + " / " << cache->GetInterface ()->GetAddress () << + " || dst: " << toMac << " / " << toIp); arp.SetReply (cache->GetDevice ()->GetAddress (), cache->GetInterface ()->GetAddress (), toMac, toIp); From c2c923ba116ab20486faefad72998c92b9afd033 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 26 Jul 2007 12:26:21 +0100 Subject: [PATCH 05/61] Support dynamic routing and multiple routing protocols; static routing table is refactored as a "routing protocol". Support sending IP broadcast (255.255.255.255) packets (bug #36). --- src/internet-node/ipv4-impl.cc | 7 + src/internet-node/ipv4-impl.h | 3 + src/internet-node/ipv4-l3-protocol.cc | 257 +++++++---------------- src/internet-node/ipv4-l3-protocol.h | 34 +-- src/internet-node/ipv4-static-routing.cc | 253 ++++++++++++++++++++++ src/internet-node/ipv4-static-routing.h | 101 +++++++++ src/internet-node/wscript | 2 + src/node/ipv4.h | 30 ++- 8 files changed, 494 insertions(+), 193 deletions(-) create mode 100644 src/internet-node/ipv4-static-routing.cc create mode 100644 src/internet-node/ipv4-static-routing.h diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-node/ipv4-impl.cc index 9c7754be9..020413896 100644 --- a/src/internet-node/ipv4-impl.cc +++ b/src/internet-node/ipv4-impl.cc @@ -39,6 +39,13 @@ Ipv4Impl::DoDispose (void) m_ipv4 = 0; } +void +Ipv4Impl::AddRoutingProtocol (Ptr routingProtocol, + int priority) +{ + m_ipv4->AddRoutingProtocol (routingProtocol, priority); +} + void Ipv4Impl::AddHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, diff --git a/src/internet-node/ipv4-impl.h b/src/internet-node/ipv4-impl.h index 979eb02f9..32d9e5c68 100644 --- a/src/internet-node/ipv4-impl.h +++ b/src/internet-node/ipv4-impl.h @@ -35,6 +35,9 @@ public: virtual ~Ipv4Impl (); + virtual void AddRoutingProtocol (Ptr routingProtocol, + int priority); + virtual void AddHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, uint32_t interface); diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index 4a46290e6..114eca9cc 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -48,9 +48,10 @@ Ipv4L3Protocol::Ipv4L3Protocol(Ptr node) m_nInterfaces (0), m_defaultTtl (64), m_identification (0), - m_defaultRoute (0), m_node (node) { + m_staticRouting = Create (); + AddRoutingProtocol (m_staticRouting, 0); SetupLoopback (); } Ipv4L3Protocol::~Ipv4L3Protocol () @@ -64,25 +65,10 @@ Ipv4L3Protocol::DoDispose (void) delete (*i); } m_interfaces.clear (); - for (HostRoutesI i = m_hostRoutes.begin (); - i != m_hostRoutes.end (); - i = m_hostRoutes.erase (i)) - { - delete (*i); - } - for (NetworkRoutesI j = m_networkRoutes.begin (); - j != m_networkRoutes.end (); - j = m_networkRoutes.erase (j)) - { - delete (*j); - } - if (m_defaultRoute != 0) - { - delete m_defaultRoute; - m_defaultRoute = 0; - } m_node = 0; L3Protocol::DoDispose (); + m_staticRouting->Dispose (); + m_staticRouting = 0; } void @@ -132,17 +118,13 @@ Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, uint32_t interface) { - Ipv4Route *route = new Ipv4Route (); - *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface); - m_hostRoutes.push_back (route); + m_staticRouting->AddHostRouteTo (dest, nextHop, interface); } void Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, uint32_t interface) { - Ipv4Route *route = new Ipv4Route (); - *route = Ipv4Route::CreateHostRouteTo (dest, interface); - m_hostRoutes.push_back (route); + m_staticRouting->AddHostRouteTo (dest, interface); } void Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, @@ -150,163 +132,63 @@ Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, Ipv4Address nextHop, uint32_t interface) { - Ipv4Route *route = new Ipv4Route (); - *route = Ipv4Route::CreateNetworkRouteTo (network, - networkMask, - nextHop, - interface); - m_networkRoutes.push_back (route); + m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface); } void Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, Ipv4Mask networkMask, uint32_t interface) { - Ipv4Route *route = new Ipv4Route (); - *route = Ipv4Route::CreateNetworkRouteTo (network, - networkMask, - interface); - m_networkRoutes.push_back (route); + m_staticRouting->AddNetworkRouteTo (network, networkMask, interface); } void Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop, uint32_t interface) { - Ipv4Route *route = new Ipv4Route (); - *route = Ipv4Route::CreateDefaultRoute (nextHop, interface); - delete m_defaultRoute; - m_defaultRoute = route; + m_staticRouting->SetDefaultRoute (nextHop, interface); } -Ipv4Route * -Ipv4L3Protocol::Lookup (Ipv4Address dest) + +void +Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader, + Packet packet, + Ipv4RoutingProtocol::RouteReplyCallback routeReply) { - for (HostRoutesCI i = m_hostRoutes.begin (); - i != m_hostRoutes.end (); - i++) + for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin (); + rprotoIter != m_routingProtocols.end (); rprotoIter++) { - NS_ASSERT ((*i)->IsHost ()); - if ((*i)->GetDest ().IsEqual (dest)) - { - return (*i); - } + if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply)) + return; } - for (NetworkRoutesI j = m_networkRoutes.begin (); - j != m_networkRoutes.end (); - j++) - { - NS_ASSERT ((*j)->IsNetwork ()); - Ipv4Mask mask = (*j)->GetDestNetworkMask (); - Ipv4Address entry = (*j)->GetDestNetwork (); - if (mask.IsMatch (dest, entry)) - { - return (*j); - } - } - if (m_defaultRoute != 0) - { - NS_ASSERT (m_defaultRoute->IsDefault ()); - return m_defaultRoute; - } - return 0; + // No route found + routeReply (false, Ipv4Route (), packet, ipHeader); +} + +void +Ipv4L3Protocol::AddRoutingProtocol (Ptr routingProtocol, + int priority) +{ + m_routingProtocols.push_back + (std::pair > (-priority, routingProtocol)); + m_routingProtocols.sort (); } uint32_t Ipv4L3Protocol::GetNRoutes (void) { - uint32_t n = 0; - if (m_defaultRoute != 0) - { - n++; - } - n += m_hostRoutes.size (); - n += m_networkRoutes.size (); - return n; + return m_staticRouting->GetNRoutes (); } + Ipv4Route * Ipv4L3Protocol::GetRoute (uint32_t index) { - if (index == 0 && m_defaultRoute != 0) - { - return m_defaultRoute; - } - if (index > 0 && m_defaultRoute != 0) - { - index--; - } - if (index < m_hostRoutes.size ()) - { - uint32_t tmp = 0; - for (HostRoutesCI i = m_hostRoutes.begin (); - i != m_hostRoutes.end (); - i++) - { - if (tmp == index) - { - return *i; - } - tmp++; - } - } - index -= m_hostRoutes.size (); - uint32_t tmp = 0; - for (NetworkRoutesI j = m_networkRoutes.begin (); - j != m_networkRoutes.end (); - j++) - { - if (tmp == index) - { - return *j; - } - tmp++; - } - NS_ASSERT (false); - // quiet compiler. - return 0; + return m_staticRouting->GetRoute (index); } + void Ipv4L3Protocol::RemoveRoute (uint32_t index) { - if (index == 0 && m_defaultRoute != 0) - { - delete m_defaultRoute; - m_defaultRoute = 0; - } - if (index > 0 && m_defaultRoute != 0) - { - index--; - } - if (index < m_hostRoutes.size ()) - { - uint32_t tmp = 0; - for (HostRoutesI i = m_hostRoutes.begin (); - i != m_hostRoutes.end (); - i++) - { - if (tmp == index) - { - delete *i; - m_hostRoutes.erase (i); - return; - } - tmp++; - } - } - index -= m_hostRoutes.size (); - uint32_t tmp = 0; - for (NetworkRoutesI j = m_networkRoutes.begin (); - j != m_networkRoutes.end (); - j++) - { - if (tmp == index) - { - delete *j; - m_networkRoutes.erase (j); - return; - } - tmp++; - } - NS_ASSERT (false); + m_staticRouting->RemoveRoute (index); } @@ -386,6 +268,7 @@ Ipv4L3Protocol::Receive(Packet& packet, Ptr device) ForwardUp (packet, ipHeader); } + void Ipv4L3Protocol::Send (Packet const &packet, Ipv4Address source, @@ -404,30 +287,49 @@ Ipv4L3Protocol::Send (Packet const &packet, m_identification ++; - // XXX Note here that in most ipv4 stacks in the world, - // the route calculation for an outgoing packet is not - // done in the ip layer. It is done within the application - // socket when the first packet is sent to avoid this - // costly lookup on a per-packet basis. - // That would require us to get the route from the packet, - // most likely with a packet tag. The higher layers do not - // do this yet for us. - Ipv4Route *route = Lookup (ipHeader.GetDestination ()); - if (route == 0) + if (destination.IsBroadcast ()) { - NS_DEBUG ("not for me -- forwarding but no route to host. drop."); - m_dropTrace (packet); - return; - } + uint32_t ifaceIndex = 0; + for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin (); + ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++) + { + Ipv4Interface *outInterface = *ifaceIter; + Packet packetCopy = packet; - SendRealOut (packet, ipHeader, *route); + NS_ASSERT (packetCopy.GetSize () <= outInterface->GetMtu ()); + packetCopy.AddHeader (ipHeader); + m_txTrace (packetCopy, ifaceIndex); + outInterface->Send (packetCopy, destination); + } + } + else + { + // XXX Note here that in most ipv4 stacks in the world, + // the route calculation for an outgoing packet is not + // done in the ip layer. It is done within the application + // socket when the first packet is sent to avoid this + // costly lookup on a per-packet basis. + // That would require us to get the route from the packet, + // most likely with a packet tag. The higher layers do not + // do this yet for us. + Lookup (ipHeader, packet, + MakeCallback (&Ipv4L3Protocol::SendRealOut, this)); + } } void -Ipv4L3Protocol::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route) +Ipv4L3Protocol::SendRealOut (bool found, + Ipv4Route const &route, + Packet packet, + Ipv4Header const &ipHeader) { - Packet packet = p; - packet.AddHeader (ip); + if (!found) + { + NS_DEBUG ("no route to host. drop."); + m_dropTrace (packet); + return; + } + packet.AddHeader (ipHeader); Ipv4Interface *outInterface = GetInterface (route.GetInterface ()); NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ()); m_txTrace (packet, route.GetInterface ()); @@ -437,7 +339,7 @@ Ipv4L3Protocol::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route co } else { - outInterface->Send (packet, ip.GetDestination ()); + outInterface->Send (packet, ipHeader.GetDestination ()); } } @@ -470,7 +372,7 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr routingProtocol, + int priority); protected: + virtual void DoDispose (void); + private: - void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route); + + void SendRealOut (bool found, + Ipv4Route const &route, + Packet packet, + Ipv4Header const &ipHeader); bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr device); void ForwardUp (Packet p, Ipv4Header const&ip); uint32_t AddIpv4Interface (Ipv4Interface *interface); @@ -155,26 +169,22 @@ private: TraceResolver *InterfacesCreateTraceResolver (TraceContext const &context) const; typedef std::list Ipv4InterfaceList; - typedef std::list HostRoutes; - typedef std::list::const_iterator HostRoutesCI; - typedef std::list::iterator HostRoutesI; - typedef std::list NetworkRoutes; - typedef std::list::const_iterator NetworkRoutesCI; - typedef std::list::iterator NetworkRoutesI; + typedef std::list< std::pair< int, Ptr > > Ipv4RoutingProtocolList; Ipv4InterfaceList m_interfaces; uint32_t m_nInterfaces; uint8_t m_defaultTtl; uint16_t m_identification; - HostRoutes m_hostRoutes; - NetworkRoutes m_networkRoutes; - Ipv4Route *m_defaultRoute; Ptr m_node; CallbackTraceSource m_txTrace; CallbackTraceSource m_rxTrace; CallbackTraceSource m_dropTrace; + + Ipv4RoutingProtocolList m_routingProtocols; + + Ptr m_staticRouting; }; } // Namespace ns3 -#endif /* IPV$_L3_PROTOCOL_H */ +#endif /* IPV4_L3_PROTOCOL_H */ diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-node/ipv4-static-routing.cc new file mode 100644 index 000000000..b70c1c1af --- /dev/null +++ b/src/internet-node/ipv4-static-routing.cc @@ -0,0 +1,253 @@ +// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- +// +// Copyright (c) 2006 Georgia Tech Research Corporation +// All rights reserved. +// +// 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 +// +// Author: George F. Riley +// Gustavo Carneiro + +#include "ipv4-static-routing.h" +#include "ns3/packet.h" + + +namespace ns3 { + + +void +Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, + Ipv4Address nextHop, + uint32_t interface) +{ + Ipv4Route *route = new Ipv4Route (); + *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface); + m_hostRoutes.push_back (route); +} +void +Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, + uint32_t interface) +{ + Ipv4Route *route = new Ipv4Route (); + *route = Ipv4Route::CreateHostRouteTo (dest, interface); + m_hostRoutes.push_back (route); +} +void +Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, + Ipv4Mask networkMask, + Ipv4Address nextHop, + uint32_t interface) +{ + Ipv4Route *route = new Ipv4Route (); + *route = Ipv4Route::CreateNetworkRouteTo (network, + networkMask, + nextHop, + interface); + m_networkRoutes.push_back (route); +} +void +Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, + Ipv4Mask networkMask, + uint32_t interface) +{ + Ipv4Route *route = new Ipv4Route (); + *route = Ipv4Route::CreateNetworkRouteTo (network, + networkMask, + interface); + m_networkRoutes.push_back (route); +} +void +Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop, + uint32_t interface) +{ + Ipv4Route *route = new Ipv4Route (); + *route = Ipv4Route::CreateDefaultRoute (nextHop, interface); + delete m_defaultRoute; + m_defaultRoute = route; +} + +Ipv4Route * +Ipv4StaticRouting::LookupStatic (Ipv4Address dest) +{ + for (HostRoutesCI i = m_hostRoutes.begin (); + i != m_hostRoutes.end (); + i++) + { + NS_ASSERT ((*i)->IsHost ()); + if ((*i)->GetDest ().IsEqual (dest)) + { + return (*i); + } + } + for (NetworkRoutesI j = m_networkRoutes.begin (); + j != m_networkRoutes.end (); + j++) + { + NS_ASSERT ((*j)->IsNetwork ()); + Ipv4Mask mask = (*j)->GetDestNetworkMask (); + Ipv4Address entry = (*j)->GetDestNetwork (); + if (mask.IsMatch (dest, entry)) + { + return (*j); + } + } + if (m_defaultRoute != 0) + { + NS_ASSERT (m_defaultRoute->IsDefault ()); + return m_defaultRoute; + } + return 0; +} + +uint32_t +Ipv4StaticRouting::GetNRoutes (void) +{ + uint32_t n = 0; + if (m_defaultRoute != 0) + { + n++; + } + n += m_hostRoutes.size (); + n += m_networkRoutes.size (); + return n; +} +Ipv4Route * +Ipv4StaticRouting::GetRoute (uint32_t index) +{ + if (index == 0 && m_defaultRoute != 0) + { + return m_defaultRoute; + } + if (index > 0 && m_defaultRoute != 0) + { + index--; + } + if (index < m_hostRoutes.size ()) + { + uint32_t tmp = 0; + for (HostRoutesCI i = m_hostRoutes.begin (); + i != m_hostRoutes.end (); + i++) + { + if (tmp == index) + { + return *i; + } + tmp++; + } + } + index -= m_hostRoutes.size (); + uint32_t tmp = 0; + for (NetworkRoutesI j = m_networkRoutes.begin (); + j != m_networkRoutes.end (); + j++) + { + if (tmp == index) + { + return *j; + } + tmp++; + } + NS_ASSERT (false); + // quiet compiler. + return 0; +} +void +Ipv4StaticRouting::RemoveRoute (uint32_t index) +{ + if (index == 0 && m_defaultRoute != 0) + { + delete m_defaultRoute; + m_defaultRoute = 0; + } + if (index > 0 && m_defaultRoute != 0) + { + index--; + } + if (index < m_hostRoutes.size ()) + { + uint32_t tmp = 0; + for (HostRoutesI i = m_hostRoutes.begin (); + i != m_hostRoutes.end (); + i++) + { + if (tmp == index) + { + delete *i; + m_hostRoutes.erase (i); + return; + } + tmp++; + } + } + index -= m_hostRoutes.size (); + uint32_t tmp = 0; + for (NetworkRoutesI j = m_networkRoutes.begin (); + j != m_networkRoutes.end (); + j++) + { + if (tmp == index) + { + delete *j; + m_networkRoutes.erase (j); + return; + } + tmp++; + } + NS_ASSERT (false); +} + +bool +Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader, + Packet packet, + RouteReplyCallback routeReply) +{ + Ipv4Route *route = LookupStatic (ipHeader.GetDestination ()); + if (route != 0) + { + routeReply (true, *route, packet, ipHeader); + return true; + } + else + { + return false; // Let other routing protocols try to handle this + // route request. + } +} + +void +Ipv4StaticRouting::DoDispose (void) +{ + for (HostRoutesI i = m_hostRoutes.begin (); + i != m_hostRoutes.end (); + i = m_hostRoutes.erase (i)) + { + delete (*i); + } + for (NetworkRoutesI j = m_networkRoutes.begin (); + j != m_networkRoutes.end (); + j = m_networkRoutes.erase (j)) + { + delete (*j); + } + if (m_defaultRoute != 0) + { + delete m_defaultRoute; + m_defaultRoute = 0; + } + Ipv4RoutingProtocol::DoDispose (); +} + + +}//namespace ns3 diff --git a/src/internet-node/ipv4-static-routing.h b/src/internet-node/ipv4-static-routing.h new file mode 100644 index 000000000..f7e6d52ab --- /dev/null +++ b/src/internet-node/ipv4-static-routing.h @@ -0,0 +1,101 @@ +// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- +// +// Copyright (c) 2006 Georgia Tech Research Corporation +// All rights reserved. +// +// 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 +// +// Author: George F. Riley +// Gustavo Carneiro +// + +#ifndef IPV4_STATIC_ROUTING_H +#define IPV4_STATIC_ROUTING_H + +#include +#include +#include "ns3/callback-trace-source.h" +#include "ns3/array-trace-resolver.h" +#include "ns3/ipv4-address.h" +#include "ipv4-header.h" +#include "ns3/ptr.h" +#include "ns3/ipv4.h" +#include "l3-protocol.h" + +namespace ns3 { + +class Packet; +class NetDevice; +class Ipv4Interface; +class Ipv4Address; +class Ipv4Header; +class Ipv4Route; +class Node; +class TraceResolver; +class TraceContext; + + +class Ipv4StaticRouting : public Ipv4RoutingProtocol +{ + +public: + Ipv4StaticRouting () : m_defaultRoute (0) {} + + virtual bool RequestRoute (Ipv4Header const &ipHeader, + Packet packet, + RouteReplyCallback routeReply); + + + void AddHostRouteTo (Ipv4Address dest, + Ipv4Address nextHop, + uint32_t interface); + void AddHostRouteTo (Ipv4Address dest, + uint32_t interface); + + void AddNetworkRouteTo (Ipv4Address network, + Ipv4Mask networkMask, + Ipv4Address nextHop, + uint32_t interface); + void AddNetworkRouteTo (Ipv4Address network, + Ipv4Mask networkMask, + uint32_t interface); + void SetDefaultRoute (Ipv4Address nextHop, + uint32_t interface); + uint32_t GetNRoutes (void); + Ipv4Route *GetRoute (uint32_t i); + void RemoveRoute (uint32_t i); + +protected: + void DoDispose (void); + +private: + typedef std::list HostRoutes; + typedef std::list::const_iterator HostRoutesCI; + typedef std::list::iterator HostRoutesI; + typedef std::list NetworkRoutes; + typedef std::list::const_iterator NetworkRoutesCI; + typedef std::list::iterator NetworkRoutesI; + + Ipv4Route *LookupStatic (Ipv4Address dest); + + HostRoutes m_hostRoutes; + NetworkRoutes m_networkRoutes; + Ipv4Route *m_defaultRoute; +}; + + + +} // Namespace ns3 + +#endif /* IPV4_STATIC_ROUTING_H */ diff --git a/src/internet-node/wscript b/src/internet-node/wscript index cf412d6c8..d78fe3969 100644 --- a/src/internet-node/wscript +++ b/src/internet-node/wscript @@ -17,6 +17,7 @@ def build(bld): 'ipv4-checksum.cc', 'ipv4-interface.cc', 'ipv4-l3-protocol.cc', + 'ipv4-static-routing.cc', 'ipv4-end-point.cc', 'udp-l4-protocol.cc', 'arp-header.cc', @@ -41,4 +42,5 @@ def build(bld): 'internet-node.h', 'ascii-trace.h', 'pcap-trace.h', + 'ipv4-header.h', ] diff --git a/src/node/ipv4.h b/src/node/ipv4.h index 1424884af..1a957a4ee 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -24,6 +24,7 @@ #include #include "ns3/ipv4-address.h" #include "ns3/object.h" +#include "ns3/callback.h" #include "ipv4-route.h" namespace ns3 { @@ -31,6 +32,30 @@ namespace ns3 { class NetDevice; class Packet; class Ipv4Route; +class Ipv4Header; // FIXME: ipv4-header.h needs to move from module + // "internet-node" to module "node" + +class Ipv4RoutingProtocol : public Object +{ +public: + // void (*RouteReply) (bool found, Ipv4Route route, Packet packet, Ipv4Header const &ipHeader); + typedef Callback RouteReplyCallback; + + /** + * \brief Asynchronously requests a route for a given packet and IP header + * + * \param ipHeader IP header of the packet + * \param packet packet that is being sent or forwarded + * \param routeReply callback that will receive the route reply + * + * \returns true if the routing protocol should be able to get the + * route, false otherwise. + */ + virtual bool RequestRoute (Ipv4Header const &ipHeader, + Packet packet, + RouteReplyCallback routeReply) = 0; +}; + /** * \brief Access to the Ipv4 forwarding table and to the ipv4 interfaces * @@ -47,7 +72,10 @@ public: static const InterfaceId iid; Ipv4 (); virtual ~Ipv4 (); - + + virtual void AddRoutingProtocol (Ptr routingProtocol, + int priority) = 0; + /** * \param dest destination address * \param nextHop address of next hop. From c2c7f7d71c33c641a9bc84b0e186b176017480a1 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 26 Jul 2007 12:27:49 +0100 Subject: [PATCH 06/61] Allow UDP sockets to receive broadcast (bug #51) --- src/internet-node/ipv4-end-point-demux.cc | 66 ++++++++++++++++------- src/internet-node/ipv4-end-point-demux.h | 13 ++--- src/internet-node/udp-l4-protocol.cc | 11 ++-- 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/internet-node/ipv4-end-point-demux.cc b/src/internet-node/ipv4-end-point-demux.cc index 47240c7eb..6d310e133 100644 --- a/src/internet-node/ipv4-end-point-demux.cc +++ b/src/internet-node/ipv4-end-point-demux.cc @@ -21,9 +21,12 @@ #include "ipv4-end-point-demux.h" #include "ipv4-end-point.h" +#include "ns3/debug.h" namespace ns3{ +NS_DEBUG_COMPONENT_DEFINE ("Ipv4EndPointDemux"); + Ipv4EndPointDemux::Ipv4EndPointDemux () : m_ephemeral (1025) {} @@ -68,9 +71,11 @@ Ipv4EndPointDemux::LookupLocal (Ipv4Address addr, uint16_t port) Ipv4EndPoint * Ipv4EndPointDemux::Allocate (void) { + NS_DEBUG ("Ipv4EndPointDemux::Allocate ()"); uint16_t port = AllocateEphemeralPort (); if (port == 0) { + NS_DEBUG ("Ipv4EndPointDemux::Allocate ephemeral port allocation failed."); return 0; } Ipv4EndPoint *endPoint = new Ipv4EndPoint (Ipv4Address::GetAny (), port); @@ -80,9 +85,11 @@ Ipv4EndPointDemux::Allocate (void) Ipv4EndPoint * Ipv4EndPointDemux::Allocate (Ipv4Address address) { + NS_DEBUG ("Ipv4EndPointDemux::Allocate (address=" << address << ")"); uint16_t port = AllocateEphemeralPort (); if (port == 0) { + NS_DEBUG ("Ipv4EndPointDemux::Allocate ephemeral port allocation failed."); return 0; } Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port); @@ -97,8 +104,11 @@ Ipv4EndPointDemux::Allocate (uint16_t port) Ipv4EndPoint * Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port) { + NS_DEBUG ("Ipv4EndPointDemux::Allocate (address=" << address + << ", port=" << port << ")"); if (LookupLocal (address, port)) { + NS_DEBUG ("Ipv4EndPointDemux::Allocate duplicate address/port; failing."); return 0; } Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port); @@ -110,6 +120,10 @@ Ipv4EndPoint * Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort, Ipv4Address peerAddress, uint16_t peerPort) { + NS_DEBUG ("Ipv4EndPointDemux::Allocate (localAddress=" << localAddress + << ", localPort=" << localPort + << ", peerAddress=" << peerAddress + << ", peerPort=" << peerPort << ")"); for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) { if ((*i)->GetLocalPort () == localPort && @@ -117,6 +131,7 @@ Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort, (*i)->GetPeerPort () == peerPort && (*i)->GetPeerAddress () == peerAddress) { + NS_DEBUG ("Ipv4EndPointDemux::Allocate: no way we can allocate this end-point."); /* no way we can allocate this end-point. */ return 0; } @@ -147,35 +162,46 @@ Ipv4EndPointDemux::DeAllocate (Ipv4EndPoint *endPoint) * Otherwise, if we find a generic match, we return it. * Otherwise, we return 0. */ -Ipv4EndPoint * +Ipv4EndPointDemux::EndPoints Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport, - Ipv4Address saddr, uint16_t sport) + Ipv4Address saddr, uint16_t sport) { uint32_t genericity = 3; Ipv4EndPoint *generic = 0; - //TRACE ("lookup " << daddr << ":" << dport << " " << saddr << ":" << sport); + EndPoints retval; + + NS_DEBUG ("Ipv4EndPointDemux::Lookup (daddr=" << daddr << ", dport=" << dport + << ", saddr=" << saddr << ", sport=" << sport + << ")"); for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) { -#if 0 - TRACE ("against " << - (*i)->GetLocalAddress () - << ":" << - (*i)->GetLocalPort () - << " " << - (*i)->GetPeerAddress () - << ":" - << (*i)->GetPeerPort ()); -#endif + NS_DEBUG ("Ipv4EndPointDemux::Lookup against " << + (*i)->GetLocalAddress () + << ":" << + (*i)->GetLocalPort () + << " " << + (*i)->GetPeerAddress () + << ":" + << (*i)->GetPeerPort ()); if ((*i)->GetLocalPort () != dport) { continue; } - if ((*i)->GetLocalAddress () == daddr && - (*i)->GetPeerPort () == sport && - (*i)->GetPeerAddress () == saddr) + NS_DEBUG ("Ipv4EndPointDemux::Lookup local address matches: " + << bool ((*i)->GetLocalAddress () == daddr || daddr.IsBroadcast ())); + NS_DEBUG ("Ipv4EndPointDemux::Lookup peer port matches: " + << bool ((*i)->GetPeerPort () == sport || sport == 0)); + NS_DEBUG ("Ipv4EndPointDemux::Lookup peer address matches: " + << bool ((*i)->GetPeerAddress () == saddr || + (*i)->GetPeerAddress () == Ipv4Address::GetAny ())); + + if ( ((*i)->GetLocalAddress () == daddr || daddr.IsBroadcast ()) + && ((*i)->GetPeerPort () == sport || (*i)->GetPeerPort () == 0) + && ((*i)->GetPeerAddress () == saddr || (*i)->GetPeerAddress () == Ipv4Address::GetAny ())) { + NS_DEBUG ("Ipv4EndPointDemux::Lookup MATCH"); /* this is an exact match. */ - return *i; + retval.push_back (*i); } uint32_t tmp = 0; if ((*i)->GetLocalAddress () == Ipv4Address::GetAny ()) @@ -192,7 +218,11 @@ Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport, genericity = tmp; } } - return generic; + if (retval.size () == 0 && generic != 0) + { + retval.push_back (generic); + } + return retval; } uint16_t diff --git a/src/internet-node/ipv4-end-point-demux.h b/src/internet-node/ipv4-end-point-demux.h index 7de2c17d1..e45a6267b 100644 --- a/src/internet-node/ipv4-end-point-demux.h +++ b/src/internet-node/ipv4-end-point-demux.h @@ -32,15 +32,18 @@ class Ipv4EndPoint; class Ipv4EndPointDemux { public: + typedef std::list EndPoints; + typedef std::list::iterator EndPointsI; + Ipv4EndPointDemux (); ~Ipv4EndPointDemux (); bool LookupPortLocal (uint16_t port); bool LookupLocal (Ipv4Address addr, uint16_t port); - Ipv4EndPoint *Lookup (Ipv4Address daddr, - uint16_t dport, - Ipv4Address saddr, - uint16_t sport); + EndPoints Lookup (Ipv4Address daddr, + uint16_t dport, + Ipv4Address saddr, + uint16_t sport); Ipv4EndPoint *Allocate (void); Ipv4EndPoint *Allocate (Ipv4Address address); @@ -55,8 +58,6 @@ public: private: uint16_t AllocateEphemeralPort (void); - typedef std::list EndPoints; - typedef std::list::iterator EndPointsI; uint16_t m_ephemeral; EndPoints m_endPoints; diff --git a/src/internet-node/udp-l4-protocol.cc b/src/internet-node/udp-l4-protocol.cc index d873ef582..90fb782b9 100644 --- a/src/internet-node/udp-l4-protocol.cc +++ b/src/internet-node/udp-l4-protocol.cc @@ -113,13 +113,14 @@ UdpL4Protocol::Receive(Packet& packet, { UdpHeader udpHeader; packet.RemoveHeader (udpHeader); - Ipv4EndPoint *endPoint = m_endPoints->Lookup (destination, udpHeader.GetDestination (), - source, udpHeader.GetSource ()); - if (endPoint == 0) + Ipv4EndPointDemux::EndPoints endPoints = + m_endPoints->Lookup (destination, udpHeader.GetDestination (), + source, udpHeader.GetSource ()); + for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin (); + endPoint != endPoints.end (); endPoint++) { - return; + (*endPoint)->ForwardUp (packet, source, udpHeader.GetSource ()); } - endPoint->ForwardUp (packet, source, udpHeader.GetSource ()); } void From a7089873e9b67bbc270fdb897947506492080b9c Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 26 Jul 2007 12:49:00 +0100 Subject: [PATCH 07/61] Add OLSR routing support, (loosely) based on Francisco J. Ros's NS-2 code (University of Murcia). --- examples/simple-p2p-olsr.cc | 198 +++ examples/wscript | 2 + src/routing/olsr/olsr-header.cc | 704 +++++++++ src/routing/olsr/olsr-header.h | 470 ++++++ src/routing/olsr/olsr-private.h | 187 +++ src/routing/olsr/olsr-repositories.h | 200 +++ src/routing/olsr/olsr-state.cc | 438 ++++++ src/routing/olsr/olsr-state.h | 147 ++ src/routing/olsr/olsr.cc | 2135 ++++++++++++++++++++++++++ src/routing/olsr/olsr.h | 45 + src/routing/olsr/routing-table.cc | 270 ++++ src/routing/olsr/routing-table.h | 110 ++ src/routing/olsr/wscript | 19 + src/wscript | 1 + 14 files changed, 4926 insertions(+) create mode 100644 examples/simple-p2p-olsr.cc create mode 100644 src/routing/olsr/olsr-header.cc create mode 100644 src/routing/olsr/olsr-header.h create mode 100644 src/routing/olsr/olsr-private.h create mode 100644 src/routing/olsr/olsr-repositories.h create mode 100644 src/routing/olsr/olsr-state.cc create mode 100644 src/routing/olsr/olsr-state.h create mode 100644 src/routing/olsr/olsr.cc create mode 100644 src/routing/olsr/olsr.h create mode 100644 src/routing/olsr/routing-table.cc create mode 100644 src/routing/olsr/routing-table.h create mode 100644 src/routing/olsr/wscript diff --git a/examples/simple-p2p-olsr.cc b/examples/simple-p2p-olsr.cc new file mode 100644 index 000000000..3a01240e3 --- /dev/null +++ b/examples/simple-p2p-olsr.cc @@ -0,0 +1,198 @@ +/* -*- 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 + * + * ns-2 simple.tcl script (ported from ns-2) + * Originally authored by Steve McCanne, 12/19/1996 + */ + +// Port of ns-2/tcl/ex/simple.tcl to ns-3 +// +// Network topology +// +// n0 +// \ 5 Mb/s, 2ms +// \ 1.5Mb/s, 10ms +// n2 -------------------------n3 +// / +// / 5 Mb/s, 2ms +// n1 +// +// - all links are p2p links with indicated one-way BW/delay +// - CBR/UDP flows from n0 to n3, and from n3 to n1 +// - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec. +// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. +// (i.e., DataRate of 448,000 bps) +// - DropTail queues +// - Tracing of queues and packet receptions to file "simple-p2p.tr" + +#include +#include +#include +#include + +#include "ns3/command-line.h" +#include "ns3/default-value.h" +#include "ns3/ptr.h" +#include "ns3/random-variable.h" + +#include "ns3/simulator.h" +#include "ns3/nstime.h" +#include "ns3/data-rate.h" + +#include "ns3/ascii-trace.h" +#include "ns3/pcap-trace.h" +#include "ns3/internet-node.h" +#include "ns3/p2p-channel.h" +#include "ns3/p2p-net-device.h" +#include "ns3/mac-address.h" +#include "ns3/ipv4-address.h" +#include "ns3/ipv4.h" +#include "ns3/socket.h" +#include "ns3/ipv4-route.h" +#include "ns3/p2p-topology.h" +#include "ns3/onoff-application.h" +#include "ns3/debug.h" + +#include "ns3/olsr.h" + +using namespace ns3; + +int main (int argc, char *argv[]) +{ + + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this +#if 1 +// DebugComponentEnable("Ipv4L3Protocol"); +// DebugComponentEnable("ArpL3Protocol"); +// DebugComponentEnable("OlsrRoutingTable"); +// DebugComponentEnable("Object"); +// DebugComponentEnable("Queue"); +// DebugComponentEnable("DropTailQueue"); +// DebugComponentEnable("Channel"); +// DebugComponentEnable("PointToPointChannel"); +// DebugComponentEnable("PointToPointNetDevice"); +#endif + + // Set up some default values for the simulation. Use the Bind() + // technique to tell the system what subclass of Queue to use, + // and what the queue limit is + + // The below Bind command tells the queue factory which class to + // instantiate, when the queue factory is invoked in the topology code + Bind ("Queue", "DropTailQueue"); + + Bind ("OnOffApplicationPacketSize", "210"); + Bind ("OnOffApplicationDataRate", "448kb/s"); + + //Bind ("DropTailQueue::m_maxPackets", 30); + + // Allow the user to override any of the defaults and the above + // Bind()s at run-time, via command-line arguments + CommandLine::Parse (argc, argv); + + // Here, we will explicitly create four nodes. In more sophisticated + // topologies, we could configure a node factory. + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + // We create the channels first without any IP addressing information + Ptr channel0 = + PointToPointTopology::AddPointToPointLink ( + n0, n2, DataRate(5000000), MilliSeconds(2)); + + Ptr channel1 = + PointToPointTopology::AddPointToPointLink ( + n1, n2, DataRate(5000000), MilliSeconds(2)); + + Ptr channel2 = + PointToPointTopology::AddPointToPointLink ( + n2, n3, DataRate(1500000), MilliSeconds(10)); + + // Later, we add IP addresses. + PointToPointTopology::AddIpv4Addresses ( + channel0, n0, Ipv4Address("10.1.1.1"), + n2, Ipv4Address("10.1.1.2")); + + PointToPointTopology::AddIpv4Addresses ( + channel1, n1, Ipv4Address("10.1.2.1"), + n2, Ipv4Address("10.1.2.2")); + + PointToPointTopology::AddIpv4Addresses ( + channel2, n2, Ipv4Address("10.1.3.1"), + n3, Ipv4Address("10.1.3.2")); + + + // Run OLSR in each node. + ComponentManager::Create > + (Olsr::cid, Olsr::iid, n0)->Start (); + + ComponentManager::Create > + (Olsr::cid, Olsr::iid, n1)->Start (); + + ComponentManager::Create > + (Olsr::cid, Olsr::iid, n2)->Start (); + + ComponentManager::Create > + (Olsr::cid, Olsr::iid, n3)->Start (); + + +#if 1 + // Create the OnOff application to send UDP datagrams of size + // 210 bytes at a rate of 448 Kb/s + Ptr ooff = Create ( + n0, + Ipv4Address("10.1.3.2"), + 80, + "Udp", + ConstantVariable(1), + ConstantVariable(0)); + // Start the application + ooff->Start(Seconds(1.0)); + ooff->Stop (Seconds(10.0)); + + // Create a similar flow from n3 to n1, starting at time 1.1 seconds + ooff = Create ( + n3, + Ipv4Address("10.1.2.1"), + 80, + "Udp", + ConstantVariable(1), + ConstantVariable(0)); + // Start the application + ooff->Start(Seconds(1.1)); + ooff->Stop (Seconds(10.0)); +#endif + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the simple-p2p.tr file +// AsciiTrace asciitrace ("simple-p2p-olsr.tr"); +// asciitrace.TraceAllQueues (); +// asciitrace.TraceAllNetDeviceRx (); + + // Also configure some tcpdump traces; each interface will be traced + // The output files will be named simple-p2p.pcap-- + // and can be read by the "tcpdump -r" command (use "-tt" option to + // display timestamps correctly) + PcapTrace pcaptrace ("simple-p2p-olsr.pcap"); + pcaptrace.TraceAllIp (); + + Simulator::StopAt (Seconds (10.0)); + Simulator::Run (); + + Simulator::Destroy (); +} diff --git a/examples/wscript b/examples/wscript index f535ea93f..201a5121f 100644 --- a/examples/wscript +++ b/examples/wscript @@ -10,4 +10,6 @@ def build(bld): return obj obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['p2p', 'internet-node']) + obj = create_ns_prog('simple-p2p-olsr', 'simple-p2p-olsr.cc', + deps=['p2p', 'internet-node', 'olsr']) diff --git a/src/routing/olsr/olsr-header.cc b/src/routing/olsr/olsr-header.cc new file mode 100644 index 000000000..12061ab74 --- /dev/null +++ b/src/routing/olsr/olsr-header.cc @@ -0,0 +1,704 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo J. A. M. Carneiro + */ + +#include "ns3/assert.h" + +#include "olsr-header.h" + +#define IPV4_ADDRESS_SIZE 4 +#define OLSR_MSG_HEADER_SIZE 12 +#define OLSR_PKT_HEADER_SIZE 4 + +namespace ns3 { + +/// Scaling factor used in RFC 3626. +#define OLSR_C 0.0625 + +/// +/// \brief Converts a decimal number of seconds to the mantissa/exponent format. +/// +/// \param seconds decimal number of seconds we want to convert. +/// \return the number of seconds in mantissa/exponent format. +/// +uint8_t +OlsrSecondsToEmf (double seconds) +{ + int a, b = 0; + + // find the largest integer 'b' such that: T/C >= 2^b + for (b = 0; (seconds/OLSR_C) >= (1 << b); ++b) + ; + NS_ASSERT ((seconds/OLSR_C) < (1 << b)); + b--; + NS_ASSERT ((seconds/OLSR_C) >= (1 << b)); + + // compute the expression 16*(T/(C*(2^b))-1), which may not be a integer + double tmp = 16*(seconds/(OLSR_C*(1<= 0 && a < 16); + NS_ASSERT (b >= 0 && b < 16); + + // the field will be a byte holding the value a*16+b + return (uint8_t) ((a << 4) | b); +} + +/// +/// \brief Converts a number of seconds in the mantissa/exponent format to a decimal number. +/// +/// \param olsr_format number of seconds in mantissa/exponent format. +/// \return the decimal number of seconds. +/// +double +OlsrEmfToSeconds (uint8_t olsrFormat) +{ + int a = (olsrFormat >> 4); + int b = (olsrFormat & 0xf); + // value = C*(1+a/16)*2^b [in seconds] + return OLSR_C * (1 + a/16.0) * (1 << b); +} + + + +// ---------------- OLSR Packet ------------------------------- + +OlsrPacketHeader::OlsrPacketHeader () +{} + +OlsrPacketHeader::~OlsrPacketHeader () +{} + +uint32_t +OlsrPacketHeader::GetSerializedSize (void) const +{ + return OLSR_PKT_HEADER_SIZE; +} + +void +OlsrPacketHeader::PrintTo (std::ostream &os) const +{ + // TODO +} + +void +OlsrPacketHeader::SerializeTo (Buffer::Iterator start) const +{ + Buffer::Iterator i = start; + i.WriteHtonU16 (m_packetLength); + i.WriteHtonU16 (m_packetSequenceNumber); +} + +uint32_t +OlsrPacketHeader::DeserializeFrom (Buffer::Iterator start) +{ + Buffer::Iterator i = start; + m_packetLength = i.ReadNtohU16 (); + m_packetSequenceNumber = i.ReadNtohU16 (); + return GetSerializedSize (); +} + + +// ---------------- OLSR Message ------------------------------- + +OlsrMessageHeader::OlsrMessageHeader () +{} + +OlsrMessageHeader::~OlsrMessageHeader () +{} + +uint32_t +OlsrMessageHeader::GetSerializedSize (void) const +{ + return OLSR_MSG_HEADER_SIZE; +} + +void +OlsrMessageHeader::PrintTo (std::ostream &os) const +{ + // TODO +} + +void +OlsrMessageHeader::SerializeTo (Buffer::Iterator start) const +{ + Buffer::Iterator i = start; + i.WriteU8 (m_messageType); + i.WriteU8 (m_vTime); + i.WriteHtonU16 (m_messageSize); + i.WriteHtonU32 (m_originatorAddress.GetHostOrder ()); + i.WriteU8 (m_timeToLive); + i.WriteU8 (m_hopCount); + i.WriteHtonU16 (m_messageSequenceNumber); +} + +uint32_t +OlsrMessageHeader::DeserializeFrom (Buffer::Iterator start) +{ + Buffer::Iterator i = start; + m_messageType = (MessageType) i.ReadU8 (); + NS_ASSERT (m_messageType >= HELLO_MESSAGE && m_messageType <= HNA_MESSAGE); + m_vTime = i.ReadU8 (); + m_messageSize = i.ReadNtohU16 (); + m_originatorAddress = Ipv4Address (i.ReadNtohU32 ()); + m_timeToLive = i.ReadU8 (); + m_hopCount = i.ReadU8 (); + m_messageSequenceNumber = i.ReadNtohU16 (); + return GetSerializedSize (); +} + + +// ---------------- OLSR MID Message ------------------------------- + +OlsrMidMessageHeader::OlsrMidMessageHeader () +{} + +OlsrMidMessageHeader::~OlsrMidMessageHeader () +{} + +uint32_t +OlsrMidMessageHeader::GetSerializedSize (void) const +{ + return m_interfaceAddresses.size () * IPV4_ADDRESS_SIZE; +} + +void +OlsrMidMessageHeader::PrintTo (std::ostream &os) const +{ + // TODO +} + +void +OlsrMidMessageHeader::SerializeTo (Buffer::Iterator start) const +{ + Buffer::Iterator i = start; + + for (std::vector::const_iterator iter = m_interfaceAddresses.begin (); + iter != m_interfaceAddresses.end (); iter++) + { + i.WriteHtonU32 (iter->GetHostOrder ()); + } +} + +uint32_t +OlsrMidMessageHeader::DeserializeFrom (Buffer::Iterator start) +{ + Buffer::Iterator i = start; + + m_interfaceAddresses.clear (); + NS_ASSERT (m_messageSize >= 0); + NS_ASSERT (m_messageSize % IPV4_ADDRESS_SIZE == 0); + + int numAddresses = m_messageSize / IPV4_ADDRESS_SIZE; + m_interfaceAddresses.erase (m_interfaceAddresses.begin(), + m_interfaceAddresses.end ()); + for (int n = 0; n < numAddresses; ++n) + m_interfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ())); + return GetSerializedSize (); +} + + + +// ---------------- OLSR HELLO Message ------------------------------- + +OlsrHelloMessageHeader::OlsrHelloMessageHeader () +{} + +OlsrHelloMessageHeader::~OlsrHelloMessageHeader () +{} + +uint32_t +OlsrHelloMessageHeader::GetSerializedSize (void) const +{ + uint32_t size = 4; + for (std::vector::const_iterator iter = m_linkMessages.begin (); + iter != m_linkMessages.end (); iter++) + { + const LinkMessage &lm = *iter; + size += 4; + size += IPV4_ADDRESS_SIZE * lm.neighborInterfaceAddresses.size (); + } + return size; +} + +void +OlsrHelloMessageHeader::PrintTo (std::ostream &os) const +{ + // TODO +} + +void +OlsrHelloMessageHeader::SerializeTo (Buffer::Iterator start) const +{ + Buffer::Iterator i = start; + + i.WriteU16 (0); // Reserved + i.WriteU8 (m_hTime); + i.WriteU8 (m_willingness); + + for (std::vector::const_iterator iter = m_linkMessages.begin (); + iter != m_linkMessages.end (); iter++) + { + const LinkMessage &lm = *iter; + + i.WriteU8 (lm.linkCode); + i.WriteU8 (0); // Reserved + + // The size of the link message, counted in bytes and measured + // from the beginning of the "Link Code" field and until the + // next "Link Code" field (or - if there are no more link types + // - the end of the message). + i.WriteHtonU16 (4 + lm.neighborInterfaceAddresses.size () * IPV4_ADDRESS_SIZE); + + for (std::vector::const_iterator neigh_iter = lm.neighborInterfaceAddresses.begin (); + neigh_iter != lm.neighborInterfaceAddresses.end (); neigh_iter++) + { + i.WriteHtonU32 (neigh_iter->GetHostOrder ()); + } + } +} + +uint32_t +OlsrHelloMessageHeader::DeserializeFrom (Buffer::Iterator start) +{ + Buffer::Iterator i = start; + + NS_ASSERT (m_messageSize >= 4); + + m_linkMessages.clear (); + + uint16_t helloSizeLeft = m_messageSize; + + i.ReadNtohU16 (); // Reserved + m_hTime = i.ReadU8 (); + m_willingness = i.ReadU8 (); + + helloSizeLeft -= 4; + + while (helloSizeLeft) + { + LinkMessage lm; + NS_ASSERT (helloSizeLeft >= 4); + lm.linkCode = i.ReadU8 (); + i.ReadU8 (); // Reserved + uint16_t lmSize = i.ReadNtohU16 (); + NS_ASSERT ((lmSize - 4) % IPV4_ADDRESS_SIZE == 0); + for (int n = (lmSize - 4) / IPV4_ADDRESS_SIZE; n; --n) + { + lm.neighborInterfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ())); + } + helloSizeLeft -= lmSize; + m_linkMessages.push_back (lm); + } + + return m_messageSize; +} + + + +// ---------------- OLSR TC Message ------------------------------- + +OlsrTcMessageHeader::OlsrTcMessageHeader () +{} + +OlsrTcMessageHeader::~OlsrTcMessageHeader () +{} + +uint32_t +OlsrTcMessageHeader::GetSerializedSize (void) const +{ + return 4 + m_neighborAddresses.size () * IPV4_ADDRESS_SIZE; +} + +void +OlsrTcMessageHeader::PrintTo (std::ostream &os) const +{ + // TODO +} + +void +OlsrTcMessageHeader::SerializeTo (Buffer::Iterator start) const +{ + Buffer::Iterator i = start; + + i.WriteHtonU16 (m_ansn); + i.WriteHtonU16 (0); // Reserved + + for (std::vector::const_iterator iter = m_neighborAddresses.begin (); + iter != m_neighborAddresses.end (); iter++) + { + i.WriteHtonU32 (iter->GetHostOrder ()); + } +} + +uint32_t +OlsrTcMessageHeader::DeserializeFrom (Buffer::Iterator start) +{ + Buffer::Iterator i = start; + + m_neighborAddresses.clear (); + NS_ASSERT (m_messageSize >= 4); + + m_ansn = i.ReadNtohU16 (); + i.ReadNtohU16 (); // Reserved + + NS_ASSERT ((m_messageSize - 4) % IPV4_ADDRESS_SIZE == 0); + int numAddresses = (m_messageSize - 4) / IPV4_ADDRESS_SIZE; + m_neighborAddresses.clear (); + for (int n = 0; n < numAddresses; ++n) + m_neighborAddresses.push_back (Ipv4Address (i.ReadNtohU32 ())); + + return m_messageSize; +} + + +// ---------------- OLSR HNA Message ------------------------------- + +OlsrHnaMessageHeader::OlsrHnaMessageHeader () +{} + +OlsrHnaMessageHeader::~OlsrHnaMessageHeader () +{} + +uint32_t +OlsrHnaMessageHeader::GetSerializedSize (void) const +{ + return 2*m_associations.size () * IPV4_ADDRESS_SIZE; +} + +void +OlsrHnaMessageHeader::PrintTo (std::ostream &os) const +{ + // TODO +} + +void +OlsrHnaMessageHeader::SerializeTo (Buffer::Iterator start) const +{ + Buffer::Iterator i = start; + + for (size_t n = 0; n < m_associations.size (); ++n) + { + i.WriteHtonU32 (m_associations[n].address.GetHostOrder ()); + i.WriteHtonU32 (m_associations[n].mask.GetHostOrder ()); + } +} + +uint32_t +OlsrHnaMessageHeader::DeserializeFrom (Buffer::Iterator start) +{ + Buffer::Iterator i = start; + + NS_ASSERT (m_messageSize % (IPV4_ADDRESS_SIZE*2) == 0); + int numAddresses = m_messageSize / IPV4_ADDRESS_SIZE / 2; + m_associations.clear (); + for (int n = 0; n < numAddresses; ++n) + { + Ipv4Address address (i.ReadNtohU32 ()); + Ipv4Mask mask (i.ReadNtohU32 ()); + m_associations.push_back ((Association) {address, mask}); + } + return m_messageSize; +} + + + +}; // namespace ns3 + + +#ifdef RUN_SELF_TESTS + + +#include "ns3/test.h" +#include "ns3/packet.h" +#include + + +namespace ns3 { + +class OlsrHeaderTest : public ns3::Test { +private: +public: + OlsrHeaderTest (); + virtual bool RunTests (void); + + +}; + +OlsrHeaderTest::OlsrHeaderTest () + : ns3::Test ("OlsrHeader") +{} + + +bool +OlsrHeaderTest::RunTests (void) +{ + bool result = true; + + // Testing packet header + message header + MID message + { + Packet packet; + + { + OlsrPacketHeader hdr; + OlsrMessageHeader msg1; + OlsrMidMessageHeader mid1; + OlsrMessageHeader msg2; + OlsrMidMessageHeader mid2; + + // MID message #1 + { + std::vector addresses; + addresses.push_back (Ipv4Address ("1.2.3.4")); + addresses.push_back (Ipv4Address ("1.2.3.5")); + mid1.SetInterfaceAddresses (addresses); + } + + msg1.SetMessageSize (mid1.GetSize () + msg1.GetSize ()); + msg1.SetTimeToLive (255); + msg1.SetOriginatorAddress (Ipv4Address ("11.22.33.44")); + msg1.SetVTime (Seconds (9)); + msg1.SetMessageType (OlsrMessageHeader::MID_MESSAGE); + msg1.SetMessageSequenceNumber (7); + + // MID message #2 + { + std::vector addresses; + addresses.push_back (Ipv4Address ("2.2.3.4")); + addresses.push_back (Ipv4Address ("2.2.3.5")); + mid2.SetInterfaceAddresses (addresses); + } + + msg2.SetMessageSize (mid2.GetSize () + msg2.GetSize ()); + msg2.SetTimeToLive (254); + msg2.SetOriginatorAddress (Ipv4Address ("12.22.33.44")); + msg2.SetVTime (Seconds (10)); + msg2.SetMessageType (OlsrMessageHeader::MID_MESSAGE); + msg2.SetMessageSequenceNumber (7); + + // Build an OLSR packet header + hdr.SetPacketLength (hdr.GetSize () + msg1.GetMessageSize () + msg2.GetMessageSize ()); + hdr.SetPacketSequenceNumber (123); + + + // Now add all the headers in the correct order + packet.AddHeader (mid2); + packet.AddHeader (msg2); + packet.AddHeader (mid1); + packet.AddHeader (msg1); + packet.AddHeader (hdr); + } + + { + OlsrPacketHeader hdr; + packet.RemoveHeader (hdr); + NS_TEST_ASSERT_EQUAL (hdr.GetPacketSequenceNumber (), 123); + uint32_t sizeLeft = hdr.GetPacketLength () - hdr.GetSize (); + { + OlsrMessageHeader msg1; + OlsrMidMessageHeader mid1; + + packet.RemoveHeader (msg1); + + NS_TEST_ASSERT_EQUAL (msg1.GetTimeToLive (), 255); + NS_TEST_ASSERT_EQUAL (msg1.GetOriginatorAddress (), Ipv4Address ("11.22.33.44")); + NS_TEST_ASSERT_EQUAL (msg1.GetVTime (), Seconds (9)); + NS_TEST_ASSERT_EQUAL (msg1.GetMessageType (), OlsrMessageHeader::MID_MESSAGE); + NS_TEST_ASSERT_EQUAL (msg1.GetMessageSequenceNumber (), 7); + + mid1.SetMessageSize (msg1.GetMessageSize () - msg1.GetSize ()); + packet.RemoveHeader (mid1); + NS_TEST_ASSERT_EQUAL (mid1.GetInterfaceAddresses ().size (), 2); + NS_TEST_ASSERT_EQUAL (*mid1.GetInterfaceAddresses ().begin (), Ipv4Address ("1.2.3.4")); + + sizeLeft -= msg1.GetMessageSize (); + NS_TEST_ASSERT (sizeLeft > 0); + } + { + // now read the second message + OlsrMessageHeader msg2; + OlsrMidMessageHeader mid2; + + packet.RemoveHeader (msg2); + + NS_TEST_ASSERT_EQUAL (msg2.GetTimeToLive (), 254); + NS_TEST_ASSERT_EQUAL (msg2.GetOriginatorAddress (), Ipv4Address ("12.22.33.44")); + NS_TEST_ASSERT_EQUAL (msg2.GetVTime (), Seconds (10)); + NS_TEST_ASSERT_EQUAL (msg2.GetMessageType (), OlsrMessageHeader::MID_MESSAGE); + NS_TEST_ASSERT_EQUAL (msg2.GetMessageSequenceNumber (), 7); + + mid2.SetMessageSize (msg2.GetMessageSize () - msg2.GetSize ()); + packet.RemoveHeader (mid2); + NS_TEST_ASSERT_EQUAL (mid2.GetInterfaceAddresses ().size (), 2); + NS_TEST_ASSERT_EQUAL (*mid2.GetInterfaceAddresses ().begin (), Ipv4Address ("2.2.3.4")); + + sizeLeft -= msg2.GetMessageSize (); + NS_TEST_ASSERT_EQUAL (sizeLeft, 0); + } + } + } + + // Test the HELLO message + { + Packet packet; + OlsrHelloMessageHeader helloIn; + + helloIn.SetHTime (Seconds (7)); + helloIn.SetWillingness (66); + + { + std::vector vec; + + OlsrHelloMessageHeader::LinkMessage lm1; + lm1.linkCode = 2; + lm1.neighborInterfaceAddresses.push_back (Ipv4Address ("1.2.3.4")); + lm1.neighborInterfaceAddresses.push_back (Ipv4Address ("1.2.3.5")); + vec.push_back (lm1); + + OlsrHelloMessageHeader::LinkMessage lm2; + lm2.linkCode = 3; + lm2.neighborInterfaceAddresses.push_back (Ipv4Address ("2.2.3.4")); + lm2.neighborInterfaceAddresses.push_back (Ipv4Address ("2.2.3.5")); + vec.push_back (lm2); + + helloIn.SetLinkMessages (vec); + } + + packet.AddHeader (helloIn); + + OlsrHelloMessageHeader helloOut; + helloOut.SetMessageSize (packet.GetSize ()); + packet.RemoveHeader (helloOut); + + NS_TEST_ASSERT_EQUAL (helloOut.GetHTime (), Seconds (7)); + NS_TEST_ASSERT_EQUAL (helloOut.GetWillingness (), 66); + NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ().size (), 2); + + NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[0].linkCode, 2); + NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[0].neighborInterfaceAddresses[0], + Ipv4Address ("1.2.3.4")); + NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[0].neighborInterfaceAddresses[1], + Ipv4Address ("1.2.3.5")); + + NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[1].linkCode, 3); + NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[1].neighborInterfaceAddresses[0], + Ipv4Address ("2.2.3.4")); + NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[1].neighborInterfaceAddresses[1], + Ipv4Address ("2.2.3.5")); + + // check that all bytes of the message were read + NS_TEST_ASSERT_EQUAL (packet.GetSize (), 0); + } + + // Test the TC message + { + Packet packet; + OlsrTcMessageHeader tcIn; + + tcIn.SetAnsn (0x1234); + { + std::vector vec; + vec.push_back (Ipv4Address ("1.2.3.4")); + vec.push_back (Ipv4Address ("1.2.3.5")); + tcIn.SetNeighborAddresses (vec); + } + packet.AddHeader (tcIn); + + OlsrTcMessageHeader tcOut; + tcOut.SetMessageSize (packet.GetSize ()); + packet.RemoveHeader (tcOut); + + NS_TEST_ASSERT_EQUAL (tcOut.GetAnsn (), 0x1234); + NS_TEST_ASSERT_EQUAL (tcOut.GetNeighborAddresses ().size (), 2); + + NS_TEST_ASSERT_EQUAL (tcOut.GetNeighborAddresses ()[0], + Ipv4Address ("1.2.3.4")); + NS_TEST_ASSERT_EQUAL (tcOut.GetNeighborAddresses ()[1], + Ipv4Address ("1.2.3.5")); + + // check that all bytes of the message were read + NS_TEST_ASSERT_EQUAL (packet.GetSize (), 0); + } + + // Test the HNA message + { + Packet packet; + OlsrHnaMessageHeader hnaIn; + + { + std::vector vec; + vec.push_back ((OlsrHnaMessageHeader::Association) + { Ipv4Address ("1.2.3.4"), Ipv4Mask ("255.255.255.0")}); + vec.push_back ((OlsrHnaMessageHeader::Association) + {Ipv4Address ("1.2.3.5"), Ipv4Mask ("255.255.0.0")}); + hnaIn.SetAssociations (vec); + } + packet.AddHeader (hnaIn); + + OlsrHnaMessageHeader hnaOut; + hnaOut.SetMessageSize (packet.GetSize ()); + packet.RemoveHeader (hnaOut); + + NS_TEST_ASSERT_EQUAL (hnaOut.GetAssociations ().size (), 2); + + NS_TEST_ASSERT_EQUAL (hnaOut.GetAssociations ()[0].address, + Ipv4Address ("1.2.3.4")); + NS_TEST_ASSERT_EQUAL (hnaOut.GetAssociations ()[0].mask, + Ipv4Mask ("255.255.255.0")); + + NS_TEST_ASSERT_EQUAL (hnaOut.GetAssociations ()[1].address, + Ipv4Address ("1.2.3.5")); + NS_TEST_ASSERT_EQUAL (hnaOut.GetAssociations ()[1].mask, + Ipv4Mask ("255.255.0.0")); + + // check that all bytes of the message were read + NS_TEST_ASSERT_EQUAL (packet.GetSize (), 0); + } + + for (int time = 1; time <= 30; time++) + { + uint8_t emf = OlsrSecondsToEmf (time); + double seconds = OlsrEmfToSeconds (emf); + if (seconds < 0 || fabs (seconds - time) > 0.1) + { + result = false; + Failure () << "In " << time << " out " << seconds << std::endl; + } + } + + return result; +} + +static OlsrHeaderTest gOlsrHeaderTest; + +}; // namespace + + +#endif /* RUN_SELF_TESTS */ diff --git a/src/routing/olsr/olsr-header.h b/src/routing/olsr/olsr-header.h new file mode 100644 index 000000000..f55c266b2 --- /dev/null +++ b/src/routing/olsr/olsr-header.h @@ -0,0 +1,470 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo J. A. M. Carneiro + */ + +#ifndef OLSR_HEADER_H +#define OLSR_HEADER_H + +#include +#include +#include "ns3/header.h" +#include "ns3/ipv4-address.h" +#include "ns3/nstime.h" + + +namespace ns3 { + + +double OlsrEmfToSeconds (uint8_t emf); +uint8_t OlsrSecondsToEmf (double seconds); + +// 3.3. Packet Format +// +// The basic layout of any packet in OLSR is as follows (omitting IP and +// UDP headers): +// +// 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 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Packet Length | Packet Sequence Number | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Message Type | Vtime | Message Size | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Originator Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Time To Live | Hop Count | Message Sequence Number | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// : MESSAGE : +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Message Type | Vtime | Message Size | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Originator Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Time To Live | Hop Count | Message Sequence Number | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// : MESSAGE : +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// : : +// (etc.) +class OlsrPacketHeader : public Header +{ +public: + OlsrPacketHeader (); + virtual ~OlsrPacketHeader (); + + void SetPacketLength (uint16_t length) + { + m_packetLength = length; + } + uint16_t GetPacketLength () const + { + return m_packetLength; + } + + void SetPacketSequenceNumber (uint16_t seqnum) + { + m_packetSequenceNumber = seqnum; + } + uint16_t GetPacketSequenceNumber () const + { + return m_packetSequenceNumber; + } + +private: + uint16_t m_packetLength; + uint16_t m_packetSequenceNumber; + + virtual void PrintTo (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void SerializeTo (Buffer::Iterator start) const; + virtual uint32_t DeserializeFrom (Buffer::Iterator start); + virtual std::string DoGetName (void) const { return "OlsrPacket"; } +}; + + +// 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 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Message Type | Vtime | Message Size | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Originator Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Time To Live | Hop Count | Message Sequence Number | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +class OlsrMessageHeader : public Header +{ +public: + + enum MessageType { + HELLO_MESSAGE = 1, + TC_MESSAGE = 2, + MID_MESSAGE = 3, + HNA_MESSAGE = 4, + }; + + OlsrMessageHeader (); + virtual ~OlsrMessageHeader (); + + void SetMessageType (MessageType messageType) + { + m_messageType = messageType; + } + MessageType GetMessageType () const + { + return m_messageType; + } + + void SetVTime (Time time) + { + m_vTime = OlsrSecondsToEmf (time.GetSeconds ()); + } + Time GetVTime () const + { + return Seconds (OlsrEmfToSeconds (m_vTime)); + } + + void SetOriginatorAddress (Ipv4Address originatorAddress) + { + m_originatorAddress = originatorAddress; + } + Ipv4Address GetOriginatorAddress () const + { + return m_originatorAddress; + } + + void SetTimeToLive (uint8_t timeToLive) + { + m_timeToLive = timeToLive; + } + uint8_t GetTimeToLive () const + { + return m_timeToLive; + } + + void SetHopCount (uint8_t hopCount) + { + m_hopCount = hopCount; + } + uint8_t GetHopCount () const + { + return m_hopCount; + } + + void SetMessageSequenceNumber (uint16_t messageSequenceNumber) + { + m_messageSequenceNumber = messageSequenceNumber; + } + uint16_t GetMessageSequenceNumber () const + { + return m_messageSequenceNumber; + } + + void SetMessageSize (uint16_t messageSize) + { + m_messageSize = messageSize; + } + uint16_t GetMessageSize () const + { + return m_messageSize; + } + +private: + MessageType m_messageType; + uint8_t m_vTime; + Ipv4Address m_originatorAddress; + uint8_t m_timeToLive; + uint8_t m_hopCount; + uint16_t m_messageSequenceNumber; + uint16_t m_messageSize; + + virtual void PrintTo (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void SerializeTo (Buffer::Iterator start) const; + virtual uint32_t DeserializeFrom (Buffer::Iterator start); + virtual std::string DoGetName (void) const { return "OlsrMessage"; } +}; + +// 5.1. MID Message Format +// +// The proposed format of a MID message is as follows: +// +// 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 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | OLSR Interface Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | OLSR Interface Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | ... | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +class OlsrMidMessageHeader : public Header +{ +public: + + OlsrMidMessageHeader (); + virtual ~OlsrMidMessageHeader (); + + void SetMessageSize (uint32_t messageSize) { + m_messageSize = messageSize; + } + uint32_t GetMessageSize () const { + return m_messageSize; + } + + const std::vector & GetInterfaceAddresses () const + { + return m_interfaceAddresses; + } + void SetInterfaceAddresses (const std::vector &addresses) + { + m_interfaceAddresses = addresses; + } + + +private: + std::vector m_interfaceAddresses; + uint32_t m_messageSize; // has to be manually set before deserialization + + virtual void PrintTo (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void SerializeTo (Buffer::Iterator start) const; + virtual uint32_t DeserializeFrom (Buffer::Iterator start); + virtual std::string DoGetName (void) const { return "OlsrMidMessage"; } +}; + +// 6.1. HELLO Message Format +// +// 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 +// +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Reserved | Htime | Willingness | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Link Code | Reserved | Link Message Size | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Neighbor Interface Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Neighbor Interface Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// : . . . : +// : : +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Link Code | Reserved | Link Message Size | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Neighbor Interface Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Neighbor Interface Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// : : +// : : +// (etc.) +class OlsrHelloMessageHeader : public Header +{ +public: + + OlsrHelloMessageHeader (); + virtual ~OlsrHelloMessageHeader (); + + + struct LinkMessage { + uint8_t linkCode; + std::vector neighborInterfaceAddresses; + }; + + + void SetMessageSize (uint32_t messageSize) { + m_messageSize = messageSize; + } + uint32_t GetMessageSize () const { + return m_messageSize; + } + + void SetWillingness (uint8_t willingness) + { + m_willingness = willingness; + } + uint8_t GetWillingness () const + { + return m_willingness; + } + + void SetHTime (Time time) + { + m_hTime = OlsrSecondsToEmf (time.GetSeconds ()); + } + Time GetHTime () const + { + return Seconds (OlsrEmfToSeconds (m_hTime)); + } + + const std::vector & GetLinkMessages () const + { + return m_linkMessages; + } + void SetLinkMessages (const std::vector &linkMessages) + { + m_linkMessages = linkMessages; + } + +private: + uint8_t m_hTime; + uint8_t m_willingness; + uint32_t m_messageSize; // has to be manually set before deserialization + std::vector m_linkMessages; + + virtual void PrintTo (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void SerializeTo (Buffer::Iterator start) const; + virtual uint32_t DeserializeFrom (Buffer::Iterator start); + virtual std::string DoGetName (void) const { return "OlsrHelloMessage"; } +}; + +// 9.1. TC Message Format +// +// The proposed format of a TC message is as follows: +// +// 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 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | ANSN | Reserved | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Advertised Neighbor Main Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Advertised Neighbor Main Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | ... | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +class OlsrTcMessageHeader : public Header +{ +public: + + OlsrTcMessageHeader (); + virtual ~OlsrTcMessageHeader (); + + void SetMessageSize (uint32_t messageSize) { + m_messageSize = messageSize; + } + uint32_t GetMessageSize () const { + return m_messageSize; + } + + const std::vector & GetNeighborAddresses () const + { + return m_neighborAddresses; + } + void SetNeighborAddresses (const std::vector &addresses) + { + m_neighborAddresses = addresses; + } + + void SetAnsn (uint16_t ansn) + { + m_ansn = ansn; + } + uint16_t GetAnsn () const + { + return m_ansn; + } + +private: + std::vector m_neighborAddresses; + uint16_t m_ansn; + + uint32_t m_messageSize; // has to be manually set before deserialization + + virtual void PrintTo (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void SerializeTo (Buffer::Iterator start) const; + virtual uint32_t DeserializeFrom (Buffer::Iterator start); + virtual std::string DoGetName (void) const { return "OlsrTcMessage"; } +}; + + +// 12.1. HNA Message Format +// +// The proposed format of an HNA-message is: +// +// 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 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Network Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Netmask | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Network Address | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Netmask | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | ... | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +// Note: HNA stands for Host Network Association +class OlsrHnaMessageHeader : public Header +{ +public: + + OlsrHnaMessageHeader (); + virtual ~OlsrHnaMessageHeader (); + + struct Association + { + Ipv4Address address; + Ipv4Mask mask; + }; + + void SetMessageSize (uint32_t messageSize) + { + m_messageSize = messageSize; + } + uint32_t GetMessageSize () const + { + return m_messageSize; + } + + const std::vector & GetAssociations () const + { + return m_associations; + } + void SetAssociations (const std::vector &associations) + { + m_associations = associations; + } + +private: + std::vector m_associations; + uint32_t m_messageSize; // has to be manually set before deserialization + + virtual void PrintTo (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void SerializeTo (Buffer::Iterator start) const; + virtual uint32_t DeserializeFrom (Buffer::Iterator start); + virtual std::string DoGetName (void) const { return "OlsrHnaMessage"; } +}; + + +}; // namespace ns3 + +#endif /* OLSR_HEADER_H */ + diff --git a/src/routing/olsr/olsr-private.h b/src/routing/olsr/olsr-private.h new file mode 100644 index 000000000..899ebc111 --- /dev/null +++ b/src/routing/olsr/olsr-private.h @@ -0,0 +1,187 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/*************************************************************************** + * Copyright (C) 2004 by Francisco J. Ros * + * fjrm@dif.um.es * + * * + * Modified on 2007 for NS-3 by Gustavo J. A. M. Carneiro, INESC Porto * + * * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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 __OLSR_H__ +#define __OLSR_H__ + +#include "olsr.h" + +#include + +#include "olsr-header.h" +#include "olsr-state.h" +#include "routing-table.h" +#include "olsr-repositories.h" +#include "ns3/object.h" +#include "ns3/packet.h" +#include "ns3/node.h" +#include "ns3/socket.h" +#include "ns3/timer.h" + + +namespace ns3 { namespace olsr { + + + +class Olsr : public ::ns3::Olsr +{ + friend class OlsrTest; + +public: + Olsr (Ptr node); + + virtual void Start (); + virtual void SetMainInterface (uint32_t interface); + +private: + + /// Address of the routing agent. + Ipv4Address m_routingAgentAddr; + + /// Packets sequence number counter. + uint16_t m_packetSequenceNumber; + /// Messages sequence number counter. + uint16_t m_messageSequenceNumber; + /// Advertised Neighbor Set sequence number. + uint16_t m_ansn; + + /// HELLO messages' emission interval. + Time m_helloInterval; + /// TC messages' emission interval. + Time m_tcInterval; + /// MID messages' emission interval. + Time m_midInterval; + /// Willingness for forwarding packets on behalf of other nodes. + uint8_t m_willingness; + /// Determines if layer 2 notifications are enabled or not. + bool m_useL2Notifications; + + /// Routing table. + Ptr m_routingTable; + /// Internal state with all needed data structs. + OlsrState m_state; + + Ptr m_ipv4; + +protected: + void DoDispose (); + void SendPacket (Packet packet); + + /// Increments packet sequence number and returns the new value. + inline uint16_t GetPacketSequenceNumber (); + /// Increments message sequence number and returns the new value. + inline uint16_t GetMessageSequenceNumber (); + + void RecvOlsr (Ptr socket, + const uint8_t *dataPtr, uint32_t dataSize, + const Ipv4Address &sourceAddr, + uint16_t sourcePort); + + void MprComputation (); + void RoutingTableComputation (); + Ipv4Address GetMainAddress (Ipv4Address iface_addr); + + // Timer handlers + Timer<> m_helloTimer; + void HelloTimerExpire (); + + Timer<> m_tcTimer; + void TcTimerExpire (); + + Timer<> m_midTimer; + void MidTimerExpire (); + + void DupTupleTimerExpire (DuplicateTuple tuple); + bool m_linkTupleTimerFirstTime; + void LinkTupleTimerExpire (LinkTuple tuple); + void Nb2hopTupleTimerExpire (TwoHopNeighborTuple tuple); + void MprSelTupleTimerExpire (MprSelectorTuple tuple); + void TopologyTupleTimerExpire (TopologyTuple tuple); + void IfaceAssocTupleTimerExpire (IfaceAssocTuple tuple); + + /// A list of pending messages which are buffered awaiting for being sent. + std::vector m_queuedMessages; + Timer<> m_queuedMessagesTimer; // timer for throttling outgoing messages + + void ForwardDefault (OlsrMessageHeader olsrMessage, + Packet messagePayload, + DuplicateTuple *duplicated, + const Ipv4Address &localIface, + const Ipv4Address &senderAddress); + void QueueMessage (Packet message, Time delay); + void SendQueuedMessages (); + void SendHello (); + void SendTc (); + void SendMid (); + + void NeighborLoss (const LinkTuple &tuple); + void AddDuplicateTuple (const DuplicateTuple &tuple); + void RemoveDuplicateTuple (const DuplicateTuple &tuple); + LinkTuple & AddLinkTuple (const LinkTuple &tuple, uint8_t willingness); + void RemoveLinkTuple (const LinkTuple &tuple); + void LinkTupleUpdated (const LinkTuple &tuple); + void AddNeighborTuple (const NeighborTuple &tuple); + void RemoveNeighborTuple (const NeighborTuple &tuple); + void AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple); + void RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple); + void AddMprSelectorTuple (const MprSelectorTuple &tuple); + void RemoveMprSelectorTuple (const MprSelectorTuple &tuple); + void AddTopologyTuple (const TopologyTuple &tuple); + void RemoveTopologyTuple (const TopologyTuple &tuple); + void AddIfaceAssocTuple (const IfaceAssocTuple &tuple); + void RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple); + + void ProcessHello (const OlsrMessageHeader &msg, + const OlsrHelloMessageHeader &hello, + const Ipv4Address &receiverIface, + const Ipv4Address &senderIface); + void ProcessTc (const OlsrMessageHeader &msg, + const OlsrTcMessageHeader &tc, + const Ipv4Address &senderIface); + void ProcessMid (const OlsrMessageHeader &msg, + const OlsrMidMessageHeader &mid, + const Ipv4Address &senderIface); + + void LinkSensing (const OlsrMessageHeader &msg, + const OlsrHelloMessageHeader &hello, + const Ipv4Address &receiverIface, + const Ipv4Address &sender_iface); + void PopulateNeighborSet (const OlsrMessageHeader &msg, + const OlsrHelloMessageHeader &hello); + void PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, + const OlsrHelloMessageHeader &hello); + void PopulateMprSelectorSet (const OlsrMessageHeader &msg, + const OlsrHelloMessageHeader &hello); + + int Degree (NeighborTuple const &tuple); + + Ipv4Address m_mainAddress; + Ptr m_receiveSocket; // UDP socket for receving OSLR packets + Ptr m_sendSocket; // UDP socket for sending OSLR packets +}; + +}}; // namespace ns3, olsr + +#endif diff --git a/src/routing/olsr/olsr-repositories.h b/src/routing/olsr/olsr-repositories.h new file mode 100644 index 000000000..d2362ccbb --- /dev/null +++ b/src/routing/olsr/olsr-repositories.h @@ -0,0 +1,200 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/*************************************************************************** + * Copyright (C) 2004 by Francisco J. Ros * + * fjrm@dif.um.es * + * * + * Modified on 2007 for NS-3 by Gustavo J. A. M. Carneiro, INESC Porto * + * * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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. * + ***************************************************************************/ + +/// +/// \file OLSR_repositories.h +/// \brief Here are defined all data structures needed by an OLSR node. +/// + +#ifndef __OLSR_REPOSITORIES_H__ +#define __OLSR_REPOSITORIES_H__ + +#include +#include + +#include "ns3/ipv4-address.h" +#include "ns3/nstime.h" + +namespace ns3 { namespace olsr { + + + +/// An Interface Association Tuple. +struct IfaceAssocTuple +{ + /// Interface address of a node. + Ipv4Address ifaceAddr; + /// Main address of the node. + Ipv4Address mainAddr; + /// Time at which this tuple expires and must be removed. + Time time; +}; + +static inline bool +operator == (const IfaceAssocTuple &a, const IfaceAssocTuple &b) +{ + return (a.ifaceAddr == b.ifaceAddr + && a.mainAddr == b.mainAddr); +} + +/// A Link Tuple. +struct LinkTuple +{ + /// Interface address of the local node. + Ipv4Address localIfaceAddr; + /// Interface address of the neighbor node. + Ipv4Address neighborIfaceAddr; + /// The link is considered bidirectional until this time. + Time symTime; + /// The link is considered unidirectional until this time. + Time asymTime; + /// The link is considered lost until this time (used for link layer notification). + Time lostTime; + /// Time at which this tuple expires and must be removed. + Time time; +}; + +static inline bool +operator == (const LinkTuple &a, const LinkTuple &b) +{ + return (a.localIfaceAddr == b.localIfaceAddr + && a.neighborIfaceAddr == b.neighborIfaceAddr); +} + +/// A Neighbor Tuple. +struct NeighborTuple +{ + /// Main address of a neighbor node. + Ipv4Address neighborMainAddr; + /// Neighbor Type and Link Type at the four less significative digits. + enum Status { + STATUS_NOT_SYM = 0, // "not symmetric" + STATUS_SYM = 1, // "symmetric" + } status; + /// A value between 0 and 7 specifying the node's willingness to carry traffic on behalf of other nodes. + uint8_t willingness; +}; + +static inline bool +operator == (const NeighborTuple &a, const NeighborTuple &b) +{ + return (a.neighborMainAddr == b.neighborMainAddr + && a.status == b.status + && a.willingness == b.willingness); +} + +/// A 2-hop Tuple. +struct TwoHopNeighborTuple +{ + /// Main address of a neighbor. + Ipv4Address neighborMainAddr; + /// Main address of a 2-hop neighbor with a symmetric link to nb_main_addr. + Ipv4Address twoHopNeighborAddr; + /// Time at which this tuple expires and must be removed. + Time expirationTime; // previously called 'time_' +}; + +static inline bool +operator == (const TwoHopNeighborTuple &a, const TwoHopNeighborTuple &b) +{ + return (a.neighborMainAddr == b.neighborMainAddr + && a.twoHopNeighborAddr == b.twoHopNeighborAddr); +} + +/// An MPR-Selector Tuple. +struct MprSelectorTuple +{ + /// Main address of a node which have selected this node as a MPR. + Ipv4Address mainAddr; + /// Time at which this tuple expires and must be removed. + Time expirationTime; // previously called 'time_' +}; + +static inline bool +operator == (const MprSelectorTuple &a, const MprSelectorTuple &b) +{ + return (a.mainAddr == b.mainAddr); +} + + +/// The type "list of interface addresses" +//typedef std::vector addr_list_t; + +/// A Duplicate Tuple +struct DuplicateTuple +{ + /// Originator address of the message. + Ipv4Address address; + /// Message sequence number. + uint16_t sequenceNumber; + /// Indicates whether the message has been retransmitted or not. + bool retransmitted; + /// List of interfaces which the message has been received on. + std::vector ifaceList; + /// Time at which this tuple expires and must be removed. + Time expirationTime; +}; + +static inline bool +operator == (const DuplicateTuple &a, const DuplicateTuple &b) +{ + return (a.address == b.address + && a.sequenceNumber == b.sequenceNumber); +} + +/// A Topology Tuple +struct TopologyTuple +{ + /// Main address of the destination. + Ipv4Address destAddr; + /// Main address of a node which is a neighbor of the destination. + Ipv4Address lastAddr; + /// Sequence number. + uint16_t sequenceNumber; + /// Time at which this tuple expires and must be removed. + Time expirationTime; +}; + +static inline bool +operator == (const TopologyTuple &a, const TopologyTuple &b) +{ + return (a.destAddr == b.destAddr + && a.lastAddr == b.lastAddr + && a.sequenceNumber == b.sequenceNumber); +} + + +typedef std::set MprSet; ///< MPR Set type. +typedef std::vector MprSelectorSet; ///< MPR Selector Set type. +typedef std::vector LinkSet; ///< Link Set type. +typedef std::vector NeighborSet; ///< Neighbor Set type. +typedef std::vector TwoHopNeighborSet; ///< 2-hop Neighbor Set type. +typedef std::vector TopologySet; ///< Topology Set type. +typedef std::vector DuplicateSet; ///< Duplicate Set type. +typedef std::vector IfaceAssocSet; ///< Interface Association Set type. + + +}}; // namespace ns3, olsr + +#endif /* __OLSR_REPOSITORIES_H__ */ diff --git a/src/routing/olsr/olsr-state.cc b/src/routing/olsr/olsr-state.cc new file mode 100644 index 000000000..7a1f69e4a --- /dev/null +++ b/src/routing/olsr/olsr-state.cc @@ -0,0 +1,438 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/*************************************************************************** + * Copyright (C) 2004 by Francisco J. Ros * + * fjrm@dif.um.es * + * * + * Modified for NS-3 by Gustavo J. A. M. Carneiro on 2007 * + * gjc@inescporto.pt * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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. * + ***************************************************************************/ + +/// +/// \file OlsrState.cc +/// \brief Implementation of all functions needed for manipulating the internal +/// state of an OLSR node. +/// + +#include "olsr-state.h" + + +namespace ns3 { namespace olsr { + + +/********** MPR Selector Set Manipulation **********/ + +MprSelectorTuple* +OlsrState::FindMprSelectorTuple (Ipv4Address const &mainAddr) +{ + for (MprSelectorSet::iterator it = m_mprSelectorSet.begin (); + it != m_mprSelectorSet.end (); it++) + { + if (it->mainAddr == mainAddr) + return &(*it); + } + return NULL; +} + +void +OlsrState::EraseMprSelectorTuple (const MprSelectorTuple &tuple) +{ + for (MprSelectorSet::iterator it = m_mprSelectorSet.begin (); + it != m_mprSelectorSet.end (); it++) + { + if (*it == tuple) + { + m_mprSelectorSet.erase (it); + break; + } + } +} + +void +OlsrState::EraseMprSelectorTuples (const Ipv4Address &mainAddr) +{ + for (MprSelectorSet::iterator it = m_mprSelectorSet.begin (); + it != m_mprSelectorSet.end (); it++) + { + if (it->mainAddr == mainAddr) + { + it = m_mprSelectorSet.erase (it); + it--; + } + } +} + +void +OlsrState::InsertMprSelectorTuple (MprSelectorTuple const &tuple) +{ + m_mprSelectorSet.push_back (tuple); +} + +/********** Neighbor Set Manipulation **********/ + +NeighborTuple* +OlsrState::FindNeighborTuple (Ipv4Address const &mainAddr) +{ + for (NeighborSet::iterator it = m_neighborSet.begin (); + it != m_neighborSet.end (); it++) + { + if (it->neighborMainAddr == mainAddr) + return &(*it); + } + return NULL; +} + +NeighborTuple* +OlsrState::FindSymNeighborTuple (Ipv4Address const &mainAddr) +{ + for (NeighborSet::iterator it = m_neighborSet.begin (); + it != m_neighborSet.end (); it++) + { + if (it->neighborMainAddr == mainAddr && it->status == NeighborTuple::STATUS_SYM) + return &(*it); + } + return NULL; +} + +NeighborTuple* +OlsrState::FindNeighborTuple (Ipv4Address const &mainAddr, uint8_t willingness) +{ + for (NeighborSet::iterator it = m_neighborSet.begin (); + it != m_neighborSet.end (); it++) + { + if (it->neighborMainAddr == mainAddr && it->willingness == willingness) + return &(*it); + } + return NULL; +} + +void +OlsrState::EraseNeighborTuple (const NeighborTuple &tuple) +{ + for (NeighborSet::iterator it = m_neighborSet.begin (); + it != m_neighborSet.end (); it++) + { + if (*it == tuple) + { + m_neighborSet.erase (it); + break; + } + } +} + +void +OlsrState::EraseNeighborTuple (const Ipv4Address &mainAddr) +{ + for (NeighborSet::iterator it = m_neighborSet.begin (); + it != m_neighborSet.end (); it++) + { + if (it->neighborMainAddr == mainAddr) + { + it = m_neighborSet.erase (it); + break; + } + } +} + +void +OlsrState::InsertNeighborTuple (NeighborTuple const &tuple) +{ + m_neighborSet.push_back (tuple); +} + +/********** Neighbor 2 Hop Set Manipulation **********/ + +TwoHopNeighborTuple* +OlsrState::FindTwoHopNeighborTuple (Ipv4Address const &neighborMainAddr, + Ipv4Address const &twoHopNeighborAddr) +{ + for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin (); + it != m_twoHopNeighborSet.end (); it++) + { + if (it->neighborMainAddr == neighborMainAddr + && it->twoHopNeighborAddr == twoHopNeighborAddr) + { + return &(*it); + } + } + return NULL; +} + +void +OlsrState::EraseTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple) +{ + for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin (); + it != m_twoHopNeighborSet.end (); it++) + { + if (*it == tuple) + { + m_twoHopNeighborSet.erase(it); + break; + } + } +} + +void +OlsrState::EraseTwoHopNeighborTuples (const Ipv4Address &neighborMainAddr, + const Ipv4Address &twoHopNeighborAddr) +{ + for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin (); + it != m_twoHopNeighborSet.end (); it++) + { + if (it->neighborMainAddr == neighborMainAddr + && it->twoHopNeighborAddr == twoHopNeighborAddr) + { + it = m_twoHopNeighborSet.erase (it); + it--; // FIXME: is this correct in the case 'it' pointed to the first element? + } + } +} + +void +OlsrState::EraseTwoHopNeighborTuples (const Ipv4Address &neighborMainAddr) +{ + for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin (); + it != m_twoHopNeighborSet.end (); it++) + { + if (it->neighborMainAddr == neighborMainAddr) { + it = m_twoHopNeighborSet.erase (it); + it--; + } + } +} + +void +OlsrState::InsertTwoHopNeighborTuple (TwoHopNeighborTuple const &tuple){ + m_twoHopNeighborSet.push_back (tuple); +} + +/********** MPR Set Manipulation **********/ + +bool +OlsrState::FindMprAddress (Ipv4Address const &addr) +{ + MprSet::iterator it = m_mprSet.find (addr); + return (it != m_mprSet.end ()); +} + +void +OlsrState::InsertMprAddress (Ipv4Address const & addr) +{ + m_mprSet.insert (addr); +} + +void +OlsrState::ClearMprSet () +{ + m_mprSet.clear (); +} + +/********** Duplicate Set Manipulation **********/ + +DuplicateTuple* +OlsrState::FindDuplicateTuple (Ipv4Address const &addr, uint16_t sequenceNumber) +{ + for (DuplicateSet::iterator it = m_duplicateSet.begin (); + it != m_duplicateSet.end(); it++) + { + if (it->address == addr && it->sequenceNumber == sequenceNumber) + return &(*it); + } + return NULL; +} + +void +OlsrState::EraseDuplicateTuple (const DuplicateTuple &tuple) +{ + for (DuplicateSet::iterator it = m_duplicateSet.begin (); + it != m_duplicateSet.end (); it++) + { + if (*it == tuple) + { + m_duplicateSet.erase (it); + break; + } + } +} + +void +OlsrState::InsertDuplicateTuple (DuplicateTuple const &tuple) +{ + m_duplicateSet.push_back (tuple); +} + +/********** Link Set Manipulation **********/ + +LinkTuple* +OlsrState::FindLinkTuple (Ipv4Address const & ifaceAddr) +{ + for (LinkSet::iterator it = m_linkSet.begin (); + it != m_linkSet.end (); it++) + { + if (it->neighborIfaceAddr == ifaceAddr) + return &(*it); + } + return NULL; +} + +LinkTuple* +OlsrState::FindSymLinkTuple (Ipv4Address const &ifaceAddr, Time now) +{ + for (LinkSet::iterator it = m_linkSet.begin (); + it != m_linkSet.end (); it++) + { + if (it->neighborIfaceAddr == ifaceAddr) + { + if (it->symTime > now) + return &(*it); + else + break; + } + } + return NULL; +} + +void +OlsrState::EraseLinkTuple (const LinkTuple &tuple) +{ + for (LinkSet::iterator it = m_linkSet.begin (); + it != m_linkSet.end (); it++) + { + if (*it == tuple) + { + m_linkSet.erase (it); + break; + } + } +} + +LinkTuple& +OlsrState::InsertLinkTuple (LinkTuple const &tuple) +{ + m_linkSet.push_back (tuple); + return m_linkSet.back (); +} + +/********** Topology Set Manipulation **********/ + +TopologyTuple* +OlsrState::FindTopologyTuple (Ipv4Address const &destAddr, + Ipv4Address const &lastAddr) +{ + for (TopologySet::iterator it = m_topologySet.begin (); + it != m_topologySet.end (); it++) + { + if (it->destAddr == destAddr && it->lastAddr == lastAddr) + return &(*it); + } + return NULL; +} + +TopologyTuple* +OlsrState::FindNewerTopologyTuple (Ipv4Address const & lastAddr, uint16_t ansn) +{ + for (TopologySet::iterator it = m_topologySet.begin (); + it != m_topologySet.end (); it++) + { + if (it->lastAddr == lastAddr && it->sequenceNumber > ansn) + return &(*it); + } + return NULL; +} + +void +OlsrState::EraseTopologyTuple(const TopologyTuple &tuple) +{ + for (TopologySet::iterator it = m_topologySet.begin (); + it != m_topologySet.end (); it++) + { + if (*it == tuple) + { + m_topologySet.erase (it); + break; + } + } +} + +void +OlsrState::EraseOlderTopologyTuples (const Ipv4Address &lastAddr, uint16_t ansn) +{ + for (TopologySet::iterator it = m_topologySet.begin(); + it != m_topologySet.end(); it++) + { + if (it->lastAddr == lastAddr && it->sequenceNumber < ansn) + { + it = m_topologySet.erase (it); + it--; + } + } +} + +void +OlsrState::InsertTopologyTuple (TopologyTuple const &tuple) +{ + m_topologySet.push_back (tuple); +} + +/********** Interface Association Set Manipulation **********/ + +IfaceAssocTuple* +OlsrState::FindIfaceAssocTuple (Ipv4Address const &ifaceAddr) +{ + for (IfaceAssocSet::iterator it = m_ifaceAssocSet.begin (); + it != m_ifaceAssocSet.end (); it++) + { + if (it->ifaceAddr == ifaceAddr) + return &(*it); + } + return NULL; +} + +void +OlsrState::EraseIfaceAssocTuple (const IfaceAssocTuple &tuple) +{ + for (IfaceAssocSet::iterator it = m_ifaceAssocSet.begin (); + it != m_ifaceAssocSet.end (); it++) + { + if (*it == tuple) + { + m_ifaceAssocSet.erase (it); + break; + } + } +} + +void +OlsrState::InsertIfaceAssocTuple (const IfaceAssocTuple &tuple) +{ + m_ifaceAssocSet.push_back (tuple); +} + +std::vector +OlsrState::FindNeighborInterfaces (const Ipv4Address &neighborMainAddr) const +{ + std::vector retval; + for (IfaceAssocSet::const_iterator it = m_ifaceAssocSet.begin (); + it != m_ifaceAssocSet.end (); it++) + { + if (it->mainAddr == neighborMainAddr) + retval.push_back (it->ifaceAddr); + } + return retval; +} + +}}; // namespace ns3, olsr diff --git a/src/routing/olsr/olsr-state.h b/src/routing/olsr/olsr-state.h new file mode 100644 index 000000000..dfa8b78fb --- /dev/null +++ b/src/routing/olsr/olsr-state.h @@ -0,0 +1,147 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/*************************************************************************** + * Copyright (C) 2004 by Francisco J. Ros * + * fjrm@dif.um.es * + * * + * Modified for NS-3 by Gustavo J. A. M. Carneiro on 2007 * + * gjc@inescporto.pt * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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. * + ***************************************************************************/ + +/// +/// \file OLSR_state.h +/// \brief This header file declares and defines internal state of an OLSR node. +/// + +#ifndef __OLSR_state_h__ +#define __OLSR_state_h__ + +#include "olsr-repositories.h" + +namespace ns3 { namespace olsr { + +/// This class encapsulates all data structures needed for maintaining internal state of an OLSR node. +class OlsrState +{ + // friend class Olsr; + +protected: + LinkSet m_linkSet; ///< Link Set (RFC 3626, section 4.2.1). + NeighborSet m_neighborSet; ///< Neighbor Set (RFC 3626, section 4.3.1). + TwoHopNeighborSet m_twoHopNeighborSet; ///< 2-hop Neighbor Set (RFC 3626, section 4.3.2). + TopologySet m_topologySet; ///< Topology Set (RFC 3626, section 4.4). + MprSet m_mprSet; ///< MPR Set (RFC 3626, section 4.3.3). + MprSelectorSet m_mprSelectorSet; ///< MPR Selector Set (RFC 3626, section 4.3.4). + DuplicateSet m_duplicateSet; ///< Duplicate Set (RFC 3626, section 3.4). + IfaceAssocSet m_ifaceAssocSet; ///< Interface Association Set (RFC 3626, section 4.1). + +public: + + // MPR selector + const MprSelectorSet & GetMprSelectors () const + { + return m_mprSelectorSet; + } + MprSelectorTuple* FindMprSelectorTuple (const Ipv4Address &mainAddr); + void EraseMprSelectorTuple (const MprSelectorTuple &tuple); + void EraseMprSelectorTuples (const Ipv4Address &mainAddr); + void InsertMprSelectorTuple (const MprSelectorTuple &tuple); + + // Neighbor + const NeighborSet & GetNeighbors () const + { + return m_neighborSet; + } + NeighborTuple* FindNeighborTuple (const Ipv4Address &mainAddr); + NeighborTuple* FindSymNeighborTuple (const Ipv4Address &mainAddr); + NeighborTuple* FindNeighborTuple (const Ipv4Address &mainAddr, + uint8_t willingness); + void EraseNeighborTuple (const NeighborTuple &neighborTuple); + void EraseNeighborTuple (const Ipv4Address &mainAddr); + void InsertNeighborTuple (const NeighborTuple &tuple); + + // Two-hop neighbor + const TwoHopNeighborSet & GetTwoHopNeighbors () const + { + return m_twoHopNeighborSet; + } + TwoHopNeighborTuple* FindTwoHopNeighborTuple (const Ipv4Address &neighbor, + const Ipv4Address &twoHopNeighbor); + void EraseTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple); + void EraseTwoHopNeighborTuples (const Ipv4Address &neighbor); + void EraseTwoHopNeighborTuples (const Ipv4Address &neighbor, + const Ipv4Address &twoHopNeighbor); + void InsertTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple); + + // MPR + bool FindMprAddress (const Ipv4Address &address); + void InsertMprAddress (const Ipv4Address &address); + void ClearMprSet (); + + // Duplicate + DuplicateTuple* FindDuplicateTuple (const Ipv4Address &address, + uint16_t sequenceNumber); + void EraseDuplicateTuple (const DuplicateTuple &tuple); + void InsertDuplicateTuple (const DuplicateTuple &tuple); + + // Link + const LinkSet & GetLinks () const + { + return m_linkSet; + } + LinkTuple* FindLinkTuple (const Ipv4Address &ifaceAddr); + LinkTuple* FindSymLinkTuple (const Ipv4Address &ifaceAddr, Time time); + void EraseLinkTuple (const LinkTuple &tuple); + LinkTuple& InsertLinkTuple (const LinkTuple &tuple); + + // Topology + const TopologySet & GetTopologySet () const + { + return m_topologySet; + } + TopologyTuple* FindTopologyTuple (const Ipv4Address &destAddr, + const Ipv4Address &lastAddr); + TopologyTuple* FindNewerTopologyTuple (const Ipv4Address &lastAddr, + uint16_t ansn); + void EraseTopologyTuple (const TopologyTuple &tuple); + void EraseOlderTopologyTuples (const Ipv4Address &lastAddr, + uint16_t ansn); + void InsertTopologyTuple (const TopologyTuple &tuple); + + // Interface association + const IfaceAssocSet & GetIfaceAssocSet () const + { + return m_ifaceAssocSet; + } + IfaceAssocSet & GetIfaceAssocSetMutable () + { + return m_ifaceAssocSet; + } + IfaceAssocTuple* FindIfaceAssocTuple (const Ipv4Address &ifaceAddr); + void EraseIfaceAssocTuple (const IfaceAssocTuple &tuple); + void InsertIfaceAssocTuple (const IfaceAssocTuple &tuple); + + // Returns a vector of all interfaces of a given neighbor, with the + // exception of the "main" one. + std::vector + FindNeighborInterfaces (const Ipv4Address &neighborMainAddr) const; + +}; + +}}; // namespace ns3, olsr + +#endif diff --git a/src/routing/olsr/olsr.cc b/src/routing/olsr/olsr.cc new file mode 100644 index 000000000..c3415e1f1 --- /dev/null +++ b/src/routing/olsr/olsr.cc @@ -0,0 +1,2135 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/*************************************************************************** + * Copyright (C) 2004 by Francisco J. Ros * + * fjrm@dif.um.es * + * * + * Modified on 2007 for NS-3 by Gustavo J. A. M. Carneiro, INESC Porto * + * * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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. * + ***************************************************************************/ + +/// +/// \file OLSR.cc +/// \brief Implementation of OLSR agent and related classes. +/// +/// This is the main file of this software because %OLSR's behaviour is +/// implemented here. +/// + +#include +// #include +// #include +// #include +// #include +#include +#include "olsr-private.h" +#include "ns3/socket-factory.h" +#include "ns3/udp.h" +#include "ns3/internet-node.h" +#include "ns3/simulator.h" +#include "ns3/debug.h" +#include "ns3/random-variable.h" + +#include + + +/********** Useful macros **********/ + +/// +/// \brief Gets the delay between a given time and the current time. +/// +/// If given time is previous to the current one, then this macro returns +/// a number close to 0. This is used for scheduling events at a certain moment. +/// +#define DELAY(time) (((time) < (Simulator::Now ())) ? Seconds (0.000001) : \ + (time - Simulator::Now () + Seconds (0.000001))) + + + +/********** Intervals **********/ + +/// HELLO messages emission interval. +#define OLSR_HELLO_INTERVAL Seconds (2) + +/// TC messages emission interval. +#define OLSR_TC_INTERVAL Seconds (5) + +/// MID messages emission interval. +#define OLSR_MID_INTERVAL OLSR_TC_INTERVAL + +/// +/// \brief Period at which a node must cite every link and every neighbor. +/// +/// We only use this value in order to define OLSR_NEIGHB_HOLD_TIME. +/// +#define OLSR_REFRESH_INTERVAL Seconds (2) + + +/********** Holding times **********/ + +/// Neighbor holding time. +#define OLSR_NEIGHB_HOLD_TIME (Scalar (3) * OLSR_REFRESH_INTERVAL) +/// Top holding time. +#define OLSR_TOP_HOLD_TIME (Scalar (3) * OLSR_TC_INTERVAL) +/// Dup holding time. +#define OLSR_DUP_HOLD_TIME Seconds (30) +/// MID holding time. +#define OLSR_MID_HOLD_TIME (Scalar (3) * OLSR_MID_INTERVAL) + + +/********** Link types **********/ + +/// Unspecified link type. +#define OLSR_UNSPEC_LINK 0 +/// Asymmetric link type. +#define OLSR_ASYM_LINK 1 +/// Symmetric link type. +#define OLSR_SYM_LINK 2 +/// Lost link type. +#define OLSR_LOST_LINK 3 + +/********** Neighbor types **********/ + +/// Not neighbor type. +#define OLSR_NOT_NEIGH 0 +/// Symmetric neighbor type. +#define OLSR_SYM_NEIGH 1 +/// Asymmetric neighbor type. +#define OLSR_MPR_NEIGH 2 + + +/********** Willingness **********/ + +/// Willingness for forwarding packets from other nodes: never. +#define OLSR_WILL_NEVER 0 +/// Willingness for forwarding packets from other nodes: low. +#define OLSR_WILL_LOW 1 +/// Willingness for forwarding packets from other nodes: medium. +#define OLSR_WILL_DEFAULT 3 +/// Willingness for forwarding packets from other nodes: high. +#define OLSR_WILL_HIGH 6 +/// Willingness for forwarding packets from other nodes: always. +#define OLSR_WILL_ALWAYS 7 + + +/********** Miscellaneous constants **********/ + +/// Maximum allowed jitter. +#define OLSR_MAXJITTER (OLSR_HELLO_INTERVAL.GetSeconds () / 4) +/// Maximum allowed sequence number. +#define OLSR_MAX_SEQ_NUM 65535 +/// Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission. +#define JITTER (Seconds (UniformVariable::GetSingleValue (0, OLSR_MAXJITTER))) + + +#define OLSR_PORT_NUMBER 698 +/// Maximum number of messages per packet. +#define OLSR_MAX_MSGS 64 + +/// Maximum number of hellos per message (4 possible link types * 3 possible nb types). +#define OLSR_MAX_HELLOS 12 + +/// Maximum number of addresses advertised on a message. +#define OLSR_MAX_ADDRS 64 + + +namespace ns3 { + +const InterfaceId Olsr::iid = MakeInterfaceId ("Olsr", Object::iid); +const ClassId Olsr::cid = MakeClassId< olsr::Olsr, Ptr > ("Olsr", Olsr::iid); + +namespace olsr { + +NS_DEBUG_COMPONENT_DEFINE ("Olsr"); + + +/********** OLSR class **********/ + + +Olsr::Olsr (Ptr node) + : + m_useL2Notifications (false), + m_helloTimer (OLSR_HELLO_INTERVAL, MakeCallback (&Olsr::HelloTimerExpire, this)), + m_tcTimer (OLSR_TC_INTERVAL, MakeCallback (&Olsr::TcTimerExpire, this)), + m_midTimer (OLSR_MID_INTERVAL, MakeCallback (&Olsr::MidTimerExpire, this)), + m_queuedMessagesTimer (MakeCallback (&Olsr::SendQueuedMessages, this)) +{ + SetInterfaceId (Olsr::iid); + + // Aggregate with the Node, so that OLSR dies when the node is destroyed. + node->AddInterface (this); + + m_packetSequenceNumber = OLSR_MAX_SEQ_NUM; + m_messageSequenceNumber = OLSR_MAX_SEQ_NUM; + m_ansn = OLSR_MAX_SEQ_NUM; + + m_helloInterval = OLSR_HELLO_INTERVAL; + m_tcInterval = OLSR_TC_INTERVAL; + m_midInterval = OLSR_MID_INTERVAL; + m_willingness = OLSR_WILL_ALWAYS; + + m_linkTupleTimerFirstTime = true; + + m_ipv4 = node->QueryInterface (Ipv4::iid); + NS_ASSERT (m_ipv4); + + Ptr socketFactory = node->QueryInterface (Udp::iid); + + m_receiveSocket = socketFactory->CreateSocket (); + if (m_receiveSocket->Bind (OLSR_PORT_NUMBER)) + NS_ASSERT_MSG (false, "Failed to bind() OLSR receive socket"); + + m_sendSocket = socketFactory->CreateSocket (); + m_sendSocket->Connect (Ipv4Address (0xffffffff), OLSR_PORT_NUMBER); + +} + +void Olsr::DoDispose () +{ + m_ipv4 = 0; + m_receiveSocket->Dispose (); + m_receiveSocket = 0; + m_sendSocket->Dispose (); + m_sendSocket = 0; + m_routingTable->Dispose (); + m_routingTable = 0; + + Object::DoDispose (); +} + +void Olsr::Start () +{ + if (m_mainAddress == Ipv4Address ()) + { + Ipv4Address loopback ("127.0.0.1"); + for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++) + { + Ipv4Address addr = m_ipv4->GetAddress (i); + if (addr != loopback) + { + m_mainAddress = addr; + break; + } + } + + NS_ASSERT (m_mainAddress != Ipv4Address ()); + } + + NS_DEBUG ("Starting OLSR on node " << m_mainAddress); + + m_routingTable = Create (m_ipv4, m_mainAddress); + // Add OLSR as routing protocol, with slightly lower priority than + // static routing. + m_ipv4->AddRoutingProtocol (m_routingTable, -10); + + if (m_sendSocket->Bind (m_mainAddress, OLSR_PORT_NUMBER)) + NS_ASSERT_MSG (false, "Failed to bind() OLSR send socket"); + m_receiveSocket->Recv (MakeCallback (&Olsr::RecvOlsr, this)); + m_helloTimer.Expire (); + m_tcTimer.Expire (); + m_midTimer.Expire (); + + NS_DEBUG ("OLSR on node " << m_mainAddress << " started"); +} + +void Olsr::SetMainInterface (uint32_t interface) +{ + m_mainAddress = m_ipv4->GetAddress (interface); +} + + +// +// \brief Processes an incoming %OLSR packet following RFC 3626 specification. +void +Olsr::RecvOlsr (Ptr socket, + const uint8_t *dataPtr, uint32_t dataSize, + const Ipv4Address &sourceAddress, + uint16_t sourcePort) +{ + NS_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet"); + + // All routing messages are sent from and to port RT_PORT, + // so we check it. + NS_ASSERT (sourcePort == OLSR_PORT_NUMBER); + + Packet packet (dataPtr, dataSize); + + OlsrPacketHeader olsrPacketHeader; + packet.RemoveHeader (olsrPacketHeader); + NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSize ()); + uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSize (); + + while (sizeLeft) + { + OlsrMessageHeader messageHeader; + NS_ASSERT (sizeLeft >= messageHeader.GetSize ()); + if (packet.RemoveHeader (messageHeader) == 0) + NS_ASSERT (false); + + sizeLeft -= messageHeader.GetMessageSize (); + + NS_DEBUG ("Olsr Msg received with type " + << std::dec << int (messageHeader.GetMessageType ()) + << " TTL=" << int (messageHeader.GetTimeToLive ()) + << " origAddr=" << messageHeader.GetOriginatorAddress ()); + + // If ttl is less than or equal to zero, or + // the receiver is the same as the originator, + // the message must be silently dropped + if (messageHeader.GetTimeToLive () == 0 + || messageHeader.GetOriginatorAddress () == m_mainAddress) + { + packet.RemoveAtStart (messageHeader.GetMessageSize () + - messageHeader.GetSize ()); + continue; + } + + // Save the original message payload for forwarding + Packet messagePayload = packet.CreateFragment + (0, messageHeader.GetMessageSize () - messageHeader.GetSize ()); + + // If the message has been processed it must not be processed again + bool do_forwarding = true; + DuplicateTuple *duplicated = m_state.FindDuplicateTuple + (messageHeader.GetOriginatorAddress (), + messageHeader.GetMessageSequenceNumber ()); + + if (duplicated == NULL) + { + OlsrHelloMessageHeader helloMsg; + OlsrTcMessageHeader tcMsg; + OlsrMidMessageHeader midMsg; + + switch (messageHeader.GetMessageType ()) + { + case OlsrMessageHeader::HELLO_MESSAGE: + helloMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSize ()); + packet.RemoveHeader (helloMsg); + NS_DEBUG ("OLSR node received HELLO message of size " << messageHeader.GetMessageSize ()); + ProcessHello(messageHeader, helloMsg, m_mainAddress, sourceAddress); + break; + + case OlsrMessageHeader::TC_MESSAGE: + tcMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSize ()); + packet.RemoveHeader (tcMsg); + NS_DEBUG ("OLSR node received TC message of size " << messageHeader.GetMessageSize ()); + ProcessTc(messageHeader, tcMsg, sourceAddress); + break; + + case OlsrMessageHeader::MID_MESSAGE: + midMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSize ()); + packet.RemoveHeader (midMsg); + NS_DEBUG ("OLSR node received MID message of size " << messageHeader.GetMessageSize ()); + ProcessMid(messageHeader, midMsg, sourceAddress); + break; + + default: + packet.RemoveAtStart (messageHeader.GetMessageSize () - messageHeader.GetSize ()); + NS_DEBUG ("OLSR message type " << + int (messageHeader.GetMessageType ()) << + " not implemented"); + } + } + else + { + NS_DEBUG ("OLSR message is duplicated, not reading it."); + packet.RemoveAtStart (messageHeader.GetMessageSize () - messageHeader.GetSize ()); + + // If the message has been considered for forwarding, it should + // not be retransmitted again + for (std::vector::const_iterator it = duplicated->ifaceList.begin (); + it != duplicated->ifaceList.end(); it++) + { + if (*it == m_mainAddress) + { + do_forwarding = false; + break; + } + } + } + + if (do_forwarding) + { + // HELLO messages are never forwarded. + // TC and MID messages are forwarded using the default algorithm. + // Remaining messages are also forwarded using the default algorithm. + if (messageHeader.GetMessageType () != OlsrMessageHeader::HELLO_MESSAGE) + ForwardDefault (messageHeader, messagePayload, duplicated, + m_mainAddress, sourceAddress); + } + + } + + // After processing all OLSR messages, we must recompute the routing table + RoutingTableComputation (); +} + +/// +/// \brief This auxiliary function (defined in RFC 3626) is used for calculating the MPR Set. +/// +/// \param tuple the neighbor tuple which has the main address of the node we are going to calculate its degree to. +/// \return the degree of the node. +/// +int +Olsr::Degree (NeighborTuple const &tuple) +{ + int degree = 0; + for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin (); + it != m_state.GetTwoHopNeighbors ().end (); it++) + { + TwoHopNeighborTuple const &nb2hop_tuple = *it; + if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr) + { + NeighborTuple *nb_tuple = + m_state.FindNeighborTuple (nb2hop_tuple.neighborMainAddr); + if (nb_tuple == NULL) + degree++; + } + } + return degree; +} + +/// +/// \brief Computates MPR set of a node following RFC 3626 hints. +/// +void +Olsr::MprComputation() +{ + // MPR computation should be done for each interface. See section 8.3.1 + // (RFC 3626) for details. + + m_state.ClearMprSet (); + + // N is the subset of neighbors of the node, which are + // neighbor "of the interface I" + NeighborSet N; + for (NeighborSet::const_iterator it = m_state.GetNeighbors ().begin(); + it != m_state.GetNeighbors ().end (); it++) + { + if ((*it).status == NeighborTuple::STATUS_SYM) // I think that we need this check + N.push_back (*it); + } + + // N2 is the set of 2-hop neighbors reachable from "the interface + // I", excluding: + // (i) the nodes only reachable by members of N with willingness WILL_NEVER + // (ii) the node performing the computation + // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric + // link to this node on some interface. + TwoHopNeighborSet N2; + for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin (); + it != m_state.GetTwoHopNeighbors ().end (); it++) + { + TwoHopNeighborTuple const &twoHopNeigh = *it; + bool ok = true; + NeighborTuple *nb_tuple = m_state.FindSymNeighborTuple (twoHopNeigh.neighborMainAddr); + if (nb_tuple == NULL) + { + ok = false; + } + else + { + nb_tuple = m_state.FindNeighborTuple (twoHopNeigh.neighborMainAddr, OLSR_WILL_NEVER); + if (nb_tuple != NULL) + { + ok = false; + } + else + { + nb_tuple = m_state.FindSymNeighborTuple (twoHopNeigh.neighborMainAddr); + if (nb_tuple != NULL) + ok = false; + } + } + + if (ok) + N2.push_back (twoHopNeigh); + } + + // 1. Start with an MPR set made of all members of N with + // N_willingness equal to WILL_ALWAYS + for (NeighborSet::const_iterator it = N.begin (); it != N.end (); it++) + { + NeighborTuple const &nb_tuple = *it; + if (nb_tuple.willingness == OLSR_WILL_ALWAYS) + m_state.InsertMprAddress (nb_tuple.neighborMainAddr); + } + + // 2. Calculate D(y), where y is a member of N, for all nodes in N. + // We will do this later. + // FIXME + + // 3. Add to the MPR set those nodes in N, which are the *only* + // nodes to provide reachability to a node in N2. Remove the + // nodes from N2 which are now covered by a node in the MPR set. + MprSet foundset; + std::set deleted_addrs; + for (TwoHopNeighborSet::iterator it = N2.begin (); it != N2.end (); it++) + { + TwoHopNeighborTuple const &nb2hop_tuple1 = *it; + + MprSet::const_iterator pos = foundset.find (nb2hop_tuple1.twoHopNeighborAddr); + if (pos != foundset.end ()) + continue; + + bool found = false; + for (NeighborSet::const_iterator it2 = N.begin (); + it2 != N.end (); it2++) + { + if ((*it2).neighborMainAddr == nb2hop_tuple1.neighborMainAddr) { + found = true; + break; + } + } + if (!found) + continue; + + found = false; + for (TwoHopNeighborSet::const_iterator it2 = it + 1; + it2 != N2.end (); it2++) + { + TwoHopNeighborTuple const &nb2hop_tuple2 = *it2; + if (nb2hop_tuple1.twoHopNeighborAddr == nb2hop_tuple2.twoHopNeighborAddr) + { + foundset.insert (nb2hop_tuple1.twoHopNeighborAddr); + found = true; + break; + } + } + if (!found) + { + m_state.InsertMprAddress (nb2hop_tuple1.neighborMainAddr); + + for (TwoHopNeighborSet::iterator it2 = it + 1; it2 != N2.end (); it2++) + { + TwoHopNeighborTuple const &nb2hop_tuple2 = *it2; + if (nb2hop_tuple1.neighborMainAddr == nb2hop_tuple2.neighborMainAddr) + { + deleted_addrs.insert (nb2hop_tuple2.twoHopNeighborAddr); + it2 = N2.erase (it2); + it2--; + } + } + it = N2.erase (it); + it--; + } + + for (std::set::iterator it2 = deleted_addrs.begin (); + it2 != deleted_addrs.end (); + it2++) + { + for (TwoHopNeighborSet::iterator it3 = N2.begin (); + it3 != N2.end (); + it3++) + { + if ((*it3).twoHopNeighborAddr == *it2) + { + it3 = N2.erase (it3); + it3--; + // I have to reset the external iterator because it + // may have been invalidated by the latter deletion + it = N2.begin (); + it--; + } + } + } + deleted_addrs.clear (); + } + + // 4. While there exist nodes in N2 which are not covered by at + // least one node in the MPR set: + while (N2.begin () != N2.end ()) + { + // 4.1. For each node in N, calculate the reachability, i.e., the + // number of nodes in N2 which are not yet covered by at + // least one node in the MPR set, and which are reachable + // through this 1-hop neighbor + std::map > reachability; + std::set rs; + for (NeighborSet::iterator it = N.begin(); it != N.end(); it++) + { + NeighborTuple const &nb_tuple = *it; + int r = 0; + for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++) + { + TwoHopNeighborTuple const &nb2hop_tuple = *it2; + if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr) + r++; + } + rs.insert (r); + reachability[r].push_back (&nb_tuple); + } + + // 4.2. Select as a MPR the node with highest N_willingness among + // the nodes in N with non-zero reachability. In case of + // multiple choice select the node which provides + // reachability to the maximum number of nodes in N2. In + // case of multiple nodes providing the same amount of + // reachability, select the node as MPR whose D(y) is + // greater. Remove the nodes from N2 which are now covered + // by a node in the MPR set. + NeighborTuple const *max = NULL; + int max_r = 0; + for (std::set::iterator it = rs.begin (); it != rs.end (); it++) + { + int r = *it; + if (r > 0) + { + for (std::vector::iterator it2 = reachability[r].begin (); + it2 != reachability[r].end (); + it2++) + { + const NeighborTuple *nb_tuple = *it2; + if (max == NULL || nb_tuple->willingness > max->willingness) + { + max = nb_tuple; + max_r = r; + } + else if (nb_tuple->willingness == max->willingness) + { + if (r > max_r) + { + max = nb_tuple; + max_r = r; + } + else if (r == max_r) + { + if (Degree (*nb_tuple) > Degree (*max)) + { + max = nb_tuple; + max_r = r; + } + } + } + } + } + } + + if (max != NULL) + { + m_state.InsertMprAddress (max->neighborMainAddr); + std::set nb2hop_addrs; + for (TwoHopNeighborSet::iterator it = N2.begin (); + it != N2.end (); it++) + { + TwoHopNeighborTuple const &nb2hop_tuple = *it; + if (nb2hop_tuple.neighborMainAddr == max->neighborMainAddr) + { + nb2hop_addrs.insert (nb2hop_tuple.twoHopNeighborAddr); + it = N2.erase (it); + it--; + } + } + for (TwoHopNeighborSet::iterator it = N2.begin (); + it != N2.end (); it++) + { + TwoHopNeighborTuple const &nb2hop_tuple = *it; + std::set::iterator it2 = + nb2hop_addrs.find (nb2hop_tuple.twoHopNeighborAddr); + if (it2 != nb2hop_addrs.end ()) + { + it = N2.erase (it); + it--; + } + } + } + } +} + +/// +/// \brief Gets the main address associated with a given interface address. +/// +/// \param iface_addr the interface address. +/// \return the corresponding main address. +/// +Ipv4Address +Olsr::GetMainAddress (Ipv4Address iface_addr) +{ + IfaceAssocTuple *tuple = + m_state.FindIfaceAssocTuple (iface_addr); + + if (tuple != NULL) + return tuple->mainAddr; + else + return iface_addr; +} + +/// +/// \brief Creates the routing table of the node following RFC 3626 hints. +/// +void +Olsr::RoutingTableComputation () +{ + // 1. All the entries from the routing table are removed. + m_routingTable->Clear (); + + // 2. The new routing entries are added starting with the + // symmetric neighbors (h=1) as the destination nodes. + for (NeighborSet::const_iterator it = m_state.GetNeighbors ().begin (); + it != m_state.GetNeighbors ().end(); it++) + { + NeighborTuple const &nb_tuple = *it; + if (nb_tuple.status == NeighborTuple::STATUS_SYM) + { + bool nb_main_addr = false; + const LinkTuple *lt = NULL; + for (LinkSet::const_iterator it2 = m_state.GetLinks ().begin(); + it2 != m_state.GetLinks ().end(); it2++) + { + LinkTuple const &link_tuple = *it2; + if ((GetMainAddress (link_tuple.neighborIfaceAddr) + == nb_tuple.neighborMainAddr) + && link_tuple.time >= Simulator::Now ()) + { + lt = &link_tuple; + m_routingTable->AddEntry (link_tuple.neighborIfaceAddr, + link_tuple.neighborIfaceAddr, + link_tuple.localIfaceAddr, + 1); + if (link_tuple.neighborIfaceAddr + == nb_tuple.neighborMainAddr) + nb_main_addr = true; + } + } + if (!nb_main_addr && lt != NULL) + { + m_routingTable->AddEntry(nb_tuple.neighborMainAddr, + lt->neighborIfaceAddr, + lt->localIfaceAddr, + 1); + } + } + } + + // N2 is the set of 2-hop neighbors reachable from this node, excluding: + // (i) the nodes only reachable by members of N with willingness WILL_NEVER + // (ii) the node performing the computation + // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric + // link to this node on some interface. + for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin (); + it != m_state.GetTwoHopNeighbors ().end (); it++) + { + TwoHopNeighborTuple const &nb2hop_tuple = *it; + bool ok = true; + NeighborTuple *nb_tuple = m_state.FindSymNeighborTuple + (nb2hop_tuple.neighborMainAddr); + if (nb_tuple == NULL) + ok = false; + else + { + nb_tuple = m_state.FindNeighborTuple (nb2hop_tuple.neighborMainAddr, + OLSR_WILL_NEVER); + if (nb_tuple != NULL) + ok = false; + else + { + nb_tuple = m_state.FindSymNeighborTuple (nb2hop_tuple.twoHopNeighborAddr); + + if (nb_tuple != NULL) + ok = false; + } + } + + // 3. For each node in N2 create a new entry in the routing table + if (ok) + { + RoutingTableEntry entry; + bool found_entry = m_routingTable->Lookup (nb2hop_tuple.neighborMainAddr, entry); + NS_ASSERT (found_entry); + m_routingTable->AddEntry (nb2hop_tuple.twoHopNeighborAddr, + entry.nextAddr, + entry.interface, + 2); + } + } + + for (uint32_t h = 2; ; h++) + { + bool added = false; + + // 4.1. For each topology entry in the topology table, if its + // T_dest_addr does not correspond to R_dest_addr of any + // route entry in the routing table AND its T_last_addr + // corresponds to R_dest_addr of a route entry whose R_dist + // is equal to h, then a new route entry MUST be recorded in + // the routing table (if it does not already exist) + for (TopologySet::const_iterator it = m_state.GetTopologySet ().begin (); + it != m_state.GetTopologySet ().end (); + it++) + { + TopologyTuple const &topology_tuple = *it; + RoutingTableEntry entry1, entry2; + bool have_entry1 = m_routingTable->Lookup (topology_tuple.destAddr, entry1); + bool have_entry2 = m_routingTable->Lookup (topology_tuple.lastAddr, entry2); + if (!have_entry1 && have_entry2 && entry2.distance == h) + { + m_routingTable->AddEntry (topology_tuple.destAddr, + entry2.nextAddr, + entry2.interface, + h + 1); + added = true; + } + } + + // 5. For each entry in the multiple interface association base + // where there exists a routing entry such that: + // R_dest_addr == I_main_addr (of the multiple interface association entry) + // AND there is no routing entry such that: + // R_dest_addr == I_iface_addr + // then a route entry is created in the routing table + for (IfaceAssocSet::const_iterator it = m_state.GetIfaceAssocSet ().begin (); + it != m_state.GetIfaceAssocSet ().end (); + it++) + { + IfaceAssocTuple const &tuple = *it; + RoutingTableEntry entry1, entry2; + bool have_entry1 = m_routingTable->Lookup (tuple.mainAddr, entry1); + bool have_entry2 = m_routingTable->Lookup (tuple.ifaceAddr, entry2); + if (have_entry1 && !have_entry2) + { + m_routingTable->AddEntry (tuple.ifaceAddr, + entry1.nextAddr, + entry1.interface, + entry1.distance); + added = true; + } + } + + if (!added) + break; + } +} + + +/// +/// \brief Processes a HELLO message following RFC 3626 specification. +/// +/// Link sensing and population of the Neighbor Set, 2-hop Neighbor Set and MPR +/// Selector Set are performed. +/// +/// \param msg the %OLSR message which contains the HELLO message. +/// \param receiver_iface the address of the interface where the message was received from. +/// \param sender_iface the address of the interface where the message was sent from. +/// +void +Olsr::ProcessHello (const OlsrMessageHeader &msg, + const OlsrHelloMessageHeader &hello, + const Ipv4Address &receiverIface, + const Ipv4Address &senderIface) +{ + LinkSensing (msg, hello, receiverIface, senderIface); + PopulateNeighborSet (msg, hello); + PopulateTwoHopNeighborSet (msg, hello); + MprComputation (); + PopulateMprSelectorSet (msg, hello); +} + +/// +/// \brief Processes a TC message following RFC 3626 specification. +/// +/// The Topology Set is updated (if needed) with the information of +/// the received TC message. +/// +/// \param msg the %OLSR message which contains the TC message. +/// \param sender_iface the address of the interface where the message was sent from. +/// +void +Olsr::ProcessTc (const OlsrMessageHeader &msg, + const OlsrTcMessageHeader &tc, + const Ipv4Address &senderIface) +{ + Time now = Simulator::Now (); + + // 1. If the sender interface of this message is not in the symmetric + // 1-hop neighborhood of this node, the message MUST be discarded. + LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now); + if (link_tuple == NULL) + return; + + // 2. If there exist some tuple in the topology set where: + // T_last_addr == originator address AND + // T_seq > ANSN, + // then further processing of this TC message MUST NOT be + // performed. + TopologyTuple *topologyTuple = + m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.GetAnsn ()); + if (topologyTuple != NULL) + return; + + // 3. All tuples in the topology set where: + // T_last_addr == originator address AND + // T_seq < ANSN + // MUST be removed from the topology set. + m_state.EraseOlderTopologyTuples (msg.GetOriginatorAddress (), tc.GetAnsn ()); + + // 4. For each of the advertised neighbor main address received in + // the TC message: + for (std::vector::const_iterator i = tc.GetNeighborAddresses ().begin (); + i != tc.GetNeighborAddresses ().end (); i++) + { + const Ipv4Address &addr = *i; + // 4.1. If there exist some tuple in the topology set where: + // T_dest_addr == advertised neighbor main address, AND + // T_last_addr == originator address, + // then the holding time of that tuple MUST be set to: + // T_time = current time + validity time. + TopologyTuple *topologyTuple = + m_state.FindTopologyTuple (addr, msg.GetOriginatorAddress ()); + + if (topologyTuple != NULL) + { + topologyTuple->expirationTime = now + msg.GetVTime (); + } + else + { + // 4.2. Otherwise, a new tuple MUST be recorded in the topology + // set where: + // T_dest_addr = advertised neighbor main address, + // T_last_addr = originator address, + // T_seq = ANSN, + // T_time = current time + validity time. + TopologyTuple topologyTuple;; + topologyTuple.destAddr = addr; + topologyTuple.lastAddr = msg.GetOriginatorAddress (); + topologyTuple.sequenceNumber = tc.GetAnsn (); + topologyTuple.expirationTime = now + msg.GetVTime (); + AddTopologyTuple (topologyTuple); + + // Schedules topology tuple deletion + Simulator::Schedule (DELAY (topologyTuple.expirationTime), + &Olsr::TopologyTupleTimerExpire, + this, topologyTuple); + } + } +} + +/// +/// \brief Processes a MID message following RFC 3626 specification. +/// +/// The Interface Association Set is updated (if needed) with the information +/// of the received MID message. +/// +/// \param msg the %OLSR message which contains the MID message. +/// \param sender_iface the address of the interface where the message was sent from. +/// +void +Olsr::ProcessMid (const OlsrMessageHeader &msg, + const OlsrMidMessageHeader &mid, + const Ipv4Address &senderIface) +{ + Time now = Simulator::Now (); + + // 1. If the sender interface of this message is not in the symmetric + // 1-hop neighborhood of this node, the message MUST be discarded. + LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now); + if (linkTuple == NULL) + return; + + // 2. For each interface address listed in the MID message + const std::vector &addrs = mid.GetInterfaceAddresses (); + for (std::vector::const_iterator i = addrs.begin (); + i != addrs.end (); i++) + { + bool updated = false; + IfaceAssocSet &ifaceAssoc = m_state.GetIfaceAssocSetMutable (); + for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin(); + tuple != ifaceAssoc.end(); tuple++) + { + if (tuple->ifaceAddr == *i + && tuple->mainAddr == msg.GetOriginatorAddress ()) + { + tuple->time = now + msg.GetVTime (); + updated = true; + } + } + if (!updated) + { + IfaceAssocTuple tuple; + tuple.ifaceAddr = *i; + tuple.mainAddr = msg.GetOriginatorAddress (); + tuple.time = now + msg.GetVTime (); + AddIfaceAssocTuple (tuple); + // Schedules iface association tuple deletion + Simulator::Schedule (DELAY (tuple.time), + &Olsr::IfaceAssocTupleTimerExpire, this, tuple); + } + } +} + + +/// +/// \brief OLSR's default forwarding algorithm. +/// +/// See RFC 3626 for details. +/// +/// \param p the %OLSR packet which has been received. +/// \param msg the %OLSR message which must be forwarded. +/// \param dup_tuple NULL if the message has never been considered for forwarding, +/// or a duplicate tuple in other case. +/// \param local_iface the address of the interface where the message was received from. +/// +void +Olsr::ForwardDefault (OlsrMessageHeader olsrMessage, + Packet messagePayload, + DuplicateTuple *duplicated, + const Ipv4Address &localIface, + const Ipv4Address &senderAddress) +{ + Time now = Simulator::Now (); + + // If the sender interface address is not in the symmetric + // 1-hop neighborhood the message must not be forwarded + LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now); + if (linkTuple == NULL) + return; + + // If the message has already been considered for forwarding, + // it must not be retransmitted again + if (duplicated != NULL && duplicated->retransmitted) + { +// debug("%f: Node %d does not forward a message received" +// " from %d because it is duplicated\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(dup_tuple->addr())); + return; + } + + // If the sender interface address is an interface address + // of a MPR selector of this node and ttl is greater than 1, + // the message must be retransmitted + bool retransmitted = false; + if (olsrMessage.GetTimeToLive () > 1) + { + MprSelectorTuple *mprselTuple = + m_state.FindMprSelectorTuple (GetMainAddress (senderAddress)); + if (mprselTuple != NULL) + { + olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1); + olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1); + // We have to introduce a random delay to avoid + // synchronization with neighbors. + messagePayload.AddHeader (olsrMessage); + QueueMessage (messagePayload, JITTER); + retransmitted = true; + } + } + + // Update duplicate tuple... + if (duplicated != NULL) + { + duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME; + duplicated->retransmitted = retransmitted; + duplicated->ifaceList.push_back (localIface); + } + // ...or create a new one + else + { + DuplicateTuple newDup; + newDup.address = olsrMessage.GetOriginatorAddress (); + newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber (); + newDup.expirationTime = now + OLSR_DUP_HOLD_TIME; + newDup.retransmitted = retransmitted; + newDup.ifaceList.push_back (localIface); + AddDuplicateTuple (newDup); + // Schedule dup tuple deletion + Simulator::Schedule (OLSR_DUP_HOLD_TIME, + &Olsr::DupTupleTimerExpire, this, newDup); + } +} + +/// +/// \brief Enques an %OLSR message which will be sent with a delay of (0, delay]. +/// +/// This buffering system is used in order to piggyback several %OLSR messages in +/// a same %OLSR packet. +/// +/// \param msg the %OLSR message which must be sent. +/// \param delay maximum delay the %OLSR message is going to be buffered. +/// +void +Olsr::QueueMessage (Packet message, Time delay) +{ + m_queuedMessages.push_back (message); + if (not m_queuedMessagesTimer.IsRunning ()) + { + m_queuedMessagesTimer.SetInterval (delay); + m_queuedMessagesTimer.Schedule (); + } +} + +void +Olsr::SendPacket (Packet packet) +{ + NS_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet"); + // Add a header + OlsrPacketHeader header; + header.SetPacketLength (header.GetSize () + packet.GetSize ()); + header.SetPacketSequenceNumber (GetPacketSequenceNumber ()); + packet.AddHeader (header); + // Send it + m_sendSocket->Send (packet.PeekData (), packet.GetSize ()); +} + +/// +/// \brief Creates as many %OLSR packets as needed in order to send all buffered +/// %OLSR messages. +/// +/// Maximum number of messages which can be contained in an %OLSR packet is +/// dictated by OLSR_MAX_MSGS constant. +/// +void +Olsr::SendQueuedMessages () +{ + Packet packet; + int numMessages = 0; + + NS_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages"); + + for (std::vector::const_iterator messagePkt = m_queuedMessages.begin (); + messagePkt != m_queuedMessages.end (); + messagePkt++) + { + packet.AddAtEnd (*messagePkt); + if (++numMessages == OLSR_MAX_MSGS) + { + SendPacket (packet); + // Reset variables for next packet + numMessages = 0; + packet = Packet (); + } + } + + if (packet.GetSize ()) + { + SendPacket (packet); + } + + m_queuedMessages.clear (); +} + +/// +/// \brief Creates a new %OLSR HELLO message which is buffered for being sent later on. +/// +void +Olsr::SendHello () +{ + OlsrMessageHeader msg; + OlsrHelloMessageHeader hello; + Time now = Simulator::Now (); + + msg.SetMessageType (OlsrMessageHeader::HELLO_MESSAGE); + msg.SetVTime (OLSR_NEIGHB_HOLD_TIME); + msg.SetOriginatorAddress (m_mainAddress); + msg.SetTimeToLive (1); + msg.SetHopCount (0); + msg.SetMessageSequenceNumber (GetMessageSequenceNumber ()); + + hello.SetHTime (m_helloInterval); + hello.SetWillingness (m_willingness); + + std::vector linkMessages; + + for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin (); + link_tuple != m_state.GetLinks ().end (); link_tuple++) + { + if (not (link_tuple->localIfaceAddr == m_mainAddress + && link_tuple->time >= now)) + continue; + + uint8_t link_type, nb_type; + + // Establishes link type + if (m_useL2Notifications && link_tuple->lostTime >= now) + { + link_type = OLSR_LOST_LINK; + } + else if (link_tuple->symTime >= now) + { + link_type = OLSR_SYM_LINK; + } + else if (link_tuple->asymTime >= now) + { + link_type = OLSR_ASYM_LINK; + } + else + { + link_type = OLSR_LOST_LINK; + } + // Establishes neighbor type. + if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr))) + { + nb_type = OLSR_MPR_NEIGH; + } + else + { + bool ok = false; + for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin (); + nb_tuple != m_state.GetNeighbors ().end (); + nb_tuple++) + { + if (nb_tuple->neighborMainAddr == link_tuple->neighborIfaceAddr) + { + if (nb_tuple->status == NeighborTuple::STATUS_SYM) + { + nb_type = OLSR_SYM_NEIGH; + } + else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM) + { + nb_type = OLSR_NOT_NEIGH; + } + else + { + NS_ASSERT (!"There is a neighbor tuple with an unknown status!\n"); + } + ok = true; + break; + } + } + if (!ok) + { + NS_ASSERT (!"Link tuple has no corresponding neighbor tuple\n"); + } + } + + OlsrHelloMessageHeader::LinkMessage linkMessage; + linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f); + linkMessage.neighborInterfaceAddresses.push_back + (link_tuple->neighborIfaceAddr); + + std::vector interfaces = + m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr); + + linkMessage.neighborInterfaceAddresses.insert + (linkMessage.neighborInterfaceAddresses.end (), + interfaces.begin (), interfaces.end ()); + + linkMessages.push_back (linkMessage); + } + hello.SetLinkMessages (linkMessages); + Packet packet; + packet.AddHeader (hello); + NS_DEBUG ("OLSR HELLO message size: " << int (packet.GetSize () + msg.GetSize ()) + << " (with " << int (linkMessages.size ()) << " link messages)"); + msg.SetMessageSize (packet.GetSize () + msg.GetSize ()); + packet.AddHeader (msg); + QueueMessage (packet, JITTER); +} + +/// +/// \brief Creates a new %OLSR TC message which is buffered for being sent later on. +/// +void +Olsr::SendTc () +{ + OlsrMessageHeader msg; + OlsrTcMessageHeader tc; + + msg.SetMessageType (OlsrMessageHeader::TC_MESSAGE); + msg.SetVTime (OLSR_TOP_HOLD_TIME); + msg.SetOriginatorAddress (m_mainAddress); + msg.SetTimeToLive (255); + msg.SetHopCount (0); + msg.SetMessageSequenceNumber (GetMessageSequenceNumber ()); + + tc.SetAnsn (m_ansn); + std::vector neighbors; + for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin(); + mprsel_tuple != m_state.GetMprSelectors ().end(); mprsel_tuple++) + { + neighbors.push_back (mprsel_tuple->mainAddr); + } + tc.SetNeighborAddresses (neighbors); + + Packet packet; + packet.AddHeader (tc); + msg.SetMessageSize (packet.GetSize () + msg.GetSize ()); + packet.AddHeader (msg); + QueueMessage (packet, JITTER); +} + +/// +/// \brief Creates a new %OLSR MID message which is buffered for being sent later on. +/// +void +Olsr::SendMid () +{ + OlsrMessageHeader msg; + OlsrMidMessageHeader mid; + + // A node which has only a single interface address participating in + // the MANET (i.e., running OLSR), MUST NOT generate any MID + // message. + + // A node with several interfaces, where only one is participating + // in the MANET and running OLSR (e.g., a node is connected to a + // wired network as well as to a MANET) MUST NOT generate any MID + // messages. + + // A node with several interfaces, where more than one is + // participating in the MANET and running OLSR MUST generate MID + // messages as specified. + + // [ Note: assuming here that all interfaces participate in the + // MANET; later we may want to make this configurable. ] + + Ipv4Address loopback ("127.0.0.1"); + std::vector addresses; + for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++) + { + Ipv4Address addr = m_ipv4->GetAddress (i); + if (addr != m_mainAddress && addr != loopback) + addresses.push_back (addr); + } + if (addresses.size () == 0) + return; + mid.SetInterfaceAddresses (addresses); + + msg.SetMessageType (OlsrMessageHeader::MID_MESSAGE); + msg.SetVTime (OLSR_MID_HOLD_TIME); + msg.SetOriginatorAddress (m_mainAddress); + msg.SetTimeToLive (255); + msg.SetHopCount (0); + msg.SetMessageSequenceNumber (GetMessageSequenceNumber ()); + + Packet packet; + packet.AddHeader (mid); + msg.SetMessageSize (packet.GetSize () + msg.GetSize ()); + packet.AddHeader (msg); + QueueMessage (packet, JITTER); +} + +/// +/// \brief Updates Link Set according to a new received HELLO message (following RFC 3626 +/// specification). Neighbor Set is also updated if needed. +/// +/// \param msg the OLSR message which contains the HELLO message. +/// \param receiver_iface the address of the interface where the message was received from. +/// \param sender_iface the address of the interface where the message was sent from. +/// +void +Olsr::LinkSensing (const OlsrMessageHeader &msg, + const OlsrHelloMessageHeader &hello, + const Ipv4Address &receiverIface, + const Ipv4Address &senderIface) +{ + Time now = Simulator::Now (); + bool updated = false; + bool created = false; + + LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface); + if (link_tuple == NULL) + { + LinkTuple newLinkTuple; + // We have to create a new tuple + newLinkTuple.neighborIfaceAddr = senderIface; + newLinkTuple.localIfaceAddr = receiverIface; + newLinkTuple.symTime = now - Seconds (1); + newLinkTuple.lostTime = Seconds (0); + newLinkTuple.time = now + msg.GetVTime (); + link_tuple = &AddLinkTuple (newLinkTuple, hello.GetWillingness ()); + created = true; + } + else + updated = true; + + link_tuple->asymTime = now + msg.GetVTime (); + for (std::vector::const_iterator linkMessage = + hello.GetLinkMessages ().begin (); + linkMessage != hello.GetLinkMessages ().end (); + linkMessage++) + { + int lt = linkMessage->linkCode & 0x03; // Link Type + int nt = linkMessage->linkCode >> 2; // Neighbor Type + + // We must not process invalid advertised links + if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) || + (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH + && nt != OLSR_NOT_NEIGH)) + { + continue; + } + + for (std::vector::const_iterator neighIfaceAddr = + linkMessage->neighborInterfaceAddresses.begin (); + neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end (); + neighIfaceAddr++) + { + if (*neighIfaceAddr == receiverIface) + { + if (lt == OLSR_LOST_LINK) + { + link_tuple->symTime = now - Seconds (1); + updated = true; + } + else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK) + { + link_tuple->symTime = now + msg.GetVTime (); + link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME; + link_tuple->lostTime = Seconds (0); + updated = true; + } + break; + } + } + } + link_tuple->time = std::max(link_tuple->time, link_tuple->asymTime); + + if (updated) + LinkTupleUpdated (*link_tuple); + + // Schedules link tuple deletion + if (created && link_tuple != NULL) + { + Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)), + &Olsr::LinkTupleTimerExpire, this, *link_tuple); + } +} + +/// +/// \brief Updates the Neighbor Set according to the information contained in a new received +/// HELLO message (following RFC 3626). +/// +/// \param msg the %OLSR message which contains the HELLO message. +/// +void +Olsr::PopulateNeighborSet (const OlsrMessageHeader &msg, + const OlsrHelloMessageHeader &hello) +{ + NeighborTuple *nb_tuple = m_state.FindNeighborTuple (msg.GetOriginatorAddress ()); + if (nb_tuple != NULL) + nb_tuple->willingness = hello.GetWillingness (); +} + + +/// +/// \brief Updates the 2-hop Neighbor Set according to the information contained in a new +/// received HELLO message (following RFC 3626). +/// +/// \param msg the %OLSR message which contains the HELLO message. +/// +void +Olsr::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, + const OlsrHelloMessageHeader &hello) +{ + Time now = Simulator::Now (); + + for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin (); + link_tuple != m_state.GetLinks ().end (); link_tuple++) + { + if (GetMainAddress (link_tuple->neighborIfaceAddr) == msg.GetOriginatorAddress ()) + { + if (link_tuple->symTime >= now) + { + typedef std::vector LinkMessageVec; + for (LinkMessageVec::const_iterator linkMessage = + hello.GetLinkMessages ().begin (); + linkMessage != hello.GetLinkMessages ().end (); + linkMessage++) + { + int nt = linkMessage->linkCode >> 2; + + for (std::vector::const_iterator nb2hop_addr = + linkMessage->neighborInterfaceAddresses.begin (); + nb2hop_addr != linkMessage->neighborInterfaceAddresses.end (); + nb2hop_addr++) + { + if (nt == OLSR_SYM_NEIGH || nt == OLSR_MPR_NEIGH) + { + // if the main address of the 2-hop + // neighbor address = main address of + // the receiving node: silently + // discard the 2-hop neighbor address + if (*nb2hop_addr != m_routingAgentAddr) + { + // Otherwise, a 2-hop tuple is created + TwoHopNeighborTuple *nb2hop_tuple = + m_state.FindTwoHopNeighborTuple (msg.GetOriginatorAddress (), + *nb2hop_addr); + if (nb2hop_tuple == NULL) + { + TwoHopNeighborTuple new_nb2hop_tuple; + new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress (); + new_nb2hop_tuple.twoHopNeighborAddr = *nb2hop_addr; + AddTwoHopNeighborTuple (new_nb2hop_tuple); + new_nb2hop_tuple.expirationTime = + now + msg.GetVTime (); + // Schedules nb2hop tuple + // deletion + Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime), + &Olsr::Nb2hopTupleTimerExpire, this, + new_nb2hop_tuple); + } + else + { + nb2hop_tuple->expirationTime = + now + msg.GetVTime (); + } + + } + } + else if (nt == OLSR_NOT_NEIGH) + { + // For each 2-hop node listed in the HELLO + // message with Neighbor Type equal to + // NOT_NEIGH all 2-hop tuples where: + // N_neighbor_main_addr == Originator + // Address AND N_2hop_addr == main address + // of the 2-hop neighbor are deleted. + m_state.EraseTwoHopNeighborTuples + (msg.GetOriginatorAddress (), *nb2hop_addr); + } + } + } + } + } + } +} + + + +/// +/// \brief Updates the MPR Selector Set according to the information contained in a new +/// received HELLO message (following RFC 3626). +/// +/// \param msg the %OLSR message which contains the HELLO message. +/// +void +Olsr::PopulateMprSelectorSet (const OlsrMessageHeader &msg, + const OlsrHelloMessageHeader &hello) +{ + Time now = Simulator::Now (); + + typedef std::vector LinkMessageVec; + for (LinkMessageVec::const_iterator linkMessage = hello.GetLinkMessages ().begin (); + linkMessage != hello.GetLinkMessages ().end (); + linkMessage++) + { + int nt = linkMessage->linkCode >> 2; + if (nt == OLSR_MPR_NEIGH) + { + for (std::vector::const_iterator nb_iface_addr = + linkMessage->neighborInterfaceAddresses.begin (); + nb_iface_addr != linkMessage->neighborInterfaceAddresses.end (); + nb_iface_addr++) + { + if (*nb_iface_addr == m_mainAddress) + { + // We must create a new entry into the mpr selector set + MprSelectorTuple *existing_mprsel_tuple = + m_state.FindMprSelectorTuple (msg.GetOriginatorAddress ()); + if (existing_mprsel_tuple == NULL) + { + MprSelectorTuple mprsel_tuple; + + mprsel_tuple.mainAddr = msg.GetOriginatorAddress (); + mprsel_tuple.expirationTime = now + msg.GetVTime (); + AddMprSelectorTuple (mprsel_tuple); + + // Schedules mpr selector tuple deletion + Simulator::Schedule (DELAY (mprsel_tuple.expirationTime), + &Olsr::MprSelTupleTimerExpire, + this, mprsel_tuple); + } + else + { + existing_mprsel_tuple->expirationTime = now + msg.GetVTime (); + } + } + } + } + } +} + + +#if 0 +/// +/// \brief Drops a given packet because it couldn't be delivered to the corresponding +/// destination by the MAC layer. This may cause a neighbor loss, and appropiate +/// actions are then taken. +/// +/// \param p the packet which couldn't be delivered by the MAC layer. +/// +void +OLSR::mac_failed(Packet* p) { + double now = Simulator::Now (); + struct hdr_ip* ih = HDR_IP(p); + struct hdr_cmn* ch = HDR_CMN(p); + + debug("%f: Node %d MAC Layer detects a breakage on link to %d\n", + now, + OLSR::node_id(ra_addr()), + OLSR::node_id(ch->next_hop())); + + if ((u_int32_t)ih->daddr() == IP_BROADCAST) { + drop(p, DROP_RTR_MAC_CALLBACK); + return; + } + + OLSR_link_tuple* link_tuple = state_.find_link_tuple(ch->next_hop()); + if (link_tuple != NULL) { + link_tuple->lost_time() = now + OLSR_NEIGHB_HOLD_TIME; + link_tuple->time() = now + OLSR_NEIGHB_HOLD_TIME; + nb_loss(link_tuple); + } + drop(p, DROP_RTR_MAC_CALLBACK); +} +#endif + + + + +/// +/// \brief Performs all actions needed when a neighbor loss occurs. +/// +/// Neighbor Set, 2-hop Neighbor Set, MPR Set and MPR Selector Set are updated. +/// +/// \param tuple link tuple with the information of the link to the neighbor which has been lost. +/// +void +Olsr::NeighborLoss (const LinkTuple &tuple) +{ +// debug("%f: Node %d detects neighbor %d loss\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->neighborIfaceAddr)); + + LinkTupleUpdated (tuple); + m_state.EraseTwoHopNeighborTuples (GetMainAddress (tuple.neighborIfaceAddr)); + m_state.EraseMprSelectorTuples (GetMainAddress (tuple.neighborIfaceAddr)); + + MprComputation(); + RoutingTableComputation(); +} + +/// +/// \brief Adds a duplicate tuple to the Duplicate Set. +/// +/// \param tuple the duplicate tuple to be added. +/// +void +Olsr::AddDuplicateTuple (const DuplicateTuple &tuple) +{ + /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n", + Simulator::Now (), + OLSR::node_id(ra_addr()), + OLSR::node_id(tuple->addr()), + tuple->seq_num());*/ + m_state.InsertDuplicateTuple (tuple); +} + +/// +/// \brief Removes a duplicate tuple from the Duplicate Set. +/// +/// \param tuple the duplicate tuple to be removed. +/// +void +Olsr::RemoveDuplicateTuple (const DuplicateTuple &tuple) +{ + /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n", + Simulator::Now (), + OLSR::node_id(ra_addr()), + OLSR::node_id(tuple->addr()), + tuple->seq_num());*/ + m_state.EraseDuplicateTuple (tuple); +} + +/// +/// \brief Adds a link tuple to the Link Set (and an associated neighbor tuple to the Neighbor Set). +/// +/// \param tuple the link tuple to be added. +/// \param willingness willingness of the node which is going to be inserted in the Neighbor Set. +/// +LinkTuple& +Olsr::AddLinkTuple (const LinkTuple &tuple, uint8_t willingness) +{ +// debug("%f: Node %d adds link tuple: nb_addr = %d\n", +// now, +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->neighborIfaceAddr)); + LinkTuple &addedLinkTuple = m_state.InsertLinkTuple (tuple); + // Creates associated neighbor tuple + NeighborTuple nb_tuple; + nb_tuple.neighborMainAddr = GetMainAddress (tuple.neighborIfaceAddr); + nb_tuple.willingness = willingness; + + if (tuple.symTime >= Simulator::Now ()) + nb_tuple.status = NeighborTuple::STATUS_SYM; + else + nb_tuple.status = NeighborTuple::STATUS_NOT_SYM; + + AddNeighborTuple (nb_tuple); + return addedLinkTuple; +} + +/// +/// \brief Removes a link tuple from the Link Set. +/// +/// \param tuple the link tuple to be removed. +/// +void +Olsr::RemoveLinkTuple (const LinkTuple &tuple) +{ +// nsaddr_t nb_addr = get_main_addr(tuple->neighborIfaceAddr); +// double now = Simulator::Now (); + +// debug("%f: Node %d removes link tuple: nb_addr = %d\n", +// now, +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->neighborIfaceAddr)); + // Prints this here cause we are not actually calling rm_nb_tuple() (efficiency stuff) + // debug("%f: Node %d removes neighbor tuple: nb_addr = %d\n", + // now, + // OLSR::node_id(ra_addr()), + // OLSR::node_id(nb_addr)); + + m_state.EraseLinkTuple (tuple); + m_state.EraseNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr)); +} + +/// +/// \brief This function is invoked when a link tuple is updated. Its aim is to +/// also update the corresponding neighbor tuple if it is needed. +/// +/// \param tuple the link tuple which has been updated. +/// +void +Olsr::LinkTupleUpdated (const LinkTuple &tuple) +{ + // Each time a link tuple changes, the associated neighbor tuple must be recomputed + NeighborTuple *nb_tuple = + m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr)); + if (nb_tuple != NULL) + { + if (m_useL2Notifications && tuple.lostTime >= Simulator::Now ()) + { + nb_tuple->status = NeighborTuple::STATUS_NOT_SYM; + } + else if (tuple.symTime >= Simulator::Now ()) + { + nb_tuple->status = NeighborTuple::STATUS_SYM; + } + else + { + nb_tuple->status = NeighborTuple::STATUS_NOT_SYM; + } + } + +// debug("%f: Node %d has updated link tuple: nb_addr = %d status = %s\n", +// now, +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->neighborIfaceAddr), +// ((nb_tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym")); + +} + +/// +/// \brief Adds a neighbor tuple to the Neighbor Set. +/// +/// \param tuple the neighbor tuple to be added. +/// +void +Olsr::AddNeighborTuple (const NeighborTuple &tuple) +{ +// debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->neighborMainAddr), +// ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym")); + + m_state.InsertNeighborTuple (tuple); +} + +/// +/// \brief Removes a neighbor tuple from the Neighbor Set. +/// +/// \param tuple the neighbor tuple to be removed. +/// +void +Olsr::RemoveNeighborTuple (const NeighborTuple &tuple) +{ +// debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->neighborMainAddr), +// ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym")); + + m_state.EraseNeighborTuple (tuple); +} + +/// +/// \brief Adds a 2-hop neighbor tuple to the 2-hop Neighbor Set. +/// +/// \param tuple the 2-hop neighbor tuple to be added. +/// +void +Olsr::AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple) +{ +// debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->neighborMainAddr), +// OLSR::node_id(tuple->twoHopNeighborAddr)); + + m_state.InsertTwoHopNeighborTuple (tuple); +} + +/// +/// \brief Removes a 2-hop neighbor tuple from the 2-hop Neighbor Set. +/// +/// \param tuple the 2-hop neighbor tuple to be removed. +/// +void +Olsr::RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple) +{ +// debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->neighborMainAddr), +// OLSR::node_id(tuple->twoHopNeighborAddr)); + + m_state.EraseTwoHopNeighborTuple (tuple); +} + +/// +/// \brief Adds an MPR selector tuple to the MPR Selector Set. +/// +/// Advertised Neighbor Sequence Number (ANSN) is also updated. +/// +/// \param tuple the MPR selector tuple to be added. +/// +void +Olsr::AddMprSelectorTuple (const MprSelectorTuple &tuple) +{ +// debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->main_addr())); + + m_state.InsertMprSelectorTuple (tuple); + m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1); +} + +/// +/// \brief Removes an MPR selector tuple from the MPR Selector Set. +/// +/// Advertised Neighbor Sequence Number (ANSN) is also updated. +/// +/// \param tuple the MPR selector tuple to be removed. +/// +void +Olsr::RemoveMprSelectorTuple (const MprSelectorTuple &tuple) +{ +// debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->main_addr())); + + m_state.EraseMprSelectorTuple (tuple); + m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1); +} + +/// +/// \brief Adds a topology tuple to the Topology Set. +/// +/// \param tuple the topology tuple to be added. +/// +void +Olsr::AddTopologyTuple (const TopologyTuple &tuple) +{ +// debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->dest_addr()), +// OLSR::node_id(tuple->last_addr()), +// tuple->seq()); + + m_state.InsertTopologyTuple(tuple); +} + +/// +/// \brief Removes a topology tuple from the Topology Set. +/// +/// \param tuple the topology tuple to be removed. +/// +void +Olsr::RemoveTopologyTuple (const TopologyTuple &tuple) +{ +// debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->dest_addr()), +// OLSR::node_id(tuple->last_addr()), +// tuple->seq()); + + m_state.EraseTopologyTuple (tuple); +} + +/// +/// \brief Adds an interface association tuple to the Interface Association Set. +/// +/// \param tuple the interface association tuple to be added. +/// +void +Olsr::AddIfaceAssocTuple (const IfaceAssocTuple &tuple) +{ +// debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->main_addr()), +// OLSR::node_id(tuple->iface_addr())); + + m_state.InsertIfaceAssocTuple (tuple); +} + +/// +/// \brief Removes an interface association tuple from the Interface Association Set. +/// +/// \param tuple the interface association tuple to be removed. +/// +void +Olsr::RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple) +{ +// debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n", +// Simulator::Now (), +// OLSR::node_id(ra_addr()), +// OLSR::node_id(tuple->main_addr()), +// OLSR::node_id(tuple->iface_addr())); + + m_state.EraseIfaceAssocTuple (tuple); +} + + +uint16_t Olsr::GetPacketSequenceNumber () +{ + m_packetSequenceNumber = (m_packetSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1); + return m_packetSequenceNumber; +} + +/// Increments message sequence number and returns the new value. +uint16_t Olsr::GetMessageSequenceNumber () +{ + m_messageSequenceNumber = (m_messageSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1); + return m_messageSequenceNumber; +} + + +/// +/// \brief Sends a HELLO message and reschedules the HELLO timer. +/// \param e The event which has expired. +/// +void +Olsr::HelloTimerExpire () +{ + SendHello (); + m_helloTimer.Schedule (); +} + +/// +/// \brief Sends a TC message (if there exists any MPR selector) and reschedules the TC timer. +/// \param e The event which has expired. +/// +void +Olsr::TcTimerExpire () +{ + if (m_state.GetMprSelectors ().size () > 0) + SendTc (); + m_tcTimer.Schedule (); +} + +/// +/// \brief Sends a MID message (if the node has more than one interface) and resets the MID timer. +/// \warning Currently it does nothing because there is no support for multiple interfaces. +/// \param e The event which has expired. +/// +void +Olsr::MidTimerExpire () +{ + SendMid (); + m_midTimer.Schedule (); +} + +/// +/// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time(). +/// +/// The task of actually removing the tuple is left to the OLSR agent. +/// +/// \param e The event which has expired. +/// +void +Olsr::DupTupleTimerExpire (DuplicateTuple tuple) +{ + if (tuple.expirationTime < Simulator::Now ()) + { + RemoveDuplicateTuple (tuple); + } + else + Simulator::Schedule (DELAY (tuple.expirationTime), &Olsr::DupTupleTimerExpire, this, tuple); +} + +/// +/// \brief Removes tuple_ if expired. Else if symmetric time +/// has expired then it is assumed a neighbor loss and agent_->nb_loss() +/// is called. In this case the timer is rescheduled to expire at +/// tuple_->time(). Otherwise the timer is rescheduled to expire at +/// the minimum between tuple_->time() and tuple_->sym_time(). +/// +/// The task of actually removing the tuple is left to the OLSR agent. +/// +/// \param e The event which has expired. +/// +void +Olsr::LinkTupleTimerExpire (LinkTuple tuple) +{ + Time now = Simulator::Now (); + + if (tuple.time < now) + { + RemoveLinkTuple (tuple); + } + else if (tuple.symTime < now) + { + if (m_linkTupleTimerFirstTime) + m_linkTupleTimerFirstTime = false; + else + NeighborLoss (tuple); + + Simulator::Schedule (DELAY(tuple.time), + &Olsr::LinkTupleTimerExpire, this, tuple); + + } + else + Simulator::Schedule (DELAY (std::min (tuple.time, tuple.symTime)), + &Olsr::LinkTupleTimerExpire, this, tuple); +} + +/// +/// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time(). +/// +/// The task of actually removing the tuple is left to the OLSR agent. +/// +/// \param e The event which has expired. +/// +void +Olsr::Nb2hopTupleTimerExpire (TwoHopNeighborTuple tuple) +{ + if (tuple.expirationTime < Simulator::Now ()) + { + RemoveTwoHopNeighborTuple (tuple); + } + else + Simulator::Schedule (DELAY (tuple.expirationTime), + &Olsr::Nb2hopTupleTimerExpire, this, tuple); +} + +/// +/// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time(). +/// +/// The task of actually removing the tuple is left to the OLSR agent. +/// +/// \param e The event which has expired. +/// +void +Olsr::MprSelTupleTimerExpire (MprSelectorTuple tuple) +{ + if (tuple.expirationTime < Simulator::Now ()) + { + RemoveMprSelectorTuple (tuple); + } + else + Simulator::Schedule (DELAY (tuple.expirationTime), + &Olsr::MprSelTupleTimerExpire, this, tuple); +} + +/// +/// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time(). +/// +/// The task of actually removing the tuple is left to the OLSR agent. +/// +/// \param e The event which has expired. +/// +void +Olsr::TopologyTupleTimerExpire (TopologyTuple tuple) +{ + if (tuple.expirationTime < Simulator::Now ()) + { + RemoveTopologyTuple (tuple); + } + else + Simulator::Schedule (DELAY (tuple.expirationTime), + &Olsr::TopologyTupleTimerExpire, this, tuple); +} + +/// +/// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time(). +/// \warning Actually this is never invoked because there is no support for multiple interfaces. +/// \param e The event which has expired. +/// +void +Olsr::IfaceAssocTupleTimerExpire (IfaceAssocTuple tuple) +{ + if (tuple.time < Simulator::Now ()) + { + RemoveIfaceAssocTuple (tuple); + } + else + Simulator::Schedule (DELAY (tuple.time), + &Olsr::IfaceAssocTupleTimerExpire, this, tuple); +} + + + +}}; // namespace ns3, olsr + + + +#ifdef RUN_SELF_TESTS + + +#include "ns3/test.h" + +namespace ns3 { namespace olsr { + +class OlsrTest : public ns3::Test { +private: +public: + OlsrTest (); + virtual bool RunTests (void); + + +}; + +OlsrTest::OlsrTest () + : ns3::Test ("Olsr") +{} + + +bool +OlsrTest::RunTests (void) +{ + bool result = true; + + + return result; +} + +static OlsrTest gOlsrTest; + +}}; // namespace + + +#endif /* RUN_SELF_TESTS */ diff --git a/src/routing/olsr/olsr.h b/src/routing/olsr/olsr.h new file mode 100644 index 000000000..adc1e6d82 --- /dev/null +++ b/src/routing/olsr/olsr.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo J. A. M. Carneiro + */ + +#ifndef OLSR_H +#define OLSR_H + +#include "ns3/node.h" +#include "ns3/component-manager.h" + +namespace ns3 { + + +class Olsr : public Object +{ +public: + static const InterfaceId iid; + static const ClassId cid; + + virtual void Start () = 0; + virtual void SetMainInterface (uint32_t interface) = 0; +}; + + +}; // namespace ns3 + +#endif /* OLSR_H */ + diff --git a/src/routing/olsr/routing-table.cc b/src/routing/olsr/routing-table.cc new file mode 100644 index 000000000..aa41f49fd --- /dev/null +++ b/src/routing/olsr/routing-table.cc @@ -0,0 +1,270 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/*************************************************************************** + * Copyright (C) 2004 by Francisco J. Ros * + * fjrm@dif.um.es * + * * + * Modified on 2007 for NS-3 by Gustavo J. A. M. Carneiro, INESC Porto * + * * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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. * + ***************************************************************************/ + +/// +/// \file OLSR_rtable.cc +/// \brief Implementation of our routing table. +/// + +#include "routing-table.h" +#include "ns3/packet.h" +#include "ns3/ipv4-header.h" +#include "ns3/debug.h" + +namespace ns3 { namespace olsr { + +NS_DEBUG_COMPONENT_DEFINE ("OlsrRoutingTable"); + +/// +/// \brief Clears the routing table and frees the memory assigned to each one of its entries. +/// +void +RoutingTable::Clear () +{ + m_table.clear (); +} + +/// +/// \brief Deletes the entry whose destination address is given. +/// \param dest address of the destination node. +/// +void +RoutingTable::RemoveEntry (Ipv4Address const &dest) +{ + m_table.erase (dest); +} + +/// +/// \brief Looks up an entry for the specified destination address. +/// \param dest destination address. +/// \param outEntry output parameter to hold the routing entry result, if fuond +/// \return true if found, false if not found +/// +bool +RoutingTable::Lookup (Ipv4Address const &dest, + RoutingTableEntry &outEntry) const +{ + // Get the iterator at "dest" position + std::map::const_iterator it = + m_table.find (dest); + // If there is no route to "dest", return NULL + if (it == m_table.end ()) + return false; + outEntry = it->second; + return true; +} + +/// +/// \brief Finds the appropiate entry which must be used in order to forward +/// a data packet to a next hop (given a destination). +/// +/// Imagine a routing table like this: [A,B] [B,C] [C,C]; being each pair of the +/// form [dest addr,next-hop addr]. In this case, if this function is invoked with +/// [A,B] then pair [C,C] is returned because C is the next hop that must be used +/// to forward a data packet destined to A. That is, C is a neighbor of this node, +/// but B isn't. This function finds the appropiate neighbor for forwarding a packet. +/// +/// \param entry the routing table entry which indicates the destination node +/// we are interested in. +/// \return the appropiate routing table entry which indicates the next +/// hop which must be used for forwarding a data packet, or NULL +/// if there is no such entry. +/// +bool +RoutingTable::FindSendEntry (RoutingTableEntry const &entry, + RoutingTableEntry &outEntry) const +{ + outEntry = entry; + while (outEntry.destAddr != outEntry.nextAddr) + { + if (not Lookup(outEntry.nextAddr, outEntry)) + return false; + } + return true; +} + + +bool +RoutingTable::RequestRoute (const Ipv4Header &ipHeader, + Packet packet, + RouteReplyCallback routeReply) +{ + RoutingTableEntry entry1, entry2; + if (Lookup (ipHeader.GetDestination (), entry1)) + { + bool foundSendEntry = FindSendEntry (entry1, entry2); + NS_ASSERT (foundSendEntry); + Ipv4Route route = Ipv4Route::CreateHostRouteTo + (ipHeader.GetDestination (), entry2.nextAddr, entry2.interface); + + NS_DEBUG ("Olsr node" << m_mainAddress + << ": RouteRequest for dest=" << ipHeader.GetDestination () + << " --> destHop=" << entry2.nextAddr + << " interface=" << entry2.interface); + + routeReply (true, route, packet, ipHeader); + return true; + } + else + { + NS_DEBUG ("Olsr node" << m_mainAddress + << ": RouteRequest for dest=" << ipHeader.GetDestination () + << " --> NOT FOUND"); + return false; + } +} + + +/// +/// \brief Adds a new entry into the routing table. +/// +/// If an entry for the given destination existed, it is deleted and freed. +/// +/// \param dest address of the destination node. +/// \param next address of the next hop node. +/// \param iface address of the local interface. +/// \param dist distance to the destination node. +/// +void +RoutingTable::AddEntry (Ipv4Address const &dest, + Ipv4Address const &next, + uint32_t interface, + uint32_t distance) +{ + // Creates a new rt entry with specified values + RoutingTableEntry &entry = m_table[dest]; + + entry.destAddr = dest; + entry.nextAddr = next; + entry.interface = interface; + entry.distance = distance; +} + +void +RoutingTable::AddEntry (Ipv4Address const &dest, + Ipv4Address const &next, + Ipv4Address const &interfaceAddress, + uint32_t distance) +{ + RoutingTableEntry entry; + NS_ASSERT (m_ipv4); + for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++) + { + if (m_ipv4->GetAddress (i) == interfaceAddress) + { + AddEntry (dest, next, i, distance); + return; + } + } + NS_ASSERT (false); // should not be reached + AddEntry (dest, next, 0, distance); +} + + +/// +/// \brief Returns the number of entries in the routing table. +/// \return the number of entries in the routing table. +/// +// u_int32_t +// RoutingTable::size() { +// return rt_.size(); +// } + +}}; // namespace ns3, olsr + + + +#ifdef RUN_SELF_TESTS + + +#include "ns3/test.h" + + +namespace ns3 { namespace olsr { + +class OlsrRoutingTableTest : public ns3::Test { +private: +public: + OlsrRoutingTableTest (); + virtual bool RunTests (void); + + +}; + +OlsrRoutingTableTest::OlsrRoutingTableTest () + : ns3::Test ("OlsrRoutingTable") +{} + + +bool +OlsrRoutingTableTest::RunTests (void) +{ + bool result = true; + + RoutingTable table; + + table.AddEntry (Ipv4Address ("1.2.3.5"), + Ipv4Address ("1.2.3.4"), + 0, + 1); + + table.AddEntry (Ipv4Address ("1.2.3.4"), + Ipv4Address ("1.2.3.4"), + 0, + 1); + + RoutingTableEntry entry1; + NS_TEST_ASSERT (table.Lookup (Ipv4Address ("1.2.3.5"), entry1)); + NS_TEST_ASSERT_EQUAL (entry1.destAddr, Ipv4Address ("1.2.3.5")); + NS_TEST_ASSERT_EQUAL (entry1.nextAddr, Ipv4Address ("1.2.3.4")); + NS_TEST_ASSERT_EQUAL (entry1.interface, 0); + NS_TEST_ASSERT_EQUAL (entry1.distance, 1); + + RoutingTableEntry entry2; + NS_TEST_ASSERT (table.Lookup (Ipv4Address ("1.2.3.4"), entry2)); + NS_TEST_ASSERT_EQUAL (entry2.destAddr, Ipv4Address ("1.2.3.4")); + NS_TEST_ASSERT_EQUAL (entry2.nextAddr, Ipv4Address ("1.2.3.4")); + NS_TEST_ASSERT_EQUAL (entry2.interface, 0); + NS_TEST_ASSERT_EQUAL (entry2.distance, 1); + + RoutingTableEntry sendEntry; + NS_TEST_ASSERT (table.FindSendEntry (entry1, sendEntry)); + NS_TEST_ASSERT_EQUAL (sendEntry.destAddr, Ipv4Address ("1.2.3.4")); + NS_TEST_ASSERT_EQUAL (sendEntry.nextAddr, Ipv4Address ("1.2.3.4")); + NS_TEST_ASSERT_EQUAL (sendEntry.interface, 0); + NS_TEST_ASSERT_EQUAL (sendEntry.distance, 1); + + table.RemoveEntry (Ipv4Address ("1.2.3.5")); + RoutingTableEntry removedEntry; + NS_TEST_ASSERT (not table.Lookup (Ipv4Address ("1.2.3.5"), removedEntry)); + + return result; +} + +static OlsrRoutingTableTest gOlsrRoutingTableTest; + +}}; // namespace + + +#endif /* RUN_SELF_TESTS */ diff --git a/src/routing/olsr/routing-table.h b/src/routing/olsr/routing-table.h new file mode 100644 index 000000000..aebed6316 --- /dev/null +++ b/src/routing/olsr/routing-table.h @@ -0,0 +1,110 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/*************************************************************************** + * Copyright (C) 2004 by Francisco J. Ros * + * fjrm@dif.um.es * + * * + * Modified on 2007 for NS-3 by Gustavo J. A. M. Carneiro, INESC Porto * + * * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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. * + ***************************************************************************/ + +/// +/// \file OLSR_rtable.h +/// \brief Header file for routing table's related stuff. +/// + +#ifndef __OLSR_RTABLE_H__ +#define __OLSR_RTABLE_H__ + +#include "ns3/ipv4.h" +#include + + +namespace ns3 { namespace olsr { + +/// An %OLSR's routing table entry. +struct RoutingTableEntry +{ + Ipv4Address destAddr; ///< Address of the destination node. + Ipv4Address nextAddr; ///< Address of the next hop. + uint32_t interface; ///< Interface index + uint32_t distance; ///< Distance in hops to the destination. + + RoutingTableEntry () : // default values + destAddr (), nextAddr (), + interface (0), distance (0) {}; +}; + +/// +/// \brief Defines rtable_t as a map of OLSR_rt_entry, whose key is the destination address. +/// +/// The routing table is thus defined as pairs: [dest address, entry]. Each element +/// of the pair can be accesed via "first" and "second" members. +/// +//typedef std::map RoutingTable; + +/// +/// \brief This class is a representation of the OLSR's Routing Table. +/// +class RoutingTable : public Ipv4RoutingProtocol +{ + std::map m_table; ///< Data structure for the routing table. + Ptr m_ipv4; + + Ipv4Address m_mainAddress; // used only for printing debug messages + + void DoDispose () + { + m_ipv4 = 0; + Ipv4RoutingProtocol::DoDispose (); + } + +public: + + RoutingTable () {} + RoutingTable (Ptr ipv4, const Ipv4Address &mainAddress) + : + m_ipv4 (ipv4), + m_mainAddress (mainAddress) + {} + + ~RoutingTable () {} + + void Clear (); + void RemoveEntry (const Ipv4Address &dest); + void AddEntry (const Ipv4Address &dest, + const Ipv4Address &next, + uint32_t interface, + uint32_t distance); + void AddEntry (const Ipv4Address &dest, + const Ipv4Address &next, + const Ipv4Address &interfaceAddress, + uint32_t distance); + bool Lookup (const Ipv4Address &dest, + RoutingTableEntry &outEntry) const; + bool FindSendEntry (const RoutingTableEntry &entry, + RoutingTableEntry &outEntry) const; + + // From Ipv4RoutingProtocol + virtual bool RequestRoute (const Ipv4Header &ipHeader, + Packet packet, + RouteReplyCallback routeReply); +}; + +}}; // namespace ns3, olsr + +#endif diff --git a/src/routing/olsr/wscript b/src/routing/olsr/wscript new file mode 100644 index 000000000..a2874de2a --- /dev/null +++ b/src/routing/olsr/wscript @@ -0,0 +1,19 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +def build(bld): + obj = bld.create_obj('cpp', 'shlib') + obj.name = 'ns3-olsr' + obj.target = obj.name + obj.uselib_local = ['ns3-internet-node'] + obj.includes = '.' + obj.source = [ + 'olsr-header.cc', + 'olsr-state.cc', + 'routing-table.cc', + 'olsr.cc', + ] + + headers = bld.create_obj('ns3header') + headers.source = [ + 'olsr.h', + ] diff --git a/src/wscript b/src/wscript index 4b34a9156..7516909e5 100644 --- a/src/wscript +++ b/src/wscript @@ -17,6 +17,7 @@ all_modules = ( 'internet-node', 'devices/p2p', 'applications', + 'routing/olsr', 'mobility', ) From 1177dc94b8fca82187f4e2783da8fc842459934e Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 27 Jul 2007 15:04:25 +0100 Subject: [PATCH 08/61] WAF: handle the option --doxygen before building the entire project. --- wscript | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wscript b/wscript index 35c17074a..c76724650 100644 --- a/wscript +++ b/wscript @@ -144,6 +144,10 @@ def build(bld): run_shell() return + if Params.g_options.doxygen: + doxygen() + raise SystemExit(0) + # process subfolders from here bld.add_subdirs('src') bld.add_subdirs('samples utils examples') @@ -164,9 +168,6 @@ def shutdown(): if Params.g_options.lcov_report: lcov_report() - if Params.g_options.doxygen: - doxygen() - if Params.g_options.run: run_program(Params.g_options.run, Params.g_options.command_template) raise SystemExit(0) From d6cb167a0c112ae2c42e52204a07f77df109841a Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 27 Jul 2007 15:38:04 +0100 Subject: [PATCH 09/61] Add documentation for the dynamic routing interfaces. Change Ipv4::AddRoutingProtocol priority parameter type from int to int16_t to make way for in the future providing stable sorting of routing protocols of the same priority. --- src/internet-node/ipv4-impl.cc | 2 +- src/internet-node/ipv4-impl.h | 2 +- src/node/ipv4.h | 66 +++++++++++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-node/ipv4-impl.cc index 020413896..307425114 100644 --- a/src/internet-node/ipv4-impl.cc +++ b/src/internet-node/ipv4-impl.cc @@ -41,7 +41,7 @@ Ipv4Impl::DoDispose (void) void Ipv4Impl::AddRoutingProtocol (Ptr routingProtocol, - int priority) + int16_t priority) { m_ipv4->AddRoutingProtocol (routingProtocol, priority); } diff --git a/src/internet-node/ipv4-impl.h b/src/internet-node/ipv4-impl.h index 32d9e5c68..445c10454 100644 --- a/src/internet-node/ipv4-impl.h +++ b/src/internet-node/ipv4-impl.h @@ -36,7 +36,7 @@ public: virtual ~Ipv4Impl (); virtual void AddRoutingProtocol (Ptr routingProtocol, - int priority); + int16_t priority); virtual void AddHostRouteTo (Ipv4Address dest, Ipv4Address nextHop, diff --git a/src/node/ipv4.h b/src/node/ipv4.h index 1a957a4ee..76d88faea 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -35,14 +35,40 @@ class Ipv4Route; class Ipv4Header; // FIXME: ipv4-header.h needs to move from module // "internet-node" to module "node" +/** + * \brief Base class for IPv4 routing protocols. + * + * This class represents the interface between the IPv4 routing core + * and a specific IPv4 routing protocol. The interface is + * asynchronous (callback based) in order to support reactive routing + * protocols (e.g. AODV). + */ class Ipv4RoutingProtocol : public Object { public: // void (*RouteReply) (bool found, Ipv4Route route, Packet packet, Ipv4Header const &ipHeader); - typedef Callback RouteReplyCallback; + /** - * \brief Asynchronously requests a route for a given packet and IP header + * \brief Callback to be invoked when route discovery is completed + * + * \param bool flag indicating whether a route was actually found; + * when this is false, the Ipv4Route parameter is ignored + * + * \param Ipv4Route the route found + * + * \param Packet the packet for which a route was requested; can be + * modified by the routing protocol + * + * \param Ipv4Header the IP header supplied to the route request + * method (possibly modified in case a new routing header is + * inserted and consequently the protocol type has to change). + * + */ + typedef Callback RouteReplyCallback; + + /** + * \brief Asynchronously requests a route for a given packet and IP header * * \param ipHeader IP header of the packet * \param packet packet that is being sent or forwarded @@ -50,8 +76,30 @@ public: * * \returns true if the routing protocol should be able to get the * route, false otherwise. + * + * This method is called whenever a node's IPv4 forwarding engine + * needs to lookup a route for a given packet and IP header. + * + * The routing protocol implementation may determine immediately it + * should not be handling this particular the route request. For + * instance, a routing protocol may decline to search for routes for + * certain classes of addresses, like link-local. In this case, + * RequestRoute() should return false and the routeReply callback + * must not be invoked. + * + * If the routing protocol implementations assumes it can provide + * the requested route, then it should return true, and the + * routeReply callback must be invoked, either immediately before + * returning true (synchronously), or in the future (asynchronous). + * The routing protocol may use any information available in the IP + * header and packet as routing key, although most routing protocols + * use only the destination address (as given by + * ipHeader.GetDestination ()). The routing protocol is also + * allowed to add a new header to the packet, which will appear + * immediately after the IP header, although most routing do not + * insert any extra header. */ - virtual bool RequestRoute (Ipv4Header const &ipHeader, + virtual bool RequestRoute (const Ipv4Header &ipHeader, Packet packet, RouteReplyCallback routeReply) = 0; }; @@ -73,8 +121,18 @@ public: Ipv4 (); virtual ~Ipv4 (); + /** + * \brief Register a new routing protocol to be used in this IPv4 stack + * + * \param routingProtocol new routing protocol implementation object + * \param priority priority to give to this routing protocol. + * Values may range between -32768 and +32767. The priority 0 + * corresponds to static routing table lookups, higher values have + * more priority. The order by which routing protocols with the + * same priority value are consulted is undefined. + */ virtual void AddRoutingProtocol (Ptr routingProtocol, - int priority) = 0; + int16_t priority) = 0; /** * \param dest destination address From 3cfda55a692f139b344713229dcd10854bf797e4 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 27 Jul 2007 17:15:30 +0100 Subject: [PATCH 10/61] Add an EventCollector class, based on concepts discussed in the mailing list --- src/simulator/event-collector.cc | 120 +++++++++++++++++++++++++++++++ src/simulator/event-collector.h | 68 ++++++++++++++++++ src/simulator/wscript | 2 + 3 files changed, 190 insertions(+) create mode 100644 src/simulator/event-collector.cc create mode 100644 src/simulator/event-collector.h diff --git a/src/simulator/event-collector.cc b/src/simulator/event-collector.cc new file mode 100644 index 000000000..54ee69a86 --- /dev/null +++ b/src/simulator/event-collector.cc @@ -0,0 +1,120 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo J. A. M. Carneiro + */ +#include "event-collector.h" +#include + +namespace ns3 { + +inline bool +EventExpiredPredicate (const EventId &event) +{ + return event.IsExpired (); +} + +// Called when a new event was added and the cleanup limit was exceeded in consequence. +void +EventCollector::Cleanup () +{ + m_events.remove_if (EventExpiredPredicate); + + // If after cleanup we are still over the limit, increase the limit. + if (m_events.size () >= m_nextCleanupSize) + m_nextCleanupSize = std::min (std::list::size_type (CLEANUP_CHUNK_MAX_SIZE), + m_nextCleanupSize<<1); +} + + +EventCollector::~EventCollector () +{ + for (std::list::iterator event = m_events.begin (); + event != m_events.end (); event++) + { + Simulator::Cancel (*event); + } +} + +}; // namespace ns3 + + + +#ifdef RUN_SELF_TESTS + +#include "ns3/test.h" + +namespace ns3 { + +class EventCollectorTests : public Test +{ + int m_counter; + EventCollector *m_events; + + void EventCollectorCallback (); + +public: + + EventCollectorTests (); + virtual ~EventCollectorTests (); + virtual bool RunTests (void); +}; + +EventCollectorTests::EventCollectorTests () + : Test ("EventCollector"), m_counter (0), m_events (0) +{} + +EventCollectorTests::~EventCollectorTests () +{} + +void +EventCollectorTests::EventCollectorCallback () +{ + m_counter++; + if (m_counter == 50) + { + // this should cause the remaining (50) events to be cancelled + delete m_events; + m_events = 0; + } +} + +bool EventCollectorTests::RunTests (void) +{ + bool result = true; + + m_events = new EventCollector (); + + for (int n = 0; n < 100; n++) + { + m_events->Track (Simulator::Schedule + (Simulator::Now (), + &EventCollectorTests::EventCollectorCallback, + this)); + } + Simulator::Run (); + NS_TEST_ASSERT_EQUAL (m_events, 0); + NS_TEST_ASSERT_EQUAL (m_counter, 50); + return result; +} + +static EventCollectorTests g_eventCollectorTests; + +}; + +#endif /* RUN_SELF_TESTS */ diff --git a/src/simulator/event-collector.h b/src/simulator/event-collector.h new file mode 100644 index 000000000..7e2c78e65 --- /dev/null +++ b/src/simulator/event-collector.h @@ -0,0 +1,68 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo J. A. M. Carneiro + */ +#ifndef EVENT_COLLECTOR_H +#define EVENT_COLLECTOR_H + +#include +#include "event-id.h" +#include "simulator.h" + +namespace ns3 { + +/** + * \brief An object that tracks scheduled events and automatically + * cancels them when it is destroyed. + */ +class EventCollector +{ +public: + + EventCollector () : + m_nextCleanupSize (CLEANUP_CHUNK_MIN_SIZE) + {} + + /** + * \brief Tracks a new event + */ + void Track (EventId event) + { + m_events.push_back (event); + if (m_events.size () >= m_nextCleanupSize) + Cleanup (); + } + + ~EventCollector (); + +private: + enum { + CLEANUP_CHUNK_MIN_SIZE = 8, + CLEANUP_CHUNK_MAX_SIZE = 1024 + }; + + std::list::size_type m_nextCleanupSize; + std::list m_events; + + void Cleanup (); +}; + +}; // namespace ns3 + +#endif /* EVENT_COLLECTOR_H */ diff --git a/src/simulator/wscript b/src/simulator/wscript index f043d65b6..208828bf3 100644 --- a/src/simulator/wscript +++ b/src/simulator/wscript @@ -57,6 +57,7 @@ def build(bld): 'time.cc', 'timer.cc', 'event-id.cc', + 'event-collector.cc', 'scheduler.cc', 'scheduler-factory.cc', 'scheduler-list.cc', @@ -74,6 +75,7 @@ def build(bld): 'nstime.h', 'timer.h', 'event-id.h', + 'event-collector.h', 'event-impl.h', 'simulator.h', 'scheduler.h', From fc7b62e3291dfd99c97c36b87f05a234ca598c23 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 27 Jul 2007 18:45:12 +0100 Subject: [PATCH 11/61] Add a SingleEvent class. --- src/simulator/event-collector.h | 5 +- src/simulator/single-event.cc | 95 +++++++++++++++++++++++++++++++++ src/simulator/single-event.h | 84 +++++++++++++++++++++++++++++ src/simulator/wscript | 2 + 4 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 src/simulator/single-event.cc create mode 100644 src/simulator/single-event.h diff --git a/src/simulator/event-collector.h b/src/simulator/event-collector.h index 7e2c78e65..e22a369f4 100644 --- a/src/simulator/event-collector.h +++ b/src/simulator/event-collector.h @@ -29,7 +29,10 @@ namespace ns3 { /** * \brief An object that tracks scheduled events and automatically - * cancels them when it is destroyed. + * cancels them when it is destroyed. It is useful in situations + * where multiple instances of the same type of event can + * simultaneously be scheduled, and when the events should be limited + * to the lifetime of a container object. */ class EventCollector { diff --git a/src/simulator/single-event.cc b/src/simulator/single-event.cc new file mode 100644 index 000000000..cba91dddc --- /dev/null +++ b/src/simulator/single-event.cc @@ -0,0 +1,95 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo J. A. M. Carneiro + */ + +#ifdef RUN_SELF_TESTS + +#include "single-event.h" +#include "ns3/test.h" + +namespace ns3 { + +class SingleEventTests : public Test +{ + int m_counter; + SingleEvent *m_events; + + void SingleEventCallback (); + +public: + + SingleEventTests (); + virtual ~SingleEventTests (); + virtual bool RunTests (void); +}; + +SingleEventTests::SingleEventTests () + : Test ("SingleEvent"), m_counter (0), m_events (0) +{} + +SingleEventTests::~SingleEventTests () +{} + +void +SingleEventTests::SingleEventCallback () +{ + m_counter++; +} + +bool SingleEventTests::RunTests (void) +{ + bool result = true; + + + { + SingleEvent event; + + event = Simulator::Schedule (Simulator::Now (), &SingleEventTests::SingleEventCallback, this); + Simulator::Run (); + NS_TEST_ASSERT_EQUAL (m_counter, 1); + } + + { + SingleEvent event; + + event = Simulator::Schedule (Simulator::Now (), &SingleEventTests::SingleEventCallback, this); + } // event is destroyed => the eventid cancelled + + Simulator::Run (); + NS_TEST_ASSERT_EQUAL (m_counter, 1); + + { + SingleEvent event; + + event = Simulator::Schedule (Simulator::Now (), &SingleEventTests::SingleEventCallback, this); + // the second event cancels the first one + event = Simulator::Schedule (Simulator::Now (), &SingleEventTests::SingleEventCallback, this); + Simulator::Run (); + NS_TEST_ASSERT_EQUAL (m_counter, 2); + } + + return result; +} + +static SingleEventTests g_singleEventTests; + +}; + +#endif /* RUN_SELF_TESTS */ diff --git a/src/simulator/single-event.h b/src/simulator/single-event.h new file mode 100644 index 000000000..7385e1f77 --- /dev/null +++ b/src/simulator/single-event.h @@ -0,0 +1,84 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo J. A. M. Carneiro + */ +#ifndef SINGLE_EVENT_H +#define SINGLE_EVENT_H + +#include +#include "event-id.h" +#include "simulator.h" + +namespace ns3 { + +/** + * \brief An object that tracks a single event + * + * A SingleEvent acts as a smart proxy for an EventId. It + * automatically cancels the underlying EventId when it is replaced + * for a new EventId, or when the SingleEvent is destroyed. It is + * useful in situations where only one type of an event can possibly + * be scheduled at any single time (e.g. a single timer instance), and + * when the event should be limited to the lifetime of a container + * object. + */ +class SingleEvent +{ +public: + + SingleEvent () + {} + + /** + * \brief Tracks a newly scheduled event. + * + * Tracks a newly scheduled event. Any previous event that may have + * been scheduled is first cancelled. + */ + void operator = (const EventId &event) + { + Simulator::Cancel (m_event); + m_event = event; + } + + /** + * \brief Retrives the event being tracked + * + * Returns a copy of the tracked event. The returned value can be + * used to e.g. check if the event is still running, or to manually + * Cancel it. + */ + EventId GetEvent () const + { + return m_event; + } + + ~SingleEvent () + { + Simulator::Cancel (m_event); + } + +private: + + EventId m_event; +}; + +}; // namespace ns3 + +#endif /* SINGLE_EVENT_H */ diff --git a/src/simulator/wscript b/src/simulator/wscript index 208828bf3..555b808c5 100644 --- a/src/simulator/wscript +++ b/src/simulator/wscript @@ -58,6 +58,7 @@ def build(bld): 'timer.cc', 'event-id.cc', 'event-collector.cc', + 'single-event.cc', 'scheduler.cc', 'scheduler-factory.cc', 'scheduler-list.cc', @@ -76,6 +77,7 @@ def build(bld): 'timer.h', 'event-id.h', 'event-collector.h', + 'single-event.h', 'event-impl.h', 'simulator.h', 'scheduler.h', From e6ef4109c80a29aa5ea65466640f023ccc4c1f0d Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 27 Jul 2007 18:50:45 +0100 Subject: [PATCH 12/61] Remove Timer, made mostly redundant with the introduction of SingleEvent. --- src/simulator/timer.cc | 81 --------------- src/simulator/timer.h | 223 ----------------------------------------- src/simulator/wscript | 2 - 3 files changed, 306 deletions(-) delete mode 100644 src/simulator/timer.cc delete mode 100644 src/simulator/timer.h diff --git a/src/simulator/timer.cc b/src/simulator/timer.cc deleted file mode 100644 index 823efb65b..000000000 --- a/src/simulator/timer.cc +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 INESC Porto - * All rights reserved. - * - * 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 - * - * Author: Gustavo Carneiro - */ - -#include "timer.h" - -#ifdef RUN_SELF_TESTS - -#include "ns3/test.h" - -namespace ns3 { - -class TimerTests : public Test -{ - int m_counter; -public: - TimerTests (); - virtual ~TimerTests (); - virtual bool RunTests (void); - - void TimerCallback (int x); -}; - -TimerTests::TimerTests () - : Test ("Timer"), m_counter (0) -{} -TimerTests::~TimerTests () -{} - -void -TimerTests::TimerCallback (int x) -{ - m_counter += x; -} - -bool TimerTests::RunTests (void) -{ - bool result = true; - - Timer timer1 (MilliSeconds (1), MakeCallback (&TimerTests::TimerCallback, this)); - - // Check if it works in the common case - timer1.Schedule (1); - Simulator::Run (); - NS_TEST_ASSERT_EQUAL (m_counter, 1); - - // Check that it does not repeat itself - Simulator::Run (); - NS_TEST_ASSERT_EQUAL (m_counter, 1); - - // Check cancellation - timer1.Schedule (1); - timer1.Cancel (); - Simulator::Run (); - NS_TEST_ASSERT_EQUAL (m_counter, 1); - - return result; -} - -static TimerTests g_timerTests; - -}; - -#endif /* RUN_SELF_TESTS */ diff --git a/src/simulator/timer.h b/src/simulator/timer.h deleted file mode 100644 index 6be706fa6..000000000 --- a/src/simulator/timer.h +++ /dev/null @@ -1,223 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 INESC Porto - * All rights reserved. - * - * 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 - * - * Author: Gustavo Carneiro - */ -#ifndef TIMER_H -#define TIMER_H - -#include "simulator.h" -#include "ns3/callback.h" -#include "nstime.h" - -namespace ns3 { - -template -class Timer -{ -public: - typedef Callback CallbackType; - -protected: - Time m_interval; - CallbackType m_callback; - EventId m_eventId; - T1 m_t1; - T2 m_t2; - T3 m_t3; - T4 m_t4; - T5 m_t5; - - -public: - - /** - * \brief create a new timer object - * - * Constructs a new timer object with the given interval and callback. - * The timer will not actually start until Schedule() is called. - * - * \param interval The time interval after which the timer will expire - * \param callback The callback object that will be invoked when the - * timer expires - * - */ - Timer (Time const &interval, CallbackType callback) - : m_interval (interval), m_callback (callback) - { - } - - Timer (CallbackType callback) - : m_callback (callback) - { - } - - bool IsRunning () const - { - return m_eventId.IsRunning (); - } - - /** - * \brief start the timer - * - * Calling Schedule() on a timer essentially starts running - * it. After the configured interval, the timer will expire and the - * registered callback will be invoked. - */ - void Schedule () - { - if (m_eventId.IsRunning ()) - Simulator::Cancel (m_eventId); - m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this); - } - void Schedule (T1 v1) - { - if (m_eventId.IsRunning ()) - Simulator::Cancel (m_eventId); - m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this, - v1); - } - void Schedule (T1 v1, T2 v2) - { - if (m_eventId.IsRunning ()) - Simulator::Cancel (m_eventId); - m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this, - v1, v2); - } - void Schedule (T1 v1, T2 v2, T3 v3) - { - if (m_eventId.IsRunning ()) - Simulator::Cancel (m_eventId); - m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this, - v1, v2, v3); - } - void Schedule (T1 v1, T2 v2, T3 v3, T4 v4) - { - if (m_eventId.IsRunning ()) - Simulator::Cancel (m_eventId); - m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this, - v1, v2, v3, v4); - } - void Schedule (T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) - { - if (m_eventId.IsRunning ()) - Simulator::Cancel (m_eventId); - m_eventId = Simulator::Schedule (m_interval, &Timer::Expired, this, - v1, v2, v3, v4, v5); - } - - /** - * \brief changes the time interval for future Schedule() calls - * - * \param interval The time interval after which the timer will expire - */ - void SetInterval (Time const &interval) - { - m_interval = interval; - } - - /** - * \brief cancel the timer - * - * Cancels the timer; after calling Cancel () the registered - * callback will no longer be invoked, unless Schedule() is called - * again. May be called even if the timer is not running. - */ - void Cancel () - { - if (m_eventId.IsRunning ()) - Simulator::Cancel (m_eventId); - } - - ~Timer () - { - Cancel (); - } - - /** - * \brief artificially expire the timer - * - * Expires the timer at the current time. This will result in the - * registered callback to be invoked and the previously schedule - * timeout, if any, to be cancelled. - */ - void Expire () - { - Cancel (); - Expired (); - } - void Expire (T1 v1) - { - Cancel (); - Expired (v1); - } - void Expire (T1 v1, T2 v2) - { - Cancel (); - Expired (v1, v2); - } - void Expire (T1 v1, T2 v2, T3 v3) - { - Cancel (); - Expired (v1, v2, v3); - } - void Expire (T1 v1, T2 v2, T3 v3, T4 v4) - { - Cancel (); - Expired (v1, v2, v3, v4); - } - void Expire (T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) - { - Cancel (); - Expired (v1, v2, v3, v4, v5); - } - -private: - void Expired () - { - m_callback (); - } - void Expired (T1 v1) - { - m_callback (v1); - } - void Expired (T1 v1, T2 v2) - { - m_callback (v1, v2); - } - void Expired (T1 v1, T2 v2, T3 v3) - { - m_callback (v1, v2, v3); - } - void Expired (T1 v1, T2 v2, T3 v3, T4 v4) - { - m_callback (v1, v2, v3, v4); - } - void Expired (T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) - { - m_callback (v1, v2, v3, v4, v5); - } - -}; - - -}; // namespace ns3 - -#endif /* TIMER_H */ diff --git a/src/simulator/wscript b/src/simulator/wscript index 555b808c5..5eb44cb81 100644 --- a/src/simulator/wscript +++ b/src/simulator/wscript @@ -55,7 +55,6 @@ def build(bld): sim.source = [ 'high-precision.cc', 'time.cc', - 'timer.cc', 'event-id.cc', 'event-collector.cc', 'single-event.cc', @@ -74,7 +73,6 @@ def build(bld): headers.source = [ 'high-precision.h', 'nstime.h', - 'timer.h', 'event-id.h', 'event-collector.h', 'single-event.h', From e85f337b2f5d88231f1c6312c28737749f65eaad Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 27 Jul 2007 19:21:35 +0100 Subject: [PATCH 13/61] Adapt OLSR code to use SingleEvent instead of Timer, and EventCollector. --- src/routing/olsr/olsr-private.h | 12 ++--- src/routing/olsr/olsr.cc | 77 ++++++++++++++++++--------------- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/src/routing/olsr/olsr-private.h b/src/routing/olsr/olsr-private.h index 899ebc111..20188e0d7 100644 --- a/src/routing/olsr/olsr-private.h +++ b/src/routing/olsr/olsr-private.h @@ -38,7 +38,8 @@ #include "ns3/packet.h" #include "ns3/node.h" #include "ns3/socket.h" -#include "ns3/timer.h" +#include "ns3/single-event.h" +#include "ns3/event-collector.h" namespace ns3 { namespace olsr { @@ -56,6 +57,7 @@ public: virtual void SetMainInterface (uint32_t interface); private: + EventCollector m_events; /// Address of the routing agent. Ipv4Address m_routingAgentAddr; @@ -104,13 +106,13 @@ protected: Ipv4Address GetMainAddress (Ipv4Address iface_addr); // Timer handlers - Timer<> m_helloTimer; + SingleEvent m_helloTimer; void HelloTimerExpire (); - Timer<> m_tcTimer; + SingleEvent m_tcTimer; void TcTimerExpire (); - Timer<> m_midTimer; + SingleEvent m_midTimer; void MidTimerExpire (); void DupTupleTimerExpire (DuplicateTuple tuple); @@ -123,7 +125,7 @@ protected: /// A list of pending messages which are buffered awaiting for being sent. std::vector m_queuedMessages; - Timer<> m_queuedMessagesTimer; // timer for throttling outgoing messages + SingleEvent m_queuedMessagesTimer; // timer for throttling outgoing messages void ForwardDefault (OlsrMessageHeader olsrMessage, Packet messagePayload, diff --git a/src/routing/olsr/olsr.cc b/src/routing/olsr/olsr.cc index c3415e1f1..068ad990a 100644 --- a/src/routing/olsr/olsr.cc +++ b/src/routing/olsr/olsr.cc @@ -162,11 +162,7 @@ NS_DEBUG_COMPONENT_DEFINE ("Olsr"); Olsr::Olsr (Ptr node) : - m_useL2Notifications (false), - m_helloTimer (OLSR_HELLO_INTERVAL, MakeCallback (&Olsr::HelloTimerExpire, this)), - m_tcTimer (OLSR_TC_INTERVAL, MakeCallback (&Olsr::TcTimerExpire, this)), - m_midTimer (OLSR_MID_INTERVAL, MakeCallback (&Olsr::MidTimerExpire, this)), - m_queuedMessagesTimer (MakeCallback (&Olsr::SendQueuedMessages, this)) + m_useL2Notifications (false) { SetInterfaceId (Olsr::iid); @@ -239,9 +235,10 @@ void Olsr::Start () if (m_sendSocket->Bind (m_mainAddress, OLSR_PORT_NUMBER)) NS_ASSERT_MSG (false, "Failed to bind() OLSR send socket"); m_receiveSocket->Recv (MakeCallback (&Olsr::RecvOlsr, this)); - m_helloTimer.Expire (); - m_tcTimer.Expire (); - m_midTimer.Expire (); + + HelloTimerExpire (); + TcTimerExpire (); + MidTimerExpire (); NS_DEBUG ("OLSR on node " << m_mainAddress << " started"); } @@ -1065,10 +1062,9 @@ void Olsr::QueueMessage (Packet message, Time delay) { m_queuedMessages.push_back (message); - if (not m_queuedMessagesTimer.IsRunning ()) + if (not m_queuedMessagesTimer.GetEvent ().IsRunning ()) { - m_queuedMessagesTimer.SetInterval (delay); - m_queuedMessagesTimer.Schedule (); + m_queuedMessagesTimer = Simulator::Schedule (delay, &Olsr::SendQueuedMessages, this); } } @@ -1395,8 +1391,9 @@ Olsr::LinkSensing (const OlsrMessageHeader &msg, // Schedules link tuple deletion if (created && link_tuple != NULL) { - Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)), - &Olsr::LinkTupleTimerExpire, this, *link_tuple); + m_events.Track (Simulator::Schedule + (DELAY (std::min (link_tuple->time, link_tuple->symTime)), + &Olsr::LinkTupleTimerExpire, this, *link_tuple)); } } @@ -1470,9 +1467,10 @@ Olsr::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, now + msg.GetVTime (); // Schedules nb2hop tuple // deletion - Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime), - &Olsr::Nb2hopTupleTimerExpire, this, - new_nb2hop_tuple); + m_events.Track (Simulator::Schedule + (DELAY (new_nb2hop_tuple.expirationTime), + &Olsr::Nb2hopTupleTimerExpire, this, + new_nb2hop_tuple)); } else { @@ -1541,9 +1539,10 @@ Olsr::PopulateMprSelectorSet (const OlsrMessageHeader &msg, AddMprSelectorTuple (mprsel_tuple); // Schedules mpr selector tuple deletion - Simulator::Schedule (DELAY (mprsel_tuple.expirationTime), - &Olsr::MprSelTupleTimerExpire, - this, mprsel_tuple); + m_events.Track (Simulator::Schedule + (DELAY (mprsel_tuple.expirationTime), + &Olsr::MprSelTupleTimerExpire, + this, mprsel_tuple)); } else { @@ -1936,7 +1935,7 @@ void Olsr::HelloTimerExpire () { SendHello (); - m_helloTimer.Schedule (); + m_helloTimer = Simulator::Schedule (m_helloInterval, &Olsr::HelloTimerExpire, this); } /// @@ -1948,7 +1947,7 @@ Olsr::TcTimerExpire () { if (m_state.GetMprSelectors ().size () > 0) SendTc (); - m_tcTimer.Schedule (); + m_tcTimer = Simulator::Schedule (m_tcInterval, &Olsr::TcTimerExpire, this); } /// @@ -1960,7 +1959,7 @@ void Olsr::MidTimerExpire () { SendMid (); - m_midTimer.Schedule (); + m_midTimer = Simulator::Schedule (m_midInterval, &Olsr::MidTimerExpire, this); } /// @@ -1978,7 +1977,9 @@ Olsr::DupTupleTimerExpire (DuplicateTuple tuple) RemoveDuplicateTuple (tuple); } else - Simulator::Schedule (DELAY (tuple.expirationTime), &Olsr::DupTupleTimerExpire, this, tuple); + m_events.Track (Simulator::Schedule + (DELAY (tuple.expirationTime), + &Olsr::DupTupleTimerExpire, this, tuple)); } /// @@ -2008,13 +2009,15 @@ Olsr::LinkTupleTimerExpire (LinkTuple tuple) else NeighborLoss (tuple); - Simulator::Schedule (DELAY(tuple.time), - &Olsr::LinkTupleTimerExpire, this, tuple); + m_events.Track (Simulator::Schedule + (DELAY(tuple.time), + &Olsr::LinkTupleTimerExpire, this, tuple)); } else - Simulator::Schedule (DELAY (std::min (tuple.time, tuple.symTime)), - &Olsr::LinkTupleTimerExpire, this, tuple); + m_events.Track (Simulator::Schedule + (DELAY (std::min (tuple.time, tuple.symTime)), + &Olsr::LinkTupleTimerExpire, this, tuple)); } /// @@ -2032,8 +2035,9 @@ Olsr::Nb2hopTupleTimerExpire (TwoHopNeighborTuple tuple) RemoveTwoHopNeighborTuple (tuple); } else - Simulator::Schedule (DELAY (tuple.expirationTime), - &Olsr::Nb2hopTupleTimerExpire, this, tuple); + m_events.Track (Simulator::Schedule + (DELAY (tuple.expirationTime), + &Olsr::Nb2hopTupleTimerExpire, this, tuple)); } /// @@ -2051,8 +2055,9 @@ Olsr::MprSelTupleTimerExpire (MprSelectorTuple tuple) RemoveMprSelectorTuple (tuple); } else - Simulator::Schedule (DELAY (tuple.expirationTime), - &Olsr::MprSelTupleTimerExpire, this, tuple); + m_events.Track (Simulator::Schedule + (DELAY (tuple.expirationTime), + &Olsr::MprSelTupleTimerExpire, this, tuple)); } /// @@ -2070,8 +2075,9 @@ Olsr::TopologyTupleTimerExpire (TopologyTuple tuple) RemoveTopologyTuple (tuple); } else - Simulator::Schedule (DELAY (tuple.expirationTime), - &Olsr::TopologyTupleTimerExpire, this, tuple); + m_events.Track (Simulator::Schedule + (DELAY (tuple.expirationTime), + &Olsr::TopologyTupleTimerExpire, this, tuple)); } /// @@ -2087,8 +2093,9 @@ Olsr::IfaceAssocTupleTimerExpire (IfaceAssocTuple tuple) RemoveIfaceAssocTuple (tuple); } else - Simulator::Schedule (DELAY (tuple.time), - &Olsr::IfaceAssocTupleTimerExpire, this, tuple); + m_events.Track (Simulator::Schedule + (DELAY (tuple.time), + &Olsr::IfaceAssocTupleTimerExpire, this, tuple)); } From 00e998e5f9d92b9ee04358e0387ceaca241a1ad8 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jul 2007 12:50:13 +0100 Subject: [PATCH 14/61] SingleEvent: move methods to .cc file; add EventId proxy methods, instead of a single GetEventId method. --- src/simulator/single-event.cc | 42 ++++++++++++++++++++++++++++++++++- src/simulator/single-event.h | 34 +++++++++++----------------- 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/simulator/single-event.cc b/src/simulator/single-event.cc index cba91dddc..d0fd25776 100644 --- a/src/simulator/single-event.cc +++ b/src/simulator/single-event.cc @@ -19,9 +19,49 @@ * Author: Gustavo J. A. M. Carneiro */ +#include "single-event.h" + +namespace ns3 { + +SingleEvent::SingleEvent () +{ +} + +SingleEvent::~SingleEvent () +{ + Simulator::Cancel (m_event); +} + +void +SingleEvent::operator = (const EventId &event) +{ + Simulator::Cancel (m_event); + m_event = event; +} + +void +SingleEvent::Cancel (void) +{ + m_event.Cancel (); +} + +bool +SingleEvent::IsExpired (void) const +{ + return m_event.IsExpired (); +} + +bool +SingleEvent::IsRunning (void) const +{ + return m_event.IsRunning (); +} + + +}; // namespace ns3 + #ifdef RUN_SELF_TESTS -#include "single-event.h" #include "ns3/test.h" namespace ns3 { diff --git a/src/simulator/single-event.h b/src/simulator/single-event.h index 7385e1f77..ddb8a164c 100644 --- a/src/simulator/single-event.h +++ b/src/simulator/single-event.h @@ -42,8 +42,8 @@ class SingleEvent { public: - SingleEvent () - {} + SingleEvent (); + ~SingleEvent (); /** * \brief Tracks a newly scheduled event. @@ -51,28 +51,20 @@ public: * Tracks a newly scheduled event. Any previous event that may have * been scheduled is first cancelled. */ - void operator = (const EventId &event) - { - Simulator::Cancel (m_event); - m_event = event; - } + void operator = (const EventId &event); /** - * \brief Retrives the event being tracked - * - * Returns a copy of the tracked event. The returned value can be - * used to e.g. check if the event is still running, or to manually - * Cancel it. + * This method is syntactic sugar for the ns3::Simulator::cancel + * method. */ - EventId GetEvent () const - { - return m_event; - } - - ~SingleEvent () - { - Simulator::Cancel (m_event); - } + void Cancel (void); + /** + * This method is syntactic sugar for the ns3::Simulator::isExpired + * method. + * \returns true if the event has expired, false otherwise. + */ + bool IsExpired (void) const; + bool IsRunning (void) const; private: From 5b558714de182cadf29a54880eaf146e41f2054a Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jul 2007 13:09:02 +0100 Subject: [PATCH 15/61] EventCollector: move methods to the .cc file --- src/simulator/event-collector.cc | 17 +++++++++++++++++ src/simulator/event-collector.h | 15 ++------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/simulator/event-collector.cc b/src/simulator/event-collector.cc index 54ee69a86..a804df4d8 100644 --- a/src/simulator/event-collector.cc +++ b/src/simulator/event-collector.cc @@ -21,8 +21,25 @@ #include "event-collector.h" #include +#define CLEANUP_CHUNK_MIN_SIZE 8 +#define CLEANUP_CHUNK_MAX_SIZE 1024 + + namespace ns3 { + +EventCollector::EventCollector () : + m_nextCleanupSize (CLEANUP_CHUNK_MIN_SIZE) +{} + +void +EventCollector::Track (EventId event) +{ + m_events.push_back (event); + if (m_events.size () >= m_nextCleanupSize) + Cleanup (); +} + inline bool EventExpiredPredicate (const EventId &event) { diff --git a/src/simulator/event-collector.h b/src/simulator/event-collector.h index e22a369f4..7cf7c28db 100644 --- a/src/simulator/event-collector.h +++ b/src/simulator/event-collector.h @@ -38,27 +38,16 @@ class EventCollector { public: - EventCollector () : - m_nextCleanupSize (CLEANUP_CHUNK_MIN_SIZE) - {} + EventCollector (); /** * \brief Tracks a new event */ - void Track (EventId event) - { - m_events.push_back (event); - if (m_events.size () >= m_nextCleanupSize) - Cleanup (); - } + void Track (EventId event); ~EventCollector (); private: - enum { - CLEANUP_CHUNK_MIN_SIZE = 8, - CLEANUP_CHUNK_MAX_SIZE = 1024 - }; std::list::size_type m_nextCleanupSize; std::list m_events; From 98abf1d81241710aa0c41274a3e2b27517d5c8bc Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jul 2007 14:22:12 +0100 Subject: [PATCH 16/61] Add simple EventCollector benchmark --- utils/bench-event-collector.cc | 35 ++++++++++++++++++++++++++++++++++ utils/wscript | 3 +++ 2 files changed, 38 insertions(+) create mode 100644 utils/bench-event-collector.cc diff --git a/utils/bench-event-collector.cc b/utils/bench-event-collector.cc new file mode 100644 index 000000000..2e3110476 --- /dev/null +++ b/utils/bench-event-collector.cc @@ -0,0 +1,35 @@ +#include +#include +#include +#include "ns3/event-collector.h" +#include "ns3/simulator.h" + +using namespace ns3; + +void Foo () +{ + +} + +int main (int argc, char *argv[]) +{ + EventCollector events; + + if (argc < 3) + { + std::cerr << "usage: bench-event-collector NUM_EVENTS NUM_REPETITIONS" << std::endl; + return 1; + } + int numEvents = atoi (argv[1]); + int numRepetitions = atoi (argv[2]); + + for (int repetition = 0; repetition < numRepetitions; ++repetition) + { + for (int n = 0; n < numEvents; ++n) + { + events.Track (Simulator::Schedule (Simulator::Now (), Foo)); + } + Simulator::Run (); + } +} + diff --git a/utils/wscript b/utils/wscript index 27c509c01..739861360 100644 --- a/utils/wscript +++ b/utils/wscript @@ -21,3 +21,6 @@ def build(bld): obj = create_ns_prog('replay-simulation', 'replay-simulation.cc') obj.uselib_local = "ns3-core ns3-common ns3-simulator" + + obj = create_ns_prog('bench-event-collector', 'bench-event-collector.cc') + obj.uselib_local = "ns3-simulator" From ea0a9ae7abd6b3aed44fa4051ecaca6476f788fa Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jul 2007 14:48:56 +0100 Subject: [PATCH 17/61] EventCollector: tune the parameters and add a shrinking heuristic. --- src/simulator/event-collector.cc | 23 +++++++++++++++++++---- src/simulator/event-collector.h | 2 ++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/simulator/event-collector.cc b/src/simulator/event-collector.cc index a804df4d8..d47b4cc84 100644 --- a/src/simulator/event-collector.cc +++ b/src/simulator/event-collector.cc @@ -19,10 +19,9 @@ * Author: Gustavo J. A. M. Carneiro */ #include "event-collector.h" -#include #define CLEANUP_CHUNK_MIN_SIZE 8 -#define CLEANUP_CHUNK_MAX_SIZE 1024 +#define CLEANUP_CHUNK_MAX_SIZE 128 namespace ns3 { @@ -46,6 +45,21 @@ EventExpiredPredicate (const EventId &event) return event.IsExpired (); } +void +EventCollector::Grow () +{ + m_nextCleanupSize += (m_nextCleanupSize < CLEANUP_CHUNK_MAX_SIZE? + m_nextCleanupSize : CLEANUP_CHUNK_MAX_SIZE); +} + +void +EventCollector::Shrink () +{ + while (m_nextCleanupSize > m_events.size ()) + m_nextCleanupSize >>= 1; + Grow (); +} + // Called when a new event was added and the cleanup limit was exceeded in consequence. void EventCollector::Cleanup () @@ -54,8 +68,9 @@ EventCollector::Cleanup () // If after cleanup we are still over the limit, increase the limit. if (m_events.size () >= m_nextCleanupSize) - m_nextCleanupSize = std::min (std::list::size_type (CLEANUP_CHUNK_MAX_SIZE), - m_nextCleanupSize<<1); + Grow (); + else + Shrink (); } diff --git a/src/simulator/event-collector.h b/src/simulator/event-collector.h index 7cf7c28db..d0e48460d 100644 --- a/src/simulator/event-collector.h +++ b/src/simulator/event-collector.h @@ -53,6 +53,8 @@ private: std::list m_events; void Cleanup (); + void Grow (); + void Shrink (); }; }; // namespace ns3 From f597f961528c02eb69c6dffc222391228ea2fb17 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jul 2007 15:03:45 +0100 Subject: [PATCH 18/61] solve some merge problems --- examples/simple-p2p-olsr.cc | 6 +++--- examples/wscript | 2 +- src/routing/olsr/olsr.cc | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/simple-p2p-olsr.cc b/examples/simple-p2p-olsr.cc index 3a01240e3..cc60622ca 100644 --- a/examples/simple-p2p-olsr.cc +++ b/examples/simple-p2p-olsr.cc @@ -54,14 +54,14 @@ #include "ns3/ascii-trace.h" #include "ns3/pcap-trace.h" #include "ns3/internet-node.h" -#include "ns3/p2p-channel.h" -#include "ns3/p2p-net-device.h" +#include "ns3/point-to-point-channel.h" +#include "ns3/point-to-point-net-device.h" #include "ns3/mac-address.h" #include "ns3/ipv4-address.h" #include "ns3/ipv4.h" #include "ns3/socket.h" #include "ns3/ipv4-route.h" -#include "ns3/p2p-topology.h" +#include "ns3/point-to-point-topology.h" #include "ns3/onoff-application.h" #include "ns3/debug.h" diff --git a/examples/wscript b/examples/wscript index 5ea43c780..51d8eb824 100644 --- a/examples/wscript +++ b/examples/wscript @@ -13,5 +13,5 @@ def build(bld): obj = create_ns_prog('csma-cd-one-subnet', 'csma-cd-one-subnet.cc', deps=['csma-cd', 'internet-node']) obj = create_ns_prog('simple-p2p-olsr', 'simple-p2p-olsr.cc', - deps=['p2p', 'internet-node', 'olsr']) + deps=['point-to-point', 'internet-node', 'olsr']) diff --git a/src/routing/olsr/olsr.cc b/src/routing/olsr/olsr.cc index 068ad990a..18dffed18 100644 --- a/src/routing/olsr/olsr.cc +++ b/src/routing/olsr/olsr.cc @@ -1062,7 +1062,7 @@ void Olsr::QueueMessage (Packet message, Time delay) { m_queuedMessages.push_back (message); - if (not m_queuedMessagesTimer.GetEvent ().IsRunning ()) + if (not m_queuedMessagesTimer.IsRunning ()) { m_queuedMessagesTimer = Simulator::Schedule (delay, &Olsr::SendQueuedMessages, this); } From 8cb57d43d6a44d92c4f5b9778ab5e85f4b559a82 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jul 2007 17:06:06 +0100 Subject: [PATCH 19/61] Reorganize source tree and rename classes in a more sensible way; Olsr becomes OlsrAgent, olsr::Olsr becomes OlsrAgentImpl. --- examples/simple-p2p-olsr.cc | 18 +-- .../olsr/{olsr.cc => olsr-agent-impl.cc} | 153 +++++++++--------- .../{olsr-private.h => olsr-agent-impl.h} | 22 +-- src/routing/olsr/olsr-agent.cc | 30 ++++ src/routing/olsr/{olsr.h => olsr-agent.h} | 8 +- src/routing/olsr/olsr-state.cc | 4 +- src/routing/olsr/olsr-state.h | 15 +- .../{olsr-repositories.h => repositories.h} | 0 src/routing/olsr/wscript | 5 +- 9 files changed, 141 insertions(+), 114 deletions(-) rename src/routing/olsr/{olsr.cc => olsr-agent-impl.cc} (93%) rename src/routing/olsr/{olsr-private.h => olsr-agent-impl.h} (96%) create mode 100644 src/routing/olsr/olsr-agent.cc rename src/routing/olsr/{olsr.h => olsr-agent.h} (91%) rename src/routing/olsr/{olsr-repositories.h => repositories.h} (100%) diff --git a/examples/simple-p2p-olsr.cc b/examples/simple-p2p-olsr.cc index cc60622ca..1050f9e42 100644 --- a/examples/simple-p2p-olsr.cc +++ b/examples/simple-p2p-olsr.cc @@ -65,7 +65,7 @@ #include "ns3/onoff-application.h" #include "ns3/debug.h" -#include "ns3/olsr.h" +#include "ns3/olsr-agent.h" using namespace ns3; @@ -138,17 +138,17 @@ int main (int argc, char *argv[]) // Run OLSR in each node. - ComponentManager::Create > - (Olsr::cid, Olsr::iid, n0)->Start (); + ComponentManager::Create > + (OlsrAgent::cid, OlsrAgent::iid, n0)->Start (); - ComponentManager::Create > - (Olsr::cid, Olsr::iid, n1)->Start (); + ComponentManager::Create > + (OlsrAgent::cid, OlsrAgent::iid, n1)->Start (); - ComponentManager::Create > - (Olsr::cid, Olsr::iid, n2)->Start (); + ComponentManager::Create > + (OlsrAgent::cid, OlsrAgent::iid, n2)->Start (); - ComponentManager::Create > - (Olsr::cid, Olsr::iid, n3)->Start (); + ComponentManager::Create > + (OlsrAgent::cid, OlsrAgent::iid, n3)->Start (); #if 1 diff --git a/src/routing/olsr/olsr.cc b/src/routing/olsr/olsr-agent-impl.cc similarity index 93% rename from src/routing/olsr/olsr.cc rename to src/routing/olsr/olsr-agent-impl.cc index 18dffed18..63259e1b2 100644 --- a/src/routing/olsr/olsr.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -36,7 +36,7 @@ // #include // #include #include -#include "olsr-private.h" +#include "olsr-agent-impl.h" #include "ns3/socket-factory.h" #include "ns3/udp.h" #include "ns3/internet-node.h" @@ -149,22 +149,17 @@ namespace ns3 { -const InterfaceId Olsr::iid = MakeInterfaceId ("Olsr", Object::iid); -const ClassId Olsr::cid = MakeClassId< olsr::Olsr, Ptr > ("Olsr", Olsr::iid); - -namespace olsr { - -NS_DEBUG_COMPONENT_DEFINE ("Olsr"); +NS_DEBUG_COMPONENT_DEFINE ("OlsrAgent"); /********** OLSR class **********/ -Olsr::Olsr (Ptr node) +OlsrAgentImpl::OlsrAgentImpl (Ptr node) : m_useL2Notifications (false) { - SetInterfaceId (Olsr::iid); + SetInterfaceId (OlsrAgentImpl::iid); // Aggregate with the Node, so that OLSR dies when the node is destroyed. node->AddInterface (this); @@ -194,7 +189,7 @@ Olsr::Olsr (Ptr node) } -void Olsr::DoDispose () +void OlsrAgentImpl::DoDispose () { m_ipv4 = 0; m_receiveSocket->Dispose (); @@ -207,7 +202,7 @@ void Olsr::DoDispose () Object::DoDispose (); } -void Olsr::Start () +void OlsrAgentImpl::Start () { if (m_mainAddress == Ipv4Address ()) { @@ -234,7 +229,7 @@ void Olsr::Start () if (m_sendSocket->Bind (m_mainAddress, OLSR_PORT_NUMBER)) NS_ASSERT_MSG (false, "Failed to bind() OLSR send socket"); - m_receiveSocket->Recv (MakeCallback (&Olsr::RecvOlsr, this)); + m_receiveSocket->Recv (MakeCallback (&OlsrAgentImpl::RecvOlsr, this)); HelloTimerExpire (); TcTimerExpire (); @@ -243,7 +238,7 @@ void Olsr::Start () NS_DEBUG ("OLSR on node " << m_mainAddress << " started"); } -void Olsr::SetMainInterface (uint32_t interface) +void OlsrAgentImpl::SetMainInterface (uint32_t interface) { m_mainAddress = m_ipv4->GetAddress (interface); } @@ -252,7 +247,7 @@ void Olsr::SetMainInterface (uint32_t interface) // // \brief Processes an incoming %OLSR packet following RFC 3626 specification. void -Olsr::RecvOlsr (Ptr socket, +OlsrAgentImpl::RecvOlsr (Ptr socket, const uint8_t *dataPtr, uint32_t dataSize, const Ipv4Address &sourceAddress, uint16_t sourcePort) @@ -382,7 +377,7 @@ Olsr::RecvOlsr (Ptr socket, /// \return the degree of the node. /// int -Olsr::Degree (NeighborTuple const &tuple) +OlsrAgentImpl::Degree (NeighborTuple const &tuple) { int degree = 0; for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin (); @@ -404,7 +399,7 @@ Olsr::Degree (NeighborTuple const &tuple) /// \brief Computates MPR set of a node following RFC 3626 hints. /// void -Olsr::MprComputation() +OlsrAgentImpl::MprComputation() { // MPR computation should be done for each interface. See section 8.3.1 // (RFC 3626) for details. @@ -654,7 +649,7 @@ Olsr::MprComputation() /// \return the corresponding main address. /// Ipv4Address -Olsr::GetMainAddress (Ipv4Address iface_addr) +OlsrAgentImpl::GetMainAddress (Ipv4Address iface_addr) { IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (iface_addr); @@ -669,7 +664,7 @@ Olsr::GetMainAddress (Ipv4Address iface_addr) /// \brief Creates the routing table of the node following RFC 3626 hints. /// void -Olsr::RoutingTableComputation () +OlsrAgentImpl::RoutingTableComputation () { // 1. All the entries from the routing table are removed. m_routingTable->Clear (); @@ -823,7 +818,7 @@ Olsr::RoutingTableComputation () /// \param sender_iface the address of the interface where the message was sent from. /// void -Olsr::ProcessHello (const OlsrMessageHeader &msg, +OlsrAgentImpl::ProcessHello (const OlsrMessageHeader &msg, const OlsrHelloMessageHeader &hello, const Ipv4Address &receiverIface, const Ipv4Address &senderIface) @@ -845,7 +840,7 @@ Olsr::ProcessHello (const OlsrMessageHeader &msg, /// \param sender_iface the address of the interface where the message was sent from. /// void -Olsr::ProcessTc (const OlsrMessageHeader &msg, +OlsrAgentImpl::ProcessTc (const OlsrMessageHeader &msg, const OlsrTcMessageHeader &tc, const Ipv4Address &senderIface) { @@ -908,7 +903,7 @@ Olsr::ProcessTc (const OlsrMessageHeader &msg, // Schedules topology tuple deletion Simulator::Schedule (DELAY (topologyTuple.expirationTime), - &Olsr::TopologyTupleTimerExpire, + &OlsrAgentImpl::TopologyTupleTimerExpire, this, topologyTuple); } } @@ -924,7 +919,7 @@ Olsr::ProcessTc (const OlsrMessageHeader &msg, /// \param sender_iface the address of the interface where the message was sent from. /// void -Olsr::ProcessMid (const OlsrMessageHeader &msg, +OlsrAgentImpl::ProcessMid (const OlsrMessageHeader &msg, const OlsrMidMessageHeader &mid, const Ipv4Address &senderIface) { @@ -962,7 +957,7 @@ Olsr::ProcessMid (const OlsrMessageHeader &msg, AddIfaceAssocTuple (tuple); // Schedules iface association tuple deletion Simulator::Schedule (DELAY (tuple.time), - &Olsr::IfaceAssocTupleTimerExpire, this, tuple); + &OlsrAgentImpl::IfaceAssocTupleTimerExpire, this, tuple); } } } @@ -980,7 +975,7 @@ Olsr::ProcessMid (const OlsrMessageHeader &msg, /// \param local_iface the address of the interface where the message was received from. /// void -Olsr::ForwardDefault (OlsrMessageHeader olsrMessage, +OlsrAgentImpl::ForwardDefault (OlsrMessageHeader olsrMessage, Packet messagePayload, DuplicateTuple *duplicated, const Ipv4Address &localIface, @@ -1045,7 +1040,7 @@ Olsr::ForwardDefault (OlsrMessageHeader olsrMessage, AddDuplicateTuple (newDup); // Schedule dup tuple deletion Simulator::Schedule (OLSR_DUP_HOLD_TIME, - &Olsr::DupTupleTimerExpire, this, newDup); + &OlsrAgentImpl::DupTupleTimerExpire, this, newDup); } } @@ -1059,17 +1054,17 @@ Olsr::ForwardDefault (OlsrMessageHeader olsrMessage, /// \param delay maximum delay the %OLSR message is going to be buffered. /// void -Olsr::QueueMessage (Packet message, Time delay) +OlsrAgentImpl::QueueMessage (Packet message, Time delay) { m_queuedMessages.push_back (message); if (not m_queuedMessagesTimer.IsRunning ()) { - m_queuedMessagesTimer = Simulator::Schedule (delay, &Olsr::SendQueuedMessages, this); + m_queuedMessagesTimer = Simulator::Schedule (delay, &OlsrAgentImpl::SendQueuedMessages, this); } } void -Olsr::SendPacket (Packet packet) +OlsrAgentImpl::SendPacket (Packet packet) { NS_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet"); // Add a header @@ -1089,7 +1084,7 @@ Olsr::SendPacket (Packet packet) /// dictated by OLSR_MAX_MSGS constant. /// void -Olsr::SendQueuedMessages () +OlsrAgentImpl::SendQueuedMessages () { Packet packet; int numMessages = 0; @@ -1122,7 +1117,7 @@ Olsr::SendQueuedMessages () /// \brief Creates a new %OLSR HELLO message which is buffered for being sent later on. /// void -Olsr::SendHello () +OlsrAgentImpl::SendHello () { OlsrMessageHeader msg; OlsrHelloMessageHeader hello; @@ -1230,7 +1225,7 @@ Olsr::SendHello () /// \brief Creates a new %OLSR TC message which is buffered for being sent later on. /// void -Olsr::SendTc () +OlsrAgentImpl::SendTc () { OlsrMessageHeader msg; OlsrTcMessageHeader tc; @@ -1262,7 +1257,7 @@ Olsr::SendTc () /// \brief Creates a new %OLSR MID message which is buffered for being sent later on. /// void -Olsr::SendMid () +OlsrAgentImpl::SendMid () { OlsrMessageHeader msg; OlsrMidMessageHeader mid; @@ -1318,7 +1313,7 @@ Olsr::SendMid () /// \param sender_iface the address of the interface where the message was sent from. /// void -Olsr::LinkSensing (const OlsrMessageHeader &msg, +OlsrAgentImpl::LinkSensing (const OlsrMessageHeader &msg, const OlsrHelloMessageHeader &hello, const Ipv4Address &receiverIface, const Ipv4Address &senderIface) @@ -1393,7 +1388,7 @@ Olsr::LinkSensing (const OlsrMessageHeader &msg, { m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)), - &Olsr::LinkTupleTimerExpire, this, *link_tuple)); + &OlsrAgentImpl::LinkTupleTimerExpire, this, *link_tuple)); } } @@ -1404,7 +1399,7 @@ Olsr::LinkSensing (const OlsrMessageHeader &msg, /// \param msg the %OLSR message which contains the HELLO message. /// void -Olsr::PopulateNeighborSet (const OlsrMessageHeader &msg, +OlsrAgentImpl::PopulateNeighborSet (const OlsrMessageHeader &msg, const OlsrHelloMessageHeader &hello) { NeighborTuple *nb_tuple = m_state.FindNeighborTuple (msg.GetOriginatorAddress ()); @@ -1420,7 +1415,7 @@ Olsr::PopulateNeighborSet (const OlsrMessageHeader &msg, /// \param msg the %OLSR message which contains the HELLO message. /// void -Olsr::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, +OlsrAgentImpl::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, const OlsrHelloMessageHeader &hello) { Time now = Simulator::Now (); @@ -1469,7 +1464,7 @@ Olsr::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, // deletion m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime), - &Olsr::Nb2hopTupleTimerExpire, this, + &OlsrAgentImpl::Nb2hopTupleTimerExpire, this, new_nb2hop_tuple)); } else @@ -1507,7 +1502,7 @@ Olsr::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, /// \param msg the %OLSR message which contains the HELLO message. /// void -Olsr::PopulateMprSelectorSet (const OlsrMessageHeader &msg, +OlsrAgentImpl::PopulateMprSelectorSet (const OlsrMessageHeader &msg, const OlsrHelloMessageHeader &hello) { Time now = Simulator::Now (); @@ -1541,7 +1536,7 @@ Olsr::PopulateMprSelectorSet (const OlsrMessageHeader &msg, // Schedules mpr selector tuple deletion m_events.Track (Simulator::Schedule (DELAY (mprsel_tuple.expirationTime), - &Olsr::MprSelTupleTimerExpire, + &OlsrAgentImpl::MprSelTupleTimerExpire, this, mprsel_tuple)); } else @@ -1600,7 +1595,7 @@ OLSR::mac_failed(Packet* p) { /// \param tuple link tuple with the information of the link to the neighbor which has been lost. /// void -Olsr::NeighborLoss (const LinkTuple &tuple) +OlsrAgentImpl::NeighborLoss (const LinkTuple &tuple) { // debug("%f: Node %d detects neighbor %d loss\n", // Simulator::Now (), @@ -1621,7 +1616,7 @@ Olsr::NeighborLoss (const LinkTuple &tuple) /// \param tuple the duplicate tuple to be added. /// void -Olsr::AddDuplicateTuple (const DuplicateTuple &tuple) +OlsrAgentImpl::AddDuplicateTuple (const DuplicateTuple &tuple) { /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n", Simulator::Now (), @@ -1637,7 +1632,7 @@ Olsr::AddDuplicateTuple (const DuplicateTuple &tuple) /// \param tuple the duplicate tuple to be removed. /// void -Olsr::RemoveDuplicateTuple (const DuplicateTuple &tuple) +OlsrAgentImpl::RemoveDuplicateTuple (const DuplicateTuple &tuple) { /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n", Simulator::Now (), @@ -1654,7 +1649,7 @@ Olsr::RemoveDuplicateTuple (const DuplicateTuple &tuple) /// \param willingness willingness of the node which is going to be inserted in the Neighbor Set. /// LinkTuple& -Olsr::AddLinkTuple (const LinkTuple &tuple, uint8_t willingness) +OlsrAgentImpl::AddLinkTuple (const LinkTuple &tuple, uint8_t willingness) { // debug("%f: Node %d adds link tuple: nb_addr = %d\n", // now, @@ -1681,7 +1676,7 @@ Olsr::AddLinkTuple (const LinkTuple &tuple, uint8_t willingness) /// \param tuple the link tuple to be removed. /// void -Olsr::RemoveLinkTuple (const LinkTuple &tuple) +OlsrAgentImpl::RemoveLinkTuple (const LinkTuple &tuple) { // nsaddr_t nb_addr = get_main_addr(tuple->neighborIfaceAddr); // double now = Simulator::Now (); @@ -1707,7 +1702,7 @@ Olsr::RemoveLinkTuple (const LinkTuple &tuple) /// \param tuple the link tuple which has been updated. /// void -Olsr::LinkTupleUpdated (const LinkTuple &tuple) +OlsrAgentImpl::LinkTupleUpdated (const LinkTuple &tuple) { // Each time a link tuple changes, the associated neighbor tuple must be recomputed NeighborTuple *nb_tuple = @@ -1742,7 +1737,7 @@ Olsr::LinkTupleUpdated (const LinkTuple &tuple) /// \param tuple the neighbor tuple to be added. /// void -Olsr::AddNeighborTuple (const NeighborTuple &tuple) +OlsrAgentImpl::AddNeighborTuple (const NeighborTuple &tuple) { // debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n", // Simulator::Now (), @@ -1759,7 +1754,7 @@ Olsr::AddNeighborTuple (const NeighborTuple &tuple) /// \param tuple the neighbor tuple to be removed. /// void -Olsr::RemoveNeighborTuple (const NeighborTuple &tuple) +OlsrAgentImpl::RemoveNeighborTuple (const NeighborTuple &tuple) { // debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n", // Simulator::Now (), @@ -1776,7 +1771,7 @@ Olsr::RemoveNeighborTuple (const NeighborTuple &tuple) /// \param tuple the 2-hop neighbor tuple to be added. /// void -Olsr::AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple) +OlsrAgentImpl::AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple) { // debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n", // Simulator::Now (), @@ -1793,7 +1788,7 @@ Olsr::AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple) /// \param tuple the 2-hop neighbor tuple to be removed. /// void -Olsr::RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple) +OlsrAgentImpl::RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple) { // debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n", // Simulator::Now (), @@ -1812,7 +1807,7 @@ Olsr::RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple) /// \param tuple the MPR selector tuple to be added. /// void -Olsr::AddMprSelectorTuple (const MprSelectorTuple &tuple) +OlsrAgentImpl::AddMprSelectorTuple (const MprSelectorTuple &tuple) { // debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n", // Simulator::Now (), @@ -1831,7 +1826,7 @@ Olsr::AddMprSelectorTuple (const MprSelectorTuple &tuple) /// \param tuple the MPR selector tuple to be removed. /// void -Olsr::RemoveMprSelectorTuple (const MprSelectorTuple &tuple) +OlsrAgentImpl::RemoveMprSelectorTuple (const MprSelectorTuple &tuple) { // debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n", // Simulator::Now (), @@ -1848,7 +1843,7 @@ Olsr::RemoveMprSelectorTuple (const MprSelectorTuple &tuple) /// \param tuple the topology tuple to be added. /// void -Olsr::AddTopologyTuple (const TopologyTuple &tuple) +OlsrAgentImpl::AddTopologyTuple (const TopologyTuple &tuple) { // debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n", // Simulator::Now (), @@ -1866,7 +1861,7 @@ Olsr::AddTopologyTuple (const TopologyTuple &tuple) /// \param tuple the topology tuple to be removed. /// void -Olsr::RemoveTopologyTuple (const TopologyTuple &tuple) +OlsrAgentImpl::RemoveTopologyTuple (const TopologyTuple &tuple) { // debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n", // Simulator::Now (), @@ -1884,7 +1879,7 @@ Olsr::RemoveTopologyTuple (const TopologyTuple &tuple) /// \param tuple the interface association tuple to be added. /// void -Olsr::AddIfaceAssocTuple (const IfaceAssocTuple &tuple) +OlsrAgentImpl::AddIfaceAssocTuple (const IfaceAssocTuple &tuple) { // debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n", // Simulator::Now (), @@ -1901,7 +1896,7 @@ Olsr::AddIfaceAssocTuple (const IfaceAssocTuple &tuple) /// \param tuple the interface association tuple to be removed. /// void -Olsr::RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple) +OlsrAgentImpl::RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple) { // debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n", // Simulator::Now (), @@ -1913,14 +1908,14 @@ Olsr::RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple) } -uint16_t Olsr::GetPacketSequenceNumber () +uint16_t OlsrAgentImpl::GetPacketSequenceNumber () { m_packetSequenceNumber = (m_packetSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1); return m_packetSequenceNumber; } /// Increments message sequence number and returns the new value. -uint16_t Olsr::GetMessageSequenceNumber () +uint16_t OlsrAgentImpl::GetMessageSequenceNumber () { m_messageSequenceNumber = (m_messageSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1); return m_messageSequenceNumber; @@ -1932,10 +1927,10 @@ uint16_t Olsr::GetMessageSequenceNumber () /// \param e The event which has expired. /// void -Olsr::HelloTimerExpire () +OlsrAgentImpl::HelloTimerExpire () { SendHello (); - m_helloTimer = Simulator::Schedule (m_helloInterval, &Olsr::HelloTimerExpire, this); + m_helloTimer = Simulator::Schedule (m_helloInterval, &OlsrAgentImpl::HelloTimerExpire, this); } /// @@ -1943,11 +1938,11 @@ Olsr::HelloTimerExpire () /// \param e The event which has expired. /// void -Olsr::TcTimerExpire () +OlsrAgentImpl::TcTimerExpire () { if (m_state.GetMprSelectors ().size () > 0) SendTc (); - m_tcTimer = Simulator::Schedule (m_tcInterval, &Olsr::TcTimerExpire, this); + m_tcTimer = Simulator::Schedule (m_tcInterval, &OlsrAgentImpl::TcTimerExpire, this); } /// @@ -1956,10 +1951,10 @@ Olsr::TcTimerExpire () /// \param e The event which has expired. /// void -Olsr::MidTimerExpire () +OlsrAgentImpl::MidTimerExpire () { SendMid (); - m_midTimer = Simulator::Schedule (m_midInterval, &Olsr::MidTimerExpire, this); + m_midTimer = Simulator::Schedule (m_midInterval, &OlsrAgentImpl::MidTimerExpire, this); } /// @@ -1970,7 +1965,7 @@ Olsr::MidTimerExpire () /// \param e The event which has expired. /// void -Olsr::DupTupleTimerExpire (DuplicateTuple tuple) +OlsrAgentImpl::DupTupleTimerExpire (DuplicateTuple tuple) { if (tuple.expirationTime < Simulator::Now ()) { @@ -1979,7 +1974,7 @@ Olsr::DupTupleTimerExpire (DuplicateTuple tuple) else m_events.Track (Simulator::Schedule (DELAY (tuple.expirationTime), - &Olsr::DupTupleTimerExpire, this, tuple)); + &OlsrAgentImpl::DupTupleTimerExpire, this, tuple)); } /// @@ -1994,7 +1989,7 @@ Olsr::DupTupleTimerExpire (DuplicateTuple tuple) /// \param e The event which has expired. /// void -Olsr::LinkTupleTimerExpire (LinkTuple tuple) +OlsrAgentImpl::LinkTupleTimerExpire (LinkTuple tuple) { Time now = Simulator::Now (); @@ -2011,13 +2006,13 @@ Olsr::LinkTupleTimerExpire (LinkTuple tuple) m_events.Track (Simulator::Schedule (DELAY(tuple.time), - &Olsr::LinkTupleTimerExpire, this, tuple)); + &OlsrAgentImpl::LinkTupleTimerExpire, this, tuple)); } else m_events.Track (Simulator::Schedule (DELAY (std::min (tuple.time, tuple.symTime)), - &Olsr::LinkTupleTimerExpire, this, tuple)); + &OlsrAgentImpl::LinkTupleTimerExpire, this, tuple)); } /// @@ -2028,7 +2023,7 @@ Olsr::LinkTupleTimerExpire (LinkTuple tuple) /// \param e The event which has expired. /// void -Olsr::Nb2hopTupleTimerExpire (TwoHopNeighborTuple tuple) +OlsrAgentImpl::Nb2hopTupleTimerExpire (TwoHopNeighborTuple tuple) { if (tuple.expirationTime < Simulator::Now ()) { @@ -2037,7 +2032,7 @@ Olsr::Nb2hopTupleTimerExpire (TwoHopNeighborTuple tuple) else m_events.Track (Simulator::Schedule (DELAY (tuple.expirationTime), - &Olsr::Nb2hopTupleTimerExpire, this, tuple)); + &OlsrAgentImpl::Nb2hopTupleTimerExpire, this, tuple)); } /// @@ -2048,7 +2043,7 @@ Olsr::Nb2hopTupleTimerExpire (TwoHopNeighborTuple tuple) /// \param e The event which has expired. /// void -Olsr::MprSelTupleTimerExpire (MprSelectorTuple tuple) +OlsrAgentImpl::MprSelTupleTimerExpire (MprSelectorTuple tuple) { if (tuple.expirationTime < Simulator::Now ()) { @@ -2057,7 +2052,7 @@ Olsr::MprSelTupleTimerExpire (MprSelectorTuple tuple) else m_events.Track (Simulator::Schedule (DELAY (tuple.expirationTime), - &Olsr::MprSelTupleTimerExpire, this, tuple)); + &OlsrAgentImpl::MprSelTupleTimerExpire, this, tuple)); } /// @@ -2068,7 +2063,7 @@ Olsr::MprSelTupleTimerExpire (MprSelectorTuple tuple) /// \param e The event which has expired. /// void -Olsr::TopologyTupleTimerExpire (TopologyTuple tuple) +OlsrAgentImpl::TopologyTupleTimerExpire (TopologyTuple tuple) { if (tuple.expirationTime < Simulator::Now ()) { @@ -2077,7 +2072,7 @@ Olsr::TopologyTupleTimerExpire (TopologyTuple tuple) else m_events.Track (Simulator::Schedule (DELAY (tuple.expirationTime), - &Olsr::TopologyTupleTimerExpire, this, tuple)); + &OlsrAgentImpl::TopologyTupleTimerExpire, this, tuple)); } /// @@ -2086,7 +2081,7 @@ Olsr::TopologyTupleTimerExpire (TopologyTuple tuple) /// \param e The event which has expired. /// void -Olsr::IfaceAssocTupleTimerExpire (IfaceAssocTuple tuple) +OlsrAgentImpl::IfaceAssocTupleTimerExpire (IfaceAssocTuple tuple) { if (tuple.time < Simulator::Now ()) { @@ -2095,12 +2090,12 @@ Olsr::IfaceAssocTupleTimerExpire (IfaceAssocTuple tuple) else m_events.Track (Simulator::Schedule (DELAY (tuple.time), - &Olsr::IfaceAssocTupleTimerExpire, this, tuple)); + &OlsrAgentImpl::IfaceAssocTupleTimerExpire, this, tuple)); } -}}; // namespace ns3, olsr +} // namespace ns3 @@ -2109,7 +2104,7 @@ Olsr::IfaceAssocTupleTimerExpire (IfaceAssocTuple tuple) #include "ns3/test.h" -namespace ns3 { namespace olsr { +namespace ns3 { class OlsrTest : public ns3::Test { private: @@ -2136,7 +2131,7 @@ OlsrTest::RunTests (void) static OlsrTest gOlsrTest; -}}; // namespace +} #endif /* RUN_SELF_TESTS */ diff --git a/src/routing/olsr/olsr-private.h b/src/routing/olsr/olsr-agent-impl.h similarity index 96% rename from src/routing/olsr/olsr-private.h rename to src/routing/olsr/olsr-agent-impl.h index 20188e0d7..e1a392410 100644 --- a/src/routing/olsr/olsr-private.h +++ b/src/routing/olsr/olsr-agent-impl.h @@ -23,17 +23,18 @@ ***************************************************************************/ -#ifndef __OLSR_H__ -#define __OLSR_H__ - -#include "olsr.h" +#ifndef __OLSR_AGENT_IMPL_H__ +#define __OLSR_AGENT_IMPL_H__ #include +#include "olsr-agent.h" #include "olsr-header.h" #include "olsr-state.h" + #include "routing-table.h" -#include "olsr-repositories.h" +#include "repositories.h" + #include "ns3/object.h" #include "ns3/packet.h" #include "ns3/node.h" @@ -42,16 +43,17 @@ #include "ns3/event-collector.h" -namespace ns3 { namespace olsr { +namespace ns3 { + +using namespace olsr; - -class Olsr : public ::ns3::Olsr +class OlsrAgentImpl : public OlsrAgent { friend class OlsrTest; public: - Olsr (Ptr node); + OlsrAgentImpl (Ptr node); virtual void Start (); virtual void SetMainInterface (uint32_t interface); @@ -184,6 +186,6 @@ protected: Ptr m_sendSocket; // UDP socket for sending OSLR packets }; -}}; // namespace ns3, olsr +} // namespace ns3 #endif diff --git a/src/routing/olsr/olsr-agent.cc b/src/routing/olsr/olsr-agent.cc new file mode 100644 index 000000000..0f2ac17ca --- /dev/null +++ b/src/routing/olsr/olsr-agent.cc @@ -0,0 +1,30 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo J. A. M. Carneiro + */ + +#include "olsr-agent.h" +#include "olsr-agent-impl.h" + +namespace ns3 { + +const InterfaceId OlsrAgent::iid = MakeInterfaceId ("OlsrAgent", Object::iid); +const ClassId OlsrAgent::cid = MakeClassId< OlsrAgentImpl, Ptr > ("OlsrAgent", OlsrAgent::iid); + +} diff --git a/src/routing/olsr/olsr.h b/src/routing/olsr/olsr-agent.h similarity index 91% rename from src/routing/olsr/olsr.h rename to src/routing/olsr/olsr-agent.h index adc1e6d82..903aec261 100644 --- a/src/routing/olsr/olsr.h +++ b/src/routing/olsr/olsr-agent.h @@ -19,8 +19,8 @@ * Author: Gustavo J. A. M. Carneiro */ -#ifndef OLSR_H -#define OLSR_H +#ifndef OLSR_AGENT_H +#define OLSR_AGENT_H #include "ns3/node.h" #include "ns3/component-manager.h" @@ -28,7 +28,7 @@ namespace ns3 { -class Olsr : public Object +class OlsrAgent : public Object { public: static const InterfaceId iid; @@ -41,5 +41,5 @@ public: }; // namespace ns3 -#endif /* OLSR_H */ +#endif /* OLSR_AGENT_H */ diff --git a/src/routing/olsr/olsr-state.cc b/src/routing/olsr/olsr-state.cc index 7a1f69e4a..828aac467 100644 --- a/src/routing/olsr/olsr-state.cc +++ b/src/routing/olsr/olsr-state.cc @@ -31,7 +31,7 @@ #include "olsr-state.h" -namespace ns3 { namespace olsr { +namespace ns3 { /********** MPR Selector Set Manipulation **********/ @@ -435,4 +435,4 @@ OlsrState::FindNeighborInterfaces (const Ipv4Address &neighborMainAddr) const return retval; } -}}; // namespace ns3, olsr +} // namespace ns3 diff --git a/src/routing/olsr/olsr-state.h b/src/routing/olsr/olsr-state.h index dfa8b78fb..01c7116a7 100644 --- a/src/routing/olsr/olsr-state.h +++ b/src/routing/olsr/olsr-state.h @@ -22,17 +22,16 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -/// -/// \file OLSR_state.h /// \brief This header file declares and defines internal state of an OLSR node. -/// -#ifndef __OLSR_state_h__ -#define __OLSR_state_h__ +#ifndef __OLSR_STATE_H__ +#define __OLSR_STATE_H__ -#include "olsr-repositories.h" +#include "repositories.h" -namespace ns3 { namespace olsr { +namespace ns3 { + +using namespace olsr; /// This class encapsulates all data structures needed for maintaining internal state of an OLSR node. class OlsrState @@ -142,6 +141,6 @@ public: }; -}}; // namespace ns3, olsr +} // namespace ns3 #endif diff --git a/src/routing/olsr/olsr-repositories.h b/src/routing/olsr/repositories.h similarity index 100% rename from src/routing/olsr/olsr-repositories.h rename to src/routing/olsr/repositories.h diff --git a/src/routing/olsr/wscript b/src/routing/olsr/wscript index a2874de2a..8b6b05a22 100644 --- a/src/routing/olsr/wscript +++ b/src/routing/olsr/wscript @@ -10,10 +10,11 @@ def build(bld): 'olsr-header.cc', 'olsr-state.cc', 'routing-table.cc', - 'olsr.cc', + 'olsr-agent.cc', + 'olsr-agent-impl.cc', ] headers = bld.create_obj('ns3header') headers.source = [ - 'olsr.h', + 'olsr-agent.h', ] From acde0b63110291f535f375247517af5f3fab3456 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jul 2007 17:15:35 +0100 Subject: [PATCH 20/61] fix indentation in some places (was broken due to class rename) --- src/routing/olsr/olsr-agent-impl.cc | 54 +++++++++++------------------ 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index 63259e1b2..1d8391597 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -248,9 +248,9 @@ void OlsrAgentImpl::SetMainInterface (uint32_t interface) // \brief Processes an incoming %OLSR packet following RFC 3626 specification. void OlsrAgentImpl::RecvOlsr (Ptr socket, - const uint8_t *dataPtr, uint32_t dataSize, - const Ipv4Address &sourceAddress, - uint16_t sourcePort) + const uint8_t *dataPtr, uint32_t dataSize, + const Ipv4Address &sourceAddress, + uint16_t sourcePort) { NS_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet"); @@ -819,9 +819,9 @@ OlsrAgentImpl::RoutingTableComputation () /// void OlsrAgentImpl::ProcessHello (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello, - const Ipv4Address &receiverIface, - const Ipv4Address &senderIface) + const OlsrHelloMessageHeader &hello, + const Ipv4Address &receiverIface, + const Ipv4Address &senderIface) { LinkSensing (msg, hello, receiverIface, senderIface); PopulateNeighborSet (msg, hello); @@ -841,8 +841,8 @@ OlsrAgentImpl::ProcessHello (const OlsrMessageHeader &msg, /// void OlsrAgentImpl::ProcessTc (const OlsrMessageHeader &msg, - const OlsrTcMessageHeader &tc, - const Ipv4Address &senderIface) + const OlsrTcMessageHeader &tc, + const Ipv4Address &senderIface) { Time now = Simulator::Now (); @@ -920,8 +920,8 @@ OlsrAgentImpl::ProcessTc (const OlsrMessageHeader &msg, /// void OlsrAgentImpl::ProcessMid (const OlsrMessageHeader &msg, - const OlsrMidMessageHeader &mid, - const Ipv4Address &senderIface) + const OlsrMidMessageHeader &mid, + const Ipv4Address &senderIface) { Time now = Simulator::Now (); @@ -976,10 +976,10 @@ OlsrAgentImpl::ProcessMid (const OlsrMessageHeader &msg, /// void OlsrAgentImpl::ForwardDefault (OlsrMessageHeader olsrMessage, - Packet messagePayload, - DuplicateTuple *duplicated, - const Ipv4Address &localIface, - const Ipv4Address &senderAddress) + Packet messagePayload, + DuplicateTuple *duplicated, + const Ipv4Address &localIface, + const Ipv4Address &senderAddress) { Time now = Simulator::Now (); @@ -1307,16 +1307,11 @@ OlsrAgentImpl::SendMid () /// /// \brief Updates Link Set according to a new received HELLO message (following RFC 3626 /// specification). Neighbor Set is also updated if needed. -/// -/// \param msg the OLSR message which contains the HELLO message. -/// \param receiver_iface the address of the interface where the message was received from. -/// \param sender_iface the address of the interface where the message was sent from. -/// void OlsrAgentImpl::LinkSensing (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello, - const Ipv4Address &receiverIface, - const Ipv4Address &senderIface) + const OlsrHelloMessageHeader &hello, + const Ipv4Address &receiverIface, + const Ipv4Address &senderIface) { Time now = Simulator::Now (); bool updated = false; @@ -1395,12 +1390,9 @@ OlsrAgentImpl::LinkSensing (const OlsrMessageHeader &msg, /// /// \brief Updates the Neighbor Set according to the information contained in a new received /// HELLO message (following RFC 3626). -/// -/// \param msg the %OLSR message which contains the HELLO message. -/// void OlsrAgentImpl::PopulateNeighborSet (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello) + const OlsrHelloMessageHeader &hello) { NeighborTuple *nb_tuple = m_state.FindNeighborTuple (msg.GetOriginatorAddress ()); if (nb_tuple != NULL) @@ -1411,12 +1403,9 @@ OlsrAgentImpl::PopulateNeighborSet (const OlsrMessageHeader &msg, /// /// \brief Updates the 2-hop Neighbor Set according to the information contained in a new /// received HELLO message (following RFC 3626). -/// -/// \param msg the %OLSR message which contains the HELLO message. -/// void OlsrAgentImpl::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello) + const OlsrHelloMessageHeader &hello) { Time now = Simulator::Now (); @@ -1498,12 +1487,9 @@ OlsrAgentImpl::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, /// /// \brief Updates the MPR Selector Set according to the information contained in a new /// received HELLO message (following RFC 3626). -/// -/// \param msg the %OLSR message which contains the HELLO message. -/// void OlsrAgentImpl::PopulateMprSelectorSet (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello) + const OlsrHelloMessageHeader &hello) { Time now = Simulator::Now (); From e4dedb226f57cd4a10b268c006814316d6448724 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jul 2007 17:33:12 +0100 Subject: [PATCH 21/61] Add a simpler olsr::EnableAllNodes API as suggested by Mathieu. --- examples/simple-p2p-olsr.cc | 16 ++---------- src/routing/olsr/olsr.cc | 52 +++++++++++++++++++++++++++++++++++++ src/routing/olsr/olsr.h | 37 ++++++++++++++++++++++++++ src/routing/olsr/wscript | 2 ++ 4 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 src/routing/olsr/olsr.cc create mode 100644 src/routing/olsr/olsr.h diff --git a/examples/simple-p2p-olsr.cc b/examples/simple-p2p-olsr.cc index 1050f9e42..731b49c32 100644 --- a/examples/simple-p2p-olsr.cc +++ b/examples/simple-p2p-olsr.cc @@ -65,7 +65,7 @@ #include "ns3/onoff-application.h" #include "ns3/debug.h" -#include "ns3/olsr-agent.h" +#include "ns3/olsr.h" using namespace ns3; @@ -138,20 +138,9 @@ int main (int argc, char *argv[]) // Run OLSR in each node. - ComponentManager::Create > - (OlsrAgent::cid, OlsrAgent::iid, n0)->Start (); - - ComponentManager::Create > - (OlsrAgent::cid, OlsrAgent::iid, n1)->Start (); - - ComponentManager::Create > - (OlsrAgent::cid, OlsrAgent::iid, n2)->Start (); - - ComponentManager::Create > - (OlsrAgent::cid, OlsrAgent::iid, n3)->Start (); + olsr::EnableAllNodes (); -#if 1 // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s Ptr ooff = Create ( @@ -176,7 +165,6 @@ int main (int argc, char *argv[]) // Start the application ooff->Start(Seconds(1.1)); ooff->Stop (Seconds(10.0)); -#endif // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the simple-p2p.tr file diff --git a/src/routing/olsr/olsr.cc b/src/routing/olsr/olsr.cc new file mode 100644 index 000000000..298c65216 --- /dev/null +++ b/src/routing/olsr/olsr.cc @@ -0,0 +1,52 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo J. A. M. Carneiro + */ + +#include "olsr-agent.h" +#include "olsr.h" + +namespace ns3 { namespace olsr { + + +void +EnableAllNodes (void) +{ + EnableNodes (NodeList::Begin (), NodeList::End ()); +} + +void +EnableNodes (NodeList::Iterator begin, NodeList::Iterator end) +{ + for (NodeList::Iterator i = begin; i != end; i++) + { + EnableNode (*i); + } +} + +void +EnableNode (Ptr node) +{ + ComponentManager::Create > + (OlsrAgent::cid, OlsrAgent::iid, node)->Start (); +} + + +}} // namespace ns3, olsr + diff --git a/src/routing/olsr/olsr.h b/src/routing/olsr/olsr.h new file mode 100644 index 000000000..914b4021e --- /dev/null +++ b/src/routing/olsr/olsr.h @@ -0,0 +1,37 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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 + * + * Author: Gustavo J. A. M. Carneiro + */ + +#ifndef OLSR_H +#define OLSR_H + +#include "ns3/node-list.h" + +namespace ns3 +{ + namespace olsr + { + void EnableAllNodes (void); + void EnableNodes (NodeList::Iterator begin, NodeList::Iterator end); + void EnableNode (Ptr node); + } +} + +#endif /* OLSR_H */ diff --git a/src/routing/olsr/wscript b/src/routing/olsr/wscript index 8b6b05a22..576af164f 100644 --- a/src/routing/olsr/wscript +++ b/src/routing/olsr/wscript @@ -12,9 +12,11 @@ def build(bld): 'routing-table.cc', 'olsr-agent.cc', 'olsr-agent-impl.cc', + 'olsr.cc', ] headers = bld.create_obj('ns3header') headers.source = [ 'olsr-agent.h', + 'olsr.h', ] From 072626d390659c480d0e5ba04194e132a2092c25 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jul 2007 17:43:52 +0100 Subject: [PATCH 22/61] Add documentation for the (few) OLSR public APIs --- src/routing/olsr/olsr-agent.h | 21 ++++++++++++++++++++- src/routing/olsr/olsr.h | 5 +++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/routing/olsr/olsr-agent.h b/src/routing/olsr/olsr-agent.h index 903aec261..398dc4c34 100644 --- a/src/routing/olsr/olsr-agent.h +++ b/src/routing/olsr/olsr-agent.h @@ -34,8 +34,27 @@ public: static const InterfaceId iid; static const ClassId cid; - virtual void Start () = 0; + /* \brief Sets the main interface to be used by OLSR + * + * Normally OLSR supports multiple interfaces, but the protocol + * requires the definition of a "main interface". This interface's + * IPv4 address provides the identity of the node, and all outgoing + * OLSR routing messages must have the main interface address, + * regardless of the actual interface used to transmit the packet. + * This method allows one to explicitly select an interface as the + * main interface. It must be called before the agent starts, but + * calling it is optional; if not called, the agent tries to guess + * and uses a suitable interface. + */ virtual void SetMainInterface (uint32_t interface) = 0; + + /* \brief Starts the OLSR protocol operation + * + * Calling this method essentially bootstraps the OLSR protocol, and + * causes the agent to start broadcasting OLSR messages to + * neighbors, as well start listening to messages from neighbors. + */ + virtual void Start () = 0; }; diff --git a/src/routing/olsr/olsr.h b/src/routing/olsr/olsr.h index 914b4021e..3239e153a 100644 --- a/src/routing/olsr/olsr.h +++ b/src/routing/olsr/olsr.h @@ -28,8 +28,13 @@ namespace ns3 { namespace olsr { + // \brief Start the OLSR routing agent on all nodes void EnableAllNodes (void); + + // \brief Start the OLSR routing agent on a given list of nodes void EnableNodes (NodeList::Iterator begin, NodeList::Iterator end); + + // \brief Start the OLSR routing agent on the given nodes void EnableNode (Ptr node); } } From 222eea66fa2d876c734b3bbac7a3232189d4ea6d Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jul 2007 19:11:21 +0100 Subject: [PATCH 23/61] Patch from Mathieu, makes EnableNodes templated --- src/routing/olsr/olsr.cc | 15 +++------------ src/routing/olsr/olsr.h | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/routing/olsr/olsr.cc b/src/routing/olsr/olsr.cc index 298c65216..1f6b0aa30 100644 --- a/src/routing/olsr/olsr.cc +++ b/src/routing/olsr/olsr.cc @@ -28,23 +28,14 @@ namespace ns3 { namespace olsr { void EnableAllNodes (void) { - EnableNodes (NodeList::Begin (), NodeList::End ()); -} - -void -EnableNodes (NodeList::Iterator begin, NodeList::Iterator end) -{ - for (NodeList::Iterator i = begin; i != end; i++) - { - EnableNode (*i); - } + EnableNodes (NodeList::Begin (), NodeList::End ()); } void EnableNode (Ptr node) { - ComponentManager::Create > - (OlsrAgent::cid, OlsrAgent::iid, node)->Start (); + ComponentManager::Create > + (OlsrAgent::cid, OlsrAgent::iid, node)->Start (); } diff --git a/src/routing/olsr/olsr.h b/src/routing/olsr/olsr.h index 3239e153a..b06c63097 100644 --- a/src/routing/olsr/olsr.h +++ b/src/routing/olsr/olsr.h @@ -32,11 +32,30 @@ namespace ns3 void EnableAllNodes (void); // \brief Start the OLSR routing agent on a given list of nodes - void EnableNodes (NodeList::Iterator begin, NodeList::Iterator end); + template + void EnableNodes (InputIterator begin, InputIterator end); // \brief Start the OLSR routing agent on the given nodes void EnableNode (Ptr node); } } + +// implementation +namespace ns3 +{ + namespace olsr + { + template + void EnableNodes (InputIterator begin, InputIterator end) + { + for (InputIterator i = begin; i != end; i++) + { + EnableNode (*i); + } + } + } +} + + #endif /* OLSR_H */ From 93ad9161ec91ce70090baa131ef41195056f24bb Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Tue, 31 Jul 2007 11:53:11 +0100 Subject: [PATCH 24/61] Fix the OLSR documentation. --- doc/doxygen.conf | 3 +++ doc/main.txt | 2 +- src/routing/olsr/olsr-agent.h | 22 ++++++++++++++++++++-- src/routing/olsr/olsr.h | 12 +++++++++--- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/doc/doxygen.conf b/doc/doxygen.conf index a8b337f0a..d71b47412 100644 --- a/doc/doxygen.conf +++ b/doc/doxygen.conf @@ -472,6 +472,9 @@ RECURSIVE = YES # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = \ + src/routing/olsr/olsr-state.h \ + src/routing/olsr/repositories.h \ + src/routing/olsr/routing-table.h \ src/simulator/high-precision.h \ src/simulator/high-precision-128.h \ src/simulator/high-precision-double.h diff --git a/doc/main.txt b/doc/main.txt index 3fc144687..b492641b8 100644 --- a/doc/main.txt +++ b/doc/main.txt @@ -65,4 +65,4 @@ /** * \defgroup constants Constants * \brief Constants you can change - */ \ No newline at end of file + */ diff --git a/src/routing/olsr/olsr-agent.h b/src/routing/olsr/olsr-agent.h index 398dc4c34..2a88f31c1 100644 --- a/src/routing/olsr/olsr-agent.h +++ b/src/routing/olsr/olsr-agent.h @@ -28,13 +28,30 @@ namespace ns3 { +/** + * \brief Class implementing the OLSR state machine + * + * This class represents an instance of the OLSR protocol. It + * attaches itself to a Node, and its lifecycle is bound to that node. + * Normally the functions in the ns3::olsr namespace are more simple + * to use to start OLSR on nodes, but access to the underlying OLSR + * agent can be useful in order to customize the OLSR parameters. + * Example: + * + * \code + * Ptr olsr = ComponentManager::Create > (OlsrAgent::cid, OlsrAgent::iid, node); + * agent->SetMainInterface (2); + * agent->Start (); + * \endcode + */ class OlsrAgent : public Object { public: static const InterfaceId iid; static const ClassId cid; - /* \brief Sets the main interface to be used by OLSR + /** + * \brief Sets the main interface to be used by OLSR * * Normally OLSR supports multiple interfaces, but the protocol * requires the definition of a "main interface". This interface's @@ -48,7 +65,8 @@ public: */ virtual void SetMainInterface (uint32_t interface) = 0; - /* \brief Starts the OLSR protocol operation + /** + * \brief Starts the OLSR protocol operation * * Calling this method essentially bootstraps the OLSR protocol, and * causes the agent to start broadcasting OLSR messages to diff --git a/src/routing/olsr/olsr.h b/src/routing/olsr/olsr.h index b06c63097..cbfa40c44 100644 --- a/src/routing/olsr/olsr.h +++ b/src/routing/olsr/olsr.h @@ -26,16 +26,22 @@ namespace ns3 { + /** + * \namespace ns3::olsr + * \brief Includes a set of utility functions to enable OLSR on + * certain nodes with default parameters. For finer grained control + * of OLSR parameters, see OlsrAgent. + */ namespace olsr { - // \brief Start the OLSR routing agent on all nodes + /// \brief Start the OLSR routing agent on all nodes void EnableAllNodes (void); - // \brief Start the OLSR routing agent on a given list of nodes + /// \brief Start the OLSR routing agent on a given list of nodes template void EnableNodes (InputIterator begin, InputIterator end); - // \brief Start the OLSR routing agent on the given nodes + /// \brief Start the OLSR routing agent on the given node void EnableNode (Ptr node); } } From 4a6a601b5af8dd6ef5d1506f81f892d0c63c7c9a Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 5 Sep 2007 18:46:13 +0100 Subject: [PATCH 25/61] fix olsr wscript --- src/routing/olsr/wscript | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/routing/olsr/wscript b/src/routing/olsr/wscript index 576af164f..bc6268f8b 100644 --- a/src/routing/olsr/wscript +++ b/src/routing/olsr/wscript @@ -1,12 +1,9 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- def build(bld): - obj = bld.create_obj('cpp', 'shlib') - obj.name = 'ns3-olsr' - obj.target = obj.name - obj.uselib_local = ['ns3-internet-node'] - obj.includes = '.' - obj.source = [ + module = bld.create_ns3_module('olsr', ['internet-node']) + module.includes = '.' + module.source = [ 'olsr-header.cc', 'olsr-state.cc', 'routing-table.cc', From 42189e5c529d534f894c863d74c277643f42411c Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 6 Sep 2007 13:34:54 +0100 Subject: [PATCH 26/61] Update OLSR code to NS-3 API changes. --- ...-olsr.cc => simple-point-to-point-olsr.cc} | 63 ++++++------ examples/wscript | 2 +- src/routing/olsr/olsr-agent-impl.cc | 61 ++++++------ src/routing/olsr/olsr-agent-impl.h | 5 +- src/routing/olsr/olsr-header.cc | 96 ++++++++++++++----- src/routing/olsr/olsr-header.h | 62 +++++++----- 6 files changed, 176 insertions(+), 113 deletions(-) rename examples/{simple-p2p-olsr.cc => simple-point-to-point-olsr.cc} (75%) diff --git a/examples/simple-p2p-olsr.cc b/examples/simple-point-to-point-olsr.cc similarity index 75% rename from examples/simple-p2p-olsr.cc rename to examples/simple-point-to-point-olsr.cc index 731b49c32..3f89a0331 100644 --- a/examples/simple-p2p-olsr.cc +++ b/examples/simple-point-to-point-olsr.cc @@ -29,13 +29,14 @@ // / 5 Mb/s, 2ms // n1 // -// - all links are p2p links with indicated one-way BW/delay +// - all links are point-to-point links with indicated one-way BW/delay // - CBR/UDP flows from n0 to n3, and from n3 to n1 // - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec. // - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. // (i.e., DataRate of 448,000 bps) // - DropTail queues -// - Tracing of queues and packet receptions to file "simple-p2p.tr" +// - Tracing of queues and packet receptions to file +// "simple-point-to-point.tr" #include #include @@ -56,14 +57,13 @@ #include "ns3/internet-node.h" #include "ns3/point-to-point-channel.h" #include "ns3/point-to-point-net-device.h" -#include "ns3/mac-address.h" #include "ns3/ipv4-address.h" +#include "ns3/inet-socket-address.h" #include "ns3/ipv4.h" #include "ns3/socket.h" #include "ns3/ipv4-route.h" #include "ns3/point-to-point-topology.h" #include "ns3/onoff-application.h" -#include "ns3/debug.h" #include "ns3/olsr.h" @@ -74,16 +74,14 @@ int main (int argc, char *argv[]) // Users may find it convenient to turn on explicit debugging // for selected modules; the below lines suggest how to do this -#if 1 -// DebugComponentEnable("Ipv4L3Protocol"); -// DebugComponentEnable("ArpL3Protocol"); -// DebugComponentEnable("OlsrRoutingTable"); -// DebugComponentEnable("Object"); -// DebugComponentEnable("Queue"); -// DebugComponentEnable("DropTailQueue"); -// DebugComponentEnable("Channel"); -// DebugComponentEnable("PointToPointChannel"); -// DebugComponentEnable("PointToPointNetDevice"); + // remember to add #include "ns3/debug.h" before enabling these +#if 0 + DebugComponentEnable("Object"); + DebugComponentEnable("Queue"); + DebugComponentEnable("DropTailQueue"); + DebugComponentEnable("Channel"); + DebugComponentEnable("PointToPointChannel"); + DebugComponentEnable("PointToPointNetDevice"); #endif // Set up some default values for the simulation. Use the Bind() @@ -92,12 +90,12 @@ int main (int argc, char *argv[]) // The below Bind command tells the queue factory which class to // instantiate, when the queue factory is invoked in the topology code - Bind ("Queue", "DropTailQueue"); + DefaultValue::Bind ("Queue", "DropTailQueue"); - Bind ("OnOffApplicationPacketSize", "210"); - Bind ("OnOffApplicationDataRate", "448kb/s"); + DefaultValue::Bind ("OnOffApplicationPacketSize", "210"); + DefaultValue::Bind ("OnOffApplicationDataRate", "448kb/s"); - //Bind ("DropTailQueue::m_maxPackets", 30); + //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30); // Allow the user to override any of the defaults and the above // Bind()s at run-time, via command-line arguments @@ -136,17 +134,20 @@ int main (int argc, char *argv[]) channel2, n2, Ipv4Address("10.1.3.1"), n3, Ipv4Address("10.1.3.2")); - - // Run OLSR in each node. - olsr::EnableAllNodes (); + // Finally, we add static routes. These three steps (Channel and + // NetDevice creation, IP Address assignment, and routing) are + // separated because there may be a need to postpone IP Address + // assignment (emulation) or modify to use dynamic routing + PointToPointTopology::AddIpv4Routes(n0, n2, channel0); + PointToPointTopology::AddIpv4Routes(n1, n2, channel1); + PointToPointTopology::AddIpv4Routes(n2, n3, channel2); // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s Ptr ooff = Create ( n0, - Ipv4Address("10.1.3.2"), - 80, + InetSocketAddress ("10.1.3.2", 80), "Udp", ConstantVariable(1), ConstantVariable(0)); @@ -157,8 +158,7 @@ int main (int argc, char *argv[]) // Create a similar flow from n3 to n1, starting at time 1.1 seconds ooff = Create ( n3, - Ipv4Address("10.1.2.1"), - 80, + InetSocketAddress ("10.1.2.1", 80), "Udp", ConstantVariable(1), ConstantVariable(0)); @@ -166,20 +166,23 @@ int main (int argc, char *argv[]) ooff->Start(Seconds(1.1)); ooff->Stop (Seconds(10.0)); + // Start OLSR in all nodes + olsr::EnableAllNodes (); + // Configure tracing of all enqueue, dequeue, and NetDevice receive events - // Trace output will be sent to the simple-p2p.tr file -// AsciiTrace asciitrace ("simple-p2p-olsr.tr"); + // Trace output will be sent to the simple-point-to-point.tr file +// AsciiTrace asciitrace ("simple-point-to-point.tr"); // asciitrace.TraceAllQueues (); // asciitrace.TraceAllNetDeviceRx (); // Also configure some tcpdump traces; each interface will be traced - // The output files will be named simple-p2p.pcap-- + // The output files will be named + // simple-point-to-point.pcap-- // and can be read by the "tcpdump -r" command (use "-tt" option to // display timestamps correctly) - PcapTrace pcaptrace ("simple-p2p-olsr.pcap"); + PcapTrace pcaptrace ("simple-point-to-point-olsr.pcap"); pcaptrace.TraceAllIp (); - Simulator::StopAt (Seconds (10.0)); Simulator::Run (); Simulator::Destroy (); diff --git a/examples/wscript b/examples/wscript index a2268eb53..98177444a 100644 --- a/examples/wscript +++ b/examples/wscript @@ -24,4 +24,4 @@ def build(bld): obj = bld.create_ns3_program('simple-point-to-point-olsr', ['point-to-point', 'internet-node', 'olsr']) - obj.source = 'simple-p2p-olsr.cc' + obj.source = 'simple-point-to-point-olsr.cc' diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index 1d8391597..14667f686 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -43,6 +43,7 @@ #include "ns3/simulator.h" #include "ns3/debug.h" #include "ns3/random-variable.h" +#include "ns3/inet-socket-address.h" #include @@ -181,11 +182,11 @@ OlsrAgentImpl::OlsrAgentImpl (Ptr node) Ptr socketFactory = node->QueryInterface (Udp::iid); m_receiveSocket = socketFactory->CreateSocket (); - if (m_receiveSocket->Bind (OLSR_PORT_NUMBER)) + if (m_receiveSocket->Bind (InetSocketAddress (OLSR_PORT_NUMBER))) NS_ASSERT_MSG (false, "Failed to bind() OLSR receive socket"); m_sendSocket = socketFactory->CreateSocket (); - m_sendSocket->Connect (Ipv4Address (0xffffffff), OLSR_PORT_NUMBER); + m_sendSocket->Connect (InetSocketAddress (Ipv4Address (0xffffffff), OLSR_PORT_NUMBER)); } @@ -227,9 +228,9 @@ void OlsrAgentImpl::Start () // static routing. m_ipv4->AddRoutingProtocol (m_routingTable, -10); - if (m_sendSocket->Bind (m_mainAddress, OLSR_PORT_NUMBER)) + if (m_sendSocket->Bind (InetSocketAddress (m_mainAddress, OLSR_PORT_NUMBER))) NS_ASSERT_MSG (false, "Failed to bind() OLSR send socket"); - m_receiveSocket->Recv (MakeCallback (&OlsrAgentImpl::RecvOlsr, this)); + m_receiveSocket->SetRecvCallback (MakeCallback (&OlsrAgentImpl::RecvOlsr, this)); HelloTimerExpire (); TcTimerExpire (); @@ -248,27 +249,27 @@ void OlsrAgentImpl::SetMainInterface (uint32_t interface) // \brief Processes an incoming %OLSR packet following RFC 3626 specification. void OlsrAgentImpl::RecvOlsr (Ptr socket, - const uint8_t *dataPtr, uint32_t dataSize, - const Ipv4Address &sourceAddress, - uint16_t sourcePort) + const Packet &receivedPacket, + const Address &sourceAddress) { NS_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet"); - + InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress); + // All routing messages are sent from and to port RT_PORT, // so we check it. - NS_ASSERT (sourcePort == OLSR_PORT_NUMBER); + NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER); - Packet packet (dataPtr, dataSize); + Packet packet = receivedPacket; OlsrPacketHeader olsrPacketHeader; packet.RemoveHeader (olsrPacketHeader); - NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSize ()); - uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSize (); + NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ()); + uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize (); while (sizeLeft) { OlsrMessageHeader messageHeader; - NS_ASSERT (sizeLeft >= messageHeader.GetSize ()); + NS_ASSERT (sizeLeft >= messageHeader.GetSerializedSize ()); if (packet.RemoveHeader (messageHeader) == 0) NS_ASSERT (false); @@ -286,13 +287,13 @@ OlsrAgentImpl::RecvOlsr (Ptr socket, || messageHeader.GetOriginatorAddress () == m_mainAddress) { packet.RemoveAtStart (messageHeader.GetMessageSize () - - messageHeader.GetSize ()); + - messageHeader.GetSerializedSize ()); continue; } // Save the original message payload for forwarding Packet messagePayload = packet.CreateFragment - (0, messageHeader.GetMessageSize () - messageHeader.GetSize ()); + (0, messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); // If the message has been processed it must not be processed again bool do_forwarding = true; @@ -309,28 +310,28 @@ OlsrAgentImpl::RecvOlsr (Ptr socket, switch (messageHeader.GetMessageType ()) { case OlsrMessageHeader::HELLO_MESSAGE: - helloMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSize ()); + helloMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); packet.RemoveHeader (helloMsg); NS_DEBUG ("OLSR node received HELLO message of size " << messageHeader.GetMessageSize ()); - ProcessHello(messageHeader, helloMsg, m_mainAddress, sourceAddress); + ProcessHello (messageHeader, helloMsg, m_mainAddress, inetSourceAddr.GetIpv4 ()); break; case OlsrMessageHeader::TC_MESSAGE: - tcMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSize ()); + tcMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); packet.RemoveHeader (tcMsg); NS_DEBUG ("OLSR node received TC message of size " << messageHeader.GetMessageSize ()); - ProcessTc(messageHeader, tcMsg, sourceAddress); + ProcessTc (messageHeader, tcMsg, inetSourceAddr.GetIpv4 ()); break; case OlsrMessageHeader::MID_MESSAGE: - midMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSize ()); + midMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); packet.RemoveHeader (midMsg); NS_DEBUG ("OLSR node received MID message of size " << messageHeader.GetMessageSize ()); - ProcessMid(messageHeader, midMsg, sourceAddress); + ProcessMid (messageHeader, midMsg, inetSourceAddr.GetIpv4 ()); break; default: - packet.RemoveAtStart (messageHeader.GetMessageSize () - messageHeader.GetSize ()); + packet.RemoveAtStart (messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); NS_DEBUG ("OLSR message type " << int (messageHeader.GetMessageType ()) << " not implemented"); @@ -339,7 +340,7 @@ OlsrAgentImpl::RecvOlsr (Ptr socket, else { NS_DEBUG ("OLSR message is duplicated, not reading it."); - packet.RemoveAtStart (messageHeader.GetMessageSize () - messageHeader.GetSize ()); + packet.RemoveAtStart (messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); // If the message has been considered for forwarding, it should // not be retransmitted again @@ -361,7 +362,7 @@ OlsrAgentImpl::RecvOlsr (Ptr socket, // Remaining messages are also forwarded using the default algorithm. if (messageHeader.GetMessageType () != OlsrMessageHeader::HELLO_MESSAGE) ForwardDefault (messageHeader, messagePayload, duplicated, - m_mainAddress, sourceAddress); + m_mainAddress, inetSourceAddr.GetIpv4 ()); } } @@ -1069,11 +1070,11 @@ OlsrAgentImpl::SendPacket (Packet packet) NS_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet"); // Add a header OlsrPacketHeader header; - header.SetPacketLength (header.GetSize () + packet.GetSize ()); + header.SetPacketLength (header.GetSerializedSize () + packet.GetSize ()); header.SetPacketSequenceNumber (GetPacketSequenceNumber ()); packet.AddHeader (header); // Send it - m_sendSocket->Send (packet.PeekData (), packet.GetSize ()); + m_sendSocket->Send (packet); } /// @@ -1214,9 +1215,9 @@ OlsrAgentImpl::SendHello () hello.SetLinkMessages (linkMessages); Packet packet; packet.AddHeader (hello); - NS_DEBUG ("OLSR HELLO message size: " << int (packet.GetSize () + msg.GetSize ()) + NS_DEBUG ("OLSR HELLO message size: " << int (packet.GetSize () + msg.GetSerializedSize ()) << " (with " << int (linkMessages.size ()) << " link messages)"); - msg.SetMessageSize (packet.GetSize () + msg.GetSize ()); + msg.SetMessageSize (packet.GetSize () + msg.GetSerializedSize ()); packet.AddHeader (msg); QueueMessage (packet, JITTER); } @@ -1248,7 +1249,7 @@ OlsrAgentImpl::SendTc () Packet packet; packet.AddHeader (tc); - msg.SetMessageSize (packet.GetSize () + msg.GetSize ()); + msg.SetMessageSize (packet.GetSize () + msg.GetSerializedSize ()); packet.AddHeader (msg); QueueMessage (packet, JITTER); } @@ -1299,7 +1300,7 @@ OlsrAgentImpl::SendMid () Packet packet; packet.AddHeader (mid); - msg.SetMessageSize (packet.GetSize () + msg.GetSize ()); + msg.SetMessageSize (packet.GetSize () + msg.GetSerializedSize ()); packet.AddHeader (msg); QueueMessage (packet, JITTER); } diff --git a/src/routing/olsr/olsr-agent-impl.h b/src/routing/olsr/olsr-agent-impl.h index e1a392410..7758664d1 100644 --- a/src/routing/olsr/olsr-agent-impl.h +++ b/src/routing/olsr/olsr-agent-impl.h @@ -99,9 +99,8 @@ protected: inline uint16_t GetMessageSequenceNumber (); void RecvOlsr (Ptr socket, - const uint8_t *dataPtr, uint32_t dataSize, - const Ipv4Address &sourceAddr, - uint16_t sourcePort); + const Packet &receivedPacket, + const Address &sourceAddress); void MprComputation (); void RoutingTableComputation (); diff --git a/src/routing/olsr/olsr-header.cc b/src/routing/olsr/olsr-header.cc index 12061ab74..7d6184756 100644 --- a/src/routing/olsr/olsr-header.cc +++ b/src/routing/olsr/olsr-header.cc @@ -96,6 +96,14 @@ OlsrPacketHeader::OlsrPacketHeader () OlsrPacketHeader::~OlsrPacketHeader () {} +uint32_t +OlsrPacketHeader::GetUid (void) +{ + static uint32_t uid = AllocateUid + ("OlsrPacketHeader.nsnam.org"); + return uid; +} + uint32_t OlsrPacketHeader::GetSerializedSize (void) const { @@ -103,13 +111,13 @@ OlsrPacketHeader::GetSerializedSize (void) const } void -OlsrPacketHeader::PrintTo (std::ostream &os) const +OlsrPacketHeader::Print (std::ostream &os) const { // TODO } void -OlsrPacketHeader::SerializeTo (Buffer::Iterator start) const +OlsrPacketHeader::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; i.WriteHtonU16 (m_packetLength); @@ -117,7 +125,7 @@ OlsrPacketHeader::SerializeTo (Buffer::Iterator start) const } uint32_t -OlsrPacketHeader::DeserializeFrom (Buffer::Iterator start) +OlsrPacketHeader::Deserialize (Buffer::Iterator start) { Buffer::Iterator i = start; m_packetLength = i.ReadNtohU16 (); @@ -134,6 +142,14 @@ OlsrMessageHeader::OlsrMessageHeader () OlsrMessageHeader::~OlsrMessageHeader () {} +uint32_t +OlsrMessageHeader::GetUid (void) +{ + static uint32_t uid = AllocateUid + ("OlsrMessageHeader.nsnam.org"); + return uid; +} + uint32_t OlsrMessageHeader::GetSerializedSize (void) const { @@ -141,13 +157,13 @@ OlsrMessageHeader::GetSerializedSize (void) const } void -OlsrMessageHeader::PrintTo (std::ostream &os) const +OlsrMessageHeader::Print (std::ostream &os) const { // TODO } void -OlsrMessageHeader::SerializeTo (Buffer::Iterator start) const +OlsrMessageHeader::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; i.WriteU8 (m_messageType); @@ -160,7 +176,7 @@ OlsrMessageHeader::SerializeTo (Buffer::Iterator start) const } uint32_t -OlsrMessageHeader::DeserializeFrom (Buffer::Iterator start) +OlsrMessageHeader::Deserialize (Buffer::Iterator start) { Buffer::Iterator i = start; m_messageType = (MessageType) i.ReadU8 (); @@ -183,6 +199,14 @@ OlsrMidMessageHeader::OlsrMidMessageHeader () OlsrMidMessageHeader::~OlsrMidMessageHeader () {} +uint32_t +OlsrMidMessageHeader::GetUid (void) +{ + static uint32_t uid = AllocateUid + ("OlsrMidMessageHeader.nsnam.org"); + return uid; +} + uint32_t OlsrMidMessageHeader::GetSerializedSize (void) const { @@ -190,13 +214,13 @@ OlsrMidMessageHeader::GetSerializedSize (void) const } void -OlsrMidMessageHeader::PrintTo (std::ostream &os) const +OlsrMidMessageHeader::Print (std::ostream &os) const { // TODO } void -OlsrMidMessageHeader::SerializeTo (Buffer::Iterator start) const +OlsrMidMessageHeader::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; @@ -208,7 +232,7 @@ OlsrMidMessageHeader::SerializeTo (Buffer::Iterator start) const } uint32_t -OlsrMidMessageHeader::DeserializeFrom (Buffer::Iterator start) +OlsrMidMessageHeader::Deserialize (Buffer::Iterator start) { Buffer::Iterator i = start; @@ -234,6 +258,14 @@ OlsrHelloMessageHeader::OlsrHelloMessageHeader () OlsrHelloMessageHeader::~OlsrHelloMessageHeader () {} +uint32_t +OlsrHelloMessageHeader::GetUid (void) +{ + static uint32_t uid = AllocateUid + ("OlsrHelloMessageHeader.nsnam.org"); + return uid; +} + uint32_t OlsrHelloMessageHeader::GetSerializedSize (void) const { @@ -249,13 +281,13 @@ OlsrHelloMessageHeader::GetSerializedSize (void) const } void -OlsrHelloMessageHeader::PrintTo (std::ostream &os) const +OlsrHelloMessageHeader::Print (std::ostream &os) const { // TODO } void -OlsrHelloMessageHeader::SerializeTo (Buffer::Iterator start) const +OlsrHelloMessageHeader::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; @@ -286,7 +318,7 @@ OlsrHelloMessageHeader::SerializeTo (Buffer::Iterator start) const } uint32_t -OlsrHelloMessageHeader::DeserializeFrom (Buffer::Iterator start) +OlsrHelloMessageHeader::Deserialize (Buffer::Iterator start) { Buffer::Iterator i = start; @@ -331,6 +363,14 @@ OlsrTcMessageHeader::OlsrTcMessageHeader () OlsrTcMessageHeader::~OlsrTcMessageHeader () {} +uint32_t +OlsrTcMessageHeader::GetUid (void) +{ + static uint32_t uid = AllocateUid + ("OlsrTcMessageHeader.nsnam.org"); + return uid; +} + uint32_t OlsrTcMessageHeader::GetSerializedSize (void) const { @@ -338,13 +378,13 @@ OlsrTcMessageHeader::GetSerializedSize (void) const } void -OlsrTcMessageHeader::PrintTo (std::ostream &os) const +OlsrTcMessageHeader::Print (std::ostream &os) const { // TODO } void -OlsrTcMessageHeader::SerializeTo (Buffer::Iterator start) const +OlsrTcMessageHeader::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; @@ -359,7 +399,7 @@ OlsrTcMessageHeader::SerializeTo (Buffer::Iterator start) const } uint32_t -OlsrTcMessageHeader::DeserializeFrom (Buffer::Iterator start) +OlsrTcMessageHeader::Deserialize (Buffer::Iterator start) { Buffer::Iterator i = start; @@ -387,6 +427,14 @@ OlsrHnaMessageHeader::OlsrHnaMessageHeader () OlsrHnaMessageHeader::~OlsrHnaMessageHeader () {} +uint32_t +OlsrHnaMessageHeader::GetUid (void) +{ + static uint32_t uid = AllocateUid + ("OlsrHnaMessageHeader.nsnam.org"); + return uid; +} + uint32_t OlsrHnaMessageHeader::GetSerializedSize (void) const { @@ -394,13 +442,13 @@ OlsrHnaMessageHeader::GetSerializedSize (void) const } void -OlsrHnaMessageHeader::PrintTo (std::ostream &os) const +OlsrHnaMessageHeader::Print (std::ostream &os) const { // TODO } void -OlsrHnaMessageHeader::SerializeTo (Buffer::Iterator start) const +OlsrHnaMessageHeader::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; @@ -412,7 +460,7 @@ OlsrHnaMessageHeader::SerializeTo (Buffer::Iterator start) const } uint32_t -OlsrHnaMessageHeader::DeserializeFrom (Buffer::Iterator start) +OlsrHnaMessageHeader::Deserialize (Buffer::Iterator start) { Buffer::Iterator i = start; @@ -481,7 +529,7 @@ OlsrHeaderTest::RunTests (void) mid1.SetInterfaceAddresses (addresses); } - msg1.SetMessageSize (mid1.GetSize () + msg1.GetSize ()); + msg1.SetMessageSize (mid1.GetSerializedSize () + msg1.GetSerializedSize ()); msg1.SetTimeToLive (255); msg1.SetOriginatorAddress (Ipv4Address ("11.22.33.44")); msg1.SetVTime (Seconds (9)); @@ -496,7 +544,7 @@ OlsrHeaderTest::RunTests (void) mid2.SetInterfaceAddresses (addresses); } - msg2.SetMessageSize (mid2.GetSize () + msg2.GetSize ()); + msg2.SetMessageSize (mid2.GetSerializedSize () + msg2.GetSerializedSize ()); msg2.SetTimeToLive (254); msg2.SetOriginatorAddress (Ipv4Address ("12.22.33.44")); msg2.SetVTime (Seconds (10)); @@ -504,7 +552,7 @@ OlsrHeaderTest::RunTests (void) msg2.SetMessageSequenceNumber (7); // Build an OLSR packet header - hdr.SetPacketLength (hdr.GetSize () + msg1.GetMessageSize () + msg2.GetMessageSize ()); + hdr.SetPacketLength (hdr.GetSerializedSize () + msg1.GetMessageSize () + msg2.GetMessageSize ()); hdr.SetPacketSequenceNumber (123); @@ -520,7 +568,7 @@ OlsrHeaderTest::RunTests (void) OlsrPacketHeader hdr; packet.RemoveHeader (hdr); NS_TEST_ASSERT_EQUAL (hdr.GetPacketSequenceNumber (), 123); - uint32_t sizeLeft = hdr.GetPacketLength () - hdr.GetSize (); + uint32_t sizeLeft = hdr.GetPacketLength () - hdr.GetSerializedSize (); { OlsrMessageHeader msg1; OlsrMidMessageHeader mid1; @@ -533,7 +581,7 @@ OlsrHeaderTest::RunTests (void) NS_TEST_ASSERT_EQUAL (msg1.GetMessageType (), OlsrMessageHeader::MID_MESSAGE); NS_TEST_ASSERT_EQUAL (msg1.GetMessageSequenceNumber (), 7); - mid1.SetMessageSize (msg1.GetMessageSize () - msg1.GetSize ()); + mid1.SetMessageSize (msg1.GetMessageSize () - msg1.GetSerializedSize ()); packet.RemoveHeader (mid1); NS_TEST_ASSERT_EQUAL (mid1.GetInterfaceAddresses ().size (), 2); NS_TEST_ASSERT_EQUAL (*mid1.GetInterfaceAddresses ().begin (), Ipv4Address ("1.2.3.4")); @@ -554,7 +602,7 @@ OlsrHeaderTest::RunTests (void) NS_TEST_ASSERT_EQUAL (msg2.GetMessageType (), OlsrMessageHeader::MID_MESSAGE); NS_TEST_ASSERT_EQUAL (msg2.GetMessageSequenceNumber (), 7); - mid2.SetMessageSize (msg2.GetMessageSize () - msg2.GetSize ()); + mid2.SetMessageSize (msg2.GetMessageSize () - msg2.GetSerializedSize ()); packet.RemoveHeader (mid2); NS_TEST_ASSERT_EQUAL (mid2.GetInterfaceAddresses ().size (), 2); NS_TEST_ASSERT_EQUAL (*mid2.GetInterfaceAddresses ().begin (), Ipv4Address ("2.2.3.4")); diff --git a/src/routing/olsr/olsr-header.h b/src/routing/olsr/olsr-header.h index f55c266b2..b52840564 100644 --- a/src/routing/olsr/olsr-header.h +++ b/src/routing/olsr/olsr-header.h @@ -94,12 +94,14 @@ public: private: uint16_t m_packetLength; uint16_t m_packetSequenceNumber; - - virtual void PrintTo (std::ostream &os) const; + +public: + static uint32_t GetUid (void); + virtual void Print (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; - virtual void SerializeTo (Buffer::Iterator start) const; - virtual uint32_t DeserializeFrom (Buffer::Iterator start); - virtual std::string DoGetName (void) const { return "OlsrPacket"; } + virtual void Serialize (Buffer::Iterator start) const; + virtual uint32_t Deserialize (Buffer::Iterator start); + virtual std::string GetName (void) const { return "OlsrPacket"; } }; @@ -198,11 +200,13 @@ private: uint16_t m_messageSequenceNumber; uint16_t m_messageSize; - virtual void PrintTo (std::ostream &os) const; +public: + static uint32_t GetUid (void); + virtual void Print (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; - virtual void SerializeTo (Buffer::Iterator start) const; - virtual uint32_t DeserializeFrom (Buffer::Iterator start); - virtual std::string DoGetName (void) const { return "OlsrMessage"; } + virtual void Serialize (Buffer::Iterator start) const; + virtual uint32_t Deserialize (Buffer::Iterator start); + virtual std::string GetName (void) const { return "OlsrMessage"; } }; // 5.1. MID Message Format @@ -246,11 +250,13 @@ private: std::vector m_interfaceAddresses; uint32_t m_messageSize; // has to be manually set before deserialization - virtual void PrintTo (std::ostream &os) const; +public: + static uint32_t GetUid (void); + virtual void Print (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; - virtual void SerializeTo (Buffer::Iterator start) const; - virtual uint32_t DeserializeFrom (Buffer::Iterator start); - virtual std::string DoGetName (void) const { return "OlsrMidMessage"; } + virtual void Serialize (Buffer::Iterator start) const; + virtual uint32_t Deserialize (Buffer::Iterator start); + virtual std::string GetName (void) const { return "OlsrMidMessage"; } }; // 6.1. HELLO Message Format @@ -333,11 +339,13 @@ private: uint32_t m_messageSize; // has to be manually set before deserialization std::vector m_linkMessages; - virtual void PrintTo (std::ostream &os) const; +public: + static uint32_t GetUid (void); + virtual void Print (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; - virtual void SerializeTo (Buffer::Iterator start) const; - virtual uint32_t DeserializeFrom (Buffer::Iterator start); - virtual std::string DoGetName (void) const { return "OlsrHelloMessage"; } + virtual void Serialize (Buffer::Iterator start) const; + virtual uint32_t Deserialize (Buffer::Iterator start); + virtual std::string GetName (void) const { return "OlsrHelloMessage"; } }; // 9.1. TC Message Format @@ -394,11 +402,13 @@ private: uint32_t m_messageSize; // has to be manually set before deserialization - virtual void PrintTo (std::ostream &os) const; +public: + static uint32_t GetUid (void); + virtual void Print (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; - virtual void SerializeTo (Buffer::Iterator start) const; - virtual uint32_t DeserializeFrom (Buffer::Iterator start); - virtual std::string DoGetName (void) const { return "OlsrTcMessage"; } + virtual void Serialize (Buffer::Iterator start) const; + virtual uint32_t Deserialize (Buffer::Iterator start); + virtual std::string GetName (void) const { return "OlsrTcMessage"; } }; @@ -456,11 +466,13 @@ private: std::vector m_associations; uint32_t m_messageSize; // has to be manually set before deserialization - virtual void PrintTo (std::ostream &os) const; +public: + static uint32_t GetUid (void); + virtual void Print (std::ostream &os) const; virtual uint32_t GetSerializedSize (void) const; - virtual void SerializeTo (Buffer::Iterator start) const; - virtual uint32_t DeserializeFrom (Buffer::Iterator start); - virtual std::string DoGetName (void) const { return "OlsrHnaMessage"; } + virtual void Serialize (Buffer::Iterator start) const; + virtual uint32_t Deserialize (Buffer::Iterator start); + virtual std::string GetName (void) const { return "OlsrHnaMessage"; } }; From a08faa038fc6599cf930921ce057203124e14b83 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 6 Sep 2007 15:18:14 +0100 Subject: [PATCH 27/61] Stop OLSR simulation after 10 seconds (since OLSR never stops generating events) --- examples/simple-point-to-point-olsr.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/simple-point-to-point-olsr.cc b/examples/simple-point-to-point-olsr.cc index 3f89a0331..dc003718d 100644 --- a/examples/simple-point-to-point-olsr.cc +++ b/examples/simple-point-to-point-olsr.cc @@ -183,6 +183,8 @@ int main (int argc, char *argv[]) PcapTrace pcaptrace ("simple-point-to-point-olsr.pcap"); pcaptrace.TraceAllIp (); + Simulator::StopAt (Seconds (10)); + Simulator::Run (); Simulator::Destroy (); From d09deab2f1fc6857acb05b21e70f02dd5636497a Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 12 Sep 2007 18:28:18 +0100 Subject: [PATCH 28/61] Adapt OLSR to routing API changes --- examples/simple-point-to-point-olsr.cc | 1 - src/routing/olsr/routing-table.cc | 21 ++++++++++++++++++++- src/routing/olsr/routing-table.h | 6 +++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/examples/simple-point-to-point-olsr.cc b/examples/simple-point-to-point-olsr.cc index db4ca96c5..7f1d14441 100644 --- a/examples/simple-point-to-point-olsr.cc +++ b/examples/simple-point-to-point-olsr.cc @@ -184,7 +184,6 @@ int main (int argc, char *argv[]) // Start the sink sink->Start (Seconds (1.1)); sink->Stop (Seconds (10.0)); - sink->SetQuiet (); // disable output from the Receive callback // Here, finish off packet routing configuration // This will likely set by some global StaticRouting object in the future diff --git a/src/routing/olsr/routing-table.cc b/src/routing/olsr/routing-table.cc index aa41f49fd..2ed82c3ab 100644 --- a/src/routing/olsr/routing-table.cc +++ b/src/routing/olsr/routing-table.cc @@ -106,7 +106,8 @@ RoutingTable::FindSendEntry (RoutingTableEntry const &entry, bool -RoutingTable::RequestRoute (const Ipv4Header &ipHeader, +RoutingTable::RequestRoute (uint32_t ifIndex, + const Ipv4Header &ipHeader, Packet packet, RouteReplyCallback routeReply) { @@ -135,6 +136,24 @@ RoutingTable::RequestRoute (const Ipv4Header &ipHeader, } } +bool +RoutingTable::RequestIfIndex (Ipv4Address destination, + uint32_t& ifIndex) +{ + RoutingTableEntry entry1, entry2; + if (Lookup (destination, entry1)) + { + bool foundSendEntry = FindSendEntry (entry1, entry2); + NS_ASSERT (foundSendEntry); + ifIndex = entry2.interface; + return true; + } + else + { + return false; + } +} + /// /// \brief Adds a new entry into the routing table. diff --git a/src/routing/olsr/routing-table.h b/src/routing/olsr/routing-table.h index aebed6316..f8b397f07 100644 --- a/src/routing/olsr/routing-table.h +++ b/src/routing/olsr/routing-table.h @@ -100,9 +100,13 @@ public: RoutingTableEntry &outEntry) const; // From Ipv4RoutingProtocol - virtual bool RequestRoute (const Ipv4Header &ipHeader, + virtual bool RequestRoute (uint32_t ifIndex, + const Ipv4Header &ipHeader, Packet packet, RouteReplyCallback routeReply); + virtual bool RequestIfIndex (Ipv4Address destination, + uint32_t& ifIndex); + }; }}; // namespace ns3, olsr From 1f6d0347ccdd8f28bbd9cf2b653e2f2da1cb8ffe Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 21 Sep 2007 14:28:05 +0100 Subject: [PATCH 29/61] Update OLSR example. --- examples/simple-point-to-point-olsr.cc | 78 ++++++++++++++++---------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/examples/simple-point-to-point-olsr.cc b/examples/simple-point-to-point-olsr.cc index 7f1d14441..d13addbf8 100644 --- a/examples/simple-point-to-point-olsr.cc +++ b/examples/simple-point-to-point-olsr.cc @@ -38,11 +38,7 @@ // - Tracing of queues and packet receptions to file // "simple-point-to-point.tr" -#include -#include -#include -#include - +#include "ns3/log.h" #include "ns3/command-line.h" #include "ns3/default-value.h" #include "ns3/ptr.h" @@ -65,24 +61,41 @@ #include "ns3/point-to-point-topology.h" #include "ns3/onoff-application.h" #include "ns3/packet-sink.h" - #include "ns3/olsr.h" using namespace ns3; -int main (int argc, char *argv[]) -{ +NS_LOG_COMPONENT_DEFINE ("SimplePointToPointExample"); +int +main (int argc, char *argv[]) +{ // Users may find it convenient to turn on explicit debugging // for selected modules; the below lines suggest how to do this - // remember to add #include "ns3/debug.h" before enabling these #if 0 - DebugComponentEnable("Object"); - DebugComponentEnable("Queue"); - DebugComponentEnable("DropTailQueue"); - DebugComponentEnable("Channel"); - DebugComponentEnable("PointToPointChannel"); - DebugComponentEnable("PointToPointNetDevice"); + LogComponentEnable ("SimplePointToPointExample", LOG_LEVEL_INFO); + + LogComponentEnable("Object", LOG_LEVEL_ALL); + LogComponentEnable("Queue", LOG_LEVEL_ALL); + LogComponentEnable("DropTailQueue", LOG_LEVEL_ALL); + LogComponentEnable("Channel", LOG_LEVEL_ALL); + LogComponentEnable("CsmaChannel", LOG_LEVEL_ALL); + LogComponentEnable("NetDevice", LOG_LEVEL_ALL); + LogComponentEnable("CsmaNetDevice", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL); + LogComponentEnable("PacketSocket", LOG_LEVEL_ALL); + LogComponentEnable("Socket", LOG_LEVEL_ALL); + LogComponentEnable("UdpSocket", LOG_LEVEL_ALL); + LogComponentEnable("UdpL4Protocol", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4StaticRouting", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4Interface", LOG_LEVEL_ALL); + LogComponentEnable("ArpIpv4Interface", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4LoopbackInterface", LOG_LEVEL_ALL); + LogComponentEnable("OnOffApplication", LOG_LEVEL_ALL); + LogComponentEnable("PacketSinkApplication", LOG_LEVEL_ALL); + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_ALL); + LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_ALL); #endif // Set up some default values for the simulation. Use the Bind() @@ -104,12 +117,14 @@ int main (int argc, char *argv[]) // Here, we will explicitly create four nodes. In more sophisticated // topologies, we could configure a node factory. + NS_LOG_INFO ("Create nodes."); Ptr n0 = Create (); Ptr n1 = Create (); Ptr n2 = Create (); Ptr n3 = Create (); // We create the channels first without any IP addressing information + NS_LOG_INFO ("Create channels."); Ptr channel0 = PointToPointTopology::AddPointToPointLink ( n0, n2, DataRate(5000000), MilliSeconds(2)); @@ -123,6 +138,7 @@ int main (int argc, char *argv[]) n2, n3, DataRate(1500000), MilliSeconds(10)); // Later, we add IP addresses. + NS_LOG_INFO ("Assign IP Addresses."); PointToPointTopology::AddIpv4Addresses ( channel0, n0, Ipv4Address("10.1.1.1"), n2, Ipv4Address("10.1.1.2")); @@ -139,16 +155,16 @@ int main (int argc, char *argv[]) // NetDevice creation, IP Address assignment, and routing) are // separated because there may be a need to postpone IP Address // assignment (emulation) or modify to use dynamic routing - PointToPointTopology::AddIpv4Routes(n0, n2, channel0); - PointToPointTopology::AddIpv4Routes(n1, n2, channel1); - PointToPointTopology::AddIpv4Routes(n2, n3, channel2); - + NS_LOG_INFO ("Enabling OLSR Routing."); + olsr::EnableAllNodes (); // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s + NS_LOG_INFO ("Create Applications."); + uint16_t port = 9; // Discard port (RFC 863) Ptr ooff = Create ( n0, - InetSocketAddress ("10.1.3.2", 80), + InetSocketAddress ("10.1.3.2", port), "Udp", ConstantVariable(1), ConstantVariable(0)); @@ -159,7 +175,7 @@ int main (int argc, char *argv[]) // Create an optional packet sink to receive these packets Ptr sink = Create ( n3, - InetSocketAddress (Ipv4Address::GetAny (), 80), + InetSocketAddress (Ipv4Address::GetAny (), port), "Udp"); // Start the sink sink->Start (Seconds (1.0)); @@ -168,7 +184,7 @@ int main (int argc, char *argv[]) // Create a similar flow from n3 to n1, starting at time 1.1 seconds ooff = Create ( n3, - InetSocketAddress ("10.1.2.1", 80), + InetSocketAddress ("10.1.2.1", port), "Udp", ConstantVariable(1), ConstantVariable(0)); @@ -179,7 +195,7 @@ int main (int argc, char *argv[]) // Create a packet sink to receive these packets sink = Create ( n1, - InetSocketAddress (Ipv4Address::GetAny (), 80), + InetSocketAddress (Ipv4Address::GetAny (), port), "Udp"); // Start the sink sink->Start (Seconds (1.1)); @@ -187,6 +203,7 @@ int main (int argc, char *argv[]) // Here, finish off packet routing configuration // This will likely set by some global StaticRouting object in the future + NS_LOG_INFO ("Set Default Routes."); Ptr ipv4; ipv4 = n0->QueryInterface (Ipv4::iid); ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1); @@ -195,9 +212,12 @@ int main (int argc, char *argv[]) // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the simple-point-to-point.tr file -// AsciiTrace asciitrace ("simple-point-to-point.tr"); -// asciitrace.TraceAllQueues (); -// asciitrace.TraceAllNetDeviceRx (); +#if 0 // causes: assert failed. file=../src/common/packet-metadata.cc, line=1043, cond="GetTotalSize () == data.GetSize ()" + NS_LOG_INFO ("Configure Tracing."); + AsciiTrace asciitrace ("simple-point-to-point-olsr.tr"); + asciitrace.TraceAllQueues (); + asciitrace.TraceAllNetDeviceRx (); +#endif // Also configure some tcpdump traces; each interface will be traced // The output files will be named @@ -207,9 +227,9 @@ int main (int argc, char *argv[]) PcapTrace pcaptrace ("simple-point-to-point-olsr.pcap"); pcaptrace.TraceAllIp (); + NS_LOG_INFO ("Run Simulation."); Simulator::StopAt (Seconds (10)); - - Simulator::Run (); - + Simulator::Run (); Simulator::Destroy (); + NS_LOG_INFO ("Done."); } From eecce3f414f5d74e60e4d2b976f3d699d3330989 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 24 Sep 2007 11:39:31 +0100 Subject: [PATCH 30/61] Move EventCollector and SingleEvent classes, making them private to the OLSR code. --- src/{simulator => routing/olsr}/event-collector.cc | 0 src/{simulator => routing/olsr}/event-collector.h | 4 ++-- src/routing/olsr/olsr-agent-impl.h | 4 ++-- src/{simulator => routing/olsr}/single-event.cc | 0 src/{simulator => routing/olsr}/single-event.h | 4 ++-- src/routing/olsr/wscript | 7 +++++++ src/simulator/wscript | 4 ---- 7 files changed, 13 insertions(+), 10 deletions(-) rename src/{simulator => routing/olsr}/event-collector.cc (100%) rename src/{simulator => routing/olsr}/event-collector.h (96%) rename src/{simulator => routing/olsr}/single-event.cc (100%) rename src/{simulator => routing/olsr}/single-event.h (97%) diff --git a/src/simulator/event-collector.cc b/src/routing/olsr/event-collector.cc similarity index 100% rename from src/simulator/event-collector.cc rename to src/routing/olsr/event-collector.cc diff --git a/src/simulator/event-collector.h b/src/routing/olsr/event-collector.h similarity index 96% rename from src/simulator/event-collector.h rename to src/routing/olsr/event-collector.h index d0e48460d..c29809402 100644 --- a/src/simulator/event-collector.h +++ b/src/routing/olsr/event-collector.h @@ -22,8 +22,8 @@ #define EVENT_COLLECTOR_H #include -#include "event-id.h" -#include "simulator.h" +#include "ns3/event-id.h" +#include "ns3/simulator.h" namespace ns3 { diff --git a/src/routing/olsr/olsr-agent-impl.h b/src/routing/olsr/olsr-agent-impl.h index 7758664d1..32b1ef347 100644 --- a/src/routing/olsr/olsr-agent-impl.h +++ b/src/routing/olsr/olsr-agent-impl.h @@ -39,8 +39,8 @@ #include "ns3/packet.h" #include "ns3/node.h" #include "ns3/socket.h" -#include "ns3/single-event.h" -#include "ns3/event-collector.h" +#include "single-event.h" +#include "event-collector.h" namespace ns3 { diff --git a/src/simulator/single-event.cc b/src/routing/olsr/single-event.cc similarity index 100% rename from src/simulator/single-event.cc rename to src/routing/olsr/single-event.cc diff --git a/src/simulator/single-event.h b/src/routing/olsr/single-event.h similarity index 97% rename from src/simulator/single-event.h rename to src/routing/olsr/single-event.h index ddb8a164c..cb7ab4be5 100644 --- a/src/simulator/single-event.h +++ b/src/routing/olsr/single-event.h @@ -22,8 +22,8 @@ #define SINGLE_EVENT_H #include -#include "event-id.h" -#include "simulator.h" +#include "ns3/event-id.h" +#include "ns3/simulator.h" namespace ns3 { diff --git a/src/routing/olsr/wscript b/src/routing/olsr/wscript index bc6268f8b..84718ec6b 100644 --- a/src/routing/olsr/wscript +++ b/src/routing/olsr/wscript @@ -17,3 +17,10 @@ def build(bld): 'olsr-agent.h', 'olsr.h', ] + + + ## globally useful classes, temporarily private... + module.source.extend([ + 'event-collector.cc', + 'single-event.cc', + ]) diff --git a/src/simulator/wscript b/src/simulator/wscript index 01124f5ea..970a43aea 100644 --- a/src/simulator/wscript +++ b/src/simulator/wscript @@ -52,8 +52,6 @@ def build(bld): 'high-precision.cc', 'time.cc', 'event-id.cc', - 'event-collector.cc', - 'single-event.cc', 'scheduler.cc', 'scheduler-factory.cc', 'scheduler-list.cc', @@ -69,8 +67,6 @@ def build(bld): 'high-precision.h', 'nstime.h', 'event-id.h', - 'event-collector.h', - 'single-event.h', 'event-impl.h', 'simulator.h', 'scheduler.h', From 7d23d0c5b02ff038095784d45937335e2aa9b2e2 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Tue, 25 Sep 2007 16:26:02 +0100 Subject: [PATCH 31/61] Cleanup copyright headers and some unused includes. --- src/routing/olsr/olsr-agent-impl.cc | 51 +++++++++++++---------------- src/routing/olsr/olsr-agent-impl.h | 43 ++++++++++++------------ src/routing/olsr/olsr-state.cc | 43 ++++++++++++------------ src/routing/olsr/olsr-state.h | 43 ++++++++++++------------ src/routing/olsr/repositories.h | 43 ++++++++++++------------ src/routing/olsr/routing-table.cc | 43 ++++++++++++------------ src/routing/olsr/routing-table.h | 43 ++++++++++++------------ 7 files changed, 148 insertions(+), 161 deletions(-) diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index 14667f686..b66f1f7cf 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -1,26 +1,26 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/*************************************************************************** - * Copyright (C) 2004 by Francisco J. Ros * - * fjrm@dif.um.es * - * * - * Modified on 2007 for NS-3 by Gustavo J. A. M. Carneiro, INESC Porto * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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. * - ***************************************************************************/ +/* + * Copyright (c) 2004 Francisco J. Ros + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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: Francisco J. Ros + * Gustavo J. A. M. Carneiro + */ + /// /// \file OLSR.cc @@ -30,12 +30,6 @@ /// implemented here. /// -#include -// #include -// #include -// #include -// #include -#include #include "olsr-agent-impl.h" #include "ns3/socket-factory.h" #include "ns3/udp.h" @@ -45,7 +39,6 @@ #include "ns3/random-variable.h" #include "ns3/inet-socket-address.h" -#include /********** Useful macros **********/ diff --git a/src/routing/olsr/olsr-agent-impl.h b/src/routing/olsr/olsr-agent-impl.h index 32b1ef347..9da10bb7b 100644 --- a/src/routing/olsr/olsr-agent-impl.h +++ b/src/routing/olsr/olsr-agent-impl.h @@ -1,26 +1,25 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/*************************************************************************** - * Copyright (C) 2004 by Francisco J. Ros * - * fjrm@dif.um.es * - * * - * Modified on 2007 for NS-3 by Gustavo J. A. M. Carneiro, INESC Porto * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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. * - ***************************************************************************/ +/* + * Copyright (c) 2004 Francisco J. Ros + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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: Francisco J. Ros + * Gustavo J. A. M. Carneiro + */ #ifndef __OLSR_AGENT_IMPL_H__ diff --git a/src/routing/olsr/olsr-state.cc b/src/routing/olsr/olsr-state.cc index 828aac467..c994d8116 100644 --- a/src/routing/olsr/olsr-state.cc +++ b/src/routing/olsr/olsr-state.cc @@ -1,26 +1,25 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/*************************************************************************** - * Copyright (C) 2004 by Francisco J. Ros * - * fjrm@dif.um.es * - * * - * Modified for NS-3 by Gustavo J. A. M. Carneiro on 2007 * - * gjc@inescporto.pt * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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. * - ***************************************************************************/ +/* + * Copyright (c) 2004 Francisco J. Ros + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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: Francisco J. Ros + * Gustavo J. A. M. Carneiro + */ /// /// \file OlsrState.cc diff --git a/src/routing/olsr/olsr-state.h b/src/routing/olsr/olsr-state.h index 01c7116a7..dbaf973d2 100644 --- a/src/routing/olsr/olsr-state.h +++ b/src/routing/olsr/olsr-state.h @@ -1,26 +1,25 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/*************************************************************************** - * Copyright (C) 2004 by Francisco J. Ros * - * fjrm@dif.um.es * - * * - * Modified for NS-3 by Gustavo J. A. M. Carneiro on 2007 * - * gjc@inescporto.pt * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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. * - ***************************************************************************/ +/* + * Copyright (c) 2004 Francisco J. Ros + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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: Francisco J. Ros + * Gustavo J. A. M. Carneiro + */ /// \brief This header file declares and defines internal state of an OLSR node. diff --git a/src/routing/olsr/repositories.h b/src/routing/olsr/repositories.h index d2362ccbb..ec5213d86 100644 --- a/src/routing/olsr/repositories.h +++ b/src/routing/olsr/repositories.h @@ -1,26 +1,25 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/*************************************************************************** - * Copyright (C) 2004 by Francisco J. Ros * - * fjrm@dif.um.es * - * * - * Modified on 2007 for NS-3 by Gustavo J. A. M. Carneiro, INESC Porto * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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. * - ***************************************************************************/ +/* + * Copyright (c) 2004 Francisco J. Ros + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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: Francisco J. Ros + * Gustavo J. A. M. Carneiro + */ /// /// \file OLSR_repositories.h diff --git a/src/routing/olsr/routing-table.cc b/src/routing/olsr/routing-table.cc index 2ed82c3ab..6e688468c 100644 --- a/src/routing/olsr/routing-table.cc +++ b/src/routing/olsr/routing-table.cc @@ -1,26 +1,25 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/*************************************************************************** - * Copyright (C) 2004 by Francisco J. Ros * - * fjrm@dif.um.es * - * * - * Modified on 2007 for NS-3 by Gustavo J. A. M. Carneiro, INESC Porto * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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. * - ***************************************************************************/ +/* + * Copyright (c) 2004 Francisco J. Ros + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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: Francisco J. Ros + * Gustavo J. A. M. Carneiro + */ /// /// \file OLSR_rtable.cc diff --git a/src/routing/olsr/routing-table.h b/src/routing/olsr/routing-table.h index f8b397f07..86d98b4c6 100644 --- a/src/routing/olsr/routing-table.h +++ b/src/routing/olsr/routing-table.h @@ -1,26 +1,25 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/*************************************************************************** - * Copyright (C) 2004 by Francisco J. Ros * - * fjrm@dif.um.es * - * * - * Modified on 2007 for NS-3 by Gustavo J. A. M. Carneiro, INESC Porto * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * 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. * - ***************************************************************************/ +/* + * Copyright (c) 2004 Francisco J. Ros + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * 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: Francisco J. Ros + * Gustavo J. A. M. Carneiro + */ /// /// \file OLSR_rtable.h From 299015ae5dd8b9c923b29b6308c49df2d9f058b9 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 26 Sep 2007 18:09:19 +0100 Subject: [PATCH 32/61] Add a couple of NS_LOG_PARAM calls for debugging. --- src/common/packet-metadata.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 04adfdc18..fe4ad4fe0 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -697,6 +697,8 @@ PacketMetadata::DoAddHeader (uint32_t uid, uint32_t size) m_metadataSkipped = true; return; } + NS_LOG_PARAM ("(uid=" << uid << ", size=" << size << ")"); + struct PacketMetadata::SmallItem item; item.next = m_head; item.prev = 0xffff; @@ -715,6 +717,7 @@ PacketMetadata::DoRemoveHeader (uint32_t uid, uint32_t size) m_metadataSkipped = true; return; } + NS_LOG_PARAM ("(uid=" << uid << ", size=" << size << ")"); struct PacketMetadata::SmallItem item; struct PacketMetadata::ExtraItem extraItem; uint32_t read = ReadItems (m_head, &item, &extraItem); From 166563d343436e0ed852ae439eabee66ff20b1ba Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 26 Sep 2007 18:27:52 +0100 Subject: [PATCH 33/61] Make the OLSR headers usable from the AciiTracing point of view --- src/routing/olsr/olsr-agent-impl.cc | 152 ++++----- src/routing/olsr/olsr-agent-impl.h | 16 +- src/routing/olsr/olsr-header.cc | 383 +++++++++++----------- src/routing/olsr/olsr-header.h | 475 +++++++++++++--------------- 4 files changed, 463 insertions(+), 563 deletions(-) diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index b66f1f7cf..df3911f50 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -262,11 +262,10 @@ OlsrAgentImpl::RecvOlsr (Ptr socket, while (sizeLeft) { OlsrMessageHeader messageHeader; - NS_ASSERT (sizeLeft >= messageHeader.GetSerializedSize ()); if (packet.RemoveHeader (messageHeader) == 0) NS_ASSERT (false); - sizeLeft -= messageHeader.GetMessageSize (); + sizeLeft -= messageHeader.GetSerializedSize (); NS_DEBUG ("Olsr Msg received with type " << std::dec << int (messageHeader.GetMessageType ()) @@ -279,15 +278,11 @@ OlsrAgentImpl::RecvOlsr (Ptr socket, if (messageHeader.GetTimeToLive () == 0 || messageHeader.GetOriginatorAddress () == m_mainAddress) { - packet.RemoveAtStart (messageHeader.GetMessageSize () + packet.RemoveAtStart (messageHeader.GetSerializedSize () - messageHeader.GetSerializedSize ()); continue; } - // Save the original message payload for forwarding - Packet messagePayload = packet.CreateFragment - (0, messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); - // If the message has been processed it must not be processed again bool do_forwarding = true; DuplicateTuple *duplicated = m_state.FindDuplicateTuple @@ -296,35 +291,24 @@ OlsrAgentImpl::RecvOlsr (Ptr socket, if (duplicated == NULL) { - OlsrHelloMessageHeader helloMsg; - OlsrTcMessageHeader tcMsg; - OlsrMidMessageHeader midMsg; - switch (messageHeader.GetMessageType ()) { case OlsrMessageHeader::HELLO_MESSAGE: - helloMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); - packet.RemoveHeader (helloMsg); - NS_DEBUG ("OLSR node received HELLO message of size " << messageHeader.GetMessageSize ()); - ProcessHello (messageHeader, helloMsg, m_mainAddress, inetSourceAddr.GetIpv4 ()); + NS_DEBUG ("OLSR node received HELLO message of size " << messageHeader.GetSerializedSize ()); + ProcessHello (messageHeader, m_mainAddress, inetSourceAddr.GetIpv4 ()); break; case OlsrMessageHeader::TC_MESSAGE: - tcMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); - packet.RemoveHeader (tcMsg); - NS_DEBUG ("OLSR node received TC message of size " << messageHeader.GetMessageSize ()); - ProcessTc (messageHeader, tcMsg, inetSourceAddr.GetIpv4 ()); + NS_DEBUG ("OLSR node received TC message of size " << messageHeader.GetSerializedSize ()); + ProcessTc (messageHeader, inetSourceAddr.GetIpv4 ()); break; case OlsrMessageHeader::MID_MESSAGE: - midMsg.SetMessageSize (messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); - packet.RemoveHeader (midMsg); - NS_DEBUG ("OLSR node received MID message of size " << messageHeader.GetMessageSize ()); - ProcessMid (messageHeader, midMsg, inetSourceAddr.GetIpv4 ()); + NS_DEBUG ("OLSR node received MID message of size " << messageHeader.GetSerializedSize ()); + ProcessMid (messageHeader, inetSourceAddr.GetIpv4 ()); break; default: - packet.RemoveAtStart (messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); NS_DEBUG ("OLSR message type " << int (messageHeader.GetMessageType ()) << " not implemented"); @@ -333,7 +317,6 @@ OlsrAgentImpl::RecvOlsr (Ptr socket, else { NS_DEBUG ("OLSR message is duplicated, not reading it."); - packet.RemoveAtStart (messageHeader.GetMessageSize () - messageHeader.GetSerializedSize ()); // If the message has been considered for forwarding, it should // not be retransmitted again @@ -354,7 +337,7 @@ OlsrAgentImpl::RecvOlsr (Ptr socket, // TC and MID messages are forwarded using the default algorithm. // Remaining messages are also forwarded using the default algorithm. if (messageHeader.GetMessageType () != OlsrMessageHeader::HELLO_MESSAGE) - ForwardDefault (messageHeader, messagePayload, duplicated, + ForwardDefault (messageHeader, duplicated, m_mainAddress, inetSourceAddr.GetIpv4 ()); } @@ -813,10 +796,10 @@ OlsrAgentImpl::RoutingTableComputation () /// void OlsrAgentImpl::ProcessHello (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello, const Ipv4Address &receiverIface, const Ipv4Address &senderIface) { + const OlsrMessageHeader::Hello &hello = msg.GetHello (); LinkSensing (msg, hello, receiverIface, senderIface); PopulateNeighborSet (msg, hello); PopulateTwoHopNeighborSet (msg, hello); @@ -835,9 +818,9 @@ OlsrAgentImpl::ProcessHello (const OlsrMessageHeader &msg, /// void OlsrAgentImpl::ProcessTc (const OlsrMessageHeader &msg, - const OlsrTcMessageHeader &tc, const Ipv4Address &senderIface) { + const OlsrMessageHeader::Tc &tc = msg.GetTc (); Time now = Simulator::Now (); // 1. If the sender interface of this message is not in the symmetric @@ -852,7 +835,7 @@ OlsrAgentImpl::ProcessTc (const OlsrMessageHeader &msg, // then further processing of this TC message MUST NOT be // performed. TopologyTuple *topologyTuple = - m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.GetAnsn ()); + m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.ansn); if (topologyTuple != NULL) return; @@ -860,12 +843,12 @@ OlsrAgentImpl::ProcessTc (const OlsrMessageHeader &msg, // T_last_addr == originator address AND // T_seq < ANSN // MUST be removed from the topology set. - m_state.EraseOlderTopologyTuples (msg.GetOriginatorAddress (), tc.GetAnsn ()); + m_state.EraseOlderTopologyTuples (msg.GetOriginatorAddress (), tc.ansn); // 4. For each of the advertised neighbor main address received in // the TC message: - for (std::vector::const_iterator i = tc.GetNeighborAddresses ().begin (); - i != tc.GetNeighborAddresses ().end (); i++) + for (std::vector::const_iterator i = tc.neighborAddresses.begin (); + i != tc.neighborAddresses.end (); i++) { const Ipv4Address &addr = *i; // 4.1. If there exist some tuple in the topology set where: @@ -891,7 +874,7 @@ OlsrAgentImpl::ProcessTc (const OlsrMessageHeader &msg, TopologyTuple topologyTuple;; topologyTuple.destAddr = addr; topologyTuple.lastAddr = msg.GetOriginatorAddress (); - topologyTuple.sequenceNumber = tc.GetAnsn (); + topologyTuple.sequenceNumber = tc.ansn; topologyTuple.expirationTime = now + msg.GetVTime (); AddTopologyTuple (topologyTuple); @@ -914,9 +897,9 @@ OlsrAgentImpl::ProcessTc (const OlsrMessageHeader &msg, /// void OlsrAgentImpl::ProcessMid (const OlsrMessageHeader &msg, - const OlsrMidMessageHeader &mid, const Ipv4Address &senderIface) { + const OlsrMessageHeader::Mid &mid = msg.GetMid (); Time now = Simulator::Now (); // 1. If the sender interface of this message is not in the symmetric @@ -926,9 +909,8 @@ OlsrAgentImpl::ProcessMid (const OlsrMessageHeader &msg, return; // 2. For each interface address listed in the MID message - const std::vector &addrs = mid.GetInterfaceAddresses (); - for (std::vector::const_iterator i = addrs.begin (); - i != addrs.end (); i++) + for (std::vector::const_iterator i = mid.interfaceAddresses.begin (); + i != mid.interfaceAddresses.end (); i++) { bool updated = false; IfaceAssocSet &ifaceAssoc = m_state.GetIfaceAssocSetMutable (); @@ -970,7 +952,6 @@ OlsrAgentImpl::ProcessMid (const OlsrMessageHeader &msg, /// void OlsrAgentImpl::ForwardDefault (OlsrMessageHeader olsrMessage, - Packet messagePayload, DuplicateTuple *duplicated, const Ipv4Address &localIface, const Ipv4Address &senderAddress) @@ -1009,8 +990,7 @@ OlsrAgentImpl::ForwardDefault (OlsrMessageHeader olsrMessage, olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1); // We have to introduce a random delay to avoid // synchronization with neighbors. - messagePayload.AddHeader (olsrMessage); - QueueMessage (messagePayload, JITTER); + QueueMessage (olsrMessage, JITTER); retransmitted = true; } } @@ -1048,7 +1028,7 @@ OlsrAgentImpl::ForwardDefault (OlsrMessageHeader olsrMessage, /// \param delay maximum delay the %OLSR message is going to be buffered. /// void -OlsrAgentImpl::QueueMessage (Packet message, Time delay) +OlsrAgentImpl::QueueMessage (const OlsrMessageHeader &message, Time delay) { m_queuedMessages.push_back (message); if (not m_queuedMessagesTimer.IsRunning ()) @@ -1085,11 +1065,13 @@ OlsrAgentImpl::SendQueuedMessages () NS_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages"); - for (std::vector::const_iterator messagePkt = m_queuedMessages.begin (); - messagePkt != m_queuedMessages.end (); - messagePkt++) + for (std::vector::const_iterator message = m_queuedMessages.begin (); + message != m_queuedMessages.end (); + message++) { - packet.AddAtEnd (*messagePkt); + Packet p; + p.AddHeader (*message); + packet.AddAtEnd (p); if (++numMessages == OLSR_MAX_MSGS) { SendPacket (packet); @@ -1114,20 +1096,20 @@ void OlsrAgentImpl::SendHello () { OlsrMessageHeader msg; - OlsrHelloMessageHeader hello; Time now = Simulator::Now (); - msg.SetMessageType (OlsrMessageHeader::HELLO_MESSAGE); msg.SetVTime (OLSR_NEIGHB_HOLD_TIME); msg.SetOriginatorAddress (m_mainAddress); msg.SetTimeToLive (1); msg.SetHopCount (0); msg.SetMessageSequenceNumber (GetMessageSequenceNumber ()); + OlsrMessageHeader::Hello &hello = msg.GetHello (); hello.SetHTime (m_helloInterval); - hello.SetWillingness (m_willingness); + hello.willingness = m_willingness; - std::vector linkMessages; + std::vector + &linkMessages = hello.linkMessages; for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin (); link_tuple != m_state.GetLinks ().end (); link_tuple++) @@ -1191,7 +1173,7 @@ OlsrAgentImpl::SendHello () } } - OlsrHelloMessageHeader::LinkMessage linkMessage; + OlsrMessageHeader::Hello::LinkMessage linkMessage; linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f); linkMessage.neighborInterfaceAddresses.push_back (link_tuple->neighborIfaceAddr); @@ -1205,14 +1187,9 @@ OlsrAgentImpl::SendHello () linkMessages.push_back (linkMessage); } - hello.SetLinkMessages (linkMessages); - Packet packet; - packet.AddHeader (hello); - NS_DEBUG ("OLSR HELLO message size: " << int (packet.GetSize () + msg.GetSerializedSize ()) + NS_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ()) << " (with " << int (linkMessages.size ()) << " link messages)"); - msg.SetMessageSize (packet.GetSize () + msg.GetSerializedSize ()); - packet.AddHeader (msg); - QueueMessage (packet, JITTER); + QueueMessage (msg, JITTER); } /// @@ -1222,29 +1199,21 @@ void OlsrAgentImpl::SendTc () { OlsrMessageHeader msg; - OlsrTcMessageHeader tc; - msg.SetMessageType (OlsrMessageHeader::TC_MESSAGE); msg.SetVTime (OLSR_TOP_HOLD_TIME); msg.SetOriginatorAddress (m_mainAddress); msg.SetTimeToLive (255); msg.SetHopCount (0); msg.SetMessageSequenceNumber (GetMessageSequenceNumber ()); - tc.SetAnsn (m_ansn); - std::vector neighbors; + OlsrMessageHeader::Tc &tc = msg.GetTc (); + tc.ansn = m_ansn; for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin(); mprsel_tuple != m_state.GetMprSelectors ().end(); mprsel_tuple++) { - neighbors.push_back (mprsel_tuple->mainAddr); + tc.neighborAddresses.push_back (mprsel_tuple->mainAddr); } - tc.SetNeighborAddresses (neighbors); - - Packet packet; - packet.AddHeader (tc); - msg.SetMessageSize (packet.GetSize () + msg.GetSerializedSize ()); - packet.AddHeader (msg); - QueueMessage (packet, JITTER); + QueueMessage (msg, JITTER); } /// @@ -1254,7 +1223,7 @@ void OlsrAgentImpl::SendMid () { OlsrMessageHeader msg; - OlsrMidMessageHeader mid; + OlsrMessageHeader::Mid &mid = msg.GetMid (); // A node which has only a single interface address participating in // the MANET (i.e., running OLSR), MUST NOT generate any MID @@ -1273,29 +1242,22 @@ OlsrAgentImpl::SendMid () // MANET; later we may want to make this configurable. ] Ipv4Address loopback ("127.0.0.1"); - std::vector addresses; for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++) { Ipv4Address addr = m_ipv4->GetAddress (i); if (addr != m_mainAddress && addr != loopback) - addresses.push_back (addr); + mid.interfaceAddresses.push_back (addr); } - if (addresses.size () == 0) + if (mid.interfaceAddresses.size () == 0) return; - mid.SetInterfaceAddresses (addresses); - msg.SetMessageType (OlsrMessageHeader::MID_MESSAGE); msg.SetVTime (OLSR_MID_HOLD_TIME); msg.SetOriginatorAddress (m_mainAddress); msg.SetTimeToLive (255); msg.SetHopCount (0); msg.SetMessageSequenceNumber (GetMessageSequenceNumber ()); - Packet packet; - packet.AddHeader (mid); - msg.SetMessageSize (packet.GetSize () + msg.GetSerializedSize ()); - packet.AddHeader (msg); - QueueMessage (packet, JITTER); + QueueMessage (msg, JITTER); } /// @@ -1303,7 +1265,7 @@ OlsrAgentImpl::SendMid () /// specification). Neighbor Set is also updated if needed. void OlsrAgentImpl::LinkSensing (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello, + const OlsrMessageHeader::Hello &hello, const Ipv4Address &receiverIface, const Ipv4Address &senderIface) { @@ -1321,16 +1283,16 @@ OlsrAgentImpl::LinkSensing (const OlsrMessageHeader &msg, newLinkTuple.symTime = now - Seconds (1); newLinkTuple.lostTime = Seconds (0); newLinkTuple.time = now + msg.GetVTime (); - link_tuple = &AddLinkTuple (newLinkTuple, hello.GetWillingness ()); + link_tuple = &AddLinkTuple (newLinkTuple, hello.willingness); created = true; } else updated = true; link_tuple->asymTime = now + msg.GetVTime (); - for (std::vector::const_iterator linkMessage = - hello.GetLinkMessages ().begin (); - linkMessage != hello.GetLinkMessages ().end (); + for (std::vector::const_iterator linkMessage = + hello.linkMessages.begin (); + linkMessage != hello.linkMessages.end (); linkMessage++) { int lt = linkMessage->linkCode & 0x03; // Link Type @@ -1386,11 +1348,11 @@ OlsrAgentImpl::LinkSensing (const OlsrMessageHeader &msg, /// HELLO message (following RFC 3626). void OlsrAgentImpl::PopulateNeighborSet (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello) + const OlsrMessageHeader::Hello &hello) { NeighborTuple *nb_tuple = m_state.FindNeighborTuple (msg.GetOriginatorAddress ()); if (nb_tuple != NULL) - nb_tuple->willingness = hello.GetWillingness (); + nb_tuple->willingness = hello.willingness; } @@ -1399,7 +1361,7 @@ OlsrAgentImpl::PopulateNeighborSet (const OlsrMessageHeader &msg, /// received HELLO message (following RFC 3626). void OlsrAgentImpl::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello) + const OlsrMessageHeader::Hello &hello) { Time now = Simulator::Now (); @@ -1410,10 +1372,10 @@ OlsrAgentImpl::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, { if (link_tuple->symTime >= now) { - typedef std::vector LinkMessageVec; + typedef std::vector LinkMessageVec; for (LinkMessageVec::const_iterator linkMessage = - hello.GetLinkMessages ().begin (); - linkMessage != hello.GetLinkMessages ().end (); + hello.linkMessages.begin (); + linkMessage != hello.linkMessages.end (); linkMessage++) { int nt = linkMessage->linkCode >> 2; @@ -1483,13 +1445,13 @@ OlsrAgentImpl::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, /// received HELLO message (following RFC 3626). void OlsrAgentImpl::PopulateMprSelectorSet (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello) + const OlsrMessageHeader::Hello &hello) { Time now = Simulator::Now (); - typedef std::vector LinkMessageVec; - for (LinkMessageVec::const_iterator linkMessage = hello.GetLinkMessages ().begin (); - linkMessage != hello.GetLinkMessages ().end (); + typedef std::vector LinkMessageVec; + for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin (); + linkMessage != hello.linkMessages.end (); linkMessage++) { int nt = linkMessage->linkCode >> 2; diff --git a/src/routing/olsr/olsr-agent-impl.h b/src/routing/olsr/olsr-agent-impl.h index 9da10bb7b..34b09d953 100644 --- a/src/routing/olsr/olsr-agent-impl.h +++ b/src/routing/olsr/olsr-agent-impl.h @@ -124,15 +124,14 @@ protected: void IfaceAssocTupleTimerExpire (IfaceAssocTuple tuple); /// A list of pending messages which are buffered awaiting for being sent. - std::vector m_queuedMessages; + std::vector m_queuedMessages; SingleEvent m_queuedMessagesTimer; // timer for throttling outgoing messages void ForwardDefault (OlsrMessageHeader olsrMessage, - Packet messagePayload, DuplicateTuple *duplicated, const Ipv4Address &localIface, const Ipv4Address &senderAddress); - void QueueMessage (Packet message, Time delay); + void QueueMessage (const OlsrMessageHeader &message, Time delay); void SendQueuedMessages (); void SendHello (); void SendTc (); @@ -156,26 +155,23 @@ protected: void RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple); void ProcessHello (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello, const Ipv4Address &receiverIface, const Ipv4Address &senderIface); void ProcessTc (const OlsrMessageHeader &msg, - const OlsrTcMessageHeader &tc, const Ipv4Address &senderIface); void ProcessMid (const OlsrMessageHeader &msg, - const OlsrMidMessageHeader &mid, const Ipv4Address &senderIface); void LinkSensing (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello, + const OlsrMessageHeader::Hello &hello, const Ipv4Address &receiverIface, const Ipv4Address &sender_iface); void PopulateNeighborSet (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello); + const OlsrMessageHeader::Hello &hello); void PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello); + const OlsrMessageHeader::Hello &hello); void PopulateMprSelectorSet (const OlsrMessageHeader &msg, - const OlsrHelloMessageHeader &hello); + const OlsrMessageHeader::Hello &hello); int Degree (NeighborTuple const &tuple); diff --git a/src/routing/olsr/olsr-header.cc b/src/routing/olsr/olsr-header.cc index 7d6184756..b3c641eeb 100644 --- a/src/routing/olsr/olsr-header.cc +++ b/src/routing/olsr/olsr-header.cc @@ -137,6 +137,7 @@ OlsrPacketHeader::Deserialize (Buffer::Iterator start) // ---------------- OLSR Message ------------------------------- OlsrMessageHeader::OlsrMessageHeader () + : m_messageType (OlsrMessageHeader::MessageType (0)) {} OlsrMessageHeader::~OlsrMessageHeader () @@ -150,10 +151,28 @@ OlsrMessageHeader::GetUid (void) return uid; } -uint32_t +uint32_t OlsrMessageHeader::GetSerializedSize (void) const { - return OLSR_MSG_HEADER_SIZE; + uint32_t size = OLSR_MSG_HEADER_SIZE; + switch (m_messageType) + { + case MID_MESSAGE: + size += m_message.mid.GetSerializedSize (); + break; + case HELLO_MESSAGE: + size += m_message.hello.GetSerializedSize (); + break; + case TC_MESSAGE: + size += m_message.tc.GetSerializedSize (); + break; + case HNA_MESSAGE: + size += m_message.hna.GetSerializedSize (); + break; + default: + NS_ASSERT (false); + } + return size; } void @@ -168,16 +187,36 @@ OlsrMessageHeader::Serialize (Buffer::Iterator start) const Buffer::Iterator i = start; i.WriteU8 (m_messageType); i.WriteU8 (m_vTime); - i.WriteHtonU16 (m_messageSize); + i.WriteHtonU16 (GetSerializedSize () - OLSR_MSG_HEADER_SIZE); i.WriteHtonU32 (m_originatorAddress.GetHostOrder ()); i.WriteU8 (m_timeToLive); i.WriteU8 (m_hopCount); i.WriteHtonU16 (m_messageSequenceNumber); + + switch (m_messageType) + { + case MID_MESSAGE: + m_message.mid.Serialize (i); + break; + case HELLO_MESSAGE: + m_message.hello.Serialize (i); + break; + case TC_MESSAGE: + m_message.tc.Serialize (i); + break; + case HNA_MESSAGE: + m_message.hna.Serialize (i); + break; + default: + NS_ASSERT (false); + } + } uint32_t OlsrMessageHeader::Deserialize (Buffer::Iterator start) { + uint32_t size; Buffer::Iterator i = start; m_messageType = (MessageType) i.ReadU8 (); NS_ASSERT (m_messageType >= HELLO_MESSAGE && m_messageType <= HNA_MESSAGE); @@ -187,64 +226,68 @@ OlsrMessageHeader::Deserialize (Buffer::Iterator start) m_timeToLive = i.ReadU8 (); m_hopCount = i.ReadU8 (); m_messageSequenceNumber = i.ReadNtohU16 (); - return GetSerializedSize (); + size = OLSR_MSG_HEADER_SIZE; + switch (m_messageType) + { + case MID_MESSAGE: + size += m_message.mid.Deserialize (i, m_messageSize); + break; + case HELLO_MESSAGE: + size += m_message.hello.Deserialize (i, m_messageSize); + break; + case TC_MESSAGE: + size += m_message.tc.Deserialize (i, m_messageSize); + break; + case HNA_MESSAGE: + size += m_message.hna.Deserialize (i, m_messageSize); + break; + default: + NS_ASSERT (false); + } + return size; } // ---------------- OLSR MID Message ------------------------------- -OlsrMidMessageHeader::OlsrMidMessageHeader () -{} - -OlsrMidMessageHeader::~OlsrMidMessageHeader () -{} - -uint32_t -OlsrMidMessageHeader::GetUid (void) -{ - static uint32_t uid = AllocateUid - ("OlsrMidMessageHeader.nsnam.org"); - return uid; -} - uint32_t -OlsrMidMessageHeader::GetSerializedSize (void) const +OlsrMessageHeader::Mid::GetSerializedSize (void) const { - return m_interfaceAddresses.size () * IPV4_ADDRESS_SIZE; + return this->interfaceAddresses.size () * IPV4_ADDRESS_SIZE; } void -OlsrMidMessageHeader::Print (std::ostream &os) const +OlsrMessageHeader::Mid::Print (std::ostream &os) const { // TODO } void -OlsrMidMessageHeader::Serialize (Buffer::Iterator start) const +OlsrMessageHeader::Mid::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; - for (std::vector::const_iterator iter = m_interfaceAddresses.begin (); - iter != m_interfaceAddresses.end (); iter++) + for (std::vector::const_iterator iter = this->interfaceAddresses.begin (); + iter != this->interfaceAddresses.end (); iter++) { i.WriteHtonU32 (iter->GetHostOrder ()); } } uint32_t -OlsrMidMessageHeader::Deserialize (Buffer::Iterator start) +OlsrMessageHeader::Mid::Deserialize (Buffer::Iterator start, uint32_t messageSize) { Buffer::Iterator i = start; - m_interfaceAddresses.clear (); - NS_ASSERT (m_messageSize >= 0); - NS_ASSERT (m_messageSize % IPV4_ADDRESS_SIZE == 0); + this->interfaceAddresses.clear (); + NS_ASSERT (messageSize >= 0); + NS_ASSERT (messageSize % IPV4_ADDRESS_SIZE == 0); - int numAddresses = m_messageSize / IPV4_ADDRESS_SIZE; - m_interfaceAddresses.erase (m_interfaceAddresses.begin(), - m_interfaceAddresses.end ()); + int numAddresses = messageSize / IPV4_ADDRESS_SIZE; + this->interfaceAddresses.erase (this->interfaceAddresses.begin(), + this->interfaceAddresses.end ()); for (int n = 0; n < numAddresses; ++n) - m_interfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ())); + this->interfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ())); return GetSerializedSize (); } @@ -252,26 +295,12 @@ OlsrMidMessageHeader::Deserialize (Buffer::Iterator start) // ---------------- OLSR HELLO Message ------------------------------- -OlsrHelloMessageHeader::OlsrHelloMessageHeader () -{} - -OlsrHelloMessageHeader::~OlsrHelloMessageHeader () -{} - -uint32_t -OlsrHelloMessageHeader::GetUid (void) -{ - static uint32_t uid = AllocateUid - ("OlsrHelloMessageHeader.nsnam.org"); - return uid; -} - uint32_t -OlsrHelloMessageHeader::GetSerializedSize (void) const +OlsrMessageHeader::Hello::GetSerializedSize (void) const { uint32_t size = 4; - for (std::vector::const_iterator iter = m_linkMessages.begin (); - iter != m_linkMessages.end (); iter++) + for (std::vector::const_iterator iter = this->linkMessages.begin (); + iter != this->linkMessages.end (); iter++) { const LinkMessage &lm = *iter; size += 4; @@ -281,22 +310,22 @@ OlsrHelloMessageHeader::GetSerializedSize (void) const } void -OlsrHelloMessageHeader::Print (std::ostream &os) const +OlsrMessageHeader::Hello::Print (std::ostream &os) const { // TODO } void -OlsrHelloMessageHeader::Serialize (Buffer::Iterator start) const +OlsrMessageHeader::Hello::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; i.WriteU16 (0); // Reserved - i.WriteU8 (m_hTime); - i.WriteU8 (m_willingness); + i.WriteU8 (this->hTime); + i.WriteU8 (this->willingness); - for (std::vector::const_iterator iter = m_linkMessages.begin (); - iter != m_linkMessages.end (); iter++) + for (std::vector::const_iterator iter = this->linkMessages.begin (); + iter != this->linkMessages.end (); iter++) { const LinkMessage &lm = *iter; @@ -318,19 +347,19 @@ OlsrHelloMessageHeader::Serialize (Buffer::Iterator start) const } uint32_t -OlsrHelloMessageHeader::Deserialize (Buffer::Iterator start) +OlsrMessageHeader::Hello::Deserialize (Buffer::Iterator start, uint32_t messageSize) { Buffer::Iterator i = start; - NS_ASSERT (m_messageSize >= 4); + NS_ASSERT (messageSize >= 4); - m_linkMessages.clear (); + this->linkMessages.clear (); - uint16_t helloSizeLeft = m_messageSize; + uint16_t helloSizeLeft = messageSize; i.ReadNtohU16 (); // Reserved - m_hTime = i.ReadU8 (); - m_willingness = i.ReadU8 (); + this->hTime = i.ReadU8 (); + this->willingness = i.ReadU8 (); helloSizeLeft -= 4; @@ -347,133 +376,105 @@ OlsrHelloMessageHeader::Deserialize (Buffer::Iterator start) lm.neighborInterfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ())); } helloSizeLeft -= lmSize; - m_linkMessages.push_back (lm); + this->linkMessages.push_back (lm); } - return m_messageSize; + return messageSize; } // ---------------- OLSR TC Message ------------------------------- -OlsrTcMessageHeader::OlsrTcMessageHeader () -{} - -OlsrTcMessageHeader::~OlsrTcMessageHeader () -{} - -uint32_t -OlsrTcMessageHeader::GetUid (void) -{ - static uint32_t uid = AllocateUid - ("OlsrTcMessageHeader.nsnam.org"); - return uid; -} - uint32_t -OlsrTcMessageHeader::GetSerializedSize (void) const +OlsrMessageHeader::Tc::GetSerializedSize (void) const { - return 4 + m_neighborAddresses.size () * IPV4_ADDRESS_SIZE; + return 4 + this->neighborAddresses.size () * IPV4_ADDRESS_SIZE; } void -OlsrTcMessageHeader::Print (std::ostream &os) const +OlsrMessageHeader::Tc::Print (std::ostream &os) const { // TODO } void -OlsrTcMessageHeader::Serialize (Buffer::Iterator start) const +OlsrMessageHeader::Tc::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; - i.WriteHtonU16 (m_ansn); + i.WriteHtonU16 (this->ansn); i.WriteHtonU16 (0); // Reserved - for (std::vector::const_iterator iter = m_neighborAddresses.begin (); - iter != m_neighborAddresses.end (); iter++) + for (std::vector::const_iterator iter = this->neighborAddresses.begin (); + iter != this->neighborAddresses.end (); iter++) { i.WriteHtonU32 (iter->GetHostOrder ()); } } uint32_t -OlsrTcMessageHeader::Deserialize (Buffer::Iterator start) +OlsrMessageHeader::Tc::Deserialize (Buffer::Iterator start, uint32_t messageSize) { Buffer::Iterator i = start; - m_neighborAddresses.clear (); - NS_ASSERT (m_messageSize >= 4); + this->neighborAddresses.clear (); + NS_ASSERT (messageSize >= 4); - m_ansn = i.ReadNtohU16 (); + this->ansn = i.ReadNtohU16 (); i.ReadNtohU16 (); // Reserved - NS_ASSERT ((m_messageSize - 4) % IPV4_ADDRESS_SIZE == 0); - int numAddresses = (m_messageSize - 4) / IPV4_ADDRESS_SIZE; - m_neighborAddresses.clear (); + NS_ASSERT ((messageSize - 4) % IPV4_ADDRESS_SIZE == 0); + int numAddresses = (messageSize - 4) / IPV4_ADDRESS_SIZE; + this->neighborAddresses.clear (); for (int n = 0; n < numAddresses; ++n) - m_neighborAddresses.push_back (Ipv4Address (i.ReadNtohU32 ())); + this->neighborAddresses.push_back (Ipv4Address (i.ReadNtohU32 ())); - return m_messageSize; + return messageSize; } // ---------------- OLSR HNA Message ------------------------------- -OlsrHnaMessageHeader::OlsrHnaMessageHeader () -{} - -OlsrHnaMessageHeader::~OlsrHnaMessageHeader () -{} - -uint32_t -OlsrHnaMessageHeader::GetUid (void) -{ - static uint32_t uid = AllocateUid - ("OlsrHnaMessageHeader.nsnam.org"); - return uid; -} - uint32_t -OlsrHnaMessageHeader::GetSerializedSize (void) const +OlsrMessageHeader::Hna::GetSerializedSize (void) const { - return 2*m_associations.size () * IPV4_ADDRESS_SIZE; + return 2*this->associations.size () * IPV4_ADDRESS_SIZE; } void -OlsrHnaMessageHeader::Print (std::ostream &os) const +OlsrMessageHeader::Hna::Print (std::ostream &os) const { // TODO } void -OlsrHnaMessageHeader::Serialize (Buffer::Iterator start) const +OlsrMessageHeader::Hna::Serialize (Buffer::Iterator start) const { Buffer::Iterator i = start; - for (size_t n = 0; n < m_associations.size (); ++n) + for (size_t n = 0; n < this->associations.size (); ++n) { - i.WriteHtonU32 (m_associations[n].address.GetHostOrder ()); - i.WriteHtonU32 (m_associations[n].mask.GetHostOrder ()); + i.WriteHtonU32 (this->associations[n].address.GetHostOrder ()); + i.WriteHtonU32 (this->associations[n].mask.GetHostOrder ()); } } uint32_t -OlsrHnaMessageHeader::Deserialize (Buffer::Iterator start) +OlsrMessageHeader::Hna::Deserialize (Buffer::Iterator start, uint32_t messageSize) { Buffer::Iterator i = start; - NS_ASSERT (m_messageSize % (IPV4_ADDRESS_SIZE*2) == 0); - int numAddresses = m_messageSize / IPV4_ADDRESS_SIZE / 2; - m_associations.clear (); + NS_ASSERT (messageSize % (IPV4_ADDRESS_SIZE*2) == 0); + int numAddresses = messageSize / IPV4_ADDRESS_SIZE / 2; + this->associations.clear (); for (int n = 0; n < numAddresses; ++n) { Ipv4Address address (i.ReadNtohU32 ()); Ipv4Mask mask (i.ReadNtohU32 ()); - m_associations.push_back ((Association) {address, mask}); + this->associations.push_back ((Association) {address, mask}); } - return m_messageSize; + return messageSize; } @@ -517,34 +518,31 @@ OlsrHeaderTest::RunTests (void) { OlsrPacketHeader hdr; OlsrMessageHeader msg1; - OlsrMidMessageHeader mid1; + OlsrMessageHeader::Mid &mid1 = msg1.GetMid (); OlsrMessageHeader msg2; - OlsrMidMessageHeader mid2; + OlsrMessageHeader::Mid &mid2 = msg2.GetMid (); // MID message #1 { - std::vector addresses; + std::vector &addresses = mid1.interfaceAddresses; + addresses.clear (); addresses.push_back (Ipv4Address ("1.2.3.4")); addresses.push_back (Ipv4Address ("1.2.3.5")); - mid1.SetInterfaceAddresses (addresses); } - msg1.SetMessageSize (mid1.GetSerializedSize () + msg1.GetSerializedSize ()); msg1.SetTimeToLive (255); msg1.SetOriginatorAddress (Ipv4Address ("11.22.33.44")); msg1.SetVTime (Seconds (9)); - msg1.SetMessageType (OlsrMessageHeader::MID_MESSAGE); msg1.SetMessageSequenceNumber (7); // MID message #2 { - std::vector addresses; + std::vector &addresses = mid2.interfaceAddresses; + addresses.clear (); addresses.push_back (Ipv4Address ("2.2.3.4")); addresses.push_back (Ipv4Address ("2.2.3.5")); - mid2.SetInterfaceAddresses (addresses); } - msg2.SetMessageSize (mid2.GetSerializedSize () + msg2.GetSerializedSize ()); msg2.SetTimeToLive (254); msg2.SetOriginatorAddress (Ipv4Address ("12.22.33.44")); msg2.SetVTime (Seconds (10)); @@ -552,14 +550,12 @@ OlsrHeaderTest::RunTests (void) msg2.SetMessageSequenceNumber (7); // Build an OLSR packet header - hdr.SetPacketLength (hdr.GetSerializedSize () + msg1.GetMessageSize () + msg2.GetMessageSize ()); + hdr.SetPacketLength (hdr.GetSerializedSize () + msg1.GetSerializedSize () + msg2.GetSerializedSize ()); hdr.SetPacketSequenceNumber (123); // Now add all the headers in the correct order - packet.AddHeader (mid2); packet.AddHeader (msg2); - packet.AddHeader (mid1); packet.AddHeader (msg1); packet.AddHeader (hdr); } @@ -571,7 +567,6 @@ OlsrHeaderTest::RunTests (void) uint32_t sizeLeft = hdr.GetPacketLength () - hdr.GetSerializedSize (); { OlsrMessageHeader msg1; - OlsrMidMessageHeader mid1; packet.RemoveHeader (msg1); @@ -581,18 +576,16 @@ OlsrHeaderTest::RunTests (void) NS_TEST_ASSERT_EQUAL (msg1.GetMessageType (), OlsrMessageHeader::MID_MESSAGE); NS_TEST_ASSERT_EQUAL (msg1.GetMessageSequenceNumber (), 7); - mid1.SetMessageSize (msg1.GetMessageSize () - msg1.GetSerializedSize ()); - packet.RemoveHeader (mid1); - NS_TEST_ASSERT_EQUAL (mid1.GetInterfaceAddresses ().size (), 2); - NS_TEST_ASSERT_EQUAL (*mid1.GetInterfaceAddresses ().begin (), Ipv4Address ("1.2.3.4")); + OlsrMessageHeader::Mid &mid1 = msg1.GetMid (); + NS_TEST_ASSERT_EQUAL (mid1.interfaceAddresses.size (), 2); + NS_TEST_ASSERT_EQUAL (*mid1.interfaceAddresses.begin (), Ipv4Address ("1.2.3.4")); - sizeLeft -= msg1.GetMessageSize (); + sizeLeft -= msg1.GetSerializedSize (); NS_TEST_ASSERT (sizeLeft > 0); } { // now read the second message OlsrMessageHeader msg2; - OlsrMidMessageHeader mid2; packet.RemoveHeader (msg2); @@ -602,12 +595,11 @@ OlsrHeaderTest::RunTests (void) NS_TEST_ASSERT_EQUAL (msg2.GetMessageType (), OlsrMessageHeader::MID_MESSAGE); NS_TEST_ASSERT_EQUAL (msg2.GetMessageSequenceNumber (), 7); - mid2.SetMessageSize (msg2.GetMessageSize () - msg2.GetSerializedSize ()); - packet.RemoveHeader (mid2); - NS_TEST_ASSERT_EQUAL (mid2.GetInterfaceAddresses ().size (), 2); - NS_TEST_ASSERT_EQUAL (*mid2.GetInterfaceAddresses ().begin (), Ipv4Address ("2.2.3.4")); + OlsrMessageHeader::Mid mid2 = msg2.GetMid (); + NS_TEST_ASSERT_EQUAL (mid2.interfaceAddresses.size (), 2); + NS_TEST_ASSERT_EQUAL (*mid2.interfaceAddresses.begin (), Ipv4Address ("2.2.3.4")); - sizeLeft -= msg2.GetMessageSize (); + sizeLeft -= msg2.GetSerializedSize (); NS_TEST_ASSERT_EQUAL (sizeLeft, 0); } } @@ -616,49 +608,46 @@ OlsrHeaderTest::RunTests (void) // Test the HELLO message { Packet packet; - OlsrHelloMessageHeader helloIn; + OlsrMessageHeader msgIn; + OlsrMessageHeader::Hello &helloIn = msgIn.GetHello (); helloIn.SetHTime (Seconds (7)); - helloIn.SetWillingness (66); + helloIn.willingness = 66; { - std::vector vec; - - OlsrHelloMessageHeader::LinkMessage lm1; + OlsrMessageHeader::Hello::LinkMessage lm1; lm1.linkCode = 2; lm1.neighborInterfaceAddresses.push_back (Ipv4Address ("1.2.3.4")); lm1.neighborInterfaceAddresses.push_back (Ipv4Address ("1.2.3.5")); - vec.push_back (lm1); + helloIn.linkMessages.push_back (lm1); - OlsrHelloMessageHeader::LinkMessage lm2; + OlsrMessageHeader::Hello::LinkMessage lm2; lm2.linkCode = 3; lm2.neighborInterfaceAddresses.push_back (Ipv4Address ("2.2.3.4")); lm2.neighborInterfaceAddresses.push_back (Ipv4Address ("2.2.3.5")); - vec.push_back (lm2); - - helloIn.SetLinkMessages (vec); + helloIn.linkMessages.push_back (lm2); } - packet.AddHeader (helloIn); + packet.AddHeader (msgIn); - OlsrHelloMessageHeader helloOut; - helloOut.SetMessageSize (packet.GetSize ()); - packet.RemoveHeader (helloOut); + OlsrMessageHeader msgOut; + packet.RemoveHeader (msgOut); + OlsrMessageHeader::Hello &helloOut = msgOut.GetHello (); NS_TEST_ASSERT_EQUAL (helloOut.GetHTime (), Seconds (7)); - NS_TEST_ASSERT_EQUAL (helloOut.GetWillingness (), 66); - NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ().size (), 2); + NS_TEST_ASSERT_EQUAL (helloOut.willingness, 66); + NS_TEST_ASSERT_EQUAL (helloOut.linkMessages.size (), 2); - NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[0].linkCode, 2); - NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[0].neighborInterfaceAddresses[0], + NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[0].linkCode, 2); + NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[0].neighborInterfaceAddresses[0], Ipv4Address ("1.2.3.4")); - NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[0].neighborInterfaceAddresses[1], + NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[0].neighborInterfaceAddresses[1], Ipv4Address ("1.2.3.5")); - NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[1].linkCode, 3); - NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[1].neighborInterfaceAddresses[0], + NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[1].linkCode, 3); + NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[1].neighborInterfaceAddresses[0], Ipv4Address ("2.2.3.4")); - NS_TEST_ASSERT_EQUAL (helloOut.GetLinkMessages ()[1].neighborInterfaceAddresses[1], + NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[1].neighborInterfaceAddresses[1], Ipv4Address ("2.2.3.5")); // check that all bytes of the message were read @@ -668,27 +657,24 @@ OlsrHeaderTest::RunTests (void) // Test the TC message { Packet packet; - OlsrTcMessageHeader tcIn; + OlsrMessageHeader msgIn; + OlsrMessageHeader::Tc &tcIn = msgIn.GetTc (); - tcIn.SetAnsn (0x1234); - { - std::vector vec; - vec.push_back (Ipv4Address ("1.2.3.4")); - vec.push_back (Ipv4Address ("1.2.3.5")); - tcIn.SetNeighborAddresses (vec); - } - packet.AddHeader (tcIn); + tcIn.ansn = 0x1234; + tcIn.neighborAddresses.push_back (Ipv4Address ("1.2.3.4")); + tcIn.neighborAddresses.push_back (Ipv4Address ("1.2.3.5")); + packet.AddHeader (msgIn); - OlsrTcMessageHeader tcOut; - tcOut.SetMessageSize (packet.GetSize ()); - packet.RemoveHeader (tcOut); + OlsrMessageHeader msgOut; + packet.RemoveHeader (msgOut); + OlsrMessageHeader::Tc &tcOut = msgOut.GetTc (); - NS_TEST_ASSERT_EQUAL (tcOut.GetAnsn (), 0x1234); - NS_TEST_ASSERT_EQUAL (tcOut.GetNeighborAddresses ().size (), 2); + NS_TEST_ASSERT_EQUAL (tcOut.ansn, 0x1234); + NS_TEST_ASSERT_EQUAL (tcOut.neighborAddresses.size (), 2); - NS_TEST_ASSERT_EQUAL (tcOut.GetNeighborAddresses ()[0], + NS_TEST_ASSERT_EQUAL (tcOut.neighborAddresses[0], Ipv4Address ("1.2.3.4")); - NS_TEST_ASSERT_EQUAL (tcOut.GetNeighborAddresses ()[1], + NS_TEST_ASSERT_EQUAL (tcOut.neighborAddresses[1], Ipv4Address ("1.2.3.5")); // check that all bytes of the message were read @@ -698,32 +684,29 @@ OlsrHeaderTest::RunTests (void) // Test the HNA message { Packet packet; - OlsrHnaMessageHeader hnaIn; + OlsrMessageHeader msgIn; + OlsrMessageHeader::Hna &hnaIn = msgIn.GetHna (); - { - std::vector vec; - vec.push_back ((OlsrHnaMessageHeader::Association) - { Ipv4Address ("1.2.3.4"), Ipv4Mask ("255.255.255.0")}); - vec.push_back ((OlsrHnaMessageHeader::Association) - {Ipv4Address ("1.2.3.5"), Ipv4Mask ("255.255.0.0")}); - hnaIn.SetAssociations (vec); - } - packet.AddHeader (hnaIn); + hnaIn.associations.push_back ((OlsrMessageHeader::Hna::Association) + { Ipv4Address ("1.2.3.4"), Ipv4Mask ("255.255.255.0")}); + hnaIn.associations.push_back ((OlsrMessageHeader::Hna::Association) + {Ipv4Address ("1.2.3.5"), Ipv4Mask ("255.255.0.0")}); + packet.AddHeader (msgIn); - OlsrHnaMessageHeader hnaOut; - hnaOut.SetMessageSize (packet.GetSize ()); - packet.RemoveHeader (hnaOut); + OlsrMessageHeader msgOut; + packet.RemoveHeader (msgOut); + OlsrMessageHeader::Hna &hnaOut = msgOut.GetHna (); - NS_TEST_ASSERT_EQUAL (hnaOut.GetAssociations ().size (), 2); + NS_TEST_ASSERT_EQUAL (hnaOut.associations.size (), 2); - NS_TEST_ASSERT_EQUAL (hnaOut.GetAssociations ()[0].address, + NS_TEST_ASSERT_EQUAL (hnaOut.associations[0].address, Ipv4Address ("1.2.3.4")); - NS_TEST_ASSERT_EQUAL (hnaOut.GetAssociations ()[0].mask, + NS_TEST_ASSERT_EQUAL (hnaOut.associations[0].mask, Ipv4Mask ("255.255.255.0")); - NS_TEST_ASSERT_EQUAL (hnaOut.GetAssociations ()[1].address, + NS_TEST_ASSERT_EQUAL (hnaOut.associations[1].address, Ipv4Address ("1.2.3.5")); - NS_TEST_ASSERT_EQUAL (hnaOut.GetAssociations ()[1].mask, + NS_TEST_ASSERT_EQUAL (hnaOut.associations[1].mask, Ipv4Mask ("255.255.0.0")); // check that all bytes of the message were read diff --git a/src/routing/olsr/olsr-header.h b/src/routing/olsr/olsr-header.h index b52840564..e783ab9b1 100644 --- a/src/routing/olsr/olsr-header.h +++ b/src/routing/olsr/olsr-header.h @@ -182,14 +182,14 @@ public: return m_messageSequenceNumber; } - void SetMessageSize (uint16_t messageSize) - { - m_messageSize = messageSize; - } - uint16_t GetMessageSize () const - { - return m_messageSize; - } +// void SetMessageSize (uint16_t messageSize) +// { +// m_messageSize = messageSize; +// } +// uint16_t GetMessageSize () const +// { +// return m_messageSize; +// } private: MessageType m_messageType; @@ -207,275 +207,234 @@ public: virtual void Serialize (Buffer::Iterator start) const; virtual uint32_t Deserialize (Buffer::Iterator start); virtual std::string GetName (void) const { return "OlsrMessage"; } -}; -// 5.1. MID Message Format -// -// The proposed format of a MID message is as follows: -// -// 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 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | OLSR Interface Address | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | OLSR Interface Address | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | ... | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -class OlsrMidMessageHeader : public Header -{ -public: - - OlsrMidMessageHeader (); - virtual ~OlsrMidMessageHeader (); - - void SetMessageSize (uint32_t messageSize) { - m_messageSize = messageSize; - } - uint32_t GetMessageSize () const { - return m_messageSize; - } - - const std::vector & GetInterfaceAddresses () const + // 5.1. MID Message Format + // + // The proposed format of a MID message is as follows: + // + // 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 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | OLSR Interface Address | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | OLSR Interface Address | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | ... | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + struct Mid { - return m_interfaceAddresses; - } - void SetInterfaceAddresses (const std::vector &addresses) + std::vector interfaceAddresses; + void Print (std::ostream &os) const; + uint32_t GetSerializedSize (void) const; + void Serialize (Buffer::Iterator start) const; + uint32_t Deserialize (Buffer::Iterator start, uint32_t messageSize); + }; + + // 6.1. HELLO Message Format + // + // 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 + // + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Reserved | Htime | Willingness | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Link Code | Reserved | Link Message Size | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Neighbor Interface Address | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Neighbor Interface Address | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // : . . . : + // : : + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Link Code | Reserved | Link Message Size | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Neighbor Interface Address | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Neighbor Interface Address | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // : : + // : : + // (etc.) + struct Hello { - m_interfaceAddresses = addresses; - } - - -private: - std::vector m_interfaceAddresses; - uint32_t m_messageSize; // has to be manually set before deserialization + struct LinkMessage { + uint8_t linkCode; + std::vector neighborInterfaceAddresses; + }; -public: - static uint32_t GetUid (void); - virtual void Print (std::ostream &os) const; - virtual uint32_t GetSerializedSize (void) const; - virtual void Serialize (Buffer::Iterator start) const; - virtual uint32_t Deserialize (Buffer::Iterator start); - virtual std::string GetName (void) const { return "OlsrMidMessage"; } -}; + uint8_t hTime; + void SetHTime (Time time) + { + this->hTime = OlsrSecondsToEmf (time.GetSeconds ()); + } + Time GetHTime () const + { + return Seconds (OlsrEmfToSeconds (this->hTime)); + } -// 6.1. HELLO Message Format -// -// 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 -// -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Reserved | Htime | Willingness | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Link Code | Reserved | Link Message Size | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Neighbor Interface Address | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Neighbor Interface Address | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// : . . . : -// : : -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Link Code | Reserved | Link Message Size | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Neighbor Interface Address | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Neighbor Interface Address | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// : : -// : : -// (etc.) -class OlsrHelloMessageHeader : public Header -{ -public: + uint8_t willingness; + std::vector linkMessages; - OlsrHelloMessageHeader (); - virtual ~OlsrHelloMessageHeader (); + void Print (std::ostream &os) const; + uint32_t GetSerializedSize (void) const; + void Serialize (Buffer::Iterator start) const; + uint32_t Deserialize (Buffer::Iterator start, uint32_t messageSize); + }; - - struct LinkMessage { - uint8_t linkCode; - std::vector neighborInterfaceAddresses; + // 9.1. TC Message Format + // + // The proposed format of a TC message is as follows: + // + // 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 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | ANSN | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Advertised Neighbor Main Address | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Advertised Neighbor Main Address | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | ... | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + struct Tc + { + std::vector neighborAddresses; + uint16_t ansn; + + void Print (std::ostream &os) const; + uint32_t GetSerializedSize (void) const; + void Serialize (Buffer::Iterator start) const; + uint32_t Deserialize (Buffer::Iterator start, uint32_t messageSize); }; - void SetMessageSize (uint32_t messageSize) { - m_messageSize = messageSize; - } - uint32_t GetMessageSize () const { - return m_messageSize; - } + // 12.1. HNA Message Format + // + // The proposed format of an HNA-message is: + // + // 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 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Network Address | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Netmask | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Network Address | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Netmask | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | ... | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - void SetWillingness (uint8_t willingness) + // Note: HNA stands for Host Network Association + struct Hna { - m_willingness = willingness; - } - uint8_t GetWillingness () const - { - return m_willingness; - } + struct Association + { + Ipv4Address address; + Ipv4Mask mask; + }; + std::vector associations; - void SetHTime (Time time) - { - m_hTime = OlsrSecondsToEmf (time.GetSeconds ()); - } - Time GetHTime () const - { - return Seconds (OlsrEmfToSeconds (m_hTime)); - } - - const std::vector & GetLinkMessages () const - { - return m_linkMessages; - } - void SetLinkMessages (const std::vector &linkMessages) - { - m_linkMessages = linkMessages; - } - -private: - uint8_t m_hTime; - uint8_t m_willingness; - uint32_t m_messageSize; // has to be manually set before deserialization - std::vector m_linkMessages; - -public: - static uint32_t GetUid (void); - virtual void Print (std::ostream &os) const; - virtual uint32_t GetSerializedSize (void) const; - virtual void Serialize (Buffer::Iterator start) const; - virtual uint32_t Deserialize (Buffer::Iterator start); - virtual std::string GetName (void) const { return "OlsrHelloMessage"; } -}; - -// 9.1. TC Message Format -// -// The proposed format of a TC message is as follows: -// -// 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 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | ANSN | Reserved | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Advertised Neighbor Main Address | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Advertised Neighbor Main Address | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | ... | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - -class OlsrTcMessageHeader : public Header -{ -public: - - OlsrTcMessageHeader (); - virtual ~OlsrTcMessageHeader (); - - void SetMessageSize (uint32_t messageSize) { - m_messageSize = messageSize; - } - uint32_t GetMessageSize () const { - return m_messageSize; - } - - const std::vector & GetNeighborAddresses () const - { - return m_neighborAddresses; - } - void SetNeighborAddresses (const std::vector &addresses) - { - m_neighborAddresses = addresses; - } - - void SetAnsn (uint16_t ansn) - { - m_ansn = ansn; - } - uint16_t GetAnsn () const - { - return m_ansn; - } - -private: - std::vector m_neighborAddresses; - uint16_t m_ansn; - - uint32_t m_messageSize; // has to be manually set before deserialization - -public: - static uint32_t GetUid (void); - virtual void Print (std::ostream &os) const; - virtual uint32_t GetSerializedSize (void) const; - virtual void Serialize (Buffer::Iterator start) const; - virtual uint32_t Deserialize (Buffer::Iterator start); - virtual std::string GetName (void) const { return "OlsrTcMessage"; } -}; - - -// 12.1. HNA Message Format -// -// The proposed format of an HNA-message is: -// -// 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 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Network Address | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Netmask | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Network Address | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Netmask | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | ... | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - -// Note: HNA stands for Host Network Association -class OlsrHnaMessageHeader : public Header -{ -public: - - OlsrHnaMessageHeader (); - virtual ~OlsrHnaMessageHeader (); - - struct Association - { - Ipv4Address address; - Ipv4Mask mask; + void Print (std::ostream &os) const; + uint32_t GetSerializedSize (void) const; + void Serialize (Buffer::Iterator start) const; + uint32_t Deserialize (Buffer::Iterator start, uint32_t messageSize); }; - void SetMessageSize (uint32_t messageSize) - { - m_messageSize = messageSize; - } - uint32_t GetMessageSize () const - { - return m_messageSize; - } - - const std::vector & GetAssociations () const - { - return m_associations; - } - void SetAssociations (const std::vector &associations) - { - m_associations = associations; - } - private: - std::vector m_associations; - uint32_t m_messageSize; // has to be manually set before deserialization + struct + { + Mid mid; + Hello hello; + Tc tc; + Hna hna; + } m_message; // union not allowed -public: - static uint32_t GetUid (void); - virtual void Print (std::ostream &os) const; - virtual uint32_t GetSerializedSize (void) const; - virtual void Serialize (Buffer::Iterator start) const; - virtual uint32_t Deserialize (Buffer::Iterator start); - virtual std::string GetName (void) const { return "OlsrHnaMessage"; } +public: + + Mid& GetMid () + { + if (m_messageType == 0) + { + m_messageType = MID_MESSAGE; + } + else + { + NS_ASSERT (m_messageType == MID_MESSAGE); + } + return m_message.mid; + } + + Hello& GetHello () + { + if (m_messageType == 0) + { + m_messageType = HELLO_MESSAGE; + } + else + { + NS_ASSERT (m_messageType == HELLO_MESSAGE); + } + return m_message.hello; + } + + Tc& GetTc () + { + if (m_messageType == 0) + { + m_messageType = TC_MESSAGE; + } + else + { + NS_ASSERT (m_messageType == TC_MESSAGE); + } + return m_message.tc; + } + + Hna& GetHna () + { + if (m_messageType == 0) + { + m_messageType = HNA_MESSAGE; + } + else + { + NS_ASSERT (m_messageType == HNA_MESSAGE); + } + return m_message.hna; + } + + + const Mid& GetMid () const + { + NS_ASSERT (m_messageType == MID_MESSAGE); + return m_message.mid; + } + + const Hello& GetHello () const + { + NS_ASSERT (m_messageType == HELLO_MESSAGE); + return m_message.hello; + } + + const Tc& GetTc () const + { + NS_ASSERT (m_messageType == TC_MESSAGE); + return m_message.tc; + } + + const Hna& GetHna () const + { + NS_ASSERT (m_messageType == HNA_MESSAGE); + return m_message.hna; + } + + }; - }; // namespace ns3 #endif /* OLSR_HEADER_H */ From eb4e4b6b059134da934dc50aa3c7942d3c264074 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 26 Sep 2007 18:28:42 +0100 Subject: [PATCH 34/61] Enable ASCII tracing unconditionally, now that the associated problem is fixed in OLSR. --- examples/simple-point-to-point-olsr.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/simple-point-to-point-olsr.cc b/examples/simple-point-to-point-olsr.cc index d13addbf8..b4343acfe 100644 --- a/examples/simple-point-to-point-olsr.cc +++ b/examples/simple-point-to-point-olsr.cc @@ -212,12 +212,10 @@ main (int argc, char *argv[]) // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the simple-point-to-point.tr file -#if 0 // causes: assert failed. file=../src/common/packet-metadata.cc, line=1043, cond="GetTotalSize () == data.GetSize ()" NS_LOG_INFO ("Configure Tracing."); AsciiTrace asciitrace ("simple-point-to-point-olsr.tr"); asciitrace.TraceAllQueues (); asciitrace.TraceAllNetDeviceRx (); -#endif // Also configure some tcpdump traces; each interface will be traced // The output files will be named From c00aa2d8079e0ab320c48a4ec065d9f49228f76b Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 3 Oct 2007 19:06:31 +0100 Subject: [PATCH 35/61] Fix unused variable warning in optimized build. --- src/routing/olsr/routing-table.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/routing/olsr/routing-table.cc b/src/routing/olsr/routing-table.cc index 6e688468c..73f01b715 100644 --- a/src/routing/olsr/routing-table.cc +++ b/src/routing/olsr/routing-table.cc @@ -114,7 +114,9 @@ RoutingTable::RequestRoute (uint32_t ifIndex, if (Lookup (ipHeader.GetDestination (), entry1)) { bool foundSendEntry = FindSendEntry (entry1, entry2); - NS_ASSERT (foundSendEntry); + if (!foundSendEntry) + NS_FATAL_ERROR ("FindSendEntry failure"); + Ipv4Route route = Ipv4Route::CreateHostRouteTo (ipHeader.GetDestination (), entry2.nextAddr, entry2.interface); @@ -143,7 +145,8 @@ RoutingTable::RequestIfIndex (Ipv4Address destination, if (Lookup (destination, entry1)) { bool foundSendEntry = FindSendEntry (entry1, entry2); - NS_ASSERT (foundSendEntry); + if (!foundSendEntry) + NS_FATAL_ERROR ("FindSendEntry failure"); ifIndex = entry2.interface; return true; } From 2422ec276dce571e2531b2367beefb3d627234f8 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 3 Oct 2007 19:11:46 +0100 Subject: [PATCH 36/61] Fix a couple more warnings in OLSR --- src/routing/olsr/olsr-agent-impl.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index df3911f50..68855322f 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -717,7 +717,10 @@ OlsrAgentImpl::RoutingTableComputation () if (ok) { RoutingTableEntry entry; - bool found_entry = m_routingTable->Lookup (nb2hop_tuple.neighborMainAddr, entry); + bool foundEntry = m_routingTable->Lookup (nb2hop_tuple.neighborMainAddr, entry); + if (!foundEntry) + NS_FATAL_ERROR ("m_routingTable->Lookup failure"); + NS_ASSERT (found_entry); m_routingTable->AddEntry (nb2hop_tuple.twoHopNeighborAddr, entry.nextAddr, @@ -1118,7 +1121,7 @@ OlsrAgentImpl::SendHello () && link_tuple->time >= now)) continue; - uint8_t link_type, nb_type; + uint8_t link_type, nb_type = 0xff; // Establishes link type if (m_useL2Notifications && link_tuple->lostTime >= now) From 6c1d1db4b4915a34919ef837e9a358def75dd607 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 8 Oct 2007 11:23:53 +0100 Subject: [PATCH 37/61] Fix typo --- src/routing/olsr/olsr-agent-impl.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index 68855322f..0f0fad0cb 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -721,7 +721,6 @@ OlsrAgentImpl::RoutingTableComputation () if (!foundEntry) NS_FATAL_ERROR ("m_routingTable->Lookup failure"); - NS_ASSERT (found_entry); m_routingTable->AddEntry (nb2hop_tuple.twoHopNeighborAddr, entry.nextAddr, entry.interface, From 743a4eaf027ebe0edc346e13ca30c7bafbab72d6 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 8 Oct 2007 11:37:03 +0100 Subject: [PATCH 38/61] Adapt the OLSR agent code to use the new Timer class. --- src/routing/olsr/event-collector.cc | 152 ---------------------------- src/routing/olsr/event-collector.h | 62 ------------ src/routing/olsr/olsr-agent-impl.cc | 110 ++++++++++++-------- src/routing/olsr/olsr-agent-impl.h | 15 +-- src/routing/olsr/single-event.cc | 135 ------------------------ src/routing/olsr/single-event.h | 76 -------------- src/routing/olsr/wscript | 6 -- 7 files changed, 74 insertions(+), 482 deletions(-) delete mode 100644 src/routing/olsr/event-collector.cc delete mode 100644 src/routing/olsr/event-collector.h delete mode 100644 src/routing/olsr/single-event.cc delete mode 100644 src/routing/olsr/single-event.h diff --git a/src/routing/olsr/event-collector.cc b/src/routing/olsr/event-collector.cc deleted file mode 100644 index d47b4cc84..000000000 --- a/src/routing/olsr/event-collector.cc +++ /dev/null @@ -1,152 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 INESC Porto - * All rights reserved. - * - * 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 - * - * Author: Gustavo J. A. M. Carneiro - */ -#include "event-collector.h" - -#define CLEANUP_CHUNK_MIN_SIZE 8 -#define CLEANUP_CHUNK_MAX_SIZE 128 - - -namespace ns3 { - - -EventCollector::EventCollector () : - m_nextCleanupSize (CLEANUP_CHUNK_MIN_SIZE) -{} - -void -EventCollector::Track (EventId event) -{ - m_events.push_back (event); - if (m_events.size () >= m_nextCleanupSize) - Cleanup (); -} - -inline bool -EventExpiredPredicate (const EventId &event) -{ - return event.IsExpired (); -} - -void -EventCollector::Grow () -{ - m_nextCleanupSize += (m_nextCleanupSize < CLEANUP_CHUNK_MAX_SIZE? - m_nextCleanupSize : CLEANUP_CHUNK_MAX_SIZE); -} - -void -EventCollector::Shrink () -{ - while (m_nextCleanupSize > m_events.size ()) - m_nextCleanupSize >>= 1; - Grow (); -} - -// Called when a new event was added and the cleanup limit was exceeded in consequence. -void -EventCollector::Cleanup () -{ - m_events.remove_if (EventExpiredPredicate); - - // If after cleanup we are still over the limit, increase the limit. - if (m_events.size () >= m_nextCleanupSize) - Grow (); - else - Shrink (); -} - - -EventCollector::~EventCollector () -{ - for (std::list::iterator event = m_events.begin (); - event != m_events.end (); event++) - { - Simulator::Cancel (*event); - } -} - -}; // namespace ns3 - - - -#ifdef RUN_SELF_TESTS - -#include "ns3/test.h" - -namespace ns3 { - -class EventCollectorTests : public Test -{ - int m_counter; - EventCollector *m_events; - - void EventCollectorCallback (); - -public: - - EventCollectorTests (); - virtual ~EventCollectorTests (); - virtual bool RunTests (void); -}; - -EventCollectorTests::EventCollectorTests () - : Test ("EventCollector"), m_counter (0), m_events (0) -{} - -EventCollectorTests::~EventCollectorTests () -{} - -void -EventCollectorTests::EventCollectorCallback () -{ - m_counter++; - if (m_counter == 50) - { - // this should cause the remaining (50) events to be cancelled - delete m_events; - m_events = 0; - } -} - -bool EventCollectorTests::RunTests (void) -{ - bool result = true; - - m_events = new EventCollector (); - - for (int n = 0; n < 100; n++) - { - m_events->Track (Simulator::Schedule - (Simulator::Now (), - &EventCollectorTests::EventCollectorCallback, - this)); - } - Simulator::Run (); - NS_TEST_ASSERT_EQUAL (m_events, 0); - NS_TEST_ASSERT_EQUAL (m_counter, 50); - return result; -} - -static EventCollectorTests g_eventCollectorTests; - -}; - -#endif /* RUN_SELF_TESTS */ diff --git a/src/routing/olsr/event-collector.h b/src/routing/olsr/event-collector.h deleted file mode 100644 index c29809402..000000000 --- a/src/routing/olsr/event-collector.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 INESC Porto - * All rights reserved. - * - * 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 - * - * Author: Gustavo J. A. M. Carneiro - */ -#ifndef EVENT_COLLECTOR_H -#define EVENT_COLLECTOR_H - -#include -#include "ns3/event-id.h" -#include "ns3/simulator.h" - -namespace ns3 { - -/** - * \brief An object that tracks scheduled events and automatically - * cancels them when it is destroyed. It is useful in situations - * where multiple instances of the same type of event can - * simultaneously be scheduled, and when the events should be limited - * to the lifetime of a container object. - */ -class EventCollector -{ -public: - - EventCollector (); - - /** - * \brief Tracks a new event - */ - void Track (EventId event); - - ~EventCollector (); - -private: - - std::list::size_type m_nextCleanupSize; - std::list m_events; - - void Cleanup (); - void Grow (); - void Shrink (); -}; - -}; // namespace ns3 - -#endif /* EVENT_COLLECTOR_H */ diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index 0f0fad0cb..75820775b 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -151,8 +151,18 @@ NS_DEBUG_COMPONENT_DEFINE ("OlsrAgent"); OlsrAgentImpl::OlsrAgentImpl (Ptr node) : - m_useL2Notifications (false) + m_events (Timer::GARBAGE_COLLECT), + m_useL2Notifications (false), + m_helloTimer (Timer::CHECK_ON_SCHEDULE, Timer::CANCEL_ON_DESTROY), + m_tcTimer (Timer::CHECK_ON_SCHEDULE, Timer::CANCEL_ON_DESTROY), + m_midTimer (Timer::CHECK_ON_SCHEDULE, Timer::CANCEL_ON_DESTROY) { + m_helloTimer.SetFunction (&OlsrAgentImpl::HelloTimerExpire, this); + m_tcTimer.SetFunction (&OlsrAgentImpl::TcTimerExpire, this); + m_midTimer.SetFunction (&OlsrAgentImpl::MidTimerExpire, this); + m_queuedMessagesTimer.SetFunction (&OlsrAgentImpl::SendQueuedMessages, this); + + SetInterfaceId (OlsrAgentImpl::iid); // Aggregate with the Node, so that OLSR dies when the node is destroyed. @@ -881,9 +891,9 @@ OlsrAgentImpl::ProcessTc (const OlsrMessageHeader &msg, AddTopologyTuple (topologyTuple); // Schedules topology tuple deletion - Simulator::Schedule (DELAY (topologyTuple.expirationTime), - &OlsrAgentImpl::TopologyTupleTimerExpire, - this, topologyTuple); + m_events.SetFunction (&OlsrAgentImpl::TopologyTupleTimerExpire, this); + m_events.SetArguments (topologyTuple); + m_events.Schedule (DELAY (topologyTuple.expirationTime)); } } } @@ -1035,7 +1045,8 @@ OlsrAgentImpl::QueueMessage (const OlsrMessageHeader &message, Time delay) m_queuedMessages.push_back (message); if (not m_queuedMessagesTimer.IsRunning ()) { - m_queuedMessagesTimer = Simulator::Schedule (delay, &OlsrAgentImpl::SendQueuedMessages, this); + m_queuedMessagesTimer.SetDelay (delay); + m_queuedMessagesTimer.Schedule (); } } @@ -1339,9 +1350,9 @@ OlsrAgentImpl::LinkSensing (const OlsrMessageHeader &msg, // Schedules link tuple deletion if (created && link_tuple != NULL) { - m_events.Track (Simulator::Schedule - (DELAY (std::min (link_tuple->time, link_tuple->symTime)), - &OlsrAgentImpl::LinkTupleTimerExpire, this, *link_tuple)); + m_events.SetFunction (&OlsrAgentImpl::LinkTupleTimerExpire, this); + m_events.SetArguments (*link_tuple); + m_events.Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime))); } } @@ -1409,10 +1420,9 @@ OlsrAgentImpl::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, now + msg.GetVTime (); // Schedules nb2hop tuple // deletion - m_events.Track (Simulator::Schedule - (DELAY (new_nb2hop_tuple.expirationTime), - &OlsrAgentImpl::Nb2hopTupleTimerExpire, this, - new_nb2hop_tuple)); + m_events.SetFunction (&OlsrAgentImpl::Nb2hopTupleTimerExpire, this); + m_events.SetArguments (new_nb2hop_tuple); + m_events.Schedule (DELAY (new_nb2hop_tuple.expirationTime)); } else { @@ -1478,10 +1488,9 @@ OlsrAgentImpl::PopulateMprSelectorSet (const OlsrMessageHeader &msg, AddMprSelectorTuple (mprsel_tuple); // Schedules mpr selector tuple deletion - m_events.Track (Simulator::Schedule - (DELAY (mprsel_tuple.expirationTime), - &OlsrAgentImpl::MprSelTupleTimerExpire, - this, mprsel_tuple)); + m_events.SetFunction (&OlsrAgentImpl::MprSelTupleTimerExpire, this); + m_events.SetArguments (mprsel_tuple); + m_events.Schedule (DELAY (mprsel_tuple.expirationTime)); } else { @@ -1874,7 +1883,7 @@ void OlsrAgentImpl::HelloTimerExpire () { SendHello (); - m_helloTimer = Simulator::Schedule (m_helloInterval, &OlsrAgentImpl::HelloTimerExpire, this); + m_helloTimer.Schedule (m_helloInterval); } /// @@ -1885,8 +1894,10 @@ void OlsrAgentImpl::TcTimerExpire () { if (m_state.GetMprSelectors ().size () > 0) - SendTc (); - m_tcTimer = Simulator::Schedule (m_tcInterval, &OlsrAgentImpl::TcTimerExpire, this); + { + SendTc (); + } + m_tcTimer.Schedule (m_tcInterval); } /// @@ -1898,15 +1909,15 @@ void OlsrAgentImpl::MidTimerExpire () { SendMid (); - m_midTimer = Simulator::Schedule (m_midInterval, &OlsrAgentImpl::MidTimerExpire, this); + m_midTimer.Schedule (m_midInterval); } /// -/// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time(). +/// \brief Removes tuple if expired. Else timer is rescheduled to expire at tuple.expirationTime. /// /// The task of actually removing the tuple is left to the OLSR agent. /// -/// \param e The event which has expired. +/// \param tuple The tuple which has expired. /// void OlsrAgentImpl::DupTupleTimerExpire (DuplicateTuple tuple) @@ -1916,9 +1927,11 @@ OlsrAgentImpl::DupTupleTimerExpire (DuplicateTuple tuple) RemoveDuplicateTuple (tuple); } else - m_events.Track (Simulator::Schedule - (DELAY (tuple.expirationTime), - &OlsrAgentImpl::DupTupleTimerExpire, this, tuple)); + { + m_events.SetFunction (&OlsrAgentImpl::DupTupleTimerExpire, this); + m_events.SetArguments (tuple); + m_events.Schedule (DELAY (tuple.expirationTime)); + } } /// @@ -1948,15 +1961,16 @@ OlsrAgentImpl::LinkTupleTimerExpire (LinkTuple tuple) else NeighborLoss (tuple); - m_events.Track (Simulator::Schedule - (DELAY(tuple.time), - &OlsrAgentImpl::LinkTupleTimerExpire, this, tuple)); - + m_events.SetFunction (&OlsrAgentImpl::LinkTupleTimerExpire, this); + m_events.SetArguments (tuple); + m_events.Schedule (DELAY (tuple.time)); } else - m_events.Track (Simulator::Schedule - (DELAY (std::min (tuple.time, tuple.symTime)), - &OlsrAgentImpl::LinkTupleTimerExpire, this, tuple)); + { + m_events.SetFunction (&OlsrAgentImpl::LinkTupleTimerExpire, this); + m_events.SetArguments (tuple); + m_events.Schedule (DELAY (std::min (tuple.time, tuple.symTime))); + } } /// @@ -1974,9 +1988,11 @@ OlsrAgentImpl::Nb2hopTupleTimerExpire (TwoHopNeighborTuple tuple) RemoveTwoHopNeighborTuple (tuple); } else - m_events.Track (Simulator::Schedule - (DELAY (tuple.expirationTime), - &OlsrAgentImpl::Nb2hopTupleTimerExpire, this, tuple)); + { + m_events.SetFunction (&OlsrAgentImpl::Nb2hopTupleTimerExpire, this); + m_events.SetArguments (tuple); + m_events.Schedule (DELAY (tuple.expirationTime)); + } } /// @@ -1994,9 +2010,11 @@ OlsrAgentImpl::MprSelTupleTimerExpire (MprSelectorTuple tuple) RemoveMprSelectorTuple (tuple); } else - m_events.Track (Simulator::Schedule - (DELAY (tuple.expirationTime), - &OlsrAgentImpl::MprSelTupleTimerExpire, this, tuple)); + { + m_events.SetFunction (&OlsrAgentImpl::MprSelTupleTimerExpire, this); + m_events.SetArguments (tuple); + m_events.Schedule (DELAY (tuple.expirationTime)); + } } /// @@ -2014,9 +2032,11 @@ OlsrAgentImpl::TopologyTupleTimerExpire (TopologyTuple tuple) RemoveTopologyTuple (tuple); } else - m_events.Track (Simulator::Schedule - (DELAY (tuple.expirationTime), - &OlsrAgentImpl::TopologyTupleTimerExpire, this, tuple)); + { + m_events.SetFunction (&OlsrAgentImpl::TopologyTupleTimerExpire, this); + m_events.SetArguments (tuple); + m_events.Schedule (DELAY (tuple.expirationTime)); + } } /// @@ -2032,9 +2052,11 @@ OlsrAgentImpl::IfaceAssocTupleTimerExpire (IfaceAssocTuple tuple) RemoveIfaceAssocTuple (tuple); } else - m_events.Track (Simulator::Schedule - (DELAY (tuple.time), - &OlsrAgentImpl::IfaceAssocTupleTimerExpire, this, tuple)); + { + m_events.SetFunction (&OlsrAgentImpl::IfaceAssocTupleTimerExpire, this); + m_events.SetArguments (tuple); + m_events.Schedule (DELAY (tuple.time)); + } } diff --git a/src/routing/olsr/olsr-agent-impl.h b/src/routing/olsr/olsr-agent-impl.h index 34b09d953..4423c3e26 100644 --- a/src/routing/olsr/olsr-agent-impl.h +++ b/src/routing/olsr/olsr-agent-impl.h @@ -38,8 +38,9 @@ #include "ns3/packet.h" #include "ns3/node.h" #include "ns3/socket.h" -#include "single-event.h" -#include "event-collector.h" +//#include "single-event.h" +//#include "event-collector.h" +#include "ns3/timer.h" namespace ns3 { @@ -58,7 +59,7 @@ public: virtual void SetMainInterface (uint32_t interface); private: - EventCollector m_events; + Timer m_events; /// Address of the routing agent. Ipv4Address m_routingAgentAddr; @@ -106,13 +107,13 @@ protected: Ipv4Address GetMainAddress (Ipv4Address iface_addr); // Timer handlers - SingleEvent m_helloTimer; + Timer m_helloTimer; void HelloTimerExpire (); - SingleEvent m_tcTimer; + Timer m_tcTimer; void TcTimerExpire (); - SingleEvent m_midTimer; + Timer m_midTimer; void MidTimerExpire (); void DupTupleTimerExpire (DuplicateTuple tuple); @@ -125,7 +126,7 @@ protected: /// A list of pending messages which are buffered awaiting for being sent. std::vector m_queuedMessages; - SingleEvent m_queuedMessagesTimer; // timer for throttling outgoing messages + Timer m_queuedMessagesTimer; // timer for throttling outgoing messages void ForwardDefault (OlsrMessageHeader olsrMessage, DuplicateTuple *duplicated, diff --git a/src/routing/olsr/single-event.cc b/src/routing/olsr/single-event.cc deleted file mode 100644 index d0fd25776..000000000 --- a/src/routing/olsr/single-event.cc +++ /dev/null @@ -1,135 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 INESC Porto - * All rights reserved. - * - * 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 - * - * Author: Gustavo J. A. M. Carneiro - */ - -#include "single-event.h" - -namespace ns3 { - -SingleEvent::SingleEvent () -{ -} - -SingleEvent::~SingleEvent () -{ - Simulator::Cancel (m_event); -} - -void -SingleEvent::operator = (const EventId &event) -{ - Simulator::Cancel (m_event); - m_event = event; -} - -void -SingleEvent::Cancel (void) -{ - m_event.Cancel (); -} - -bool -SingleEvent::IsExpired (void) const -{ - return m_event.IsExpired (); -} - -bool -SingleEvent::IsRunning (void) const -{ - return m_event.IsRunning (); -} - - -}; // namespace ns3 - -#ifdef RUN_SELF_TESTS - -#include "ns3/test.h" - -namespace ns3 { - -class SingleEventTests : public Test -{ - int m_counter; - SingleEvent *m_events; - - void SingleEventCallback (); - -public: - - SingleEventTests (); - virtual ~SingleEventTests (); - virtual bool RunTests (void); -}; - -SingleEventTests::SingleEventTests () - : Test ("SingleEvent"), m_counter (0), m_events (0) -{} - -SingleEventTests::~SingleEventTests () -{} - -void -SingleEventTests::SingleEventCallback () -{ - m_counter++; -} - -bool SingleEventTests::RunTests (void) -{ - bool result = true; - - - { - SingleEvent event; - - event = Simulator::Schedule (Simulator::Now (), &SingleEventTests::SingleEventCallback, this); - Simulator::Run (); - NS_TEST_ASSERT_EQUAL (m_counter, 1); - } - - { - SingleEvent event; - - event = Simulator::Schedule (Simulator::Now (), &SingleEventTests::SingleEventCallback, this); - } // event is destroyed => the eventid cancelled - - Simulator::Run (); - NS_TEST_ASSERT_EQUAL (m_counter, 1); - - { - SingleEvent event; - - event = Simulator::Schedule (Simulator::Now (), &SingleEventTests::SingleEventCallback, this); - // the second event cancels the first one - event = Simulator::Schedule (Simulator::Now (), &SingleEventTests::SingleEventCallback, this); - Simulator::Run (); - NS_TEST_ASSERT_EQUAL (m_counter, 2); - } - - return result; -} - -static SingleEventTests g_singleEventTests; - -}; - -#endif /* RUN_SELF_TESTS */ diff --git a/src/routing/olsr/single-event.h b/src/routing/olsr/single-event.h deleted file mode 100644 index cb7ab4be5..000000000 --- a/src/routing/olsr/single-event.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 INESC Porto - * All rights reserved. - * - * 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 - * - * Author: Gustavo J. A. M. Carneiro - */ -#ifndef SINGLE_EVENT_H -#define SINGLE_EVENT_H - -#include -#include "ns3/event-id.h" -#include "ns3/simulator.h" - -namespace ns3 { - -/** - * \brief An object that tracks a single event - * - * A SingleEvent acts as a smart proxy for an EventId. It - * automatically cancels the underlying EventId when it is replaced - * for a new EventId, or when the SingleEvent is destroyed. It is - * useful in situations where only one type of an event can possibly - * be scheduled at any single time (e.g. a single timer instance), and - * when the event should be limited to the lifetime of a container - * object. - */ -class SingleEvent -{ -public: - - SingleEvent (); - ~SingleEvent (); - - /** - * \brief Tracks a newly scheduled event. - * - * Tracks a newly scheduled event. Any previous event that may have - * been scheduled is first cancelled. - */ - void operator = (const EventId &event); - - /** - * This method is syntactic sugar for the ns3::Simulator::cancel - * method. - */ - void Cancel (void); - /** - * This method is syntactic sugar for the ns3::Simulator::isExpired - * method. - * \returns true if the event has expired, false otherwise. - */ - bool IsExpired (void) const; - bool IsRunning (void) const; - -private: - - EventId m_event; -}; - -}; // namespace ns3 - -#endif /* SINGLE_EVENT_H */ diff --git a/src/routing/olsr/wscript b/src/routing/olsr/wscript index 84718ec6b..cb803023b 100644 --- a/src/routing/olsr/wscript +++ b/src/routing/olsr/wscript @@ -18,9 +18,3 @@ def build(bld): 'olsr.h', ] - - ## globally useful classes, temporarily private... - module.source.extend([ - 'event-collector.cc', - 'single-event.cc', - ]) From bf2adc6861dbbb9995ace0ce10bf008546846453 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 8 Oct 2007 18:13:26 -0700 Subject: [PATCH 39/61] log verbosity changes --- src/core/log.cc | 33 +++++++++++- src/core/log.h | 102 ++++++++++++++++++++++++------------ tutorial/hello-simulator.cc | 3 +- 3 files changed, 102 insertions(+), 36 deletions(-) diff --git a/src/core/log.cc b/src/core/log.cc index 6f5bd6acf..97d82cc4c 100644 --- a/src/core/log.cc +++ b/src/core/log.cc @@ -207,7 +207,7 @@ LogComponentEnableEnvVar (void) } LogComponent::LogComponent (char const * name) - : m_levels (0) + : m_levels (0), m_name (name) { ComponentList *components = GetComponentList (); for (ComponentListI i = components->begin (); @@ -244,6 +244,13 @@ LogComponent::Disable (enum LogLevel level) m_levels &= ~level; } +char const * +LogComponent::Name (void) const +{ + return m_name; +} + + void LogComponentEnable (char const *name, enum LogLevel level) { @@ -260,6 +267,18 @@ LogComponentEnable (char const *name, enum LogLevel level) } } +void +LogComponentEnableAll (enum LogLevel level) +{ + ComponentList *components = GetComponentList (); + for (ComponentListI i = components->begin (); + i != components->end (); + i++) + { + i->second->Enable (level); + } +} + void LogComponentDisable (char const *name, enum LogLevel level) { @@ -276,6 +295,18 @@ LogComponentDisable (char const *name, enum LogLevel level) } } +void +LogComponentDisableAll (enum LogLevel level) +{ + ComponentList *components = GetComponentList (); + for (ComponentListI i = components->begin (); + i != components->end (); + i++) + { + i->second->Disable (level); + } +} + void LogComponentPrintList (void) { diff --git a/src/core/log.h b/src/core/log.h index 267419bf5..d54b8fcdf 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -92,20 +92,25 @@ { \ if (g_log.IsEnabled (level)) \ { \ - std::clog << __PRETTY_FUNCTION__ << " ==> " << \ - msg << std::endl; \ + if (g_log.IsEnabled (ns3::LOG_PREFIX_ALL)) \ + { \ + std::clog << g_log.Name () << ":" << \ + __FUNCTION__ << "(): "; \ + } \ + std::clog << msg << std::endl; \ } \ } \ while (false) -#define NS_LOG_F(level) \ - do \ - { \ - if (g_log.IsEnabled (level)) \ - { \ - std::clog << __PRETTY_FUNCTION__ << std::endl;\ - } \ - } \ +#define NS_LOG_F(level) \ + do \ + { \ + if (g_log.IsEnabled (level)) \ + { \ + std::clog << g_log.Name () << ":" << __FUNCTION__ << \ + "(): " << std::endl; \ + } \ + } \ while (false) #define NS_LOG_ERROR(msg) \ @@ -129,9 +134,6 @@ #define NS_LOG_LOGIC(msg) \ NS_LOG(ns3::LOG_LOGIC, msg) -#define NS_LOG_ALL(msg) \ - NS_LOG(ns3::LOG_ALL, msg) - #define NS_LOG_UNCOND(msg) \ do \ { \ @@ -150,7 +152,6 @@ #define NS_LOG_FUNCTION #define NS_LOG_PARAM(msg) #define NS_LOG_LOGIC(msg) -#define NS_LOG_ALL(msg) #define NS_LOG_UNCOND(msg) #endif @@ -160,59 +161,88 @@ namespace ns3 { #ifdef NS3_LOG_ENABLE enum LogLevel { - LOG_ERROR = 0x0001, // serious error messages only - LOG_LEVEL_ERROR = 0x0001, + LOG_NONE = 0x00000000, // no logging - LOG_WARN = 0x0002, // warning messages - LOG_LEVEL_WARN = 0x0003, + LOG_ERROR = 0x00000001, // serious error messages only + LOG_LEVEL_ERROR = 0x00000001, - LOG_DEBUG = 0x0004, // rare ad-hoc debug messages - LOG_LEVEL_DEBUG = 0x0007, + LOG_WARN = 0x00000002, // warning messages + LOG_LEVEL_WARN = 0x00000003, - LOG_INFO = 0x0008, // informational messages (e.g., banners) - LOG_LEVEL_INFO = 0x000f, + LOG_DEBUG = 0x00000004, // rare ad-hoc debug messages + LOG_LEVEL_DEBUG = 0x00000007, - LOG_FUNCTION = 0x0010, // function tracing - LOG_LEVEL_FUNCTION = 0x001f, + LOG_INFO = 0x00000008, // informational messages (e.g., banners) + LOG_LEVEL_INFO = 0x0000000f, - LOG_PARAM = 0x0020, // parameters to functions - LOG_LEVEL_PARAM = 0x003f, + LOG_FUNCTION = 0x00000010, // function tracing + LOG_LEVEL_FUNCTION = 0x0000001f, - LOG_LOGIC = 0x0040, // control flow tracing within functions - LOG_LEVEL_LOGIC = 0x007f, + LOG_PARAM = 0x00000020, // parameters to functions + LOG_LEVEL_PARAM = 0x0000003f, - LOG_ALL = 0x4000, // print everything - LOG_LEVEL_ALL = 0x7fff + LOG_LOGIC = 0x00000040, // control flow tracing within functions + LOG_LEVEL_LOGIC = 0x0000007f, + + LOG_ALL = 0x7fffffff, // print everything + LOG_LEVEL_ALL = LOG_ALL, + + LOG_PREFIX_ALL = 0x80000000 }; #endif +#ifdef NS3_LOG_ENABLE /** * \param name a log component name + * \param level a logging level + * \param decorate whether or not to add function names to all logs * \ingroup logging * * Enable the logging output associated with that log component. * The logging output can be later disabled with a call * to ns3::LogComponentDisable. */ -#ifdef NS3_LOG_ENABLE -void LogComponentEnable (char const *name, enum LogLevel level); + void LogComponentEnable (char const *name, enum LogLevel level); +/** + * \param level a logging level + * \param decorate whether or not to add function names to all logs + * \ingroup logging + * + * Enable the logging output for all registered log components. + */ + void LogComponentEnableAll (enum LogLevel level); #else #define LogComponentEnable(a,b) +#define LogComponentEnableAll(a) #endif +#ifdef NS3_LOG_ENABLE /** * \param name a log component name + * \param level a logging level * \ingroup logging * * Disable the logging output associated with that log component. * The logging output can be later re-enabled with a call * to ns3::LogComponentEnable. */ -#ifdef NS3_LOG_ENABLE void LogComponentDisable (char const *name, enum LogLevel level); + +/** + * \param name a log component name + * \param level a logging level + * \ingroup logging + * + * Disable the logging output associated with that log component. + * The logging output can be later re-enabled with a call + * to ns3::LogComponentEnable. + */ +void LogComponentDisableAll (enum LogLevel level); + #else #define LogComponentDisable(a,b) +#define LogComponentDisableAll(a) #endif /** @@ -240,8 +270,12 @@ public: bool IsNoneEnabled (void) const; void Enable (enum LogLevel level); void Disable (enum LogLevel level); + bool Decorate (void) const; + char const *Name (void) const; private: - int32_t m_levels; + int32_t m_levels; + char const *m_name; + bool m_decorate; }; #endif diff --git a/tutorial/hello-simulator.cc b/tutorial/hello-simulator.cc index 735d98130..885597be2 100644 --- a/tutorial/hello-simulator.cc +++ b/tutorial/hello-simulator.cc @@ -23,7 +23,8 @@ using namespace ns3; int main (int argc, char *argv[]) { - LogComponentEnable ("HelloSimulator", LOG_LEVEL_INFO); + LogComponentEnable ("HelloSimulator", + LogLevel (LOG_LEVEL_INFO | LOG_PREFIX_ALL)); NS_LOG_INFO ("Hello Simulator"); } From 4585f14b5f7340fc0da7c512c73b580b15b4f4fa Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 11 Oct 2007 17:59:59 +0200 Subject: [PATCH 40/61] bug 87: do not export the garbage collection facility from the Timer class. --- src/simulator/timer.cc | 32 ++++---------------------------- src/simulator/timer.h | 36 +----------------------------------- 2 files changed, 5 insertions(+), 63 deletions(-) diff --git a/src/simulator/timer.cc b/src/simulator/timer.cc index 2642698cb..128d11140 100644 --- a/src/simulator/timer.cc +++ b/src/simulator/timer.cc @@ -20,7 +20,6 @@ #include "timer.h" #include "simulator.h" #include "simulation-singleton.h" -#include "event-garbage-collector.h" namespace ns3 { @@ -31,16 +30,8 @@ Timer::Timer () m_impl (0) {} -Timer::Timer (enum SchedulePolicy schedulePolicy, - enum DestroyPolicy destroyPolicy) - : m_flags (schedulePolicy | destroyPolicy), - m_delay (FemtoSeconds (0)), - m_event (), - m_impl (0) -{} - -Timer::Timer (enum GarbageCollectPolicy policy) - : m_flags (GARBAGE_COLLECT), +Timer::Timer (enum DestroyPolicy destroyPolicy) + : m_flags (destroyPolicy), m_delay (FemtoSeconds (0)), m_event (), m_impl (0) @@ -149,26 +140,11 @@ void Timer::Schedule (Time delay) { NS_ASSERT (m_impl != 0); - if (m_flags & CHECK_ON_SCHEDULE) + if (m_event.IsRunning ()) { - if (m_event.IsRunning ()) - { - NS_FATAL_ERROR ("Event is still running while re-scheduling."); - } - } - else if (m_flags & CANCEL_ON_SCHEDULE) - { - m_event.Cancel (); - } - else if (m_flags & REMOVE_ON_SCHEDULE) - { - Simulator::Remove (m_event); + NS_FATAL_ERROR ("Event is still running while re-scheduling."); } m_event = m_impl->Schedule (delay); - if (m_flags & GARBAGE_COLLECT) - { - SimulationSingleton::Get ()->Track (m_event); - } } void diff --git a/src/simulator/timer.h b/src/simulator/timer.h index 969ea8ad3..7e5a8d636 100644 --- a/src/simulator/timer.h +++ b/src/simulator/timer.h @@ -43,23 +43,6 @@ class TimerImpl; class Timer { public: - enum SchedulePolicy { - /** - * This policy cancels the event before scheduling a new event - * for each call to Timer::Schedule. - */ - CANCEL_ON_SCHEDULE = (1<<0), - /** - * This policy removes the event from the simulation event list - * before scheduling a new event for each call to Timer::Schedule. - */ - REMOVE_ON_SCHEDULE = (1<<1), - /** - * This policy enforces a check before each call to Timer::Schedule - * to verify that the timer has already expired. - */ - CHECK_ON_SCHEDULE = (1<<2), - }; enum DestroyPolicy { /** * This policy cancels the event from the destructor of the Timer @@ -77,15 +60,6 @@ public: */ CHECK_ON_DESTROY = (1<<5) }; - enum GarbageCollectPolicy { - /** - * Every event scheduled with this policy is kept track of by an - * event garbage collector which makes sure that all events - * of timers with a GARBAGE_COLLECT policy are cancelled at the - * end of the simulation. - */ - GARBAGE_COLLECT = (1<<6) - }; enum State { RUNNING, EXPIRED, @@ -93,21 +67,13 @@ public: }; /** * create a timer with a default event lifetime management policy: - * - CHECK_ON_SCHEDULE * - CHECK_ON_DESTROY */ Timer (); /** - * \param scheduleFlags the event lifetime management policies to use for schedule events * \param destroyFlags the event lifetime management policies to use for destroy events */ - Timer (enum SchedulePolicy schedulePolicy, - enum DestroyPolicy destroyPolicy); - /** - * \param policy the garbage collect policy. Only one - * value is possible. - */ - Timer (enum GarbageCollectPolicy policy); + Timer (enum DestroyPolicy destroyPolicy); ~Timer (); /** From 6218b0048633a74dad6a5c8f69ebb7d77b109756 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 11 Oct 2007 15:39:39 +0100 Subject: [PATCH 41/61] Bug #88 (Ipv4Address operator ==, !=, < should be inline for performance reasons) --- src/node/ipv4-address.cc | 23 ----------------------- src/node/ipv4-address.h | 25 +++++++++++++++++++++---- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/src/node/ipv4-address.cc b/src/node/ipv4-address.cc index 7e264b4cf..f01dbed51 100644 --- a/src/node/ipv4-address.cc +++ b/src/node/ipv4-address.cc @@ -151,16 +151,6 @@ Ipv4Address::Set (char const *address) m_address = AsciiToIpv4Host (address); } -bool -Ipv4Address::IsEqual (Ipv4Address other) const -{ - if (other.m_address == m_address) { - return true; - } else { - return false; - } -} - Ipv4Address Ipv4Address::CombineMask (Ipv4Mask const &mask) const { @@ -296,19 +286,6 @@ Ipv4Address::GetLoopback (void) return loopback; } -bool operator == (Ipv4Address const &a, Ipv4Address const &b) -{ - return a.IsEqual (b); -} -bool operator != (Ipv4Address const &a, Ipv4Address const &b) -{ - return !a.IsEqual (b); -} -bool operator < (Ipv4Address const &addrA, Ipv4Address const &addrB) -{ - return (addrA.GetHostOrder () < addrB.GetHostOrder ()); -} - size_t Ipv4AddressHash::operator()(Ipv4Address const &x) const { return x.GetHostOrder (); diff --git a/src/node/ipv4-address.h b/src/node/ipv4-address.h index 8a7807a49..2f41421af 100644 --- a/src/node/ipv4-address.h +++ b/src/node/ipv4-address.h @@ -73,7 +73,10 @@ public: * \param other address to which to compare this address * \return True if the addresses are equal. False otherwise. */ - bool IsEqual (Ipv4Address other) const; + bool IsEqual (const Ipv4Address &other) const + { + return m_address == other.m_address; + } /** * \brief Get the host-order 32-bit IP address @@ -142,6 +145,10 @@ private: Address ConvertTo (void) const; static uint8_t GetType (void); uint32_t m_address; + + friend bool operator == (Ipv4Address const &a, Ipv4Address const &b); + friend bool operator != (Ipv4Address const &a, Ipv4Address const &b); + friend bool operator < (Ipv4Address const &addrA, Ipv4Address const &addrB); }; @@ -177,9 +184,19 @@ private: std::ostream& operator<< (std::ostream& os, Ipv4Address const& address); std::ostream& operator<< (std::ostream& os, Ipv4Mask const& mask); -bool operator == (Ipv4Address const &a, Ipv4Address const &b); -bool operator != (Ipv4Address const &a, Ipv4Address const &b); -bool operator < (Ipv4Address const &addrA, Ipv4Address const &addrB); +inline bool operator == (const Ipv4Address &a, const Ipv4Address &b) +{ + return (a.m_address == b.m_address); +} +inline bool operator != (const Ipv4Address &a, const Ipv4Address &b) +{ + return (a.m_address != b.m_address); +} +inline bool operator < (const Ipv4Address &a, const Ipv4Address &b) +{ + return (a.m_address < b.m_address); +} + class Ipv4AddressHash : public std::unary_function { public: From f77b8a91376c57080bea3e9e6142de1f3f8ee7ac Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 11 Oct 2007 16:17:27 +0100 Subject: [PATCH 42/61] Make EventGarbageCollector private to the olsr module; adapt olsr to Timer API changes. --- .../olsr}/event-garbage-collector.cc | 0 .../olsr}/event-garbage-collector.h | 4 +- src/routing/olsr/olsr-agent-impl.cc | 73 +++++++++---------- src/routing/olsr/olsr-agent-impl.h | 5 +- src/routing/olsr/wscript | 1 + src/simulator/wscript | 1 - 6 files changed, 41 insertions(+), 43 deletions(-) rename src/{simulator => routing/olsr}/event-garbage-collector.cc (100%) rename src/{simulator => routing/olsr}/event-garbage-collector.h (96%) diff --git a/src/simulator/event-garbage-collector.cc b/src/routing/olsr/event-garbage-collector.cc similarity index 100% rename from src/simulator/event-garbage-collector.cc rename to src/routing/olsr/event-garbage-collector.cc diff --git a/src/simulator/event-garbage-collector.h b/src/routing/olsr/event-garbage-collector.h similarity index 96% rename from src/simulator/event-garbage-collector.h rename to src/routing/olsr/event-garbage-collector.h index b03b86322..a9fe05f16 100644 --- a/src/simulator/event-garbage-collector.h +++ b/src/routing/olsr/event-garbage-collector.h @@ -22,8 +22,8 @@ #define EVENT_GARBAGE_COLLECTOR_H #include -#include "event-id.h" -#include "simulator.h" +#include "ns3/event-id.h" +#include "ns3/simulator.h" namespace ns3 { diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index 75820775b..c260ac018 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -151,11 +151,10 @@ NS_DEBUG_COMPONENT_DEFINE ("OlsrAgent"); OlsrAgentImpl::OlsrAgentImpl (Ptr node) : - m_events (Timer::GARBAGE_COLLECT), m_useL2Notifications (false), - m_helloTimer (Timer::CHECK_ON_SCHEDULE, Timer::CANCEL_ON_DESTROY), - m_tcTimer (Timer::CHECK_ON_SCHEDULE, Timer::CANCEL_ON_DESTROY), - m_midTimer (Timer::CHECK_ON_SCHEDULE, Timer::CANCEL_ON_DESTROY) + m_helloTimer (Timer::CANCEL_ON_DESTROY), + m_tcTimer (Timer::CANCEL_ON_DESTROY), + m_midTimer (Timer::CANCEL_ON_DESTROY) { m_helloTimer.SetFunction (&OlsrAgentImpl::HelloTimerExpire, this); m_tcTimer.SetFunction (&OlsrAgentImpl::TcTimerExpire, this); @@ -891,9 +890,9 @@ OlsrAgentImpl::ProcessTc (const OlsrMessageHeader &msg, AddTopologyTuple (topologyTuple); // Schedules topology tuple deletion - m_events.SetFunction (&OlsrAgentImpl::TopologyTupleTimerExpire, this); - m_events.SetArguments (topologyTuple); - m_events.Schedule (DELAY (topologyTuple.expirationTime)); + m_events.Track (Simulator::Schedule (DELAY (topologyTuple.expirationTime), + &OlsrAgentImpl::TopologyTupleTimerExpire, + this, topologyTuple)); } } } @@ -1350,9 +1349,8 @@ OlsrAgentImpl::LinkSensing (const OlsrMessageHeader &msg, // Schedules link tuple deletion if (created && link_tuple != NULL) { - m_events.SetFunction (&OlsrAgentImpl::LinkTupleTimerExpire, this); - m_events.SetArguments (*link_tuple); - m_events.Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime))); + m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)), + &OlsrAgentImpl::LinkTupleTimerExpire, this, *link_tuple)); } } @@ -1420,9 +1418,9 @@ OlsrAgentImpl::PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg, now + msg.GetVTime (); // Schedules nb2hop tuple // deletion - m_events.SetFunction (&OlsrAgentImpl::Nb2hopTupleTimerExpire, this); - m_events.SetArguments (new_nb2hop_tuple); - m_events.Schedule (DELAY (new_nb2hop_tuple.expirationTime)); + m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime), + &OlsrAgentImpl::Nb2hopTupleTimerExpire, this, + new_nb2hop_tuple)); } else { @@ -1488,9 +1486,10 @@ OlsrAgentImpl::PopulateMprSelectorSet (const OlsrMessageHeader &msg, AddMprSelectorTuple (mprsel_tuple); // Schedules mpr selector tuple deletion - m_events.SetFunction (&OlsrAgentImpl::MprSelTupleTimerExpire, this); - m_events.SetArguments (mprsel_tuple); - m_events.Schedule (DELAY (mprsel_tuple.expirationTime)); + m_events.Track (Simulator::Schedule + (DELAY (mprsel_tuple.expirationTime), + &OlsrAgentImpl::MprSelTupleTimerExpire, this, + mprsel_tuple)); } else { @@ -1928,9 +1927,9 @@ OlsrAgentImpl::DupTupleTimerExpire (DuplicateTuple tuple) } else { - m_events.SetFunction (&OlsrAgentImpl::DupTupleTimerExpire, this); - m_events.SetArguments (tuple); - m_events.Schedule (DELAY (tuple.expirationTime)); + m_events.Track (Simulator::Schedule (DELAY (tuple.expirationTime), + &OlsrAgentImpl::DupTupleTimerExpire, this, + tuple)); } } @@ -1961,15 +1960,15 @@ OlsrAgentImpl::LinkTupleTimerExpire (LinkTuple tuple) else NeighborLoss (tuple); - m_events.SetFunction (&OlsrAgentImpl::LinkTupleTimerExpire, this); - m_events.SetArguments (tuple); - m_events.Schedule (DELAY (tuple.time)); + m_events.Track (Simulator::Schedule (DELAY (tuple.time), + &OlsrAgentImpl::LinkTupleTimerExpire, this, + tuple)); } else { - m_events.SetFunction (&OlsrAgentImpl::LinkTupleTimerExpire, this); - m_events.SetArguments (tuple); - m_events.Schedule (DELAY (std::min (tuple.time, tuple.symTime))); + m_events.Track (Simulator::Schedule (DELAY (std::min (tuple.time, tuple.symTime)), + &OlsrAgentImpl::LinkTupleTimerExpire, this, + tuple)); } } @@ -1989,9 +1988,9 @@ OlsrAgentImpl::Nb2hopTupleTimerExpire (TwoHopNeighborTuple tuple) } else { - m_events.SetFunction (&OlsrAgentImpl::Nb2hopTupleTimerExpire, this); - m_events.SetArguments (tuple); - m_events.Schedule (DELAY (tuple.expirationTime)); + m_events.Track (Simulator::Schedule (DELAY (tuple.expirationTime), + &OlsrAgentImpl::Nb2hopTupleTimerExpire, + this, tuple)); } } @@ -2011,9 +2010,9 @@ OlsrAgentImpl::MprSelTupleTimerExpire (MprSelectorTuple tuple) } else { - m_events.SetFunction (&OlsrAgentImpl::MprSelTupleTimerExpire, this); - m_events.SetArguments (tuple); - m_events.Schedule (DELAY (tuple.expirationTime)); + m_events.Track (Simulator::Schedule (DELAY (tuple.expirationTime), + &OlsrAgentImpl::MprSelTupleTimerExpire, + this, tuple)); } } @@ -2033,9 +2032,9 @@ OlsrAgentImpl::TopologyTupleTimerExpire (TopologyTuple tuple) } else { - m_events.SetFunction (&OlsrAgentImpl::TopologyTupleTimerExpire, this); - m_events.SetArguments (tuple); - m_events.Schedule (DELAY (tuple.expirationTime)); + m_events.Track (Simulator::Schedule (DELAY (tuple.expirationTime), + &OlsrAgentImpl::TopologyTupleTimerExpire, + this, tuple)); } } @@ -2053,9 +2052,9 @@ OlsrAgentImpl::IfaceAssocTupleTimerExpire (IfaceAssocTuple tuple) } else { - m_events.SetFunction (&OlsrAgentImpl::IfaceAssocTupleTimerExpire, this); - m_events.SetArguments (tuple); - m_events.Schedule (DELAY (tuple.time)); + m_events.Track (Simulator::Schedule (DELAY (tuple.time), + &OlsrAgentImpl::IfaceAssocTupleTimerExpire, + this, tuple)); } } diff --git a/src/routing/olsr/olsr-agent-impl.h b/src/routing/olsr/olsr-agent-impl.h index 4423c3e26..94618ed8c 100644 --- a/src/routing/olsr/olsr-agent-impl.h +++ b/src/routing/olsr/olsr-agent-impl.h @@ -38,8 +38,7 @@ #include "ns3/packet.h" #include "ns3/node.h" #include "ns3/socket.h" -//#include "single-event.h" -//#include "event-collector.h" +#include "event-garbage-collector.h" #include "ns3/timer.h" @@ -59,7 +58,7 @@ public: virtual void SetMainInterface (uint32_t interface); private: - Timer m_events; + EventGarbageCollector m_events; /// Address of the routing agent. Ipv4Address m_routingAgentAddr; diff --git a/src/routing/olsr/wscript b/src/routing/olsr/wscript index cb803023b..5086cd8fa 100644 --- a/src/routing/olsr/wscript +++ b/src/routing/olsr/wscript @@ -10,6 +10,7 @@ def build(bld): 'olsr-agent.cc', 'olsr-agent-impl.cc', 'olsr.cc', + 'event-garbage-collector.cc', ] headers = bld.create_obj('ns3header') diff --git a/src/simulator/wscript b/src/simulator/wscript index 68279c9e3..fd3964418 100644 --- a/src/simulator/wscript +++ b/src/simulator/wscript @@ -61,7 +61,6 @@ def build(bld): 'simulator.cc', 'time-default-value.cc', 'timer.cc', - 'event-garbage-collector.cc', ] headers = bld.create_obj('ns3header') From a2d11d810060010aedcffe1c5a975808769d1d57 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 11 Oct 2007 17:26:32 +0100 Subject: [PATCH 43/61] Optimize EventGarbageCollector by using std::multiset with EventIds sorted by expiration time. --- src/routing/olsr/event-garbage-collector.cc | 20 +++++++++++--------- src/routing/olsr/event-garbage-collector.h | 16 +++++++++++++--- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/routing/olsr/event-garbage-collector.cc b/src/routing/olsr/event-garbage-collector.cc index 776f2a999..a68478c87 100644 --- a/src/routing/olsr/event-garbage-collector.cc +++ b/src/routing/olsr/event-garbage-collector.cc @@ -34,17 +34,11 @@ EventGarbageCollector::EventGarbageCollector () : void EventGarbageCollector::Track (EventId event) { - m_events.push_back (event); + m_events.insert (event); if (m_events.size () >= m_nextCleanupSize) Cleanup (); } -inline bool -EventExpiredPredicate (const EventId &event) -{ - return event.IsExpired (); -} - void EventGarbageCollector::Grow () { @@ -64,7 +58,15 @@ EventGarbageCollector::Shrink () void EventGarbageCollector::Cleanup () { - m_events.remove_if (EventExpiredPredicate); + for (EventList::iterator iter = m_events.begin (); iter != m_events.end ();) + { + if ((*iter).IsExpired ()) + { + m_events.erase (iter++); + } + else + break; // EventIds are sorted by timestamp => further events are not expired for sure + } // If after cleanup we are still over the limit, increase the limit. if (m_events.size () >= m_nextCleanupSize) @@ -76,7 +78,7 @@ EventGarbageCollector::Cleanup () EventGarbageCollector::~EventGarbageCollector () { - for (std::list::iterator event = m_events.begin (); + for (EventList::iterator event = m_events.begin (); event != m_events.end (); event++) { Simulator::Cancel (*event); diff --git a/src/routing/olsr/event-garbage-collector.h b/src/routing/olsr/event-garbage-collector.h index a9fe05f16..e19a847b5 100644 --- a/src/routing/olsr/event-garbage-collector.h +++ b/src/routing/olsr/event-garbage-collector.h @@ -21,7 +21,7 @@ #ifndef EVENT_GARBAGE_COLLECTOR_H #define EVENT_GARBAGE_COLLECTOR_H -#include +#include #include "ns3/event-id.h" #include "ns3/simulator.h" @@ -49,8 +49,18 @@ public: private: - std::list::size_type m_nextCleanupSize; - std::list m_events; + struct EventIdLessThanTs + { + bool operator () (const EventId &a, const EventId &b) + { + return (a.GetTs () < b.GetTs ()); + } + }; + + typedef std::multiset EventList; + + EventList::size_type m_nextCleanupSize; + EventList m_events; void Cleanup (); void Grow (); From adf066acdd22412cd04fa51f5527cd7dab433e37 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 11 Oct 2007 18:34:15 +0100 Subject: [PATCH 44/61] Add a missing const. --- src/routing/olsr/event-garbage-collector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routing/olsr/event-garbage-collector.h b/src/routing/olsr/event-garbage-collector.h index e19a847b5..9d7ccbf82 100644 --- a/src/routing/olsr/event-garbage-collector.h +++ b/src/routing/olsr/event-garbage-collector.h @@ -51,7 +51,7 @@ private: struct EventIdLessThanTs { - bool operator () (const EventId &a, const EventId &b) + bool operator () (const EventId &a, const EventId &b) const { return (a.GetTs () < b.GetTs ()); } From 1a480445c95d9d694b9c086c4eb27158f9c1b3ff Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 12 Oct 2007 15:49:04 +0200 Subject: [PATCH 45/61] make sure we cleanup after ourselves in DefaultValueTests --- src/core/default-value.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/default-value.cc b/src/core/default-value.cc index 4dcfcacbc..2acb6e97d 100644 --- a/src/core/default-value.cc +++ b/src/core/default-value.cc @@ -416,6 +416,8 @@ DefaultValueTest::RunTests (void) DefaultValueList::Remove ("bool-a"); DefaultValueList::Remove ("test-i"); DefaultValueList::Remove ("test-c"); + DefaultValueList::Remove ("test-x"); + DefaultValueList::Remove ("test-y"); DefaultValueList::Remove ("test-ui32"); return result; From 90439fc8c468e1f5df855887d1bea092d81cfcc0 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 12 Oct 2007 12:30:19 -0700 Subject: [PATCH 46/61] env var changes --- src/core/log.cc | 50 ++++++++++++++++++++++++------------- tutorial/hello-simulator.cc | 7 ++++-- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/core/log.cc b/src/core/log.cc index 97d82cc4c..d3e6fe30f 100644 --- a/src/core/log.cc +++ b/src/core/log.cc @@ -66,6 +66,12 @@ LogComponentEnableEnvVar (void) isFirstLog = false; return; } + if (env == "*") + { + LogComponentEnableAll (LOG_DEBUG); + isFirstLog = false; + return; + } bool allFound = true; std::string::size_type cur = 0; std::string::size_type next = 0; @@ -88,7 +94,7 @@ LogComponentEnableEnvVar (void) } std::string::size_type equal = tmp.find ("="); std::string component; - int level; + int level = 0; if (equal == std::string::npos) { component = tmp; @@ -136,52 +142,60 @@ LogComponentEnableEnvVar (void) { level |= LOG_ALL; } - else if (lev == "errorlevel") + else if (lev == "level_error") { level |= LOG_LEVEL_ERROR; } - else if (lev == "warnlevel") + else if (lev == "level_warn") { level |= LOG_LEVEL_WARN; } - else if (lev == "debuglevel") + else if (lev == "level_debug") { level |= LOG_LEVEL_DEBUG; } - else if (lev == "infolevel") + else if (lev == "level_info") { level |= LOG_LEVEL_INFO; } - else if (lev == "functionlevel") + else if (lev == "level_function") { level |= LOG_LEVEL_FUNCTION; } - else if (lev == "paramlevel") + else if (lev == "level_param") { level |= LOG_LEVEL_PARAM; } - else if (lev == "logiclevel") + else if (lev == "level_logic") { level |= LOG_LEVEL_LOGIC; } - else if (lev == "alllevel") + else if (lev == "level_all") { level |= LOG_LEVEL_ALL; } } while (next_lev != std::string::npos); } bool found = false; - ComponentList *components = GetComponentList (); - for (ComponentListI i = components->begin (); - i != components->end (); - i++) + if (component == "*") { - if (i->first.compare (component) == 0) + found = true; + LogComponentEnableAll ((enum LogLevel)level); + } + else + { + ComponentList *components = GetComponentList (); + for (ComponentListI i = components->begin (); + i != components->end (); + i++) { - found = true; - - i->second->Enable ((enum LogLevel)level); - break; + if (i->first.compare (component) == 0) + { + found = true; + + i->second->Enable ((enum LogLevel)level); + break; + } } } if (!found) diff --git a/tutorial/hello-simulator.cc b/tutorial/hello-simulator.cc index 885597be2..50ded681c 100644 --- a/tutorial/hello-simulator.cc +++ b/tutorial/hello-simulator.cc @@ -15,6 +15,7 @@ */ #include "ns3/log.h" +#include "ns3/debug.h" NS_LOG_COMPONENT_DEFINE ("HelloSimulator"); @@ -23,8 +24,10 @@ using namespace ns3; int main (int argc, char *argv[]) { - LogComponentEnable ("HelloSimulator", - LogLevel (LOG_LEVEL_INFO | LOG_PREFIX_ALL)); + DebugComponentEnable ("Log"); + + // LogComponentEnable ("HelloSimulator", + // LogLevel (LOG_LEVEL_INFO | LOG_PREFIX_ALL)); NS_LOG_INFO ("Hello Simulator"); } From 9a7694f32a5aa64e430afd01c99e4601ca98b758 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 12 Oct 2007 13:41:24 -0700 Subject: [PATCH 47/61] deal with static constructor problem --- src/core/log.cc | 40 +++++++++++++++++++++++++++++++++++++++- src/core/log.h | 44 +++++++++++++++++++++++++++----------------- 2 files changed, 66 insertions(+), 18 deletions(-) diff --git a/src/core/log.cc b/src/core/log.cc index d3e6fe30f..0bfb978c4 100644 --- a/src/core/log.cc +++ b/src/core/log.cc @@ -48,10 +48,44 @@ void LogComponentEnableEnvVar (void) { static bool isFirstLog = true; +#if 0 +// +// Interesting static constructor bug: +// +// The RandomDirection2dMobilityModel declares a RandomVariableDefaultValue +// g_speedVariable. This variable is initialized in the +// static_initialization_and_destruction_0 function as expected. This causes +// RandomVariableDefaultValue::Parse () to be called which calls NS_LOG_X +// functions. The macro calls LogComponent::IsEnabled () which calls +// LogComponentEnableEnvVar (). The following variable called isFirstLog +// is set after the first call to prevent the environment variable from +// actually being parsed on every log call. +// +// When the RandomDirection2dMobilityModel static constructor is run, other +// log components may not have had their static constructors run yet. It is +// in those other static constructors that their log components are added to +// the list of log components. +// +// The end result is that if any code calls an NS_LOG_X function during its +// static constructor, the environment variable check is "locked out" for +// any log component declarations (in different compilation units) that have +// not yet been executed. +// +// So, the choice seems to be to either 1) parse the environment variables +// at every log call; or 2) make LogComponentEnableEnvVar explicitly called +// after all other static constructors are called. This means in main (). +// The former choice seems the only reasonable way out if we care remotely +// about performance in logging. +// +// I made LogComponentEnableEnvVar a public API that you need to call in +// main () if you want to use environment variables to drive the log output. +// if (!isFirstLog) { return; } +#endif // 0 + #ifdef HAVE_GETENV char *envVar = getenv("NS_LOG"); if (envVar == 0) @@ -142,6 +176,10 @@ LogComponentEnableEnvVar (void) { level |= LOG_ALL; } + else if (lev == "prefix") + { + level |= LOG_PREFIX_ALL; + } else if (lev == "level_error") { level |= LOG_LEVEL_ERROR; @@ -236,7 +274,7 @@ LogComponent::LogComponent (char const * name) bool LogComponent::IsEnabled (enum LogLevel level) const { - LogComponentEnableEnvVar (); + // LogComponentEnableEnvVar (); return (level & m_levels) ? 1 : 0; } diff --git a/src/core/log.h b/src/core/log.h index d54b8fcdf..61ab9026d 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -32,22 +32,8 @@ * send information out on screen. All logging messages * are disabled by default. To enable selected logging * messages, use the ns3::LogComponentEnable - * function. - * - * Alternatively, you can use the NS_LOG - * environment variable to define a ';'-separated list of - * logging components to enable. For example, NS_LOG=a;b;c;DAFD;GH - * would enable the components 'a', 'b', 'c', 'DAFD', and, 'GH'. - * - * For each component, the "debug" log level is enabled by default - * but more components can be enabled selectively with the following - * syntax: NS_LOG='Component1=func|param|warn;Component2=error|debug' - * This example would enable the 'func', 'param', and 'warn' log - * levels for 'Component1' and the 'error' and 'debug' log levels - * for 'Component2'. - * - * The list of available log components can be printed on stdout - * with the NS_LOG=print-list syntax. + * function or use the NS_LOG environment variable and + * ns3::LogComponentEnableEnvVar */ /** @@ -187,12 +173,34 @@ enum LogLevel { LOG_ALL = 0x7fffffff, // print everything LOG_LEVEL_ALL = LOG_ALL, - LOG_PREFIX_ALL = 0x80000000 + LOG_PREFIX_ALL = 0x80000000 // prefix all trace prints with function }; #endif #ifdef NS3_LOG_ENABLE +/** + * \brief Enable the logging output based on an environment variable. + * + * Use the environment variable NS_LOG to define a ';'-separated list of + * logging components to enable. For example, NS_LOG=a;b;c;DAFD;GH + * would enable the components 'a', 'b', 'c', 'DAFD', and, 'GH'. + * NS_LOG=* will enable all available log components. + * + * For each component, the "debug" log level is enabled by default + * but more components can be enabled selectively with the following + * syntax: NS_LOG='Component1=func|param|warn;Component2=error|debug' + * This example would enable the 'func', 'param', and 'warn' log + * levels for 'Component1' and the 'error' and 'debug' log levels + * for 'Component2'. The wildcard can be used here as well. For example + * NS_LOG='*=level_all|prefix' would enable all log levels and prefix all + * prints with the component and function names. + * + * The list of available log components can be printed on stdout + * with the NS_LOG=print-list syntax. + */ + void LogComponentEnableEnvVar (void); + /** * \param name a log component name * \param level a logging level @@ -204,6 +212,7 @@ enum LogLevel { * to ns3::LogComponentDisable. */ void LogComponentEnable (char const *name, enum LogLevel level); + /** * \param level a logging level * \param decorate whether or not to add function names to all logs @@ -213,6 +222,7 @@ enum LogLevel { */ void LogComponentEnableAll (enum LogLevel level); #else +#define LogComponentEnableEnvVar() #define LogComponentEnable(a,b) #define LogComponentEnableAll(a) #endif From c96ad24a35581080abfc02e80a66498ac4cd27f5 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sat, 6 Oct 2007 21:21:07 -0700 Subject: [PATCH 48/61] Add support for non-unit-cost metrics for Ipv4Interfaces (for use in routing); add example script simple-alternate-routing.cc --- examples/simple-alternate-routing.cc | 224 ++++++++++++++++++ examples/wscript | 4 + src/devices/csma/csma-ipv4-topology.cc | 4 +- src/devices/csma/csma-ipv4-topology.h | 4 +- .../point-to-point/point-to-point-topology.cc | 53 +++++ .../point-to-point/point-to-point-topology.h | 14 ++ src/internet-node/ipv4-impl.cc | 12 + src/internet-node/ipv4-impl.h | 2 + src/internet-node/ipv4-interface.cc | 18 +- src/internet-node/ipv4-interface.h | 9 + src/internet-node/ipv4-l3-protocol.cc | 18 ++ src/internet-node/ipv4-l3-protocol.h | 2 + src/node/ipv4.h | 14 ++ .../global-route-manager-impl.cc | 18 +- .../global-routing/global-router-interface.cc | 18 +- .../global-routing/global-router-interface.h | 8 +- 16 files changed, 402 insertions(+), 20 deletions(-) create mode 100644 examples/simple-alternate-routing.cc diff --git a/examples/simple-alternate-routing.cc b/examples/simple-alternate-routing.cc new file mode 100644 index 000000000..e9cedff04 --- /dev/null +++ b/examples/simple-alternate-routing.cc @@ -0,0 +1,224 @@ +/* -*- 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 + * + */ + +// +// Network topology +// +// n0 +// \ 5 Mb/s, 2ms +// \ 1.5Mb/s, 10ms +// n2 ------------------------n3 +// / / +// / 5 Mb/s, 2ms / +// n1-------------------------- +// 1.5 Mb/s, 100ms +// +// this is a modification of simple-global-routing to allow for +// a single hop but higher-cost path between n1 and n3 +// +// - Tracing of queues and packet receptions to file "simple-rerouting.tr" + +#include +#include +#include +#include + +#include "ns3/log.h" + +#include "ns3/command-line.h" +#include "ns3/default-value.h" +#include "ns3/ptr.h" +#include "ns3/random-variable.h" + +#include "ns3/simulator.h" +#include "ns3/nstime.h" +#include "ns3/data-rate.h" + +#include "ns3/ascii-trace.h" +#include "ns3/pcap-trace.h" +#include "ns3/internet-node.h" +#include "ns3/point-to-point-channel.h" +#include "ns3/point-to-point-net-device.h" +#include "ns3/ipv4-address.h" +#include "ns3/ipv4.h" +#include "ns3/socket.h" +#include "ns3/inet-socket-address.h" +#include "ns3/ipv4-route.h" +#include "ns3/point-to-point-topology.h" +#include "ns3/onoff-application.h" +#include "ns3/packet-sink.h" +#include "ns3/global-route-manager.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("SimpleAlternateRoutingExample"); + +int +main (int argc, char *argv[]) +{ + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this +#if 0 + LogComponentEnable("GlobalRouteManager", LOG_LOGIC); + LogComponentEnable("GlobalRouter", LOG_LOGIC); + LogComponentEnable("Object", LOG_LEVEL_ALL); + LogComponentEnable("Queue", LOG_LEVEL_ALL); + LogComponentEnable("DropTailQueue", LOG_LEVEL_ALL); + LogComponentEnable("Channel", LOG_LEVEL_ALL); + LogComponentEnable("CsmaChannel", LOG_LEVEL_ALL); + LogComponentEnable("NetDevice", LOG_LEVEL_ALL); + LogComponentEnable("CsmaNetDevice", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL); + LogComponentEnable("PacketSocket", LOG_LEVEL_ALL); + LogComponentEnable("Socket", LOG_LEVEL_ALL); + LogComponentEnable("UdpSocket", LOG_LEVEL_ALL); + LogComponentEnable("UdpL4Protocol", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4StaticRouting", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4Interface", LOG_LEVEL_ALL); + LogComponentEnable("ArpIpv4Interface", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4LoopbackInterface", LOG_LEVEL_ALL); + LogComponentEnable("OnOffApplication", LOG_LEVEL_ALL); + LogComponentEnable("PacketSinkApplication", LOG_LEVEL_ALL); + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_ALL); + LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_ALL); +#endif + // Set up some default values for the simulation. Use the + // DefaultValue::Bind () technique to tell the system what subclass of + // Queue to use, and what the queue limit is + + // The below Bind command tells the queue factory which class to + // instantiate, when the queue factory is invoked in the topology code + DefaultValue::Bind ("Queue", "DropTailQueue"); + + DefaultValue::Bind ("OnOffApplicationPacketSize", "210"); + DefaultValue::Bind ("OnOffApplicationDataRate", "300b/s"); + + // The below metric, if set to 3 or higher, will cause packets between + // n1 and n3 to take the 2-hop route through n2 + // + // Additionally, we plumb this metric into the default value / command + // line argument system as well, for exemplary purposes. This means + // that it can be resettable at the command-line to the program, + // rather than recompiling + // e.g. waf --run "simple-alternate-routing --AlternateCost=5" + uint16_t sampleMetric = 1; + CommandLine::AddArgValue ("AlternateCost", + "This metric is used in the example script between n3 and n1 ", + sampleMetric); + + // Allow the user to override any of the defaults and the above + // DefaultValue::Bind ()s at run-time, via command-line arguments + CommandLine::Parse (argc, argv); + + // Here, we will explicitly create four nodes. In more sophisticated + // topologies, we could configure a node factory. + NS_LOG_INFO ("Create nodes."); + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + // We create the channels first without any IP addressing information + NS_LOG_INFO ("Create channels."); + Ptr channel0 = + PointToPointTopology::AddPointToPointLink ( + n0, n2, DataRate (5000000), MilliSeconds (2)); + + Ptr channel1 = + PointToPointTopology::AddPointToPointLink ( + n1, n2, DataRate (5000000), MilliSeconds (2)); + + Ptr channel2 = + PointToPointTopology::AddPointToPointLink ( + n2, n3, DataRate (1500000), MilliSeconds (10)); + + Ptr channel3 = + PointToPointTopology::AddPointToPointLink ( + n1, n3, DataRate (1500000), MilliSeconds (100)); + + // Later, we add IP addresses. The middle two octets correspond to + // the channel number. + NS_LOG_INFO ("Assign IP Addresses."); + PointToPointTopology::AddIpv4Addresses ( + channel0, n0, Ipv4Address ("10.0.0.1"), + n2, Ipv4Address ("10.0.0.2")); + + PointToPointTopology::AddIpv4Addresses ( + channel1, n1, Ipv4Address ("10.1.1.1"), + n2, Ipv4Address ("10.1.1.2")); + + PointToPointTopology::AddIpv4Addresses ( + channel2, n2, Ipv4Address ("10.2.2.1"), + n3, Ipv4Address ("10.2.2.2")); + + PointToPointTopology::AddIpv4Addresses ( + channel3, n1, Ipv4Address ("10.3.3.1"), + n3, Ipv4Address ("10.3.3.2")); + + PointToPointTopology::SetIpv4Metric ( + channel3, n1, n3, sampleMetric); + + // Create router nodes, initialize routing database and set up the routing + // tables in the nodes. + GlobalRouteManager::PopulateRoutingTables (); + + // Create the OnOff application to send UDP datagrams + NS_LOG_INFO ("Create Application."); + uint16_t port = 9; // Discard port (RFC 863) + + // Create a flow from n3 to n1, starting at time 1.1 seconds + Ptr ooff = Create ( + n3, + InetSocketAddress ("10.1.1.1", port), + "Udp", + ConstantVariable (1), + ConstantVariable (0)); + // Start the application + ooff->Start (Seconds (1.1)); + ooff->Stop (Seconds (10.0)); + + // Create a packet sink to receive these packets + Ptr sink = Create ( + n1, + InetSocketAddress (Ipv4Address::GetAny (), port), + "Udp"); + // Start the sink + sink->Start (Seconds (1.1)); + sink->Stop (Seconds (10.0)); + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the simple-alternate-routing.tr file + NS_LOG_INFO ("Configure Tracing."); + AsciiTrace asciitrace ("simple-alternate-routing.tr"); + asciitrace.TraceAllQueues (); + asciitrace.TraceAllNetDeviceRx (); + + // Also configure some tcpdump traces; each interface will be traced + // The output files will be named simple-p2p.pcap-- + // and can be read by the "tcpdump -r" command (use "-tt" option to + // display timestamps correctly) + PcapTrace pcaptrace ("simple-alternate-routing.pcap"); + pcaptrace.TraceAllIp (); + + NS_LOG_INFO ("Run Simulation."); + Simulator::Run (); + Simulator::Destroy (); + NS_LOG_INFO ("Done."); + + return 0; +} diff --git a/examples/wscript b/examples/wscript index d65ac22e0..f597225fb 100644 --- a/examples/wscript +++ b/examples/wscript @@ -6,6 +6,10 @@ def build(bld): ['point-to-point', 'internet-node', 'global-routing']) obj.source = 'simple-global-routing.cc' + obj = bld.create_ns3_program('simple-alternate-routing', + ['point-to-point', 'internet-node', 'global-routing']) + obj.source = 'simple-alternate-routing.cc' + obj = bld.create_ns3_program('simple-point-to-point', ['point-to-point', 'internet-node']) obj.source = 'simple-point-to-point.cc' diff --git a/src/devices/csma/csma-ipv4-topology.cc b/src/devices/csma/csma-ipv4-topology.cc index 750860f4d..43e8bcf42 100644 --- a/src/devices/csma/csma-ipv4-topology.cc +++ b/src/devices/csma/csma-ipv4-topology.cc @@ -96,7 +96,8 @@ CsmaIpv4Topology::AddIpv4Address( Ptr node, uint32_t netDeviceNumber, const Ipv4Address address, - const Ipv4Mask mask) + const Ipv4Mask mask, + uint16_t metric) { Ptr nd = node->GetDevice(netDeviceNumber); @@ -105,6 +106,7 @@ CsmaIpv4Topology::AddIpv4Address( ipv4->SetAddress (ifIndex, address); ipv4->SetNetworkMask (ifIndex, mask); + ipv4->SetMetric (ifIndex, metric); ipv4->SetUp (ifIndex); return ifIndex; } diff --git a/src/devices/csma/csma-ipv4-topology.h b/src/devices/csma/csma-ipv4-topology.h index 415ea6257..9cb4ab30a 100644 --- a/src/devices/csma/csma-ipv4-topology.h +++ b/src/devices/csma/csma-ipv4-topology.h @@ -103,6 +103,7 @@ public: * the address. * \param address The Ipv4 Address for the interface. * \param network The network mask for the interface + * \param metric (optional) metric (cost) to assign for routing calculations * * Add an Ipv4Address to the Ipv4 interface associated with the * ndNum CsmaIpv4NetDevices on the provided CsmaIpv4Channel @@ -110,7 +111,8 @@ public: static uint32_t AddIpv4Address(Ptr node, uint32_t netDeviceNumber, const Ipv4Address address, - const Ipv4Mask mask); + const Ipv4Mask mask, + uint16_t metric = 1); /** * \param nd1 Node diff --git a/src/devices/point-to-point/point-to-point-topology.cc b/src/devices/point-to-point/point-to-point-topology.cc index 4c99eaf88..7e0fd4efd 100644 --- a/src/devices/point-to-point/point-to-point-topology.cc +++ b/src/devices/point-to-point/point-to-point-topology.cc @@ -103,6 +103,59 @@ PointToPointTopology::AddIpv4Addresses( } +void +PointToPointTopology::SetIpv4Metric( + Ptr chan, + Ptr n1, Ptr n2, const uint16_t metric) +{ + + // The PointToPoint channel is used to find the relevant NetDevices + NS_ASSERT (chan->GetNDevices () == 2); + Ptr nd1 = chan->GetDevice (0); + Ptr nd2 = chan->GetDevice (1); + // Make sure that nd1 belongs to n1 and nd2 to n2 + if ( (nd1->GetNode ()->GetId () == n2->GetId () ) && + (nd2->GetNode ()->GetId () == n1->GetId () ) ) + { + std::swap(nd1, nd2); + } + NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ()); + NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ()); + + // The NetDevice ifIndex does not correspond to the + // ifIndex used by Ipv4. Therefore, we have to iterate + // through the NetDevices until we find the Ipv4 ifIndex + // that corresponds to NetDevice nd1 + // Get interface indexes for both nodes corresponding to the right channel + uint32_t index = 0; + bool found = false; + Ptr ip1 = n1->QueryInterface (Ipv4::iid); + for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++) + { + if (ip1 ->GetNetDevice (i) == nd1) + { + index = i; + found = true; + } + } + NS_ASSERT(found); + ip1->SetMetric (index, metric); + + index = 0; + found = false; + Ptr ip2 = n2->QueryInterface (Ipv4::iid); + for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++) + { + if (ip2 ->GetNetDevice (i) == nd2) + { + index = i; + found = true; + } + } + NS_ASSERT(found); + ip2->SetMetric (index, metric); +} + void PointToPointTopology::AddIpv4Routes ( Ptr n1, Ptr n2, Ptr chan) diff --git a/src/devices/point-to-point/point-to-point-topology.h b/src/devices/point-to-point/point-to-point-topology.h index c1f037380..35a452269 100644 --- a/src/devices/point-to-point/point-to-point-topology.h +++ b/src/devices/point-to-point/point-to-point-topology.h @@ -70,6 +70,20 @@ public: Ptr n1, const Ipv4Address& addr1, Ptr n2, const Ipv4Address& addr2); + /** + * \param chan PointToPointChannel to use + * \param n1 Node + * \param n2 Node + * \param metric link metric to assign on Ipv4Link on chan between n1 and n2 + * + * Add a non-unit-cost link metric (bidirectionally) to the Ipv4 + * interfaces associated with the two PointToPointNetDevices on the + * provided PointToPointChannel + */ + static void SetIpv4Metric( + Ptr chan, + Ptr n1, Ptr n2, const uint16_t metric); + /** * \param channel PointToPointChannel to use * \param n1 Node diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-node/ipv4-impl.cc index a67c6a4e8..bff1bfd0b 100644 --- a/src/internet-node/ipv4-impl.cc +++ b/src/internet-node/ipv4-impl.cc @@ -201,6 +201,18 @@ Ipv4Impl::GetAddress (uint32_t i) const return m_ipv4->GetAddress (i); } +void +Ipv4Impl::SetMetric (uint32_t i, uint16_t metric) +{ + m_ipv4->SetMetric (i, metric); +} + +uint16_t +Ipv4Impl::GetMetric (uint32_t i) const +{ + return m_ipv4->GetMetric (i); +} + bool Ipv4Impl::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const { diff --git a/src/internet-node/ipv4-impl.h b/src/internet-node/ipv4-impl.h index 1f4a79f5c..0494c7c0a 100644 --- a/src/internet-node/ipv4-impl.h +++ b/src/internet-node/ipv4-impl.h @@ -88,6 +88,8 @@ public: virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask); virtual Ipv4Mask GetNetworkMask (uint32_t t) const; virtual Ipv4Address GetAddress (uint32_t i) const; + virtual void SetMetric (uint32_t i, uint16_t metric); + virtual uint16_t GetMetric (uint32_t i) const; virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const; virtual bool GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const; diff --git a/src/internet-node/ipv4-interface.cc b/src/internet-node/ipv4-interface.cc index e78d75c2d..bcc346394 100644 --- a/src/internet-node/ipv4-interface.cc +++ b/src/internet-node/ipv4-interface.cc @@ -37,7 +37,8 @@ namespace ns3 { */ Ipv4Interface::Ipv4Interface (Ptr nd) : m_netdevice (nd), - m_ifup(false) + m_ifup(false), + m_metric(1) { NS_LOG_FUNCTION; NS_LOG_PARAM ("(" << &nd << ")"); @@ -96,6 +97,21 @@ Ipv4Interface::GetNetworkMask (void) const return m_netmask; } +void +Ipv4Interface::SetMetric (uint16_t metric) +{ + NS_LOG_FUNCTION; + NS_LOG_PARAM ("(" << metric << ")"); + m_metric = metric; +} + +uint16_t +Ipv4Interface::GetMetric (void) const +{ + NS_LOG_FUNCTION; + return m_metric; +} + Ipv4Address Ipv4Interface::GetAddress (void) const { diff --git a/src/internet-node/ipv4-interface.h b/src/internet-node/ipv4-interface.h index 1836aa3b7..66e841746 100644 --- a/src/internet-node/ipv4-interface.h +++ b/src/internet-node/ipv4-interface.h @@ -96,6 +96,14 @@ public: * \returns the ipv4 netmask of this interface */ Ipv4Mask GetNetworkMask (void) const; + /** + * \param configured routing metric (cost) of this interface + */ + void SetMetric (uint16_t); + /** + * \returns configured routing metric (cost) of this interface + */ + uint16_t GetMetric (void) const; /** * \returns the ipv4 address of this interface */ @@ -147,6 +155,7 @@ private: bool m_ifup; Ipv4Address m_address; Ipv4Mask m_netmask; + uint16_t m_metric; }; }; // namespace ns3 diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index 4691b977a..908a7bb99 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -821,6 +821,24 @@ Ipv4L3Protocol::GetAddress (uint32_t i) const return interface->GetAddress (); } +void +Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric) +{ + NS_LOG_FUNCTION; + NS_LOG_PARAM ("(" << i << ", " << metric << ")"); + Ptr interface = GetInterface (i); + interface->SetMetric (metric); +} + +uint16_t +Ipv4L3Protocol::GetMetric (uint32_t i) const +{ + NS_LOG_FUNCTION; + NS_LOG_PARAM ("(" << i << ")"); + Ptr interface = GetInterface (i); + return interface->GetMetric (); +} + bool Ipv4L3Protocol::GetIfIndexForDestination ( Ipv4Address destination, uint32_t& ifIndex) const diff --git a/src/internet-node/ipv4-l3-protocol.h b/src/internet-node/ipv4-l3-protocol.h index bea82707e..54dec0678 100644 --- a/src/internet-node/ipv4-l3-protocol.h +++ b/src/internet-node/ipv4-l3-protocol.h @@ -198,6 +198,8 @@ public: void SetNetworkMask (uint32_t i, Ipv4Mask mask); Ipv4Mask GetNetworkMask (uint32_t t) const; Ipv4Address GetAddress (uint32_t i) const; + void SetMetric (uint32_t i, uint16_t metric); + uint16_t GetMetric (uint32_t i) const; bool GetIfIndexForDestination (Ipv4Address destination, uint32_t& ifIndex) const; uint16_t GetMtu (uint32_t i) const; diff --git a/src/node/ipv4.h b/src/node/ipv4.h index ba4868a4a..4dba6b2a2 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -383,6 +383,20 @@ public: */ virtual Ipv4Mask GetNetworkMask (uint32_t i) const = 0; + /** + * \param i index of ipv4 interface + * \param metric routing metric (cost) associated to the underlying + * ipv4 interface + */ + virtual void SetMetric (uint32_t i, uint16_t metric) = 0; + + /** + * \param i index of ipv4 interface + * \returns routing metric (cost) associated to the underlying + * ipv4 interface + */ + virtual uint16_t GetMetric (uint32_t i) const = 0; + /** * \param i index of ipv4 interface * \returns the address associated to the underlying ipv4 interface diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index 88d9def84..ed61f7f5c 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -529,7 +529,8 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) // Get w_lsa: In case of V is Router-LSA if (v->GetVertexType () == SPFVertex::VertexRouter) { - NS_LOG_LOGIC ("Examining " << v->GetVertexId () << "'s " << + NS_LOG_LOGIC ("Examining link " << i << " of " << + v->GetVertexId () << "'s " << v->GetLSA ()->GetNLinkRecords () << " link records"); // // (a) If this is a link to a stub network, examine the next link in V's LSA. @@ -637,7 +638,8 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) candidate.Push (w); NS_LOG_LOGIC ("Pushing " << w->GetVertexId () << ", parent vertexId: " << - v->GetVertexId ()); + v->GetVertexId () << ", distance: " << + w->GetDistanceFromRoot ()); } } else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE) @@ -688,7 +690,7 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) } // -// This method is derived from quagga ospf_next_hop_calculation() 16.1.1. +// This method is derived from quagga ospf_nexthop_calculation() 16.1.1. // // Calculate nexthop from root through V (parent) to vertex W (destination) // with given distance from root->W. @@ -784,11 +786,13 @@ GlobalRouteManagerImpl::SPFNexthopCalculation ( // w->SetOutgoingInterfaceId ( FindOutgoingInterfaceId (l->GetLinkData ())); - + w->SetDistanceFromRoot (distance); + w->SetParent (v); NS_LOG_LOGIC ("Next hop from " << v->GetVertexId () << " to " << w->GetVertexId () << " goes through next hop " << w->GetNextHop () << - " via outgoing interface " << w->GetOutgoingInterfaceId ()); + " via outgoing interface " << w->GetOutgoingInterfaceId () << + " with distance " << distance); } // end W is a router vertes else { @@ -804,7 +808,8 @@ GlobalRouteManagerImpl::SPFNexthopCalculation ( w->SetParent (v); NS_LOG_LOGIC ("Next hop from " << v->GetVertexId () << " to network " << w->GetVertexId () << - " via outgoing interface " << w->GetOutgoingInterfaceId ()); + " via outgoing interface " << w->GetOutgoingInterfaceId () << + " with distance " << distance); return 1; } } // end v is the root @@ -997,6 +1002,7 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root) m_spfroot= v; v->SetDistanceFromRoot (0); v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE); + NS_LOG_LOGIC ("Starting SPFCalculate for node " << root); for (;;) { diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 2819b7a24..ee49733c1 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -50,7 +50,7 @@ GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ( LinkType linkType, Ipv4Address linkId, Ipv4Address linkData, - uint32_t metric) + uint16_t metric) : m_linkId (linkId), m_linkData (linkData), @@ -110,7 +110,7 @@ GlobalRoutingLinkRecord::SetLinkType ( m_linkType = linkType; } - uint32_t + uint16_t GlobalRoutingLinkRecord::GetMetric (void) const { NS_LOG_FUNCTION; @@ -118,7 +118,7 @@ GlobalRoutingLinkRecord::GetMetric (void) const } void -GlobalRoutingLinkRecord::SetMetric (uint32_t metric) +GlobalRoutingLinkRecord::SetMetric (uint16_t metric) { NS_LOG_FUNCTION; m_metric = metric; @@ -202,6 +202,7 @@ GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa) pDst->SetLinkType (pSrc->GetLinkType ()); pDst->SetLinkId (pSrc->GetLinkId ()); pDst->SetLinkData (pSrc->GetLinkData ()); + pDst->SetMetric (pSrc->GetMetric ()); m_linkRecords.push_back(pDst); pDst = 0; @@ -397,6 +398,7 @@ GlobalRoutingLSA::Print (std::ostream &os) const os << "----------" << std::endl; os << "m_linkId = " << p->GetLinkId () << std::endl; os << "m_linkData = " << p->GetLinkData () << std::endl; + os << "m_metric = " << p->GetMetric () << std::endl; } } else if (m_lsType == GlobalRoutingLSA::NetworkLSA) @@ -547,6 +549,7 @@ GlobalRouter::DiscoverLSAs (void) Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); NS_LOG_LOGIC ("Working with local address " << addrLocal); + uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal); // // Now, we're going to walk over to the remote net device on the other end of // the point-to-point channel we now know we have. This is where our adjacent @@ -566,8 +569,7 @@ GlobalRouter::DiscoverLSAs (void) Ipv4Address maskLocalAddr; maskLocalAddr.Set(maskLocal.GetHostOrder ()); plr->SetLinkData (maskLocalAddr); - // Cost is interface's configured output cost (NOTYET) - plr->SetMetric (1); + plr->SetMetric (metricLocal); pLSA->AddLinkRecord(plr); plr = 0; continue; @@ -589,8 +591,7 @@ GlobalRouter::DiscoverLSAs (void) plr->SetLinkId (desigRtr); // Link Data is router's own IP address plr->SetLinkData (addrLocal); - // Cost is interface's configured output cost (NOTYET) - plr->SetMetric (1); + plr->SetMetric (metricLocal); pLSA->AddLinkRecord (plr); plr = 0; continue; @@ -613,6 +614,7 @@ GlobalRouter::DiscoverLSAs (void) Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); NS_LOG_LOGIC ("Working with local address " << addrLocal); + uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal); // // Now, we're going to walk over to the remote net device on the other end of // the point-to-point channel we now know we have. This is where our adjacent @@ -659,6 +661,7 @@ GlobalRouter::DiscoverLSAs (void) plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint); plr->SetLinkId (rtrIdRemote); plr->SetLinkData (addrLocal); + plr->SetMetric (metricLocal); pLSA->AddLinkRecord (plr); plr = 0; @@ -666,6 +669,7 @@ GlobalRouter::DiscoverLSAs (void) plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); plr->SetLinkId (addrRemote); plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown + plr->SetMetric (metricLocal); pLSA->AddLinkRecord (plr); plr = 0; } diff --git a/src/routing/global-routing/global-router-interface.h b/src/routing/global-routing/global-router-interface.h index cf3f94166..87626700b 100644 --- a/src/routing/global-routing/global-router-interface.h +++ b/src/routing/global-routing/global-router-interface.h @@ -82,7 +82,7 @@ public: LinkType linkType, Ipv4Address linkId, Ipv4Address linkData, - uint32_t metric); + uint16_t metric); /** * @brief Destroy a Global Routing Link Record. @@ -176,7 +176,7 @@ public: * * @returns The metric field of the Global Routing Link Record. */ - uint32_t GetMetric(void) const; + uint16_t GetMetric(void) const; /** * @brief Set the Metric Data field of the Global Routing Link Record. @@ -189,7 +189,7 @@ public: * * @param metric The new metric for the current Global Routing Link Record. */ - void SetMetric(uint32_t metric); + void SetMetric(uint16_t metric); private: /** @@ -230,7 +230,7 @@ private: * of two hops relate to the cost of sending a packet); rather you should * use something like delay. */ - uint32_t m_metric; + uint16_t m_metric; }; /** From f5513abfc89335ca48f71ffa17062078b3b87d61 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 12 Oct 2007 21:28:02 -0700 Subject: [PATCH 49/61] Reverting a few OLSR changes that leaked into simple-point-to-point.cc --- examples/simple-point-to-point.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/simple-point-to-point.cc b/examples/simple-point-to-point.cc index b4343acfe..d1e132211 100644 --- a/examples/simple-point-to-point.cc +++ b/examples/simple-point-to-point.cc @@ -61,7 +61,6 @@ #include "ns3/point-to-point-topology.h" #include "ns3/onoff-application.h" #include "ns3/packet-sink.h" -#include "ns3/olsr.h" using namespace ns3; @@ -155,8 +154,10 @@ main (int argc, char *argv[]) // NetDevice creation, IP Address assignment, and routing) are // separated because there may be a need to postpone IP Address // assignment (emulation) or modify to use dynamic routing - NS_LOG_INFO ("Enabling OLSR Routing."); - olsr::EnableAllNodes (); + NS_LOG_INFO ("Add Static Routes."); + PointToPointTopology::AddIpv4Routes(n0, n2, channel0); + PointToPointTopology::AddIpv4Routes(n1, n2, channel1); + PointToPointTopology::AddIpv4Routes(n2, n3, channel2); // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s @@ -213,7 +214,7 @@ main (int argc, char *argv[]) // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the simple-point-to-point.tr file NS_LOG_INFO ("Configure Tracing."); - AsciiTrace asciitrace ("simple-point-to-point-olsr.tr"); + AsciiTrace asciitrace ("simple-point-to-point.tr"); asciitrace.TraceAllQueues (); asciitrace.TraceAllNetDeviceRx (); @@ -222,7 +223,7 @@ main (int argc, char *argv[]) // simple-point-to-point.pcap-- // and can be read by the "tcpdump -r" command (use "-tt" option to // display timestamps correctly) - PcapTrace pcaptrace ("simple-point-to-point-olsr.pcap"); + PcapTrace pcaptrace ("simple-point-to-point.pcap"); pcaptrace.TraceAllIp (); NS_LOG_INFO ("Run Simulation."); From 315dfd2041e5dfdd3cc7a6db433cf38ef82c2073 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sat, 13 Oct 2007 13:09:55 +0100 Subject: [PATCH 50/61] Remove 'All rights reserved.' GPL-incompatible phrase from OLSR sources. --- src/routing/olsr/event-garbage-collector.cc | 1 - src/routing/olsr/event-garbage-collector.h | 1 - src/routing/olsr/olsr-agent-impl.cc | 1 - src/routing/olsr/olsr-agent-impl.h | 1 - src/routing/olsr/olsr-agent.cc | 1 - src/routing/olsr/olsr-agent.h | 1 - src/routing/olsr/olsr-header.cc | 1 - src/routing/olsr/olsr-header.h | 1 - src/routing/olsr/olsr-state.cc | 1 - src/routing/olsr/olsr-state.h | 1 - src/routing/olsr/olsr.cc | 1 - src/routing/olsr/olsr.h | 1 - src/routing/olsr/repositories.h | 1 - src/routing/olsr/routing-table.cc | 1 - src/routing/olsr/routing-table.h | 1 - 15 files changed, 15 deletions(-) diff --git a/src/routing/olsr/event-garbage-collector.cc b/src/routing/olsr/event-garbage-collector.cc index a68478c87..212ad7d69 100644 --- a/src/routing/olsr/event-garbage-collector.cc +++ b/src/routing/olsr/event-garbage-collector.cc @@ -1,7 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/event-garbage-collector.h b/src/routing/olsr/event-garbage-collector.h index 9d7ccbf82..674de1a42 100644 --- a/src/routing/olsr/event-garbage-collector.h +++ b/src/routing/olsr/event-garbage-collector.h @@ -1,7 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index c260ac018..12c4f55ef 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -2,7 +2,6 @@ /* * Copyright (c) 2004 Francisco J. Ros * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/olsr-agent-impl.h b/src/routing/olsr/olsr-agent-impl.h index 94618ed8c..a708a3818 100644 --- a/src/routing/olsr/olsr-agent-impl.h +++ b/src/routing/olsr/olsr-agent-impl.h @@ -2,7 +2,6 @@ /* * Copyright (c) 2004 Francisco J. Ros * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/olsr-agent.cc b/src/routing/olsr/olsr-agent.cc index 0f2ac17ca..c846aee4e 100644 --- a/src/routing/olsr/olsr-agent.cc +++ b/src/routing/olsr/olsr-agent.cc @@ -1,7 +1,6 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/olsr-agent.h b/src/routing/olsr/olsr-agent.h index 2a88f31c1..e9047e498 100644 --- a/src/routing/olsr/olsr-agent.h +++ b/src/routing/olsr/olsr-agent.h @@ -1,7 +1,6 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/olsr-header.cc b/src/routing/olsr/olsr-header.cc index b3c641eeb..5314b1e3e 100644 --- a/src/routing/olsr/olsr-header.cc +++ b/src/routing/olsr/olsr-header.cc @@ -1,7 +1,6 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/olsr-header.h b/src/routing/olsr/olsr-header.h index e783ab9b1..c95b986df 100644 --- a/src/routing/olsr/olsr-header.h +++ b/src/routing/olsr/olsr-header.h @@ -1,7 +1,6 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/olsr-state.cc b/src/routing/olsr/olsr-state.cc index c994d8116..519e9633e 100644 --- a/src/routing/olsr/olsr-state.cc +++ b/src/routing/olsr/olsr-state.cc @@ -2,7 +2,6 @@ /* * Copyright (c) 2004 Francisco J. Ros * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/olsr-state.h b/src/routing/olsr/olsr-state.h index dbaf973d2..d7788a572 100644 --- a/src/routing/olsr/olsr-state.h +++ b/src/routing/olsr/olsr-state.h @@ -2,7 +2,6 @@ /* * Copyright (c) 2004 Francisco J. Ros * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/olsr.cc b/src/routing/olsr/olsr.cc index 1f6b0aa30..dbcb6dfba 100644 --- a/src/routing/olsr/olsr.cc +++ b/src/routing/olsr/olsr.cc @@ -1,7 +1,6 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/olsr.h b/src/routing/olsr/olsr.h index cbfa40c44..1ba19c02d 100644 --- a/src/routing/olsr/olsr.h +++ b/src/routing/olsr/olsr.h @@ -1,7 +1,6 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/repositories.h b/src/routing/olsr/repositories.h index ec5213d86..d1e2101bf 100644 --- a/src/routing/olsr/repositories.h +++ b/src/routing/olsr/repositories.h @@ -2,7 +2,6 @@ /* * Copyright (c) 2004 Francisco J. Ros * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/routing-table.cc b/src/routing/olsr/routing-table.cc index 73f01b715..eb17adaf1 100644 --- a/src/routing/olsr/routing-table.cc +++ b/src/routing/olsr/routing-table.cc @@ -2,7 +2,6 @@ /* * Copyright (c) 2004 Francisco J. Ros * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 diff --git a/src/routing/olsr/routing-table.h b/src/routing/olsr/routing-table.h index 86d98b4c6..c987106b0 100644 --- a/src/routing/olsr/routing-table.h +++ b/src/routing/olsr/routing-table.h @@ -2,7 +2,6 @@ /* * Copyright (c) 2004 Francisco J. Ros * Copyright (c) 2007 INESC Porto - * All rights reserved. * * 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 From a18fc4fd93845f735f72c7c229435dba2b08622d Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Sat, 13 Oct 2007 14:21:27 +0100 Subject: [PATCH 51/61] Fix OLSR agent finalization issues. --- src/routing/olsr/olsr-agent-impl.cc | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/routing/olsr/olsr-agent-impl.cc b/src/routing/olsr/olsr-agent-impl.cc index 12c4f55ef..fb684bc9b 100644 --- a/src/routing/olsr/olsr-agent-impl.cc +++ b/src/routing/olsr/olsr-agent-impl.cc @@ -194,12 +194,21 @@ OlsrAgentImpl::OlsrAgentImpl (Ptr node) void OlsrAgentImpl::DoDispose () { m_ipv4 = 0; - m_receiveSocket->Dispose (); - m_receiveSocket = 0; - m_sendSocket->Dispose (); - m_sendSocket = 0; - m_routingTable->Dispose (); - m_routingTable = 0; + if (m_receiveSocket) + { + m_receiveSocket->Dispose (); + m_receiveSocket = 0; + } + if (m_sendSocket) + { + m_sendSocket->Dispose (); + m_sendSocket = 0; + } + if (m_routingTable) + { + m_routingTable->Dispose (); + m_routingTable = 0; + } Object::DoDispose (); } From 6804f40bc43ceeed10e8700f9f4392f652ff3dea Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sat, 13 Oct 2007 15:06:35 -0700 Subject: [PATCH 52/61] Clarify pkt-uid field in doxygen --- examples/wscript | 4 ++++ src/common/packet.h | 10 ++++++++++ src/core/object.cc | 1 + 3 files changed, 15 insertions(+) diff --git a/examples/wscript b/examples/wscript index f597225fb..819336fd2 100644 --- a/examples/wscript +++ b/examples/wscript @@ -18,6 +18,10 @@ def build(bld): ['csma', 'internet-node']) obj.source = 'csma-one-subnet.cc' + obj = bld.create_ns3_program('george', + ['csma', 'internet-node']) + obj.source = 'george.cc' + obj = bld.create_ns3_program('udp-echo', ['csma', 'internet-node']) obj.source = 'udp-echo.cc' diff --git a/src/common/packet.h b/src/common/packet.h index f1e14cf02..251d21ad1 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -243,6 +243,16 @@ public: /** * A packet is allocated a new uid when it is created * empty or with zero-filled payload. + * + * Note: This uid is an internal uid and cannot be counted on to + * provide an accurate counter of how many "simulated packets" of a + * particular protocol are in the system. It is not trivial to make + * this uid into such a counter, because of questions such as what + * should the uid be when the packet is sent over broadcast media, or + * when fragmentation occurs. If a user wants to trace actual packet + * counts, he or she should look at e.g. the IP ID field or transport + * sequence numbers, or other packet or frame counters at other + * protocol layers. * * \returns an integer identifier which uniquely * identifies this packet. diff --git a/src/core/object.cc b/src/core/object.cc index 1049b6cab..c027a46eb 100644 --- a/src/core/object.cc +++ b/src/core/object.cc @@ -197,6 +197,7 @@ Object::DoQueryInterface (InterfaceId iid) const do { NS_ASSERT (currentObject != 0); InterfaceId cur = currentObject->m_iid; + NS_LOG_LOGIC("In Loop: " << cur.GetName()); while (cur != iid && cur != Object::iid) { cur = InterfaceId::LookupParent (cur); From e5241d93e57db30fb0c0ec46ec857025818e54b2 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sat, 13 Oct 2007 15:10:23 -0700 Subject: [PATCH 53/61] back out unrelated changes --- examples/wscript | 4 ---- src/common/packet.h | 10 ---------- src/core/object.cc | 1 - 3 files changed, 15 deletions(-) diff --git a/examples/wscript b/examples/wscript index 819336fd2..f597225fb 100644 --- a/examples/wscript +++ b/examples/wscript @@ -18,10 +18,6 @@ def build(bld): ['csma', 'internet-node']) obj.source = 'csma-one-subnet.cc' - obj = bld.create_ns3_program('george', - ['csma', 'internet-node']) - obj.source = 'george.cc' - obj = bld.create_ns3_program('udp-echo', ['csma', 'internet-node']) obj.source = 'udp-echo.cc' diff --git a/src/common/packet.h b/src/common/packet.h index 251d21ad1..f1e14cf02 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -243,16 +243,6 @@ public: /** * A packet is allocated a new uid when it is created * empty or with zero-filled payload. - * - * Note: This uid is an internal uid and cannot be counted on to - * provide an accurate counter of how many "simulated packets" of a - * particular protocol are in the system. It is not trivial to make - * this uid into such a counter, because of questions such as what - * should the uid be when the packet is sent over broadcast media, or - * when fragmentation occurs. If a user wants to trace actual packet - * counts, he or she should look at e.g. the IP ID field or transport - * sequence numbers, or other packet or frame counters at other - * protocol layers. * * \returns an integer identifier which uniquely * identifies this packet. diff --git a/src/core/object.cc b/src/core/object.cc index c027a46eb..1049b6cab 100644 --- a/src/core/object.cc +++ b/src/core/object.cc @@ -197,7 +197,6 @@ Object::DoQueryInterface (InterfaceId iid) const do { NS_ASSERT (currentObject != 0); InterfaceId cur = currentObject->m_iid; - NS_LOG_LOGIC("In Loop: " << cur.GetName()); while (cur != iid && cur != Object::iid) { cur = InterfaceId::LookupParent (cur); From 302bdd366cc12bb84df34d4a42b06300c7303bc5 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sat, 13 Oct 2007 15:14:00 -0700 Subject: [PATCH 54/61] Clarify pkt-uid field in doxygen --- src/common/packet.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/common/packet.h b/src/common/packet.h index f1e14cf02..58e842292 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -244,6 +244,16 @@ public: * A packet is allocated a new uid when it is created * empty or with zero-filled payload. * + * Note: This uid is an internal uid and cannot be counted on to + * provide an accurate counter of how many "simulated packets" of a + * particular protocol are in the system. It is not trivial to make + * this uid into such a counter, because of questions such as what + * should the uid be when the packet is sent over broadcast media, or + * when fragmentation occurs. If a user wants to trace actual packet + * counts, he or she should look at e.g. the IP ID field or transport + * sequence numbers, or other packet or frame counters at other + * protocol layers. + * * \returns an integer identifier which uniquely * identifies this packet. */ From 620a465f8422ac4574b75fd9615ef4813f95147d Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 15 Oct 2007 14:54:32 -0700 Subject: [PATCH 55/61] NS_LOG parsing changes to address bug 91 --- src/core/log.cc | 276 ++++++++++++++++++------------------------------ src/core/log.h | 46 +++----- 2 files changed, 121 insertions(+), 201 deletions(-) diff --git a/src/core/log.cc b/src/core/log.cc index 0bfb978c4..de43712cf 100644 --- a/src/core/log.cc +++ b/src/core/log.cc @@ -18,6 +18,8 @@ * Author: Mathieu Lacage */ +// What about print-list!!!!!!??????? + #ifdef NS3_LOG_ENABLE #include @@ -44,69 +46,33 @@ ComponentList *GetComponentList (void) return &components; } -void -LogComponentEnableEnvVar (void) +LogComponent::LogComponent (char const * name) + : m_levels (0), m_name (name) { - static bool isFirstLog = true; -#if 0 -// -// Interesting static constructor bug: -// -// The RandomDirection2dMobilityModel declares a RandomVariableDefaultValue -// g_speedVariable. This variable is initialized in the -// static_initialization_and_destruction_0 function as expected. This causes -// RandomVariableDefaultValue::Parse () to be called which calls NS_LOG_X -// functions. The macro calls LogComponent::IsEnabled () which calls -// LogComponentEnableEnvVar (). The following variable called isFirstLog -// is set after the first call to prevent the environment variable from -// actually being parsed on every log call. -// -// When the RandomDirection2dMobilityModel static constructor is run, other -// log components may not have had their static constructors run yet. It is -// in those other static constructors that their log components are added to -// the list of log components. -// -// The end result is that if any code calls an NS_LOG_X function during its -// static constructor, the environment variable check is "locked out" for -// any log component declarations (in different compilation units) that have -// not yet been executed. -// -// So, the choice seems to be to either 1) parse the environment variables -// at every log call; or 2) make LogComponentEnableEnvVar explicitly called -// after all other static constructors are called. This means in main (). -// The former choice seems the only reasonable way out if we care remotely -// about performance in logging. -// -// I made LogComponentEnableEnvVar a public API that you need to call in -// main () if you want to use environment variables to drive the log output. -// - if (!isFirstLog) - { - return; - } -#endif // 0 + EnvVarCheck (name); + ComponentList *components = GetComponentList (); + for (ComponentListI i = components->begin (); + i != components->end (); + i++) + { + NS_ASSERT (i->first != name); + } + components->push_back (std::make_pair (name, this)); +} + +void +LogComponent::EnvVarCheck (char const * name) +{ #ifdef HAVE_GETENV char *envVar = getenv("NS_LOG"); if (envVar == 0) { - isFirstLog = false; return; } std::string env = envVar; - if (env == "print-list") - { - LogComponentPrintList (); - isFirstLog = false; - return; - } - if (env == "*") - { - LogComponentEnableAll (LOG_DEBUG); - isFirstLog = false; - return; - } - bool allFound = true; + std::string myName = name; + std::string::size_type cur = 0; std::string::size_type next = 0; while (true) @@ -128,118 +94,101 @@ LogComponentEnableEnvVar (void) } std::string::size_type equal = tmp.find ("="); std::string component; - int level = 0; if (equal == std::string::npos) { component = tmp; - level = LOG_DEBUG; + if (component == myName || component == "*") + { + Enable (LOG_DEBUG); + return; + } } else { component = tmp.substr (0, equal); - std::string::size_type cur_lev; - std::string::size_type next_lev = equal; - do + if (component == myName || component == "*") { - cur_lev = next_lev + 1; - next_lev = tmp.find ("|", cur_lev); - std::string lev = tmp.substr (cur_lev, next_lev - cur_lev); - if (lev == "error") + int level = 0; + std::string::size_type cur_lev; + std::string::size_type next_lev = equal; + do { - level |= LOG_ERROR; - } - else if (lev == "warn") - { - level |= LOG_WARN; - } - else if (lev == "debug") - { - level |= LOG_DEBUG; - } - else if (lev == "info") - { - level |= LOG_INFO; - } - else if (lev == "function") - { - level |= LOG_FUNCTION; - } - else if (lev == "param") - { - level |= LOG_PARAM; - } - else if (lev == "logic") - { - level |= LOG_LOGIC; - } - else if (lev == "all") - { - level |= LOG_ALL; - } - else if (lev == "prefix") - { - level |= LOG_PREFIX_ALL; - } - else if (lev == "level_error") - { - level |= LOG_LEVEL_ERROR; - } - else if (lev == "level_warn") - { - level |= LOG_LEVEL_WARN; - } - else if (lev == "level_debug") - { - level |= LOG_LEVEL_DEBUG; - } - else if (lev == "level_info") - { - level |= LOG_LEVEL_INFO; - } - else if (lev == "level_function") - { - level |= LOG_LEVEL_FUNCTION; - } - else if (lev == "level_param") - { - level |= LOG_LEVEL_PARAM; - } - else if (lev == "level_logic") - { - level |= LOG_LEVEL_LOGIC; - } - else if (lev == "level_all") - { - level |= LOG_LEVEL_ALL; - } - } while (next_lev != std::string::npos); - } - bool found = false; - if (component == "*") - { - found = true; - LogComponentEnableAll ((enum LogLevel)level); - } - else - { - ComponentList *components = GetComponentList (); - for (ComponentListI i = components->begin (); - i != components->end (); - i++) - { - if (i->first.compare (component) == 0) - { - found = true; - - i->second->Enable ((enum LogLevel)level); - break; - } + cur_lev = next_lev + 1; + next_lev = tmp.find ("|", cur_lev); + std::string lev = tmp.substr (cur_lev, next_lev - cur_lev); + if (lev == "error") + { + level |= LOG_ERROR; + } + else if (lev == "warn") + { + level |= LOG_WARN; + } + else if (lev == "debug") + { + level |= LOG_DEBUG; + } + else if (lev == "info") + { + level |= LOG_INFO; + } + else if (lev == "function") + { + level |= LOG_FUNCTION; + } + else if (lev == "param") + { + level |= LOG_PARAM; + } + else if (lev == "logic") + { + level |= LOG_LOGIC; + } + else if (lev == "all") + { + level |= LOG_ALL; + } + else if (lev == "prefix") + { + level |= LOG_PREFIX_ALL; + } + else if (lev == "level_error") + { + level |= LOG_LEVEL_ERROR; + } + else if (lev == "level_warn") + { + level |= LOG_LEVEL_WARN; + } + else if (lev == "level_debug") + { + level |= LOG_LEVEL_DEBUG; + } + else if (lev == "level_info") + { + level |= LOG_LEVEL_INFO; + } + else if (lev == "level_function") + { + level |= LOG_LEVEL_FUNCTION; + } + else if (lev == "level_param") + { + level |= LOG_LEVEL_PARAM; + } + else if (lev == "level_logic") + { + level |= LOG_LEVEL_LOGIC; + } + else if (lev == "level_all") + { + level |= LOG_LEVEL_ALL; + } + } while (next_lev != std::string::npos); + + Enable ((enum LogLevel)level); } } - if (!found) - { - allFound = false; - } if (next == std::string::npos) { break; @@ -250,26 +199,9 @@ LogComponentEnableEnvVar (void) break; } } - if (allFound) - { - isFirstLog = false; - } - #endif } -LogComponent::LogComponent (char const * name) - : m_levels (0), m_name (name) -{ - ComponentList *components = GetComponentList (); - for (ComponentListI i = components->begin (); - i != components->end (); - i++) - { - NS_ASSERT (i->first != name); - } - components->push_back (std::make_pair (name, this)); -} bool LogComponent::IsEnabled (enum LogLevel level) const diff --git a/src/core/log.h b/src/core/log.h index 61ab9026d..c027fa022 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -34,6 +34,21 @@ * messages, use the ns3::LogComponentEnable * function or use the NS_LOG environment variable and * ns3::LogComponentEnableEnvVar + * + * Use the environment variable NS_LOG to define a ';'-separated list of + * logging components to enable. For example, NS_LOG=a;b;c;DAFD;GH + * would enable the components 'a', 'b', 'c', 'DAFD', and, 'GH'. + * NS_LOG=* will enable all available log components. + * + * For each component, the "debug" log level is enabled by default + * but more components can be enabled selectively with the following + * syntax: NS_LOG='Component1=func|param|warn;Component2=error|debug' + * This example would enable the 'func', 'param', and 'warn' log + * levels for 'Component1' and the 'error' and 'debug' log levels + * for 'Component2'. The wildcard can be used here as well. For example + * NS_LOG='*=level_all|prefix' would enable all log levels and prefix all + * prints with the component and function names. + * */ /** @@ -94,7 +109,7 @@ if (g_log.IsEnabled (level)) \ { \ std::clog << g_log.Name () << ":" << __FUNCTION__ << \ - "(): " << std::endl; \ + "()" << std::endl; \ } \ } \ while (false) @@ -179,28 +194,6 @@ enum LogLevel { #endif #ifdef NS3_LOG_ENABLE -/** - * \brief Enable the logging output based on an environment variable. - * - * Use the environment variable NS_LOG to define a ';'-separated list of - * logging components to enable. For example, NS_LOG=a;b;c;DAFD;GH - * would enable the components 'a', 'b', 'c', 'DAFD', and, 'GH'. - * NS_LOG=* will enable all available log components. - * - * For each component, the "debug" log level is enabled by default - * but more components can be enabled selectively with the following - * syntax: NS_LOG='Component1=func|param|warn;Component2=error|debug' - * This example would enable the 'func', 'param', and 'warn' log - * levels for 'Component1' and the 'error' and 'debug' log levels - * for 'Component2'. The wildcard can be used here as well. For example - * NS_LOG='*=level_all|prefix' would enable all log levels and prefix all - * prints with the component and function names. - * - * The list of available log components can be printed on stdout - * with the NS_LOG=print-list syntax. - */ - void LogComponentEnableEnvVar (void); - /** * \param name a log component name * \param level a logging level @@ -222,7 +215,6 @@ enum LogLevel { */ void LogComponentEnableAll (enum LogLevel level); #else -#define LogComponentEnableEnvVar() #define LogComponentEnable(a,b) #define LogComponentEnableAll(a) #endif @@ -259,11 +251,6 @@ void LogComponentDisableAll (enum LogLevel level); * \ingroup logging * * Print the list of logging messages available. - * The output of this function can be obtained by setting - * the NS_LOG environment variable to the special value - * 'print-list'. - * - * For example: NS_LOG=print-list */ #ifdef NS3_LOG_ENABLE void LogComponentPrintList (void); @@ -276,6 +263,7 @@ void LogComponentPrintList (void); class LogComponent { public: LogComponent (char const *name); + void EnvVarCheck (char const *name); bool IsEnabled (enum LogLevel level) const; bool IsNoneEnabled (void) const; void Enable (enum LogLevel level); From 21ab738c7220f6b0162c1b507c238cfef00f94f8 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 15 Oct 2007 15:09:56 -0700 Subject: [PATCH 56/61] Added tag release ns-3.0.7 for changeset 36472385a1cc --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 35f08ab9c..45520a625 100644 --- a/.hgtags +++ b/.hgtags @@ -6,3 +6,4 @@ 08046b6aef37932507696a2f2f427b42d693781e release ns-3.0.5 267e2ebc28e4e4ae2f579e1cfc29902acade0c34 buffer-working-before-breaking 606df29888e7573b825fc891a002f0757166b616 release ns-3.0.6 +36472385a1cc7c44d34fb7a5951b930010f4e8d2 release ns-3.0.7 From 834eb4c1b644a4dcd782201d4f4dfd38c5b404e0 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 15 Oct 2007 21:10:46 -0700 Subject: [PATCH 57/61] Release notes for 3.0.7 --- RELEASE_NOTES | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index e429e5fec..4aff62726 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -3,6 +3,13 @@ This file contains ns-3 release notes (most recent releases first). +Release 3.0.7 (2007/10/15) +======================== + - OLSR routing protocol + - A timer class + - Additional mobility models (random waypoint, random 2D walk) + - A mobility visualization tool + Release 3.0.6 (2007/09/15) ======================== - Static multicast IPv4 routing From 9461d8ec13157d3c21ac1fdfcddb9353eadb1d19 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 15 Oct 2007 21:12:48 -0700 Subject: [PATCH 58/61] updates for 3.0.7 --- README | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README b/README index 23c9a6c71..01d2c2ccf 100644 --- a/README +++ b/README @@ -84,12 +84,12 @@ following set of platforms: - linux x86 gcc 4.2, 4.1, and, 3.4. - linux x86_64 gcc 4.0 - MacOS X ppc and x86 + - cygwin The current codebase is expected to fail to build on the following platforms: - gcc 3.3 and earlier - optimized builds on linux x86 gcc 4.0 - - cygwin Other platforms may or may not work: we welcome patches to improve the portability of the code to these @@ -102,17 +102,17 @@ On recent Linux systems, once you have built ns-3, it should be easy to run the sample programs with the following command: -./waf --run simple-p2p +./waf --run simple-point-to-point -That program should generate a simple-p2p.tr text -trace file and a set of simple-p2p-xx-xx.pcap binary +That program should generate a simple-point-to-point.tr text +trace file and a set of simple-point-to-point-xx-xx.pcap binary pcap trace files, which can be read by tcpdump. 5) Getting access to the ns-3 documentation ------------------------------------------- Once you have verified that your build of ns-3 works by running -the simple-p2p example as outlined in 4) above, it is +the simple-point-to-point example as outlined in 4) above, it is quite likely that you will want to get started on reading some ns-3 documentation. From db709dc4dc383c928c9d86653e8e90164fa4271d Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 15 Oct 2007 21:12:55 -0700 Subject: [PATCH 59/61] bump version number --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 818bd47ab..2451c27ca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.6 +3.0.7 From 31bafccb6c6e0661f8d8963e0a62cade608e8474 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 15 Oct 2007 21:13:21 -0700 Subject: [PATCH 60/61] updates for 3.0.7 --- doc/build.txt | 53 +++++++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/doc/build.txt b/doc/build.txt index bfb2b518d..95bc068e1 100644 --- a/doc/build.txt +++ b/doc/build.txt @@ -3,79 +3,62 @@ build system (http://www.freehackers.org/~tnagy/waf.html) === Installing Waf === -If this file is part of a development release tarball, the top-level -ns-3 directory should contain a current waf script. - -However, the ns-3 Mercurial code repository does not contain the waf -script. Instead, developers should check it out from a subversion -repository: - - svn checkout http://waf.googlecode.com/svn/tags/ns3/ waf - -[ note: 'tags/ns3' is a tag that represents the last svn version -tested to work correctly with ns3, although 'trunk' will likely work - as well ] - -Then it can be installed system-wide with 'sudo waf-light install'. -When preparing a distribution, the resulting 'waf' script, which is -self contained (no external files needed), can be easily included in -the tarball so that users downloading ns-3 can easily build it without -having Waf installed (although Python >= 2.3 is still needed). +The top-level ns-3 directory should contain a current waf script. === Building with Waf === -To build ns-3 with waf type the commands: - 1. waf configure [options] - 2. waf +To build ns-3 with waf type the commands from the top-level directory: + 1. ./waf configure [options] + 2. ./waf -To see valid configure options, type waf --help. The most important +To see valid configure options, type ./waf --help. The most important option is -d . Valid debug levels (which are listed in -waf --help) are: ultradebug, debug, release, and optimized. It is +waf --help) are: "debug" or "optimized". It is also possible to change the flags used for compilation with (e.g.): -CXXFLAGS="-O3" waf configure. +CXXFLAGS="-O3" ./waf configure. [ Note: Unlike some other build tools, to change the build target, the option must be supplied during the configure stage rather than -the build stage (i.e., "waf -d optimized" will not work; instead, do -"waf -d optimized configure; waf" ] +the build stage (i.e., "./waf -d optimized" will not work; instead, do +"./waf -d optimized configure; ./waf" ] The resulting binaries are placed in build//srcpath. Other waf usages include: - 1. waf check + 1. ./waf check Runs the unit tests - 2. waf --doxygen + 2. ./waf --doxygen Run doxygen to generate documentation - 3. waf --lcov-report + 3. ./waf --lcov-report Run code coverage analysis (assuming the project was configured with --enable-gcov) - 4. waf --run "program [args]" + 4. ./waf --run "program [args]" Run a ns3 program, given its target name, with the given arguments. This takes care of automatically modifying the the path for finding the ns3 dynamic libraries in the environment before running the program. Note: the "program [args]" string is parsed using POSIX shell rules. - 4.1 waf --run programname --command-template "... %s ..." + 4.1 ./waf --run programname --command-template "... %s ..." Same as --run, but uses a command template with %s replaced by the actual program (whose name is given by --run). This can be use to run ns-3 programs with helper tools. For example, to run unit tests with valgrind, use the command: - waf --run run-tests --command-template "valgrind %s" + ./waf --run run-tests --command-template "valgrind %s" - 5. waf --shell + 5. ./waf --shell Starts a nested system shell with modified environment to run ns3 programs. - 6. waf distclean + 6. ./waf distclean Cleans out the entire build/ directory - 7. waf dist + 7. ./waf dist The command 'waf dist' can be used to create a distribution tarball. It includes all files in the source directory, except some particular extensions that are blacklisted, such as back files (ending in ~). From 61ed256846a1f6ce09cdd705dc76f304d62219aa Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 15 Oct 2007 21:59:41 -0700 Subject: [PATCH 61/61] more detail in release_steps.txt --- doc/release_steps.txt | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/doc/release_steps.txt b/doc/release_steps.txt index 5fe843d77..d949b5575 100644 --- a/doc/release_steps.txt +++ b/doc/release_steps.txt @@ -1,24 +1,32 @@ Steps in doing an ns-3 release +0. check out a clean ns-3-dev somewhere 1. prepare the source files - revise and check in AUTHORS, if needed - revise and check in RELEASE_NOTES - update and check in VERSION to the latest release number 2. make a new "architecture.pdf" document and place it in the doc/ directory -3. cd ns-3-dev; ./waf configure; ./waf dist + of the ns-3-dev working directory +3. ./waf configure; ./waf dist + - this will create a ns-3.0.x.tar.bz2 tarball 4. test tarball on release platforms (waf check and maybe some other scripts) -5. tag ns-3-dev with "release ns-3.0.X" - - hg tag "release ns-3.0.x" - - hg push +5. once you are happy with the tarball, tag ns-3-dev with "release ns-3.0.X" + - hg tag "release ns-3.0.x" + - hg push 6. clone the tagged ns-3-dev and place it on the repository - - ssh code.nsnam.org; sudo; su code; - - cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.0.x - - cd /home/code/repos/ns-3.0.x/.hg and edit the hgrc appropriately -7. upload "ns-3.0.x.tar.bz2" to the releases/ directory on the server + - ssh code.nsnam.org; sudo; su code; + - cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.0.x + - cd /home/code/repos/ns-3.0.x/.hg and edit the hgrc appropriately +7. upload "ns-3.0.x.tar.bz2" to the /var/www/html/releases/ directory on + the www.nsnam.org server 8. update web page - add link to news.html - - update download.html - - update roadmap.html + - update getting_started.html + - update documents.html + - update roadmap on wiki - build and update Doxygen directory on the server + -- ssh www.nsnam.org; sudo tcsh; su nsnam; + -- ~/bin/update-doxygen-release - update and upload software architecture document (PDF, HTML) + -- note: HTML image generation is not currently automatic 9. announce to ns-developers, with summary of release notes