1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2004 Francisco J. Ros
4  * Copyright (c) 2007 INESC Porto
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * Authors: Francisco J. Ros  <fjrm@dif.um.es>
20  *          Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
21  */
22 
23 
24 ///
25 /// \brief Implementation of OLSR agent and related classes.
26 ///
27 /// This is the main file of this software because %OLSR's behaviour is
28 /// implemented here.
29 ///
30 
31 #define NS_LOG_APPEND_CONTEXT                                   \
32   if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
33 
34 
35 #include <iomanip>
36 #include "olsr-routing-protocol.h"
37 #include "ns3/socket-factory.h"
38 #include "ns3/udp-socket-factory.h"
39 #include "ns3/simulator.h"
40 #include "ns3/log.h"
41 #include "ns3/names.h"
42 #include "ns3/inet-socket-address.h"
43 #include "ns3/ipv4-routing-protocol.h"
44 #include "ns3/ipv4-routing-table-entry.h"
45 #include "ns3/ipv4-route.h"
46 #include "ns3/boolean.h"
47 #include "ns3/uinteger.h"
48 #include "ns3/enum.h"
49 #include "ns3/trace-source-accessor.h"
50 #include "ns3/ipv4-header.h"
51 #include "ns3/ipv4-packet-info-tag.h"
52 
53 /********** Useful macros **********/
54 
55 ///
56 /// \brief Gets the delay between a given time and the current time.
57 ///
58 /// If given time is previous to the current one, then this macro returns
59 /// a number close to 0. This is used for scheduling events at a certain moment.
60 ///
61 #define DELAY(time) (((time) < (Simulator::Now ())) ? Seconds (0.000001) : \
62                      (time - Simulator::Now () + Seconds (0.000001)))
63 
64 
65 
66 ///
67 /// \brief Period at which a node must cite every link and every neighbor.
68 ///
69 /// We only use this value in order to define OLSR_NEIGHB_HOLD_TIME.
70 ///
71 #define OLSR_REFRESH_INTERVAL   m_helloInterval
72 
73 
74 /********** Holding times **********/
75 
76 /// Neighbor holding time.
77 #define OLSR_NEIGHB_HOLD_TIME   Time (3 * OLSR_REFRESH_INTERVAL)
78 /// Top holding time.
79 #define OLSR_TOP_HOLD_TIME      Time (3 * m_tcInterval)
80 /// Dup holding time.
81 #define OLSR_DUP_HOLD_TIME      Seconds (30)
82 /// MID holding time.
83 #define OLSR_MID_HOLD_TIME      Time (3 * m_midInterval)
84 /// HNA holding time.
85 #define OLSR_HNA_HOLD_TIME      Time (3 * m_hnaInterval)
86 
87 /********** Link types **********/
88 
89 /// Unspecified link type.
90 #define OLSR_UNSPEC_LINK        0
91 /// Asymmetric link type.
92 #define OLSR_ASYM_LINK          1
93 /// Symmetric link type.
94 #define OLSR_SYM_LINK           2
95 /// Lost link type.
96 #define OLSR_LOST_LINK          3
97 
98 /********** Neighbor types **********/
99 
100 /// Not neighbor type.
101 #define OLSR_NOT_NEIGH          0
102 /// Symmetric neighbor type.
103 #define OLSR_SYM_NEIGH          1
104 /// Asymmetric neighbor type.
105 #define OLSR_MPR_NEIGH          2
106 
107 
108 /********** Willingness **********/
109 
110 /// Willingness for forwarding packets from other nodes: never.
111 #define OLSR_WILL_NEVER         0
112 /// Willingness for forwarding packets from other nodes: low.
113 #define OLSR_WILL_LOW           1
114 /// Willingness for forwarding packets from other nodes: medium.
115 #define OLSR_WILL_DEFAULT       3
116 /// Willingness for forwarding packets from other nodes: high.
117 #define OLSR_WILL_HIGH          6
118 /// Willingness for forwarding packets from other nodes: always.
119 #define OLSR_WILL_ALWAYS        7
120 
121 
122 /********** Miscellaneous constants **********/
123 
124 /// Maximum allowed jitter.
125 #define OLSR_MAXJITTER          (m_helloInterval.GetSeconds () / 4)
126 /// Maximum allowed sequence number.
127 #define OLSR_MAX_SEQ_NUM        65535
128 /// Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission.
129 #define JITTER (Seconds (m_uniformRandomVariable->GetValue (0, OLSR_MAXJITTER)))
130 
131 
132 /// Maximum number of messages per packet.
133 #define OLSR_MAX_MSGS           64
134 
135 /// Maximum number of hellos per message (4 possible link types * 3 possible nb types).
136 #define OLSR_MAX_HELLOS         12
137 
138 /// Maximum number of addresses advertised on a message.
139 #define OLSR_MAX_ADDRS          64
140 
141 
142 namespace ns3 {
143 
144 NS_LOG_COMPONENT_DEFINE ("OlsrRoutingProtocol");
145 
146 namespace olsr {
147 
148 /********** OLSR class **********/
149 
150 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
151 
152 /* see https://www.iana.org/assignments/service-names-port-numbers */
153 const uint16_t RoutingProtocol::OLSR_PORT_NUMBER = 698;
154 
155 TypeId
GetTypeId(void)156 RoutingProtocol::GetTypeId (void)
157 {
158   static TypeId tid = TypeId ("ns3::olsr::RoutingProtocol")
159     .SetParent<Ipv4RoutingProtocol> ()
160     .SetGroupName ("Olsr")
161     .AddConstructor<RoutingProtocol> ()
162     .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
163                    TimeValue (Seconds (2)),
164                    MakeTimeAccessor (&RoutingProtocol::m_helloInterval),
165                    MakeTimeChecker ())
166     .AddAttribute ("TcInterval", "TC messages emission interval.",
167                    TimeValue (Seconds (5)),
168                    MakeTimeAccessor (&RoutingProtocol::m_tcInterval),
169                    MakeTimeChecker ())
170     .AddAttribute ("MidInterval", "MID messages emission interval.  Normally it is equal to TcInterval.",
171                    TimeValue (Seconds (5)),
172                    MakeTimeAccessor (&RoutingProtocol::m_midInterval),
173                    MakeTimeChecker ())
174     .AddAttribute ("HnaInterval", "HNA messages emission interval.  Normally it is equal to TcInterval.",
175                    TimeValue (Seconds (5)),
176                    MakeTimeAccessor (&RoutingProtocol::m_hnaInterval),
177                    MakeTimeChecker ())
178     .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.",
179                    EnumValue (OLSR_WILL_DEFAULT),
180                    MakeEnumAccessor (&RoutingProtocol::m_willingness),
181                    MakeEnumChecker (OLSR_WILL_NEVER, "never",
182                                     OLSR_WILL_LOW, "low",
183                                     OLSR_WILL_DEFAULT, "default",
184                                     OLSR_WILL_HIGH, "high",
185                                     OLSR_WILL_ALWAYS, "always"))
186     .AddTraceSource ("Rx", "Receive OLSR packet.",
187                      MakeTraceSourceAccessor (&RoutingProtocol::m_rxPacketTrace),
188                      "ns3::olsr::RoutingProtocol::PacketTxRxTracedCallback")
189     .AddTraceSource ("Tx", "Send OLSR packet.",
190                      MakeTraceSourceAccessor (&RoutingProtocol::m_txPacketTrace),
191                      "ns3::olsr::RoutingProtocol::PacketTxRxTracedCallback")
192     .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.",
193                      MakeTraceSourceAccessor (&RoutingProtocol::m_routingTableChanged),
194                      "ns3::olsr::RoutingProtocol::TableChangeTracedCallback")
195   ;
196   return tid;
197 }
198 
199 
RoutingProtocol(void)200 RoutingProtocol::RoutingProtocol (void)
201   : m_routingTableAssociation (0),
202   m_ipv4 (0),
203   m_helloTimer (Timer::CANCEL_ON_DESTROY),
204   m_tcTimer (Timer::CANCEL_ON_DESTROY),
205   m_midTimer (Timer::CANCEL_ON_DESTROY),
206   m_hnaTimer (Timer::CANCEL_ON_DESTROY),
207   m_queuedMessagesTimer (Timer::CANCEL_ON_DESTROY)
208 {
209   m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
210 
211   m_hnaRoutingTable = Create<Ipv4StaticRouting> ();
212 }
213 
~RoutingProtocol(void)214 RoutingProtocol::~RoutingProtocol (void)
215 {
216 }
217 
218 void
SetIpv4(Ptr<Ipv4> ipv4)219 RoutingProtocol::SetIpv4 (Ptr<Ipv4> ipv4)
220 {
221   NS_ASSERT (ipv4 != 0);
222   NS_ASSERT (m_ipv4 == 0);
223   NS_LOG_DEBUG ("Created olsr::RoutingProtocol");
224   m_helloTimer.SetFunction (&RoutingProtocol::HelloTimerExpire, this);
225   m_tcTimer.SetFunction (&RoutingProtocol::TcTimerExpire, this);
226   m_midTimer.SetFunction (&RoutingProtocol::MidTimerExpire, this);
227   m_hnaTimer.SetFunction (&RoutingProtocol::HnaTimerExpire, this);
228   m_queuedMessagesTimer.SetFunction (&RoutingProtocol::SendQueuedMessages, this);
229 
230   m_packetSequenceNumber = OLSR_MAX_SEQ_NUM;
231   m_messageSequenceNumber = OLSR_MAX_SEQ_NUM;
232   m_ansn = OLSR_MAX_SEQ_NUM;
233 
234   m_linkTupleTimerFirstTime = true;
235 
236   m_ipv4 = ipv4;
237 
238   m_hnaRoutingTable->SetIpv4 (ipv4);
239 }
240 
241 Ptr<Ipv4>
GetIpv4(void) const242 RoutingProtocol::GetIpv4 (void) const
243 {
244   return m_ipv4;
245 }
246 
DoDispose(void)247 void RoutingProtocol::DoDispose (void)
248 {
249   m_ipv4 = 0;
250   m_hnaRoutingTable = 0;
251   m_routingTableAssociation = 0;
252 
253   if (m_recvSocket)
254     {
255       m_recvSocket->Close ();
256       m_recvSocket = 0;
257     }
258 
259   for (std::map< Ptr<Socket>, Ipv4InterfaceAddress >::iterator iter = m_sendSockets.begin ();
260        iter != m_sendSockets.end (); iter++)
261     {
262       iter->first->Close ();
263     }
264   m_sendSockets.clear ();
265   m_table.clear ();
266 
267   Ipv4RoutingProtocol::DoDispose ();
268 }
269 
270 void
PrintRoutingTable(Ptr<OutputStreamWrapper> stream,Time::Unit unit) const271 RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream, Time::Unit unit) const
272 {
273   std::ostream* os = stream->GetStream ();
274   // Copy the current ostream state
275   std::ios oldState (nullptr);
276   oldState.copyfmt (*os);
277 
278   *os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
279 
280   *os << "Node: " << m_ipv4->GetObject<Node> ()->GetId ()
281       << ", Time: " << Now ().As (unit)
282       << ", Local time: " << m_ipv4->GetObject<Node> ()->GetLocalTime ().As (unit)
283       << ", OLSR Routing table" << std::endl;
284 
285   *os << std::setw (16) << "Destination";
286   *os << std::setw (16) << "NextHop";
287   *os << std::setw (16) << "Interface";
288   *os << "Distance" << std::endl;
289 
290   for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
291        iter != m_table.end (); iter++)
292     {
293       *os << std::setw (16) << iter->first;
294       *os << std::setw (16) << iter->second.nextAddr;
295       *os << std::setw (16);
296       if (Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) != "")
297         {
298           *os << Names::FindName (m_ipv4->GetNetDevice (iter->second.interface));
299         }
300       else
301         {
302           *os << iter->second.interface;
303         }
304       *os << iter->second.distance << std::endl;
305     }
306   *os << std::endl;
307 
308   // Also print the HNA routing table
309   if (m_hnaRoutingTable->GetNRoutes () > 0)
310     {
311       *os << "HNA Routing Table:" << std::endl;
312       m_hnaRoutingTable->PrintRoutingTable (stream, unit);
313     }
314   else
315     {
316       *os << "HNA Routing Table: empty" << std::endl;
317     }
318   // Restore the previous ostream state
319   (*os).copyfmt (oldState);
320 }
321 
DoInitialize()322 void RoutingProtocol::DoInitialize ()
323 {
324   if (m_mainAddress == Ipv4Address ())
325     {
326       Ipv4Address loopback ("127.0.0.1");
327       for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
328         {
329           // Use primary address, if multiple
330           Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
331           if (addr != loopback)
332             {
333               m_mainAddress = addr;
334               break;
335             }
336         }
337 
338       NS_ASSERT (m_mainAddress != Ipv4Address ());
339     }
340 
341   NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
342 
343   Ipv4Address loopback ("127.0.0.1");
344 
345   bool canRunOlsr = false;
346   for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
347     {
348       Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
349       if (addr == loopback)
350         {
351           continue;
352         }
353 
354       if (addr != m_mainAddress)
355         {
356           // Create never expiring interface association tuple entries for our
357           // own network interfaces, so that GetMainAddress () works to
358           // translate the node's own interface addresses into the main address.
359           IfaceAssocTuple tuple;
360           tuple.ifaceAddr = addr;
361           tuple.mainAddr = m_mainAddress;
362           AddIfaceAssocTuple (tuple);
363           NS_ASSERT (GetMainAddress (addr) == m_mainAddress);
364         }
365 
366       if (m_interfaceExclusions.find (i) != m_interfaceExclusions.end ())
367         {
368           continue;
369         }
370 
371       // Create a socket to listen on all the interfaces
372       if (m_recvSocket == 0)
373         {
374           m_recvSocket = Socket::CreateSocket (GetObject<Node> (),
375                                                UdpSocketFactory::GetTypeId ());
376           m_recvSocket->SetAllowBroadcast (true);
377           InetSocketAddress inetAddr (Ipv4Address::GetAny (), OLSR_PORT_NUMBER);
378           m_recvSocket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvOlsr,  this));
379           if (m_recvSocket->Bind (inetAddr))
380             {
381               NS_FATAL_ERROR ("Failed to bind() OLSR socket");
382             }
383           m_recvSocket->SetRecvPktInfo (true);
384           m_recvSocket->ShutdownSend ();
385         }
386 
387       // Create a socket to send packets from this specific interfaces
388       Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
389                                                  UdpSocketFactory::GetTypeId ());
390       socket->SetAllowBroadcast (true);
391       socket->SetIpTtl (1);
392       InetSocketAddress inetAddr (m_ipv4->GetAddress (i, 0).GetLocal (), OLSR_PORT_NUMBER);
393       socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvOlsr,  this));
394       socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
395       if (socket->Bind (inetAddr))
396         {
397           NS_FATAL_ERROR ("Failed to bind() OLSR socket");
398         }
399       socket->SetRecvPktInfo (true);
400       m_sendSockets[socket] = m_ipv4->GetAddress (i, 0);
401 
402       canRunOlsr = true;
403     }
404 
405   if (canRunOlsr)
406     {
407       HelloTimerExpire ();
408       TcTimerExpire ();
409       MidTimerExpire ();
410       HnaTimerExpire ();
411 
412       NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
413     }
414 }
415 
SetMainInterface(uint32_t interface)416 void RoutingProtocol::SetMainInterface (uint32_t interface)
417 {
418   m_mainAddress = m_ipv4->GetAddress (interface, 0).GetLocal ();
419 }
420 
SetInterfaceExclusions(std::set<uint32_t> exceptions)421 void RoutingProtocol::SetInterfaceExclusions (std::set<uint32_t> exceptions)
422 {
423   m_interfaceExclusions = exceptions;
424 }
425 
426 //
427 // \brief Processes an incoming %OLSR packet following \RFC{3626} specification.
428 void
RecvOlsr(Ptr<Socket> socket)429 RoutingProtocol::RecvOlsr (Ptr<Socket> socket)
430 {
431   Ptr<Packet> receivedPacket;
432   Address sourceAddress;
433   receivedPacket = socket->RecvFrom (sourceAddress);
434 
435   Ipv4PacketInfoTag interfaceInfo;
436   if (!receivedPacket->RemovePacketTag (interfaceInfo))
437     {
438       NS_ABORT_MSG ("No incoming interface on OLSR message, aborting.");
439     }
440   uint32_t incomingIf = interfaceInfo.GetRecvIf ();
441   Ptr<Node> node = this->GetObject<Node> ();
442   Ptr<NetDevice> dev = node->GetDevice (incomingIf);
443   uint32_t recvInterfaceIndex = m_ipv4->GetInterfaceForDevice (dev);
444 
445   if (m_interfaceExclusions.find (recvInterfaceIndex) != m_interfaceExclusions.end ())
446     {
447       return;
448     }
449 
450 
451   InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
452   Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
453 
454   int32_t interfaceForAddress = m_ipv4->GetInterfaceForAddress (senderIfaceAddr);
455   if (interfaceForAddress != -1)
456     {
457       NS_LOG_LOGIC ("Ignoring a packet sent by myself.");
458       return;
459     }
460 
461   Ipv4Address receiverIfaceAddr = m_ipv4->GetAddress (recvInterfaceIndex, 0).GetLocal ();
462   NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
463   NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
464                              << senderIfaceAddr << " to " << receiverIfaceAddr);
465 
466   // All routing messages are sent from and to port RT_PORT,
467   // so we check it.
468   NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER);
469 
470   Ptr<Packet> packet = receivedPacket;
471 
472   olsr::PacketHeader olsrPacketHeader;
473   packet->RemoveHeader (olsrPacketHeader);
474   NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ());
475   uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize ();
476 
477   MessageList messages;
478 
479   while (sizeLeft)
480     {
481       MessageHeader messageHeader;
482       if (packet->RemoveHeader (messageHeader) == 0)
483         {
484           NS_ASSERT (false);
485         }
486 
487       sizeLeft -= messageHeader.GetSerializedSize ();
488 
489       NS_LOG_DEBUG ("Olsr Msg received with type "
490                     << std::dec << int (messageHeader.GetMessageType ())
491                     << " TTL=" << int (messageHeader.GetTimeToLive ())
492                     << " origAddr=" << messageHeader.GetOriginatorAddress ());
493       messages.push_back (messageHeader);
494     }
495 
496   m_rxPacketTrace (olsrPacketHeader, messages);
497 
498   for (MessageList::const_iterator messageIter = messages.begin ();
499        messageIter != messages.end (); messageIter++)
500     {
501       const MessageHeader &messageHeader = *messageIter;
502       // If ttl is less than or equal to zero, or
503       // the receiver is the same as the originator,
504       // the message must be silently dropped
505       if (messageHeader.GetTimeToLive () == 0
506           || messageHeader.GetOriginatorAddress () == m_mainAddress)
507         {
508           packet->RemoveAtStart (messageHeader.GetSerializedSize ()
509                                  - messageHeader.GetSerializedSize ());
510           continue;
511         }
512 
513       // If the message has been processed it must not be processed again
514       bool do_forwarding = true;
515       DuplicateTuple *duplicated = m_state.FindDuplicateTuple
516           (messageHeader.GetOriginatorAddress (),
517           messageHeader.GetMessageSequenceNumber ());
518 
519       // Get main address of the peer, which may be different from the packet source address
520 //       const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ());
521 //       Ipv4Address peerMainAddress;
522 //       if (ifaceAssoc != NULL)
523 //         {
524 //           peerMainAddress = ifaceAssoc->mainAddr;
525 //         }
526 //       else
527 //         {
528 //           peerMainAddress = inetSourceAddr.GetIpv4 () ;
529 //         }
530 
531       if (duplicated == NULL)
532         {
533           switch (messageHeader.GetMessageType ())
534             {
535             case olsr::MessageHeader::HELLO_MESSAGE:
536               NS_LOG_DEBUG (Simulator::Now ().As (Time::S)
537                             << " OLSR node " << m_mainAddress
538                             << " received HELLO message of size " << messageHeader.GetSerializedSize ());
539               ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr);
540               break;
541 
542             case olsr::MessageHeader::TC_MESSAGE:
543               NS_LOG_DEBUG (Simulator::Now ().As (Time::S)
544                             << " OLSR node " << m_mainAddress
545                             << " received TC message of size " << messageHeader.GetSerializedSize ());
546               ProcessTc (messageHeader, senderIfaceAddr);
547               break;
548 
549             case olsr::MessageHeader::MID_MESSAGE:
550               NS_LOG_DEBUG (Simulator::Now ().As (Time::S)
551                             << " OLSR node " << m_mainAddress
552                             <<  " received MID message of size " << messageHeader.GetSerializedSize ());
553               ProcessMid (messageHeader, senderIfaceAddr);
554               break;
555             case olsr::MessageHeader::HNA_MESSAGE:
556               NS_LOG_DEBUG (Simulator::Now ().As (Time::S)
557                             << " OLSR node " << m_mainAddress
558                             <<  " received HNA message of size " << messageHeader.GetSerializedSize ());
559               ProcessHna (messageHeader, senderIfaceAddr);
560               break;
561 
562             default:
563               NS_LOG_DEBUG ("OLSR message type " <<
564                             int (messageHeader.GetMessageType ()) <<
565                             " not implemented");
566             }
567         }
568       else
569         {
570           NS_LOG_DEBUG ("OLSR message is duplicated, not reading it.");
571 
572           // If the message has been considered for forwarding, it should
573           // not be retransmitted again
574           for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin ();
575                it != duplicated->ifaceList.end (); it++)
576             {
577               if (*it == receiverIfaceAddr)
578                 {
579                   do_forwarding = false;
580                   break;
581                 }
582             }
583         }
584 
585       if (do_forwarding)
586         {
587           // HELLO messages are never forwarded.
588           // TC and MID messages are forwarded using the default algorithm.
589           // Remaining messages are also forwarded using the default algorithm.
590           if (messageHeader.GetMessageType ()  != olsr::MessageHeader::HELLO_MESSAGE)
591             {
592               ForwardDefault (messageHeader, duplicated,
593                               receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
594             }
595         }
596     }
597 
598   // After processing all OLSR messages, we must recompute the routing table
599   RoutingTableComputation ();
600 }
601 
602 ///
603 /// \brief This auxiliary function (defined in \RFC{3626}) is used for calculating the MPR Set.
604 ///
605 /// \param tuple the neighbor tuple which has the main address of the node we are going to calculate its degree to.
606 /// \return the degree of the node.
607 ///
608 int
Degree(NeighborTuple const & tuple)609 RoutingProtocol::Degree (NeighborTuple const &tuple)
610 {
611   int degree = 0;
612   for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin ();
613        it != m_state.GetTwoHopNeighbors ().end (); it++)
614     {
615       TwoHopNeighborTuple const &nb2hop_tuple = *it;
616       if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
617         {
618           const NeighborTuple *nb_tuple =
619             m_state.FindNeighborTuple (nb2hop_tuple.neighborMainAddr);
620           if (nb_tuple == NULL)
621             {
622               degree++;
623             }
624         }
625     }
626   return degree;
627 }
628 
629 namespace {
630 ///
631 /// \brief Remove all covered 2-hop neighbors from N2 set.
632 /// This is a helper function used by MprComputation algorithm.
633 ///
634 /// \param neighborMainAddr Neighbor main address.
635 /// \param N2 Reference to the 2-hop neighbor set.
636 ///
637 void
CoverTwoHopNeighbors(Ipv4Address neighborMainAddr,TwoHopNeighborSet & N2)638 CoverTwoHopNeighbors (Ipv4Address neighborMainAddr, TwoHopNeighborSet & N2)
639 {
640   // first gather all 2-hop neighbors to be removed
641   std::set<Ipv4Address> toRemove;
642   for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
643     {
644       if (twoHopNeigh->neighborMainAddr == neighborMainAddr)
645         {
646           toRemove.insert (twoHopNeigh->twoHopNeighborAddr);
647         }
648     }
649   // Now remove all matching records from N2
650   for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); )
651     {
652       if (toRemove.find (twoHopNeigh->twoHopNeighborAddr) != toRemove.end ())
653         {
654           twoHopNeigh = N2.erase (twoHopNeigh);
655         }
656       else
657         {
658           twoHopNeigh++;
659         }
660     }
661 }
662 }  // unnamed namespace
663 
664 void
MprComputation(void)665 RoutingProtocol::MprComputation  (void)
666 {
667   NS_LOG_FUNCTION (this);
668 
669   // MPR computation should be done for each interface. See section 8.3.1
670   // (RFC 3626) for details.
671   MprSet mprSet;
672 
673   // N is the subset of neighbors of the node, which are
674   // neighbor "of the interface I"
675   NeighborSet N;
676   for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin ();
677        neighbor != m_state.GetNeighbors ().end (); neighbor++)
678     {
679       if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
680         {
681           N.push_back (*neighbor);
682         }
683     }
684 
685   // N2 is the set of 2-hop neighbors reachable from "the interface
686   // I", excluding:
687   // (i)   the nodes only reachable by members of N with willingness WILL_NEVER
688   // (ii)  the node performing the computation
689   // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
690   //       link to this node on some interface.
691   TwoHopNeighborSet N2;
692   for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin ();
693        twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++)
694     {
695       // excluding:
696       // (ii)  the node performing the computation
697       if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
698         {
699           continue;
700         }
701 
702       //  excluding:
703       // (i)   the nodes only reachable by members of N with willingness WILL_NEVER
704       bool ok = false;
705       for (NeighborSet::const_iterator neigh = N.begin ();
706            neigh != N.end (); neigh++)
707         {
708           if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
709             {
710               if (neigh->willingness == OLSR_WILL_NEVER)
711                 {
712                   ok = false;
713                   break;
714                 }
715               else
716                 {
717                   ok = true;
718                   break;
719                 }
720             }
721         }
722       if (!ok)
723         {
724           continue;
725         }
726 
727       // excluding:
728       // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
729       //       link to this node on some interface.
730       for (NeighborSet::const_iterator neigh = N.begin ();
731            neigh != N.end (); neigh++)
732         {
733           if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
734             {
735               ok = false;
736               break;
737             }
738         }
739 
740       if (ok)
741         {
742           N2.push_back (*twoHopNeigh);
743         }
744     }
745 
746 #ifdef NS3_LOG_ENABLE
747   {
748     std::ostringstream os;
749     os << "[";
750     for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
751          iter != N2.end (); iter++)
752       {
753         TwoHopNeighborSet::const_iterator next = iter;
754         next++;
755         os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
756         if (next != N2.end ())
757           {
758             os << ", ";
759           }
760       }
761     os << "]";
762     NS_LOG_DEBUG ("N2: " << os.str ());
763   }
764 #endif  //NS3_LOG_ENABLE
765 
766   // 1. Start with an MPR set made of all members of N with
767   // N_willingness equal to WILL_ALWAYS
768   for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
769     {
770       if (neighbor->willingness == OLSR_WILL_ALWAYS)
771         {
772           mprSet.insert (neighbor->neighborMainAddr);
773           // (not in RFC but I think is needed: remove the 2-hop
774           // neighbors reachable by the MPR from N2)
775           CoverTwoHopNeighbors (neighbor->neighborMainAddr, N2);
776         }
777     }
778 
779   // 2. Calculate D(y), where y is a member of N, for all nodes in N.
780   // (we do this later)
781 
782   // 3. Add to the MPR set those nodes in N, which are the *only*
783   // nodes to provide reachability to a node in N2.
784   std::set<Ipv4Address> coveredTwoHopNeighbors;
785   for (TwoHopNeighborSet::const_iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
786     {
787       bool onlyOne = true;
788       // try to find another neighbor that can reach twoHopNeigh->twoHopNeighborAddr
789       for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin (); otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
790         {
791           if (otherTwoHopNeigh->twoHopNeighborAddr == twoHopNeigh->twoHopNeighborAddr
792               && otherTwoHopNeigh->neighborMainAddr != twoHopNeigh->neighborMainAddr)
793             {
794               onlyOne = false;
795               break;
796             }
797         }
798       if (onlyOne)
799         {
800           NS_LOG_LOGIC ("Neighbor " << twoHopNeigh->neighborMainAddr
801                                     << " is the only that can reach 2-hop neigh. "
802                                     << twoHopNeigh->twoHopNeighborAddr
803                                     << " => select as MPR.");
804 
805           mprSet.insert (twoHopNeigh->neighborMainAddr);
806 
807           // take note of all the 2-hop neighbors reachable by the newly elected MPR
808           for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin ();
809                otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
810             {
811               if (otherTwoHopNeigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
812                 {
813                   coveredTwoHopNeighbors.insert (otherTwoHopNeigh->twoHopNeighborAddr);
814                 }
815             }
816         }
817     }
818   // Remove the nodes from N2 which are now covered by a node in the MPR set.
819   for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
820        twoHopNeigh != N2.end (); )
821     {
822       if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
823         {
824           // This works correctly only because it is known that twoHopNeigh is reachable by exactly one neighbor,
825           // so only one record in N2 exists for each of them. This record is erased here.
826           NS_LOG_LOGIC ("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr << " is already covered by an MPR.");
827           twoHopNeigh = N2.erase (twoHopNeigh);
828         }
829       else
830         {
831           twoHopNeigh++;
832         }
833     }
834 
835   // 4. While there exist nodes in N2 which are not covered by at
836   // least one node in the MPR set:
837   while (N2.begin () != N2.end ())
838     {
839 
840 #ifdef NS3_LOG_ENABLE
841       {
842         std::ostringstream os;
843         os << "[";
844         for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
845              iter != N2.end (); iter++)
846           {
847             TwoHopNeighborSet::const_iterator next = iter;
848             next++;
849             os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
850             if (next != N2.end ())
851               {
852                 os << ", ";
853               }
854           }
855         os << "]";
856         NS_LOG_DEBUG ("Step 4 iteration: N2=" << os.str ());
857       }
858 #endif  //NS3_LOG_ENABLE
859 
860 
861       // 4.1. For each node in N, calculate the reachability, i.e., the
862       // number of nodes in N2 which are not yet covered by at
863       // least one node in the MPR set, and which are reachable
864       // through this 1-hop neighbor
865       std::map<int, std::vector<const NeighborTuple *> > reachability;
866       std::set<int> rs;
867       for (NeighborSet::iterator it = N.begin (); it != N.end (); it++)
868         {
869           NeighborTuple const &nb_tuple = *it;
870           int r = 0;
871           for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++)
872             {
873               TwoHopNeighborTuple const &nb2hop_tuple = *it2;
874               if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
875                 {
876                   r++;
877                 }
878             }
879           rs.insert (r);
880           reachability[r].push_back (&nb_tuple);
881         }
882 
883       // 4.2. Select as a MPR the node with highest N_willingness among
884       // the nodes in N with non-zero reachability. In case of
885       // multiple choice select the node which provides
886       // reachability to the maximum number of nodes in N2. In
887       // case of multiple nodes providing the same amount of
888       // reachability, select the node as MPR whose D(y) is
889       // greater. Remove the nodes from N2 which are now covered
890       // by a node in the MPR set.
891       NeighborTuple const *max = NULL;
892       int max_r = 0;
893       for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++)
894         {
895           int r = *it;
896           if (r == 0)
897             {
898               continue;
899             }
900           for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin ();
901                it2 != reachability[r].end (); it2++)
902             {
903               const NeighborTuple *nb_tuple = *it2;
904               if (max == NULL || nb_tuple->willingness > max->willingness)
905                 {
906                   max = nb_tuple;
907                   max_r = r;
908                 }
909               else if (nb_tuple->willingness == max->willingness)
910                 {
911                   if (r > max_r)
912                     {
913                       max = nb_tuple;
914                       max_r = r;
915                     }
916                   else if (r == max_r)
917                     {
918                       if (Degree (*nb_tuple) > Degree (*max))
919                         {
920                           max = nb_tuple;
921                           max_r = r;
922                         }
923                     }
924                 }
925             }
926         }
927 
928       if (max != NULL)
929         {
930           mprSet.insert (max->neighborMainAddr);
931           CoverTwoHopNeighbors (max->neighborMainAddr, N2);
932           NS_LOG_LOGIC (N2.size () << " 2-hop neighbors left to cover!");
933         }
934     }
935 
936 #ifdef NS3_LOG_ENABLE
937   {
938     std::ostringstream os;
939     os << "[";
940     for (MprSet::const_iterator iter = mprSet.begin ();
941          iter != mprSet.end (); iter++)
942       {
943         MprSet::const_iterator next = iter;
944         next++;
945         os << *iter;
946         if (next != mprSet.end ())
947           {
948             os << ", ";
949           }
950       }
951     os << "]";
952     NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
953   }
954 #endif  //NS3_LOG_ENABLE
955 
956   m_state.SetMprSet (mprSet);
957 }
958 
959 Ipv4Address
GetMainAddress(Ipv4Address iface_addr) const960 RoutingProtocol::GetMainAddress (Ipv4Address iface_addr) const
961 {
962   const IfaceAssocTuple *tuple =
963     m_state.FindIfaceAssocTuple (iface_addr);
964 
965   if (tuple != NULL)
966     {
967       return tuple->mainAddr;
968     }
969   else
970     {
971       return iface_addr;
972     }
973 }
974 
975 void
RoutingTableComputation(void)976 RoutingProtocol::RoutingTableComputation  (void)
977 {
978   NS_LOG_DEBUG (Simulator::Now ().As (Time::S) << " : Node " << m_mainAddress
979                                                << ": RoutingTableComputation begin...");
980 
981   // 1. All the entries from the routing table are removed.
982   Clear ();
983 
984   // 2. The new routing entries are added starting with the
985   // symmetric neighbors (h=1) as the destination nodes.
986   const NeighborSet &neighborSet = m_state.GetNeighbors ();
987   for (NeighborSet::const_iterator it = neighborSet.begin ();
988        it != neighborSet.end (); it++)
989     {
990       NeighborTuple const &nb_tuple = *it;
991       NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple);
992       if (nb_tuple.status == NeighborTuple::STATUS_SYM)
993         {
994           bool nb_main_addr = false;
995           const LinkTuple *lt = NULL;
996           const LinkSet &linkSet = m_state.GetLinks ();
997           for (LinkSet::const_iterator it2 = linkSet.begin ();
998                it2 != linkSet.end (); it2++)
999             {
1000               LinkTuple const &link_tuple = *it2;
1001               NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple
1002                                                       << (link_tuple.time >= Simulator::Now () ? "" : " (expired)"));
1003               if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr)
1004                   && link_tuple.time >= Simulator::Now ())
1005                 {
1006                   NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr
1007                                                                << " => adding routing table entry to neighbor");
1008                   lt = &link_tuple;
1009                   AddEntry (link_tuple.neighborIfaceAddr,
1010                             link_tuple.neighborIfaceAddr,
1011                             link_tuple.localIfaceAddr,
1012                             1);
1013                   if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
1014                     {
1015                       nb_main_addr = true;
1016                     }
1017                 }
1018               else
1019                 {
1020                   NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr)
1021                                                                 << "; neighborMainAddr =  " << nb_tuple.neighborMainAddr
1022                                                                 << "; expired=" << int (link_tuple.time < Simulator::Now ())
1023                                                                 << " => IGNORE");
1024                 }
1025             }
1026 
1027           // If, in the above, no R_dest_addr is equal to the main
1028           // address of the neighbor, then another new routing entry
1029           // with MUST be added, with:
1030           //      R_dest_addr  = main address of the neighbor;
1031           //      R_next_addr  = L_neighbor_iface_addr of one of the
1032           //                     associated link tuple with L_time >= current time;
1033           //      R_dist       = 1;
1034           //      R_iface_addr = L_local_iface_addr of the
1035           //                     associated link tuple.
1036           if (!nb_main_addr && lt != NULL)
1037             {
1038               NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor "
1039                             "=> adding additional routing entry");
1040               AddEntry (nb_tuple.neighborMainAddr,
1041                         lt->neighborIfaceAddr,
1042                         lt->localIfaceAddr,
1043                         1);
1044             }
1045         }
1046     }
1047 
1048   //  3. for each node in N2, i.e., a 2-hop neighbor which is not a
1049   //  neighbor node or the node itself, and such that there exist at
1050   //  least one entry in the 2-hop neighbor set where
1051   //  N_neighbor_main_addr correspond to a neighbor node with
1052   //  willingness different of WILL_NEVER,
1053   const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1054   for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin ();
1055        it != twoHopNeighbors.end (); it++)
1056     {
1057       TwoHopNeighborTuple const &nb2hop_tuple = *it;
1058 
1059       NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
1060 
1061       // a 2-hop neighbor which is not a neighbor node or the node itself
1062       if (m_state.FindSymNeighborTuple (nb2hop_tuple.twoHopNeighborAddr))
1063         {
1064           NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped.");
1065           continue;
1066         }
1067 
1068       if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
1069         {
1070           NS_LOG_LOGIC ("Two-hop neighbor is self; skipped.");
1071           continue;
1072         }
1073 
1074       // ...and such that there exist at least one entry in the 2-hop
1075       // neighbor set where N_neighbor_main_addr correspond to a
1076       // neighbor node with willingness different of WILL_NEVER...
1077       bool nb2hopOk = false;
1078       for (NeighborSet::const_iterator neighbor = neighborSet.begin ();
1079            neighbor != neighborSet.end (); neighbor++)
1080         {
1081           if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr
1082               && neighbor->willingness != OLSR_WILL_NEVER)
1083             {
1084               nb2hopOk = true;
1085               break;
1086             }
1087         }
1088       if (!nb2hopOk)
1089         {
1090           NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor "
1091                         << nb2hop_tuple.twoHopNeighborAddr
1092                         << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr
1093                         << ", which was not found in the Neighbor Set.");
1094           continue;
1095         }
1096 
1097       // one selects one 2-hop tuple and creates one entry in the routing table with:
1098       //                R_dest_addr  =  the main address of the 2-hop neighbor;
1099       //                R_next_addr  = the R_next_addr of the entry in the
1100       //                               routing table with:
1101       //                                   R_dest_addr == N_neighbor_main_addr
1102       //                                                  of the 2-hop tuple;
1103       //                R_dist       = 2;
1104       //                R_iface_addr = the R_iface_addr of the entry in the
1105       //                               routing table with:
1106       //                                   R_dest_addr == N_neighbor_main_addr
1107       //                                                  of the 2-hop tuple;
1108       RoutingTableEntry entry;
1109       bool foundEntry = Lookup (nb2hop_tuple.neighborMainAddr, entry);
1110       if (foundEntry)
1111         {
1112           NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor.");
1113           AddEntry (nb2hop_tuple.twoHopNeighborAddr,
1114                     entry.nextAddr,
1115                     entry.interface,
1116                     2);
1117         }
1118       else
1119         {
1120           NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor ("
1121                         << nb2hop_tuple.twoHopNeighborAddr
1122                         << " not found in the routing table)");
1123         }
1124     }
1125 
1126   for (uint32_t h = 2;; h++)
1127     {
1128       bool added = false;
1129 
1130       // 3.1. For each topology entry in the topology table, if its
1131       // T_dest_addr does not correspond to R_dest_addr of any
1132       // route entry in the routing table AND its T_last_addr
1133       // corresponds to R_dest_addr of a route entry whose R_dist
1134       // is equal to h, then a new route entry MUST be recorded in
1135       // the routing table (if it does not already exist)
1136       const TopologySet &topology = m_state.GetTopologySet ();
1137       for (TopologySet::const_iterator it = topology.begin ();
1138            it != topology.end (); it++)
1139         {
1140           const TopologyTuple &topology_tuple = *it;
1141           NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple);
1142 
1143           RoutingTableEntry destAddrEntry, lastAddrEntry;
1144           bool have_destAddrEntry = Lookup (topology_tuple.destAddr, destAddrEntry);
1145           bool have_lastAddrEntry = Lookup (topology_tuple.lastAddr, lastAddrEntry);
1146           if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
1147             {
1148               NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple.");
1149               // then a new route entry MUST be recorded in
1150               //                the routing table (if it does not already exist) where:
1151               //                     R_dest_addr  = T_dest_addr;
1152               //                     R_next_addr  = R_next_addr of the recorded
1153               //                                    route entry where:
1154               //                                    R_dest_addr == T_last_addr
1155               //                     R_dist       = h+1; and
1156               //                     R_iface_addr = R_iface_addr of the recorded
1157               //                                    route entry where:
1158               //                                       R_dest_addr == T_last_addr.
1159               AddEntry (topology_tuple.destAddr,
1160                         lastAddrEntry.nextAddr,
1161                         lastAddrEntry.interface,
1162                         h + 1);
1163               added = true;
1164             }
1165           else
1166             {
1167               NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: "
1168                             "have_destAddrEntry=" << have_destAddrEntry
1169                                                   << " have_lastAddrEntry=" << have_lastAddrEntry
1170                                                   << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance
1171                                                   << " (h=" << h << ")");
1172             }
1173         }
1174 
1175       if (!added)
1176         {
1177           break;
1178         }
1179     }
1180 
1181   // 4. For each entry in the multiple interface association base
1182   // where there exists a routing entry such that:
1183   // R_dest_addr == I_main_addr (of the multiple interface association entry)
1184   // AND there is no routing entry such that:
1185   // R_dest_addr == I_iface_addr
1186   const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
1187   for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
1188        it != ifaceAssocSet.end (); it++)
1189     {
1190       IfaceAssocTuple const &tuple = *it;
1191       RoutingTableEntry entry1, entry2;
1192       bool have_entry1 = Lookup (tuple.mainAddr, entry1);
1193       bool have_entry2 = Lookup (tuple.ifaceAddr, entry2);
1194       if (have_entry1 && !have_entry2)
1195         {
1196           // then a route entry is created in the routing table with:
1197           //       R_dest_addr  =  I_iface_addr (of the multiple interface
1198           //                                     association entry)
1199           //       R_next_addr  =  R_next_addr  (of the recorded route entry)
1200           //       R_dist       =  R_dist       (of the recorded route entry)
1201           //       R_iface_addr =  R_iface_addr (of the recorded route entry).
1202           AddEntry (tuple.ifaceAddr,
1203                     entry1.nextAddr,
1204                     entry1.interface,
1205                     entry1.distance);
1206         }
1207     }
1208 
1209   // 5. For each tuple in the association set,
1210   //    If there is no entry in the routing table with:
1211   //        R_dest_addr     == A_network_addr/A_netmask
1212   //   and if the announced network is not announced by the node itself,
1213   //   then a new routing entry is created.
1214   const AssociationSet &associationSet = m_state.GetAssociationSet ();
1215 
1216   // Clear HNA routing table
1217   for (uint32_t i = 0; i < m_hnaRoutingTable->GetNRoutes (); i++)
1218     {
1219       m_hnaRoutingTable->RemoveRoute (0);
1220     }
1221 
1222   for (AssociationSet::const_iterator it = associationSet.begin ();
1223        it != associationSet.end (); it++)
1224     {
1225       AssociationTuple const &tuple = *it;
1226 
1227       // Test if HNA associations received from other gateways
1228       // are also announced by this node. In such a case, no route
1229       // is created for this association tuple (go to the next one).
1230       bool goToNextAssociationTuple = false;
1231       const Associations &localHnaAssociations = m_state.GetAssociations ();
1232       NS_LOG_DEBUG ("Nb local associations: " << localHnaAssociations.size ());
1233       for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1234            assocIterator != localHnaAssociations.end (); assocIterator++)
1235         {
1236           Association const &localHnaAssoc = *assocIterator;
1237           if (localHnaAssoc.networkAddr == tuple.networkAddr && localHnaAssoc.netmask == tuple.netmask)
1238             {
1239               NS_LOG_DEBUG ("HNA association received from another GW is part of local HNA associations: no route added for network "
1240                             << tuple.networkAddr << "/" << tuple.netmask);
1241               goToNextAssociationTuple = true;
1242             }
1243         }
1244       if (goToNextAssociationTuple)
1245         {
1246           continue;
1247         }
1248 
1249       RoutingTableEntry gatewayEntry;
1250 
1251       bool gatewayEntryExists = Lookup (tuple.gatewayAddr, gatewayEntry);
1252       bool addRoute = false;
1253 
1254       uint32_t routeIndex = 0;
1255 
1256       for (routeIndex = 0; routeIndex < m_hnaRoutingTable->GetNRoutes (); routeIndex++)
1257         {
1258           Ipv4RoutingTableEntry route = m_hnaRoutingTable->GetRoute (routeIndex);
1259           if (route.GetDestNetwork () == tuple.networkAddr
1260               && route.GetDestNetworkMask () == tuple.netmask)
1261             {
1262               break;
1263             }
1264         }
1265 
1266       if (routeIndex == m_hnaRoutingTable->GetNRoutes ())
1267         {
1268           addRoute = true;
1269         }
1270       else if (gatewayEntryExists && m_hnaRoutingTable->GetMetric (routeIndex) > gatewayEntry.distance)
1271         {
1272           m_hnaRoutingTable->RemoveRoute (routeIndex);
1273           addRoute = true;
1274         }
1275 
1276       if (addRoute && gatewayEntryExists)
1277         {
1278           m_hnaRoutingTable->AddNetworkRouteTo (tuple.networkAddr,
1279                                                 tuple.netmask,
1280                                                 gatewayEntry.nextAddr,
1281                                                 gatewayEntry.interface,
1282                                                 gatewayEntry.distance);
1283 
1284         }
1285     }
1286 
1287   NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
1288   m_routingTableChanged (GetSize ());
1289 }
1290 
1291 
1292 void
ProcessHello(const olsr::MessageHeader & msg,const Ipv4Address & receiverIface,const Ipv4Address & senderIface)1293 RoutingProtocol::ProcessHello (const olsr::MessageHeader &msg,
1294                                const Ipv4Address &receiverIface,
1295                                const Ipv4Address &senderIface)
1296 {
1297   NS_LOG_FUNCTION (msg << receiverIface << senderIface);
1298 
1299   const olsr::MessageHeader::Hello &hello = msg.GetHello ();
1300 
1301   LinkSensing (msg, hello, receiverIface, senderIface);
1302 
1303 #ifdef NS3_LOG_ENABLE
1304   {
1305     const LinkSet &links = m_state.GetLinks ();
1306     NS_LOG_DEBUG (Simulator::Now ().As (Time::S)
1307                   << " ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
1308     for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++)
1309       {
1310         NS_LOG_DEBUG (*link);
1311       }
1312     NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress);
1313 
1314     const NeighborSet &neighbors = m_state.GetNeighbors ();
1315     NS_LOG_DEBUG (Simulator::Now ().As (Time::S)
1316                   << " ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
1317     for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1318       {
1319         NS_LOG_DEBUG (*neighbor);
1320       }
1321     NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
1322   }
1323 #endif // NS3_LOG_ENABLE
1324 
1325   PopulateNeighborSet (msg, hello);
1326   PopulateTwoHopNeighborSet (msg, hello);
1327 
1328 #ifdef NS3_LOG_ENABLE
1329   {
1330     const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1331     NS_LOG_DEBUG (Simulator::Now ().As (Time::S)
1332                   << " ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1333     for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin ();
1334          tuple != twoHopNeighbors.end (); tuple++)
1335       {
1336         NS_LOG_DEBUG (*tuple);
1337       }
1338     NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1339   }
1340 #endif // NS3_LOG_ENABLE
1341 
1342   MprComputation ();
1343   PopulateMprSelectorSet (msg, hello);
1344 }
1345 
1346 void
ProcessTc(const olsr::MessageHeader & msg,const Ipv4Address & senderIface)1347 RoutingProtocol::ProcessTc (const olsr::MessageHeader &msg,
1348                             const Ipv4Address &senderIface)
1349 {
1350   const olsr::MessageHeader::Tc &tc = msg.GetTc ();
1351   Time now = Simulator::Now ();
1352 
1353   // 1. If the sender interface of this message is not in the symmetric
1354   // 1-hop neighborhood of this node, the message MUST be discarded.
1355   const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1356   if (link_tuple == NULL)
1357     {
1358       return;
1359     }
1360 
1361   // 2. If there exist some tuple in the topology set where:
1362   //    T_last_addr == originator address AND
1363   //    T_seq       >  ANSN,
1364   // then further processing of this TC message MUST NOT be
1365   // performed.
1366   const TopologyTuple *topologyTuple =
1367     m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.ansn);
1368   if (topologyTuple != NULL)
1369     {
1370       return;
1371     }
1372 
1373   // 3. All tuples in the topology set where:
1374   //    T_last_addr == originator address AND
1375   //    T_seq       <  ANSN
1376   // MUST be removed from the topology set.
1377   m_state.EraseOlderTopologyTuples (msg.GetOriginatorAddress (), tc.ansn);
1378 
1379   // 4. For each of the advertised neighbor main address received in
1380   // the TC message:
1381   for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin ();
1382        i != tc.neighborAddresses.end (); i++)
1383     {
1384       const Ipv4Address &addr = *i;
1385       // 4.1. If there exist some tuple in the topology set where:
1386       //      T_dest_addr == advertised neighbor main address, AND
1387       //      T_last_addr == originator address,
1388       // then the holding time of that tuple MUST be set to:
1389       //      T_time      =  current time + validity time.
1390       TopologyTuple *topologyTuple =
1391         m_state.FindTopologyTuple (addr, msg.GetOriginatorAddress ());
1392 
1393       if (topologyTuple != NULL)
1394         {
1395           topologyTuple->expirationTime = now + msg.GetVTime ();
1396         }
1397       else
1398         {
1399           // 4.2. Otherwise, a new tuple MUST be recorded in the topology
1400           // set where:
1401           //      T_dest_addr = advertised neighbor main address,
1402           //      T_last_addr = originator address,
1403           //      T_seq       = ANSN,
1404           //      T_time      = current time + validity time.
1405           TopologyTuple topologyTuple;
1406           topologyTuple.destAddr = addr;
1407           topologyTuple.lastAddr = msg.GetOriginatorAddress ();
1408           topologyTuple.sequenceNumber = tc.ansn;
1409           topologyTuple.expirationTime = now + msg.GetVTime ();
1410           AddTopologyTuple (topologyTuple);
1411 
1412           // Schedules topology tuple deletion
1413           m_events.Track (Simulator::Schedule (DELAY (topologyTuple.expirationTime),
1414                                                &RoutingProtocol::TopologyTupleTimerExpire,
1415                                                this,
1416                                                topologyTuple.destAddr,
1417                                                topologyTuple.lastAddr));
1418         }
1419     }
1420 
1421 #ifdef NS3_LOG_ENABLE
1422   {
1423     const TopologySet &topology = m_state.GetTopologySet ();
1424     NS_LOG_DEBUG (Simulator::Now ().As (Time::S)
1425                   << " ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
1426     for (TopologySet::const_iterator tuple = topology.begin ();
1427          tuple != topology.end (); tuple++)
1428       {
1429         NS_LOG_DEBUG (*tuple);
1430       }
1431     NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
1432   }
1433 #endif // NS3_LOG_ENABLE
1434 }
1435 
1436 void
ProcessMid(const olsr::MessageHeader & msg,const Ipv4Address & senderIface)1437 RoutingProtocol::ProcessMid (const olsr::MessageHeader &msg,
1438                              const Ipv4Address &senderIface)
1439 {
1440   const olsr::MessageHeader::Mid &mid = msg.GetMid ();
1441   Time now = Simulator::Now ();
1442 
1443   NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
1444   // 1. If the sender interface of this message is not in the symmetric
1445   // 1-hop neighborhood of this node, the message MUST be discarded.
1446   const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
1447   if (linkTuple == NULL)
1448     {
1449       NS_LOG_LOGIC ("Node " << m_mainAddress <<
1450                     ": the sender interface of this message is not in the "
1451                     "symmetric 1-hop neighborhood of this node,"
1452                     " the message MUST be discarded.");
1453       return;
1454     }
1455 
1456   // 2. For each interface address listed in the MID message
1457   for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
1458        i != mid.interfaceAddresses.end (); i++)
1459     {
1460       bool updated = false;
1461       IfaceAssocSet &ifaceAssoc = m_state.GetIfaceAssocSetMutable ();
1462       for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin ();
1463            tuple != ifaceAssoc.end (); tuple++)
1464         {
1465           if (tuple->ifaceAddr == *i
1466               && tuple->mainAddr == msg.GetOriginatorAddress ())
1467             {
1468               NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple);
1469               tuple->time = now + msg.GetVTime ();
1470               updated = true;
1471             }
1472         }
1473       if (!updated)
1474         {
1475           IfaceAssocTuple tuple;
1476           tuple.ifaceAddr = *i;
1477           tuple.mainAddr = msg.GetOriginatorAddress ();
1478           tuple.time = now + msg.GetVTime ();
1479           AddIfaceAssocTuple (tuple);
1480           NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple);
1481           // Schedules iface association tuple deletion
1482           Simulator::Schedule (DELAY (tuple.time),
1483                                &RoutingProtocol::IfaceAssocTupleTimerExpire, this, tuple.ifaceAddr);
1484         }
1485     }
1486 
1487   // 3. (not part of the RFC) iterate over all NeighborTuple's and
1488   // TwoHopNeighborTuples, update the neighbor addresses taking into account
1489   // the new MID information.
1490   NeighborSet &neighbors = m_state.GetNeighbors ();
1491   for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1492     {
1493       neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr);
1494     }
1495 
1496   TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1497   for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin ();
1498        twoHopNeighbor != twoHopNeighbors.end (); twoHopNeighbor++)
1499     {
1500       twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr);
1501       twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr);
1502     }
1503   NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
1504 }
1505 
1506 void
ProcessHna(const olsr::MessageHeader & msg,const Ipv4Address & senderIface)1507 RoutingProtocol::ProcessHna (const olsr::MessageHeader &msg,
1508                              const Ipv4Address &senderIface)
1509 {
1510 
1511   const olsr::MessageHeader::Hna &hna = msg.GetHna ();
1512   Time now = Simulator::Now ();
1513 
1514   // 1. If the sender interface of this message is not in the symmetric
1515   // 1-hop neighborhood of this node, the message MUST be discarded.
1516   const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1517   if (link_tuple == NULL)
1518     {
1519       return;
1520     }
1521 
1522   // 2. Otherwise, for each (network address, netmask) pair in the
1523   // message:
1524 
1525   for (std::vector<olsr::MessageHeader::Hna::Association>::const_iterator it = hna.associations.begin ();
1526        it != hna.associations.end (); it++)
1527     {
1528       AssociationTuple *tuple = m_state.FindAssociationTuple (msg.GetOriginatorAddress (),it->address,it->mask);
1529 
1530       // 2.1  if an entry in the association set already exists, where:
1531       //          A_gateway_addr == originator address
1532       //          A_network_addr == network address
1533       //          A_netmask      == netmask
1534       //      then the holding time for that tuple MUST be set to:
1535       //          A_time         =  current time + validity time
1536       if (tuple != NULL)
1537         {
1538           tuple->expirationTime = now + msg.GetVTime ();
1539         }
1540 
1541       // 2.2 otherwise, a new tuple MUST be recorded with:
1542       //          A_gateway_addr =  originator address
1543       //          A_network_addr =  network address
1544       //          A_netmask      =  netmask
1545       //          A_time         =  current time + validity time
1546       else
1547         {
1548           AssociationTuple assocTuple = {
1549             msg.GetOriginatorAddress (),
1550             it->address,
1551             it->mask,
1552             now + msg.GetVTime ()
1553           };
1554           AddAssociationTuple (assocTuple);
1555 
1556           //Schedule Association Tuple deletion
1557           Simulator::Schedule (DELAY (assocTuple.expirationTime),
1558                                &RoutingProtocol::AssociationTupleTimerExpire, this,
1559                                assocTuple.gatewayAddr,assocTuple.networkAddr,assocTuple.netmask);
1560         }
1561 
1562     }
1563 }
1564 
1565 void
ForwardDefault(olsr::MessageHeader olsrMessage,DuplicateTuple * duplicated,const Ipv4Address & localIface,const Ipv4Address & senderAddress)1566 RoutingProtocol::ForwardDefault (olsr::MessageHeader olsrMessage,
1567                                  DuplicateTuple *duplicated,
1568                                  const Ipv4Address &localIface,
1569                                  const Ipv4Address &senderAddress)
1570 {
1571   Time now = Simulator::Now ();
1572 
1573   // If the sender interface address is not in the symmetric
1574   // 1-hop neighborhood the message must not be forwarded
1575   const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
1576   if (linkTuple == NULL)
1577     {
1578       return;
1579     }
1580 
1581   // If the message has already been considered for forwarding,
1582   // it must not be retransmitted again
1583   if (duplicated != NULL && duplicated->retransmitted)
1584     {
1585       NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received"
1586                     " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
1587       return;
1588     }
1589 
1590   // If the sender interface address is an interface address
1591   // of a MPR selector of this node and ttl is greater than 1,
1592   // the message must be retransmitted
1593   bool retransmitted = false;
1594   if (olsrMessage.GetTimeToLive () > 1)
1595     {
1596       const MprSelectorTuple *mprselTuple =
1597         m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
1598       if (mprselTuple != NULL)
1599         {
1600           olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1);
1601           olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1);
1602           // We have to introduce a random delay to avoid
1603           // synchronization with neighbors.
1604           QueueMessage (olsrMessage, JITTER);
1605           retransmitted = true;
1606         }
1607     }
1608 
1609   // Update duplicate tuple...
1610   if (duplicated != NULL)
1611     {
1612       duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
1613       duplicated->retransmitted = retransmitted;
1614       duplicated->ifaceList.push_back (localIface);
1615     }
1616   // ...or create a new one
1617   else
1618     {
1619       DuplicateTuple newDup;
1620       newDup.address = olsrMessage.GetOriginatorAddress ();
1621       newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber ();
1622       newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
1623       newDup.retransmitted = retransmitted;
1624       newDup.ifaceList.push_back (localIface);
1625       AddDuplicateTuple (newDup);
1626       // Schedule dup tuple deletion
1627       Simulator::Schedule (OLSR_DUP_HOLD_TIME,
1628                            &RoutingProtocol::DupTupleTimerExpire, this,
1629                            newDup.address, newDup.sequenceNumber);
1630     }
1631 }
1632 
1633 void
QueueMessage(const olsr::MessageHeader & message,Time delay)1634 RoutingProtocol::QueueMessage (const olsr::MessageHeader &message, Time delay)
1635 {
1636   m_queuedMessages.push_back (message);
1637   if (not m_queuedMessagesTimer.IsRunning ())
1638     {
1639       m_queuedMessagesTimer.SetDelay (delay);
1640       m_queuedMessagesTimer.Schedule ();
1641     }
1642 }
1643 
1644 void
SendPacket(Ptr<Packet> packet,const MessageList & containedMessages)1645 RoutingProtocol::SendPacket (Ptr<Packet> packet,
1646                              const MessageList &containedMessages)
1647 {
1648   NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet");
1649 
1650   // Add a header
1651   olsr::PacketHeader header;
1652   header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ());
1653   header.SetPacketSequenceNumber (GetPacketSequenceNumber ());
1654   packet->AddHeader (header);
1655 
1656   // Trace it
1657   m_txPacketTrace (header, containedMessages);
1658 
1659   // Send it
1660   for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1661          m_sendSockets.begin (); i != m_sendSockets.end (); i++)
1662     {
1663       Ptr<Packet> pkt = packet->Copy ();
1664       Ipv4Address bcast = i->second.GetLocal ().GetSubnetDirectedBroadcast (i->second.GetMask ());
1665       i->first->SendTo (pkt, 0, InetSocketAddress (bcast, OLSR_PORT_NUMBER));
1666     }
1667 }
1668 
1669 void
SendQueuedMessages(void)1670 RoutingProtocol::SendQueuedMessages  (void)
1671 {
1672   Ptr<Packet> packet = Create<Packet> ();
1673   int numMessages = 0;
1674 
1675   NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages");
1676 
1677   MessageList msglist;
1678 
1679   for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin ();
1680        message != m_queuedMessages.end ();
1681        message++)
1682     {
1683       Ptr<Packet> p = Create<Packet> ();
1684       p->AddHeader (*message);
1685       packet->AddAtEnd (p);
1686       msglist.push_back (*message);
1687       if (++numMessages == OLSR_MAX_MSGS)
1688         {
1689           SendPacket (packet, msglist);
1690           msglist.clear ();
1691           // Reset variables for next packet
1692           numMessages = 0;
1693           packet = Create<Packet> ();
1694         }
1695     }
1696 
1697   if (packet->GetSize ())
1698     {
1699       SendPacket (packet, msglist);
1700     }
1701 
1702   m_queuedMessages.clear ();
1703 }
1704 
1705 void
SendHello(void)1706 RoutingProtocol::SendHello  (void)
1707 {
1708   NS_LOG_FUNCTION (this);
1709 
1710   olsr::MessageHeader msg;
1711   Time now = Simulator::Now ();
1712 
1713   msg.SetVTime (OLSR_NEIGHB_HOLD_TIME);
1714   msg.SetOriginatorAddress (m_mainAddress);
1715   msg.SetTimeToLive (1);
1716   msg.SetHopCount (0);
1717   msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
1718   olsr::MessageHeader::Hello &hello = msg.GetHello ();
1719 
1720   hello.SetHTime (m_helloInterval);
1721   hello.willingness = m_willingness;
1722 
1723   std::vector<olsr::MessageHeader::Hello::LinkMessage>
1724   &linkMessages = hello.linkMessages;
1725 
1726   const LinkSet &links = m_state.GetLinks ();
1727   for (LinkSet::const_iterator link_tuple = links.begin ();
1728        link_tuple != links.end (); link_tuple++)
1729     {
1730       if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress
1731             && link_tuple->time >= now))
1732         {
1733           continue;
1734         }
1735 
1736       uint8_t link_type, nb_type = 0xff;
1737 
1738       // Establishes link type
1739       if (link_tuple->symTime >= now)
1740         {
1741           link_type = OLSR_SYM_LINK;
1742         }
1743       else if (link_tuple->asymTime >= now)
1744         {
1745           link_type = OLSR_ASYM_LINK;
1746         }
1747       else
1748         {
1749           link_type = OLSR_LOST_LINK;
1750         }
1751       // Establishes neighbor type.
1752       if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
1753         {
1754           nb_type = OLSR_MPR_NEIGH;
1755           NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1756                                                << " to be MPR_NEIGH.");
1757         }
1758       else
1759         {
1760           bool ok = false;
1761           for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin ();
1762                nb_tuple != m_state.GetNeighbors ().end ();
1763                nb_tuple++)
1764             {
1765               if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr))
1766                 {
1767                   if (nb_tuple->status == NeighborTuple::STATUS_SYM)
1768                     {
1769                       NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1770                                                            << " to be SYM_NEIGH.");
1771                       nb_type = OLSR_SYM_NEIGH;
1772                     }
1773                   else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
1774                     {
1775                       nb_type = OLSR_NOT_NEIGH;
1776                       NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1777                                                            << " to be NOT_NEIGH.");
1778                     }
1779                   else
1780                     {
1781                       NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n");
1782                     }
1783                   ok = true;
1784                   break;
1785                 }
1786             }
1787           if (!ok)
1788             {
1789               NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
1790               continue;
1791             }
1792         }
1793 
1794       olsr::MessageHeader::Hello::LinkMessage linkMessage;
1795       linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f);
1796       linkMessage.neighborInterfaceAddresses.push_back
1797         (link_tuple->neighborIfaceAddr);
1798 
1799       std::vector<Ipv4Address> interfaces =
1800         m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr);
1801 
1802       linkMessage.neighborInterfaceAddresses.insert
1803         (linkMessage.neighborInterfaceAddresses.end (),
1804         interfaces.begin (), interfaces.end ());
1805 
1806       linkMessages.push_back (linkMessage);
1807     }
1808   NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ())
1809                                             << " (with " << int (linkMessages.size ()) << " link messages)");
1810   QueueMessage (msg, JITTER);
1811 }
1812 
1813 void
SendTc(void)1814 RoutingProtocol::SendTc  (void)
1815 {
1816   NS_LOG_FUNCTION (this);
1817 
1818   olsr::MessageHeader msg;
1819 
1820   msg.SetVTime (OLSR_TOP_HOLD_TIME);
1821   msg.SetOriginatorAddress (m_mainAddress);
1822   msg.SetTimeToLive (255);
1823   msg.SetHopCount (0);
1824   msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
1825 
1826   olsr::MessageHeader::Tc &tc = msg.GetTc ();
1827   tc.ansn = m_ansn;
1828 
1829   for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin ();
1830        mprsel_tuple != m_state.GetMprSelectors ().end (); mprsel_tuple++)
1831     {
1832       tc.neighborAddresses.push_back (mprsel_tuple->mainAddr);
1833     }
1834   QueueMessage (msg, JITTER);
1835 }
1836 
1837 void
SendMid(void)1838 RoutingProtocol::SendMid  (void)
1839 {
1840   olsr::MessageHeader msg;
1841   olsr::MessageHeader::Mid &mid = msg.GetMid ();
1842 
1843   // A node which has only a single interface address participating in
1844   // the MANET (i.e., running OLSR), MUST NOT generate any MID
1845   // message.
1846 
1847   // A node with several interfaces, where only one is participating
1848   // in the MANET and running OLSR (e.g., a node is connected to a
1849   // wired network as well as to a MANET) MUST NOT generate any MID
1850   // messages.
1851 
1852   // A node with several interfaces, where more than one is
1853   // participating in the MANET and running OLSR MUST generate MID
1854   // messages as specified.
1855 
1856   // [ Note: assuming here that all interfaces participate in the
1857   // MANET; later we may want to make this configurable. ]
1858 
1859   Ipv4Address loopback ("127.0.0.1");
1860   for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
1861     {
1862       Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
1863       if (addr != m_mainAddress && addr != loopback && m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
1864         {
1865           mid.interfaceAddresses.push_back (addr);
1866         }
1867     }
1868   if (mid.interfaceAddresses.size () == 0)
1869     {
1870       return;
1871     }
1872 
1873   msg.SetVTime (OLSR_MID_HOLD_TIME);
1874   msg.SetOriginatorAddress (m_mainAddress);
1875   msg.SetTimeToLive (255);
1876   msg.SetHopCount (0);
1877   msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
1878 
1879   QueueMessage (msg, JITTER);
1880 }
1881 
1882 void
SendHna(void)1883 RoutingProtocol::SendHna  (void)
1884 {
1885 
1886   olsr::MessageHeader msg;
1887 
1888   msg.SetVTime (OLSR_HNA_HOLD_TIME);
1889   msg.SetOriginatorAddress (m_mainAddress);
1890   msg.SetTimeToLive (255);
1891   msg.SetHopCount (0);
1892   msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
1893   olsr::MessageHeader::Hna &hna = msg.GetHna ();
1894 
1895   std::vector<olsr::MessageHeader::Hna::Association> &associations = hna.associations;
1896 
1897   // Add all local HNA associations to the HNA message
1898   const Associations &localHnaAssociations = m_state.GetAssociations ();
1899   for (Associations::const_iterator it = localHnaAssociations.begin ();
1900        it != localHnaAssociations.end (); it++)
1901     {
1902       olsr::MessageHeader::Hna::Association assoc = { it->networkAddr, it->netmask};
1903       associations.push_back (assoc);
1904     }
1905   // If there is no HNA associations to send, return without queuing the message
1906   if (associations.size () == 0)
1907     {
1908       return;
1909     }
1910 
1911   // Else, queue the message to be sent later on
1912   QueueMessage (msg, JITTER);
1913 }
1914 
1915 void
AddHostNetworkAssociation(Ipv4Address networkAddr,Ipv4Mask netmask)1916 RoutingProtocol::AddHostNetworkAssociation (Ipv4Address networkAddr, Ipv4Mask netmask)
1917 {
1918   // Check if the (networkAddr, netmask) tuple already exist
1919   // in the list of local HNA associations
1920   const Associations &localHnaAssociations = m_state.GetAssociations ();
1921   for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1922        assocIterator != localHnaAssociations.end (); assocIterator++)
1923     {
1924       Association const &localHnaAssoc = *assocIterator;
1925       if (localHnaAssoc.networkAddr == networkAddr && localHnaAssoc.netmask == netmask)
1926         {
1927           NS_LOG_INFO ("HNA association for network " << networkAddr << "/" << netmask << " already exists.");
1928           return;
1929         }
1930     }
1931   // If the tuple does not already exist, add it to the list of local HNA associations.
1932   NS_LOG_INFO ("Adding HNA association for network " << networkAddr << "/" << netmask << ".");
1933   m_state.InsertAssociation ( (Association) { networkAddr, netmask} );
1934 }
1935 
1936 void
RemoveHostNetworkAssociation(Ipv4Address networkAddr,Ipv4Mask netmask)1937 RoutingProtocol::RemoveHostNetworkAssociation (Ipv4Address networkAddr, Ipv4Mask netmask)
1938 {
1939   NS_LOG_INFO ("Removing HNA association for network " << networkAddr << "/" << netmask << ".");
1940   m_state.EraseAssociation ( (Association) { networkAddr, netmask} );
1941 }
1942 
1943 void
SetRoutingTableAssociation(Ptr<Ipv4StaticRouting> routingTable)1944 RoutingProtocol::SetRoutingTableAssociation (Ptr<Ipv4StaticRouting> routingTable)
1945 {
1946   // If a routing table has already been associated, remove
1947   // corresponding entries from the list of local HNA associations
1948   if (m_routingTableAssociation != 0)
1949     {
1950       NS_LOG_INFO ("Removing HNA entries coming from the old routing table association.");
1951       for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1952         {
1953           Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1954           // If the outgoing interface for this route is a non-olsr interface
1955           if (UsesNonOlsrOutgoingInterface (route))
1956             {
1957               // remove the corresponding entry
1958               RemoveHostNetworkAssociation (route.GetDestNetwork (), route.GetDestNetworkMask ());
1959             }
1960         }
1961     }
1962 
1963   // Sets the routingTableAssociation to its new value
1964   m_routingTableAssociation = routingTable;
1965 
1966   // Iterate over entries of the associated routing table and
1967   // add the routes using non-olsr outgoing interfaces to the list
1968   // of local HNA associations
1969   NS_LOG_DEBUG ("Nb local associations before adding some entries from"
1970                 " the associated routing table: " << m_state.GetAssociations ().size ());
1971   for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1972     {
1973       Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1974       Ipv4Address destNetworkAddress = route.GetDestNetwork ();
1975       Ipv4Mask destNetmask = route.GetDestNetworkMask ();
1976 
1977       // If the outgoing interface for this route is a non-olsr interface,
1978       if (UsesNonOlsrOutgoingInterface (route))
1979         {
1980           // Add this entry's network address and netmask to the list of local HNA entries
1981           AddHostNetworkAssociation (destNetworkAddress, destNetmask);
1982         }
1983     }
1984   NS_LOG_DEBUG ("Nb local associations after having added some entries from "
1985                 "the associated routing table: " << m_state.GetAssociations ().size ());
1986 }
1987 
1988 bool
UsesNonOlsrOutgoingInterface(const Ipv4RoutingTableEntry & route)1989 RoutingProtocol::UsesNonOlsrOutgoingInterface (const Ipv4RoutingTableEntry &route)
1990 {
1991   std::set<uint32_t>::const_iterator ci = m_interfaceExclusions.find (route.GetInterface ());
1992   // The outgoing interface is a non-OLSR interface if a match is found
1993   // before reaching the end of the list of excluded interfaces
1994   return ci != m_interfaceExclusions.end ();
1995 }
1996 
1997 void
LinkSensing(const olsr::MessageHeader & msg,const olsr::MessageHeader::Hello & hello,const Ipv4Address & receiverIface,const Ipv4Address & senderIface)1998 RoutingProtocol::LinkSensing (const olsr::MessageHeader &msg,
1999                               const olsr::MessageHeader::Hello &hello,
2000                               const Ipv4Address &receiverIface,
2001                               const Ipv4Address &senderIface)
2002 {
2003   Time now = Simulator::Now ();
2004   bool updated = false;
2005   bool created = false;
2006   NS_LOG_DEBUG ("@" << now.As (Time::S) << ": Olsr node " << m_mainAddress
2007                     << ": LinkSensing(receiverIface=" << receiverIface
2008                     << ", senderIface=" << senderIface << ") BEGIN");
2009 
2010   NS_ASSERT (msg.GetVTime () > Seconds (0));
2011   LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
2012   if (link_tuple == NULL)
2013     {
2014       LinkTuple newLinkTuple;
2015       // We have to create a new tuple
2016       newLinkTuple.neighborIfaceAddr = senderIface;
2017       newLinkTuple.localIfaceAddr = receiverIface;
2018       newLinkTuple.symTime = now - Seconds (1);
2019       newLinkTuple.time = now + msg.GetVTime ();
2020       link_tuple = &m_state.InsertLinkTuple (newLinkTuple);
2021       created = true;
2022       NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one");
2023     }
2024   else
2025     {
2026       NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
2027       updated = true;
2028     }
2029 
2030   link_tuple->asymTime = now + msg.GetVTime ();
2031   for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
2032          hello.linkMessages.begin ();
2033        linkMessage != hello.linkMessages.end ();
2034        linkMessage++)
2035     {
2036       int lt = linkMessage->linkCode & 0x03; // Link Type
2037       int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type
2038 
2039 #ifdef NS3_LOG_ENABLE
2040       const char *linkTypeName;
2041       switch (lt)
2042         {
2043         case OLSR_UNSPEC_LINK:
2044           linkTypeName = "UNSPEC_LINK";
2045           break;
2046         case OLSR_ASYM_LINK:
2047           linkTypeName = "ASYM_LINK";
2048           break;
2049         case OLSR_SYM_LINK:
2050           linkTypeName = "SYM_LINK";
2051           break;
2052         case OLSR_LOST_LINK:
2053           linkTypeName = "LOST_LINK";
2054           break;
2055         default:
2056           linkTypeName = "(invalid value!)";
2057 
2058         }
2059 
2060       const char *neighborTypeName;
2061       switch (nt)
2062         {
2063         case OLSR_NOT_NEIGH:
2064           neighborTypeName = "NOT_NEIGH";
2065           break;
2066         case OLSR_SYM_NEIGH:
2067           neighborTypeName = "SYM_NEIGH";
2068           break;
2069         case OLSR_MPR_NEIGH:
2070           neighborTypeName = "MPR_NEIGH";
2071           break;
2072         default:
2073           neighborTypeName = "(invalid value!)";
2074         }
2075 
2076       NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type "
2077                     << lt << " (" << linkTypeName
2078                     << ") and Neighbor Type " << nt
2079                     << " (" << neighborTypeName << ")");
2080 #endif // NS3_LOG_ENABLE
2081 
2082       // We must not process invalid advertised links
2083       if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH)
2084           || (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH
2085               && nt != OLSR_NOT_NEIGH))
2086         {
2087           NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING");
2088           continue;
2089         }
2090 
2091       for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr =
2092              linkMessage->neighborInterfaceAddresses.begin ();
2093            neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end ();
2094            neighIfaceAddr++)
2095         {
2096           NS_LOG_DEBUG ("   -> Neighbor: " << *neighIfaceAddr);
2097           if (*neighIfaceAddr == receiverIface)
2098             {
2099               if (lt == OLSR_LOST_LINK)
2100                 {
2101                   NS_LOG_LOGIC ("link is LOST => expiring it");
2102                   link_tuple->symTime = now - Seconds (1);
2103                   updated = true;
2104                 }
2105               else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK)
2106                 {
2107                   NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now"
2108                                 " (symTime being increased to " << now + msg.GetVTime ());
2109                   link_tuple->symTime = now + msg.GetVTime ();
2110                   link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
2111                   updated = true;
2112                 }
2113               else
2114                 {
2115                   NS_FATAL_ERROR ("bad link type");
2116                 }
2117               break;
2118             }
2119           else
2120             {
2121               NS_LOG_DEBUG ("     \\-> *neighIfaceAddr (" << *neighIfaceAddr
2122                                                           << " != receiverIface (" << receiverIface << ") => IGNORING!");
2123             }
2124         }
2125       NS_LOG_DEBUG ("Link tuple updated: " << int (updated));
2126     }
2127   link_tuple->time = std::max (link_tuple->time, link_tuple->asymTime);
2128 
2129   if (updated)
2130     {
2131       LinkTupleUpdated (*link_tuple, hello.willingness);
2132     }
2133 
2134   // Schedules link tuple deletion
2135   if (created)
2136     {
2137       LinkTupleAdded (*link_tuple, hello.willingness);
2138       m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
2139                                            &RoutingProtocol::LinkTupleTimerExpire, this,
2140                                            link_tuple->neighborIfaceAddr));
2141     }
2142   NS_LOG_DEBUG ("@" << now.As (Time::S) << ": Olsr node " << m_mainAddress
2143                     << ": LinkSensing END");
2144 }
2145 
2146 void
PopulateNeighborSet(const olsr::MessageHeader & msg,const olsr::MessageHeader::Hello & hello)2147 RoutingProtocol::PopulateNeighborSet (const olsr::MessageHeader &msg,
2148                                       const olsr::MessageHeader::Hello &hello)
2149 {
2150   NeighborTuple *nb_tuple = m_state.FindNeighborTuple (msg.GetOriginatorAddress ());
2151   if (nb_tuple != NULL)
2152     {
2153       nb_tuple->willingness = hello.willingness;
2154     }
2155 }
2156 
2157 void
PopulateTwoHopNeighborSet(const olsr::MessageHeader & msg,const olsr::MessageHeader::Hello & hello)2158 RoutingProtocol::PopulateTwoHopNeighborSet (const olsr::MessageHeader &msg,
2159                                             const olsr::MessageHeader::Hello &hello)
2160 {
2161   Time now = Simulator::Now ();
2162 
2163   NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
2164 
2165   for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
2166        link_tuple != m_state.GetLinks ().end (); link_tuple++)
2167     {
2168       NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple);
2169       if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ())
2170         {
2171           NS_LOG_LOGIC ("Link tuple ignored: "
2172                         "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
2173           NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): "
2174                                            << GetMainAddress (link_tuple->neighborIfaceAddr)
2175                                            << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ());
2176           continue;
2177         }
2178 
2179       if (link_tuple->symTime < now)
2180         {
2181           NS_LOG_LOGIC ("Link tuple ignored: expired.");
2182           continue;
2183         }
2184 
2185       typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2186       for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2187            linkMessage != hello.linkMessages.end (); linkMessage++)
2188         {
2189           int neighborType = (linkMessage->linkCode >> 2) & 0x3;
2190 #ifdef NS3_LOG_ENABLE
2191           const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" };
2192           const char *neighborTypeName = ((neighborType < 3) ?
2193                                           neighborTypeNames[neighborType]
2194                                           : "(invalid value)");
2195           NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType="
2196                         << neighborType << " (" << neighborTypeName << ")");
2197 #endif // NS3_LOG_ENABLE
2198 
2199           for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter =
2200                  linkMessage->neighborInterfaceAddresses.begin ();
2201                nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end ();
2202                nb2hop_addr_iter++)
2203             {
2204               Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter);
2205               NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: "
2206                             << *nb2hop_addr_iter
2207                             << " (main address is " << nb2hop_addr << ")");
2208               if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH)
2209                 {
2210                   // If the main address of the 2-hop neighbor address == main address
2211                   // of the receiving node, silently discard the 2-hop
2212                   // neighbor address.
2213                   if (nb2hop_addr == m_mainAddress)
2214                     {
2215                       NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)");
2216                       continue;
2217                     }
2218 
2219                   // Otherwise, a 2-hop tuple is created
2220                   TwoHopNeighborTuple *nb2hop_tuple =
2221                     m_state.FindTwoHopNeighborTuple (msg.GetOriginatorAddress (), nb2hop_addr);
2222                   NS_LOG_LOGIC ("Adding the 2-hop neighbor"
2223                                 << (nb2hop_tuple ? " (refreshing existing entry)" : ""));
2224                   if (nb2hop_tuple == NULL)
2225                     {
2226                       TwoHopNeighborTuple new_nb2hop_tuple;
2227                       new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress ();
2228                       new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
2229                       new_nb2hop_tuple.expirationTime = now + msg.GetVTime ();
2230                       AddTwoHopNeighborTuple (new_nb2hop_tuple);
2231                       // Schedules nb2hop tuple deletion
2232                       m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime),
2233                                                            &RoutingProtocol::Nb2hopTupleTimerExpire, this,
2234                                                            new_nb2hop_tuple.neighborMainAddr,
2235                                                            new_nb2hop_tuple.twoHopNeighborAddr));
2236                     }
2237                   else
2238                     {
2239                       nb2hop_tuple->expirationTime = now + msg.GetVTime ();
2240                     }
2241                 }
2242               else if (neighborType == OLSR_NOT_NEIGH)
2243                 {
2244                   // For each 2-hop node listed in the HELLO message
2245                   // with Neighbor Type equal to NOT_NEIGH all 2-hop
2246                   // tuples where: N_neighbor_main_addr == Originator
2247                   // Address AND N_2hop_addr == main address of the
2248                   // 2-hop neighbor are deleted.
2249                   NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
2250                   m_state.EraseTwoHopNeighborTuples (msg.GetOriginatorAddress (), nb2hop_addr);
2251                 }
2252               else
2253                 {
2254                   NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad"
2255                                 " neighbor type value: " << neighborType);
2256                 }
2257             }
2258         }
2259     }
2260 
2261   NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
2262 }
2263 
2264 void
PopulateMprSelectorSet(const olsr::MessageHeader & msg,const olsr::MessageHeader::Hello & hello)2265 RoutingProtocol::PopulateMprSelectorSet (const olsr::MessageHeader &msg,
2266                                          const olsr::MessageHeader::Hello &hello)
2267 {
2268   NS_LOG_FUNCTION (this);
2269 
2270   Time now = Simulator::Now ();
2271 
2272   typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2273   for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2274        linkMessage != hello.linkMessages.end ();
2275        linkMessage++)
2276     {
2277       int nt = linkMessage->linkCode >> 2;
2278       if (nt == OLSR_MPR_NEIGH)
2279         {
2280           NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
2281 
2282           for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
2283                  linkMessage->neighborInterfaceAddresses.begin ();
2284                nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
2285                nb_iface_addr++)
2286             {
2287               if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
2288                 {
2289                   NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
2290 
2291                   // We must create a new entry into the mpr selector set
2292                   MprSelectorTuple *existing_mprsel_tuple =
2293                     m_state.FindMprSelectorTuple (msg.GetOriginatorAddress ());
2294                   if (existing_mprsel_tuple == NULL)
2295                     {
2296                       MprSelectorTuple mprsel_tuple;
2297 
2298                       mprsel_tuple.mainAddr = msg.GetOriginatorAddress ();
2299                       mprsel_tuple.expirationTime = now + msg.GetVTime ();
2300                       AddMprSelectorTuple (mprsel_tuple);
2301 
2302                       // Schedules mpr selector tuple deletion
2303                       m_events.Track (Simulator::Schedule
2304                                         (DELAY (mprsel_tuple.expirationTime),
2305                                         &RoutingProtocol::MprSelTupleTimerExpire, this,
2306                                         mprsel_tuple.mainAddr));
2307                     }
2308                   else
2309                     {
2310                       existing_mprsel_tuple->expirationTime = now + msg.GetVTime ();
2311                     }
2312                 }
2313             }
2314         }
2315     }
2316   NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
2317 }
2318 
2319 
2320 #if 0
2321 ///
2322 /// \brief Drops a given packet because it couldn't be delivered to the corresponding
2323 /// destination by the MAC layer. This may cause a neighbor loss, and appropriate
2324 /// actions are then taken.
2325 ///
2326 /// \param p the packet which couldn't be delivered by the MAC layer.
2327 ///
2328 void
2329 OLSR::mac_failed (Ptr<Packet> p)
2330 {
2331   double now              = Simulator::Now ();
2332   struct hdr_ip* ih       = HDR_IP (p);
2333   struct hdr_cmn* ch      = HDR_CMN (p);
2334 
2335   debug ("%f: Node %d MAC Layer detects a breakage on link to %d\n",
2336          now,
2337          OLSR::node_id (ra_addr ()),
2338          OLSR::node_id (ch->next_hop ()));
2339 
2340   if ((uint32_t)ih->daddr () == IP_BROADCAST)
2341     {
2342       drop (p, DROP_RTR_MAC_CALLBACK);
2343       return;
2344     }
2345 
2346   OLSR_link_tuple* link_tuple = state_.find_link_tuple (ch->next_hop ());
2347   if (link_tuple != NULL)
2348     {
2349       link_tuple->lost_time () = now + OLSR_NEIGHB_HOLD_TIME;
2350       link_tuple->time ()      = now + OLSR_NEIGHB_HOLD_TIME;
2351       nb_loss (link_tuple);
2352     }
2353   drop (p, DROP_RTR_MAC_CALLBACK);
2354 }
2355 #endif
2356 
2357 
2358 
2359 
2360 void
NeighborLoss(const LinkTuple & tuple)2361 RoutingProtocol::NeighborLoss (const LinkTuple &tuple)
2362 {
2363   NS_LOG_DEBUG (Simulator::Now ().As (Time::S)
2364                 << ": OLSR Node " << m_mainAddress
2365                 << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
2366   LinkTupleUpdated (tuple, OLSR_WILL_DEFAULT);
2367   m_state.EraseTwoHopNeighborTuples (GetMainAddress (tuple.neighborIfaceAddr));
2368   m_state.EraseMprSelectorTuples (GetMainAddress (tuple.neighborIfaceAddr));
2369 
2370   MprComputation ();
2371   RoutingTableComputation ();
2372 }
2373 
2374 void
AddDuplicateTuple(const DuplicateTuple & tuple)2375 RoutingProtocol::AddDuplicateTuple (const DuplicateTuple &tuple)
2376 {
2377   /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
2378           Simulator::Now (),
2379           OLSR::node_id(ra_addr()),
2380           OLSR::node_id(tuple->addr()),
2381           tuple->seq_num());*/
2382   m_state.InsertDuplicateTuple (tuple);
2383 }
2384 
2385 void
RemoveDuplicateTuple(const DuplicateTuple & tuple)2386 RoutingProtocol::RemoveDuplicateTuple (const DuplicateTuple &tuple)
2387 {
2388   /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
2389     Simulator::Now (),
2390     OLSR::node_id(ra_addr()),
2391     OLSR::node_id(tuple->addr()),
2392     tuple->seq_num());*/
2393   m_state.EraseDuplicateTuple (tuple);
2394 }
2395 
2396 void
LinkTupleAdded(const LinkTuple & tuple,uint8_t willingness)2397 RoutingProtocol::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness)
2398 {
2399   // Creates associated neighbor tuple
2400   NeighborTuple nb_tuple;
2401   nb_tuple.neighborMainAddr = GetMainAddress (tuple.neighborIfaceAddr);
2402   nb_tuple.willingness = willingness;
2403 
2404   if (tuple.symTime >= Simulator::Now ())
2405     {
2406       nb_tuple.status = NeighborTuple::STATUS_SYM;
2407     }
2408   else
2409     {
2410       nb_tuple.status = NeighborTuple::STATUS_NOT_SYM;
2411     }
2412 
2413   AddNeighborTuple (nb_tuple);
2414 }
2415 
2416 void
RemoveLinkTuple(const LinkTuple & tuple)2417 RoutingProtocol::RemoveLinkTuple (const LinkTuple &tuple)
2418 {
2419   NS_LOG_DEBUG (Simulator::Now ().As (Time::S)
2420                 << ": OLSR Node " << m_mainAddress
2421                 << " LinkTuple " << tuple << " REMOVED.");
2422 
2423   m_state.EraseNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
2424   m_state.EraseLinkTuple (tuple);
2425 }
2426 
2427 void
LinkTupleUpdated(const LinkTuple & tuple,uint8_t willingness)2428 RoutingProtocol::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
2429 {
2430   // Each time a link tuple changes, the associated neighbor tuple must be recomputed
2431 
2432   NS_LOG_DEBUG (Simulator::Now ().As (Time::S)
2433                 << ": OLSR Node " << m_mainAddress
2434                 << " LinkTuple " << tuple << " UPDATED.");
2435 
2436   NeighborTuple *nb_tuple =
2437     m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
2438 
2439   if (nb_tuple == NULL)
2440     {
2441       LinkTupleAdded (tuple, willingness);
2442       nb_tuple = m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
2443     }
2444 
2445   if (nb_tuple != NULL)
2446     {
2447       int statusBefore = nb_tuple->status;
2448 
2449       bool hasSymmetricLink = false;
2450 
2451       const LinkSet &linkSet = m_state.GetLinks ();
2452       for (LinkSet::const_iterator it = linkSet.begin ();
2453            it != linkSet.end (); it++)
2454         {
2455           const LinkTuple &link_tuple = *it;
2456           if (GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple->neighborMainAddr
2457               && link_tuple.symTime >= Simulator::Now ())
2458             {
2459               hasSymmetricLink = true;
2460               break;
2461             }
2462         }
2463 
2464       if (hasSymmetricLink)
2465         {
2466           nb_tuple->status = NeighborTuple::STATUS_SYM;
2467           NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_SYM; changed:"
2468                                   << int (statusBefore != nb_tuple->status));
2469         }
2470       else
2471         {
2472           nb_tuple->status = NeighborTuple::STATUS_NOT_SYM;
2473           NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_NOT_SYM; changed:"
2474                                   << int (statusBefore != nb_tuple->status));
2475         }
2476     }
2477   else
2478     {
2479       NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!");
2480     }
2481 }
2482 
2483 void
AddNeighborTuple(const NeighborTuple & tuple)2484 RoutingProtocol::AddNeighborTuple (const NeighborTuple &tuple)
2485 {
2486 //   debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n",
2487 //         Simulator::Now (),
2488 //         OLSR::node_id(ra_addr()),
2489 //         OLSR::node_id(tuple->neighborMainAddr),
2490 //         ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2491 
2492   m_state.InsertNeighborTuple (tuple);
2493   IncrementAnsn ();
2494 }
2495 
2496 void
RemoveNeighborTuple(const NeighborTuple & tuple)2497 RoutingProtocol::RemoveNeighborTuple (const NeighborTuple &tuple)
2498 {
2499 //   debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n",
2500 //         Simulator::Now (),
2501 //         OLSR::node_id(ra_addr()),
2502 //         OLSR::node_id(tuple->neighborMainAddr),
2503 //         ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2504 
2505   m_state.EraseNeighborTuple (tuple);
2506   IncrementAnsn ();
2507 }
2508 
2509 void
AddTwoHopNeighborTuple(const TwoHopNeighborTuple & tuple)2510 RoutingProtocol::AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
2511 {
2512 //   debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2513 //         Simulator::Now (),
2514 //         OLSR::node_id(ra_addr()),
2515 //         OLSR::node_id(tuple->neighborMainAddr),
2516 //         OLSR::node_id(tuple->twoHopNeighborAddr));
2517 
2518   m_state.InsertTwoHopNeighborTuple (tuple);
2519 }
2520 
2521 void
RemoveTwoHopNeighborTuple(const TwoHopNeighborTuple & tuple)2522 RoutingProtocol::RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
2523 {
2524 //   debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2525 //         Simulator::Now (),
2526 //         OLSR::node_id(ra_addr()),
2527 //         OLSR::node_id(tuple->neighborMainAddr),
2528 //         OLSR::node_id(tuple->twoHopNeighborAddr));
2529 
2530   m_state.EraseTwoHopNeighborTuple (tuple);
2531 }
2532 
2533 void
IncrementAnsn(void)2534 RoutingProtocol::IncrementAnsn  (void)
2535 {
2536   m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1);
2537 }
2538 
2539 void
AddMprSelectorTuple(const MprSelectorTuple & tuple)2540 RoutingProtocol::AddMprSelectorTuple (const MprSelectorTuple  &tuple)
2541 {
2542 //   debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n",
2543 //         Simulator::Now (),
2544 //         OLSR::node_id(ra_addr()),
2545 //         OLSR::node_id(tuple->main_addr()));
2546 
2547   m_state.InsertMprSelectorTuple (tuple);
2548   IncrementAnsn ();
2549 }
2550 
2551 void
RemoveMprSelectorTuple(const MprSelectorTuple & tuple)2552 RoutingProtocol::RemoveMprSelectorTuple (const MprSelectorTuple &tuple)
2553 {
2554 //   debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n",
2555 //         Simulator::Now (),
2556 //         OLSR::node_id(ra_addr()),
2557 //         OLSR::node_id(tuple->main_addr()));
2558 
2559   m_state.EraseMprSelectorTuple (tuple);
2560   IncrementAnsn ();
2561 }
2562 
2563 void
AddTopologyTuple(const TopologyTuple & tuple)2564 RoutingProtocol::AddTopologyTuple (const TopologyTuple &tuple)
2565 {
2566 //   debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2567 //         Simulator::Now (),
2568 //         OLSR::node_id(ra_addr()),
2569 //         OLSR::node_id(tuple->dest_addr()),
2570 //         OLSR::node_id(tuple->last_addr()),
2571 //         tuple->seq());
2572 
2573   m_state.InsertTopologyTuple (tuple);
2574 }
2575 
2576 void
RemoveTopologyTuple(const TopologyTuple & tuple)2577 RoutingProtocol::RemoveTopologyTuple (const TopologyTuple &tuple)
2578 {
2579 //   debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2580 //         Simulator::Now (),
2581 //         OLSR::node_id(ra_addr()),
2582 //         OLSR::node_id(tuple->dest_addr()),
2583 //         OLSR::node_id(tuple->last_addr()),
2584 //         tuple->seq());
2585 
2586   m_state.EraseTopologyTuple (tuple);
2587 }
2588 
2589 void
AddIfaceAssocTuple(const IfaceAssocTuple & tuple)2590 RoutingProtocol::AddIfaceAssocTuple (const IfaceAssocTuple &tuple)
2591 {
2592 //   debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n",
2593 //         Simulator::Now (),
2594 //         OLSR::node_id(ra_addr()),
2595 //         OLSR::node_id(tuple->main_addr()),
2596 //         OLSR::node_id(tuple->iface_addr()));
2597 
2598   m_state.InsertIfaceAssocTuple (tuple);
2599 }
2600 
2601 void
RemoveIfaceAssocTuple(const IfaceAssocTuple & tuple)2602 RoutingProtocol::RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple)
2603 {
2604 //   debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n",
2605 //         Simulator::Now (),
2606 //         OLSR::node_id(ra_addr()),
2607 //         OLSR::node_id(tuple->main_addr()),
2608 //         OLSR::node_id(tuple->iface_addr()));
2609 
2610   m_state.EraseIfaceAssocTuple (tuple);
2611 }
2612 
2613 void
AddAssociationTuple(const AssociationTuple & tuple)2614 RoutingProtocol::AddAssociationTuple (const AssociationTuple &tuple)
2615 {
2616   m_state.InsertAssociationTuple (tuple);
2617 }
2618 
2619 void
RemoveAssociationTuple(const AssociationTuple & tuple)2620 RoutingProtocol::RemoveAssociationTuple (const AssociationTuple &tuple)
2621 {
2622   m_state.EraseAssociationTuple (tuple);
2623 }
2624 
GetPacketSequenceNumber()2625 uint16_t RoutingProtocol::GetPacketSequenceNumber ()
2626 {
2627   m_packetSequenceNumber = (m_packetSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1);
2628   return m_packetSequenceNumber;
2629 }
2630 
GetMessageSequenceNumber()2631 uint16_t RoutingProtocol::GetMessageSequenceNumber ()
2632 {
2633   m_messageSequenceNumber = (m_messageSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1);
2634   return m_messageSequenceNumber;
2635 }
2636 
2637 void
HelloTimerExpire(void)2638 RoutingProtocol::HelloTimerExpire  (void)
2639 {
2640   SendHello ();
2641   m_helloTimer.Schedule (m_helloInterval);
2642 }
2643 
2644 void
TcTimerExpire(void)2645 RoutingProtocol::TcTimerExpire  (void)
2646 {
2647   if (m_state.GetMprSelectors ().size () > 0)
2648     {
2649       SendTc ();
2650     }
2651   else
2652     {
2653       NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR.");
2654     }
2655   m_tcTimer.Schedule (m_tcInterval);
2656 }
2657 
2658 void
MidTimerExpire(void)2659 RoutingProtocol::MidTimerExpire  (void)
2660 {
2661   SendMid ();
2662   m_midTimer.Schedule (m_midInterval);
2663 }
2664 
2665 void
HnaTimerExpire(void)2666 RoutingProtocol::HnaTimerExpire  (void)
2667 {
2668   if (m_state.GetAssociations ().size () > 0)
2669     {
2670       SendHna ();
2671     }
2672   else
2673     {
2674       NS_LOG_DEBUG ("Not sending any HNA, no associations to advertise.");
2675     }
2676   m_hnaTimer.Schedule (m_hnaInterval);
2677 }
2678 
2679 void
DupTupleTimerExpire(Ipv4Address address,uint16_t sequenceNumber)2680 RoutingProtocol::DupTupleTimerExpire (Ipv4Address address, uint16_t sequenceNumber)
2681 {
2682   DuplicateTuple *tuple =
2683     m_state.FindDuplicateTuple (address, sequenceNumber);
2684   if (tuple == NULL)
2685     {
2686       return;
2687     }
2688   if (tuple->expirationTime < Simulator::Now ())
2689     {
2690       RemoveDuplicateTuple (*tuple);
2691     }
2692   else
2693     {
2694       m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
2695                                            &RoutingProtocol::DupTupleTimerExpire, this,
2696                                            address, sequenceNumber));
2697     }
2698 }
2699 
2700 void
LinkTupleTimerExpire(Ipv4Address neighborIfaceAddr)2701 RoutingProtocol::LinkTupleTimerExpire (Ipv4Address neighborIfaceAddr)
2702 {
2703   Time now = Simulator::Now ();
2704 
2705   // the tuple parameter may be a stale copy; get a newer version from m_state
2706   LinkTuple *tuple = m_state.FindLinkTuple (neighborIfaceAddr);
2707   if (tuple == NULL)
2708     {
2709       return;
2710     }
2711   if (tuple->time < now)
2712     {
2713       RemoveLinkTuple (*tuple);
2714     }
2715   else if (tuple->symTime < now)
2716     {
2717       if (m_linkTupleTimerFirstTime)
2718         {
2719           m_linkTupleTimerFirstTime = false;
2720         }
2721       else
2722         {
2723           NeighborLoss (*tuple);
2724         }
2725 
2726       m_events.Track (Simulator::Schedule (DELAY (tuple->time),
2727                                            &RoutingProtocol::LinkTupleTimerExpire, this,
2728                                            neighborIfaceAddr));
2729     }
2730   else
2731     {
2732       m_events.Track (Simulator::Schedule (DELAY (std::min (tuple->time, tuple->symTime)),
2733                                            &RoutingProtocol::LinkTupleTimerExpire, this,
2734                                            neighborIfaceAddr));
2735     }
2736 }
2737 
2738 void
Nb2hopTupleTimerExpire(Ipv4Address neighborMainAddr,Ipv4Address twoHopNeighborAddr)2739 RoutingProtocol::Nb2hopTupleTimerExpire (Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr)
2740 {
2741   TwoHopNeighborTuple *tuple;
2742   tuple = m_state.FindTwoHopNeighborTuple (neighborMainAddr, twoHopNeighborAddr);
2743   if (tuple == NULL)
2744     {
2745       return;
2746     }
2747   if (tuple->expirationTime < Simulator::Now ())
2748     {
2749       RemoveTwoHopNeighborTuple (*tuple);
2750     }
2751   else
2752     {
2753       m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
2754                                            &RoutingProtocol::Nb2hopTupleTimerExpire,
2755                                            this, neighborMainAddr, twoHopNeighborAddr));
2756     }
2757 }
2758 
2759 void
MprSelTupleTimerExpire(Ipv4Address mainAddr)2760 RoutingProtocol::MprSelTupleTimerExpire (Ipv4Address mainAddr)
2761 {
2762   MprSelectorTuple *tuple = m_state.FindMprSelectorTuple (mainAddr);
2763   if (tuple == NULL)
2764     {
2765       return;
2766     }
2767   if (tuple->expirationTime < Simulator::Now ())
2768     {
2769       RemoveMprSelectorTuple (*tuple);
2770     }
2771   else
2772     {
2773       m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
2774                                            &RoutingProtocol::MprSelTupleTimerExpire,
2775                                            this, mainAddr));
2776     }
2777 }
2778 
2779 void
TopologyTupleTimerExpire(Ipv4Address destAddr,Ipv4Address lastAddr)2780 RoutingProtocol::TopologyTupleTimerExpire (Ipv4Address destAddr, Ipv4Address lastAddr)
2781 {
2782   TopologyTuple *tuple = m_state.FindTopologyTuple (destAddr, lastAddr);
2783   if (tuple == NULL)
2784     {
2785       return;
2786     }
2787   if (tuple->expirationTime < Simulator::Now ())
2788     {
2789       RemoveTopologyTuple (*tuple);
2790     }
2791   else
2792     {
2793       m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
2794                                            &RoutingProtocol::TopologyTupleTimerExpire,
2795                                            this, tuple->destAddr, tuple->lastAddr));
2796     }
2797 }
2798 
2799 void
IfaceAssocTupleTimerExpire(Ipv4Address ifaceAddr)2800 RoutingProtocol::IfaceAssocTupleTimerExpire (Ipv4Address ifaceAddr)
2801 {
2802   IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (ifaceAddr);
2803   if (tuple == NULL)
2804     {
2805       return;
2806     }
2807   if (tuple->time < Simulator::Now ())
2808     {
2809       RemoveIfaceAssocTuple (*tuple);
2810     }
2811   else
2812     {
2813       m_events.Track (Simulator::Schedule (DELAY (tuple->time),
2814                                            &RoutingProtocol::IfaceAssocTupleTimerExpire,
2815                                            this, ifaceAddr));
2816     }
2817 }
2818 
2819 void
AssociationTupleTimerExpire(Ipv4Address gatewayAddr,Ipv4Address networkAddr,Ipv4Mask netmask)2820 RoutingProtocol::AssociationTupleTimerExpire (Ipv4Address gatewayAddr, Ipv4Address networkAddr, Ipv4Mask netmask)
2821 {
2822   AssociationTuple *tuple = m_state.FindAssociationTuple (gatewayAddr, networkAddr, netmask);
2823   if (tuple == NULL)
2824     {
2825       return;
2826     }
2827   if (tuple->expirationTime < Simulator::Now ())
2828     {
2829       RemoveAssociationTuple (*tuple);
2830     }
2831   else
2832     {
2833       m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
2834                                            &RoutingProtocol::AssociationTupleTimerExpire,
2835                                            this, gatewayAddr, networkAddr, netmask));
2836     }
2837 }
2838 
2839 void
Clear(void)2840 RoutingProtocol::Clear  (void)
2841 {
2842   NS_LOG_FUNCTION_NOARGS ();
2843   m_table.clear ();
2844 }
2845 
2846 void
RemoveEntry(Ipv4Address const & dest)2847 RoutingProtocol::RemoveEntry (Ipv4Address const &dest)
2848 {
2849   m_table.erase (dest);
2850 }
2851 
2852 bool
Lookup(Ipv4Address const & dest,RoutingTableEntry & outEntry) const2853 RoutingProtocol::Lookup (Ipv4Address const &dest,
2854                          RoutingTableEntry &outEntry) const
2855 {
2856   // Get the iterator at "dest" position
2857   std::map<Ipv4Address, RoutingTableEntry>::const_iterator it =
2858     m_table.find (dest);
2859   // If there is no route to "dest", return NULL
2860   if (it == m_table.end ())
2861     {
2862       return false;
2863     }
2864   outEntry = it->second;
2865   return true;
2866 }
2867 
2868 bool
FindSendEntry(RoutingTableEntry const & entry,RoutingTableEntry & outEntry) const2869 RoutingProtocol::FindSendEntry (RoutingTableEntry const &entry,
2870                                 RoutingTableEntry &outEntry) const
2871 {
2872   outEntry = entry;
2873   while (outEntry.destAddr != outEntry.nextAddr)
2874     {
2875       if (not Lookup (outEntry.nextAddr, outEntry))
2876         {
2877           return false;
2878         }
2879     }
2880   return true;
2881 }
2882 
2883 Ptr<Ipv4Route>
RouteOutput(Ptr<Packet> p,const Ipv4Header & header,Ptr<NetDevice> oif,Socket::SocketErrno & sockerr)2884 RoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
2885 {
2886   NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination () << " " << oif);
2887   Ptr<Ipv4Route> rtentry;
2888   RoutingTableEntry entry1, entry2;
2889   bool found = false;
2890 
2891   if (Lookup (header.GetDestination (), entry1) != 0)
2892     {
2893       bool foundSendEntry = FindSendEntry (entry1, entry2);
2894       if (!foundSendEntry)
2895         {
2896           NS_FATAL_ERROR ("FindSendEntry failure");
2897         }
2898       uint32_t interfaceIdx = entry2.interface;
2899       if (oif && m_ipv4->GetInterfaceForDevice (oif) != static_cast<int> (interfaceIdx))
2900         {
2901           // We do not attempt to perform a constrained routing search
2902           // if the caller specifies the oif; we just enforce that
2903           // that the found route matches the requested outbound interface
2904           NS_LOG_DEBUG ("Olsr node " << m_mainAddress
2905                                      << ": RouteOutput for dest=" << header.GetDestination ()
2906                                      << " Route interface " << interfaceIdx
2907                                      << " does not match requested output interface "
2908                                      << m_ipv4->GetInterfaceForDevice (oif));
2909           sockerr = Socket::ERROR_NOROUTETOHOST;
2910           return rtentry;
2911         }
2912       rtentry = Create<Ipv4Route> ();
2913       rtentry->SetDestination (header.GetDestination ());
2914       // the source address is the interface address that matches
2915       // the destination address (when multiple are present on the
2916       // outgoing interface, one is selected via scoping rules)
2917       NS_ASSERT (m_ipv4);
2918       uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
2919       NS_ASSERT (numOifAddresses > 0);
2920       Ipv4InterfaceAddress ifAddr;
2921       if (numOifAddresses == 1)
2922         {
2923           ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
2924         }
2925       else
2926         {
2927           /// \todo Implement IP aliasing and OLSR
2928           NS_FATAL_ERROR ("XXX Not implemented yet:  IP aliasing and OLSR");
2929         }
2930       rtentry->SetSource (ifAddr.GetLocal ());
2931       rtentry->SetGateway (entry2.nextAddr);
2932       rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
2933       sockerr = Socket::ERROR_NOTERROR;
2934       NS_LOG_DEBUG ("Olsr node " << m_mainAddress
2935                                  << ": RouteOutput for dest=" << header.GetDestination ()
2936                                  << " --> nextHop=" << entry2.nextAddr
2937                                  << " interface=" << entry2.interface);
2938       NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
2939       found = true;
2940     }
2941   else
2942     {
2943       rtentry = m_hnaRoutingTable->RouteOutput (p, header, oif, sockerr);
2944 
2945       if (rtentry)
2946         {
2947           found = true;
2948           NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
2949         }
2950     }
2951 
2952   if (!found)
2953     {
2954       NS_LOG_DEBUG ("Olsr node " << m_mainAddress
2955                                  << ": RouteOutput for dest=" << header.GetDestination ()
2956                                  << " No route to host");
2957       sockerr = Socket::ERROR_NOROUTETOHOST;
2958     }
2959   return rtentry;
2960 }
2961 
RouteInput(Ptr<const Packet> p,const Ipv4Header & header,Ptr<const NetDevice> idev,UnicastForwardCallback ucb,MulticastForwardCallback mcb,LocalDeliverCallback lcb,ErrorCallback ecb)2962 bool RoutingProtocol::RouteInput  (Ptr<const Packet> p,
2963                                    const Ipv4Header &header, Ptr<const NetDevice> idev,
2964                                    UnicastForwardCallback ucb, MulticastForwardCallback mcb,
2965                                    LocalDeliverCallback lcb, ErrorCallback ecb)
2966 {
2967   NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination ());
2968 
2969   Ipv4Address dst = header.GetDestination ();
2970   Ipv4Address origin = header.GetSource ();
2971 
2972   // Consume self-originated packets
2973   if (IsMyOwnAddress (origin) == true)
2974     {
2975       return true;
2976     }
2977 
2978   // Local delivery
2979   NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
2980   uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
2981   if (m_ipv4->IsDestinationAddress (dst, iif))
2982     {
2983       if (!lcb.IsNull ())
2984         {
2985           NS_LOG_LOGIC ("Local delivery to " << dst);
2986           lcb (p, header, iif);
2987           return true;
2988         }
2989       else
2990         {
2991           // The local delivery callback is null.  This may be a multicast
2992           // or broadcast packet, so return false so that another
2993           // multicast routing protocol can handle it.  It should be possible
2994           // to extend this to explicitly check whether it is a unicast
2995           // packet, and invoke the error callback if so
2996           NS_LOG_LOGIC ("Null local delivery callback");
2997           return false;
2998         }
2999     }
3000 
3001   NS_LOG_LOGIC ("Forward packet");
3002   // Forwarding
3003   Ptr<Ipv4Route> rtentry;
3004   RoutingTableEntry entry1, entry2;
3005   if (Lookup (header.GetDestination (), entry1))
3006     {
3007       bool foundSendEntry = FindSendEntry (entry1, entry2);
3008       if (!foundSendEntry)
3009         {
3010           NS_FATAL_ERROR ("FindSendEntry failure");
3011         }
3012       rtentry = Create<Ipv4Route> ();
3013       rtentry->SetDestination (header.GetDestination ());
3014       uint32_t interfaceIdx = entry2.interface;
3015       // the source address is the interface address that matches
3016       // the destination address (when multiple are present on the
3017       // outgoing interface, one is selected via scoping rules)
3018       NS_ASSERT (m_ipv4);
3019       uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
3020       NS_ASSERT (numOifAddresses > 0);
3021       Ipv4InterfaceAddress ifAddr;
3022       if (numOifAddresses == 1)
3023         {
3024           ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
3025         }
3026       else
3027         {
3028           /// \todo Implement IP aliasing and OLSR
3029           NS_FATAL_ERROR ("XXX Not implemented yet:  IP aliasing and OLSR");
3030         }
3031       rtentry->SetSource (ifAddr.GetLocal ());
3032       rtentry->SetGateway (entry2.nextAddr);
3033       rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
3034 
3035       NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3036                                  << ": RouteInput for dest=" << header.GetDestination ()
3037                                  << " --> nextHop=" << entry2.nextAddr
3038                                  << " interface=" << entry2.interface);
3039 
3040       ucb (rtentry, p, header);
3041       return true;
3042     }
3043   else
3044     {
3045       NS_LOG_LOGIC ("No dynamic route, check network routes");
3046       if (m_hnaRoutingTable->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
3047         {
3048           return true;
3049         }
3050       else
3051         {
3052 
3053 #ifdef NS3_LOG_ENABLE
3054           NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3055                                      << ": RouteInput for dest=" << header.GetDestination ()
3056                                      << " --> NOT FOUND; ** Dumping routing table...");
3057 
3058           for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3059                iter != m_table.end (); iter++)
3060             {
3061               NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
3062                                     << " via interface " << iter->second.interface);
3063             }
3064 
3065           NS_LOG_DEBUG ("** Routing table dump end.");
3066 #endif // NS3_LOG_ENABLE
3067 
3068           return false;
3069         }
3070     }
3071 }
3072 void
NotifyInterfaceUp(uint32_t i)3073 RoutingProtocol::NotifyInterfaceUp (uint32_t i)
3074 {
3075 }
3076 void
NotifyInterfaceDown(uint32_t i)3077 RoutingProtocol::NotifyInterfaceDown (uint32_t i)
3078 {
3079 }
3080 void
NotifyAddAddress(uint32_t interface,Ipv4InterfaceAddress address)3081 RoutingProtocol::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
3082 {
3083 }
3084 void
NotifyRemoveAddress(uint32_t interface,Ipv4InterfaceAddress address)3085 RoutingProtocol::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
3086 {
3087 }
3088 
3089 
3090 void
AddEntry(Ipv4Address const & dest,Ipv4Address const & next,uint32_t interface,uint32_t distance)3091 RoutingProtocol::AddEntry (Ipv4Address const &dest,
3092                            Ipv4Address const &next,
3093                            uint32_t interface,
3094                            uint32_t distance)
3095 {
3096   NS_LOG_FUNCTION (this << dest << next << interface << distance << m_mainAddress);
3097 
3098   NS_ASSERT (distance > 0);
3099 
3100   // Creates a new rt entry with specified values
3101   RoutingTableEntry &entry = m_table[dest];
3102 
3103   entry.destAddr = dest;
3104   entry.nextAddr = next;
3105   entry.interface = interface;
3106   entry.distance = distance;
3107 }
3108 
3109 void
AddEntry(Ipv4Address const & dest,Ipv4Address const & next,Ipv4Address const & interfaceAddress,uint32_t distance)3110 RoutingProtocol::AddEntry (Ipv4Address const &dest,
3111                            Ipv4Address const &next,
3112                            Ipv4Address const &interfaceAddress,
3113                            uint32_t distance)
3114 {
3115   NS_LOG_FUNCTION (this << dest << next << interfaceAddress << distance << m_mainAddress);
3116 
3117   NS_ASSERT (distance > 0);
3118   NS_ASSERT (m_ipv4);
3119 
3120   RoutingTableEntry entry;
3121   for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
3122     {
3123       for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
3124         {
3125           if (m_ipv4->GetAddress (i,j).GetLocal () == interfaceAddress)
3126             {
3127               AddEntry (dest, next, i, distance);
3128               return;
3129             }
3130         }
3131     }
3132   NS_ASSERT (false); // should not be reached
3133   AddEntry (dest, next, 0, distance);
3134 }
3135 
3136 
3137 std::vector<RoutingTableEntry>
GetRoutingTableEntries(void) const3138 RoutingProtocol::GetRoutingTableEntries  (void) const
3139 {
3140   std::vector<RoutingTableEntry> retval;
3141   for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3142        iter != m_table.end (); iter++)
3143     {
3144       retval.push_back (iter->second);
3145     }
3146   return retval;
3147 }
3148 
3149 MprSet
GetMprSet(void) const3150 RoutingProtocol::GetMprSet  (void) const
3151 {
3152   return m_state.GetMprSet ();
3153 }
3154 
3155 const MprSelectorSet &
GetMprSelectors(void) const3156 RoutingProtocol::GetMprSelectors  (void) const
3157 {
3158   return m_state.GetMprSelectors ();
3159 }
3160 
3161 const NeighborSet &
GetNeighbors(void) const3162 RoutingProtocol::GetNeighbors  (void) const
3163 {
3164   return m_state.GetNeighbors ();
3165 }
3166 
3167 const TwoHopNeighborSet &
GetTwoHopNeighbors(void) const3168 RoutingProtocol::GetTwoHopNeighbors  (void) const
3169 {
3170   return m_state.GetTwoHopNeighbors ();
3171 }
3172 
3173 const TopologySet &
GetTopologySet(void) const3174 RoutingProtocol::GetTopologySet  (void) const
3175 {
3176   return m_state.GetTopologySet ();
3177 }
3178 
3179 const OlsrState &
GetOlsrState(void) const3180 RoutingProtocol::GetOlsrState (void) const
3181 {
3182   return m_state;
3183 }
3184 
3185 int64_t
AssignStreams(int64_t stream)3186 RoutingProtocol::AssignStreams (int64_t stream)
3187 {
3188   NS_LOG_FUNCTION (this << stream);
3189   m_uniformRandomVariable->SetStream (stream);
3190   return 1;
3191 }
3192 
3193 bool
IsMyOwnAddress(const Ipv4Address & a) const3194 RoutingProtocol::IsMyOwnAddress (const Ipv4Address & a) const
3195 {
3196   std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j;
3197   for (j = m_sendSockets.begin (); j != m_sendSockets.end (); ++j)
3198     {
3199       Ipv4InterfaceAddress iface = j->second;
3200       if (a == iface.GetLocal ())
3201         {
3202           return true;
3203         }
3204     }
3205   return false;
3206 }
3207 
3208 void
Dump(void)3209 RoutingProtocol::Dump (void)
3210 {
3211 #ifdef NS3_LOG_ENABLE
3212   Time now = Simulator::Now ();
3213   NS_LOG_DEBUG ("Dumping for node with main address " << m_mainAddress);
3214   NS_LOG_DEBUG (" Neighbor set");
3215   for (NeighborSet::const_iterator iter = m_state.GetNeighbors ().begin ();
3216        iter != m_state.GetNeighbors ().end (); iter++)
3217     {
3218       NS_LOG_DEBUG ("  " << *iter);
3219     }
3220   NS_LOG_DEBUG (" Two-hop neighbor set");
3221   for (TwoHopNeighborSet::const_iterator iter = m_state.GetTwoHopNeighbors ().begin ();
3222        iter != m_state.GetTwoHopNeighbors ().end (); iter++)
3223     {
3224       if (now < iter->expirationTime)
3225         {
3226           NS_LOG_DEBUG ("  " << *iter);
3227         }
3228     }
3229   NS_LOG_DEBUG (" Routing table");
3230   for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin (); iter != m_table.end (); iter++)
3231     {
3232       NS_LOG_DEBUG ("  dest=" << iter->first << " --> next=" << iter->second.nextAddr << " via interface " << iter->second.interface);
3233     }
3234   NS_LOG_DEBUG ("");
3235 #endif  //NS3_LOG_ENABLE
3236 }
3237 
3238 Ptr<const Ipv4StaticRouting>
GetRoutingTableAssociation(void) const3239 RoutingProtocol::GetRoutingTableAssociation  (void) const
3240 {
3241   return m_hnaRoutingTable;
3242 }
3243 
3244 } // namespace olsr
3245 } // namespace ns3
3246 
3247 
3248