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