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