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