A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 namespace olsr {
143 
144 NS_LOG_COMPONENT_DEFINE ("OlsrRoutingProtocol");
145 
146 
147 /********** OLSR class **********/
148 
149 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
150 
151 TypeId
153 {
154  static TypeId tid = TypeId ("ns3::olsr::RoutingProtocol")
156  .AddConstructor<RoutingProtocol> ()
157  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
158  TimeValue (Seconds (2)),
159  MakeTimeAccessor (&RoutingProtocol::m_helloInterval),
160  MakeTimeChecker ())
161  .AddAttribute ("TcInterval", "TC messages emission interval.",
162  TimeValue (Seconds (5)),
163  MakeTimeAccessor (&RoutingProtocol::m_tcInterval),
164  MakeTimeChecker ())
165  .AddAttribute ("MidInterval", "MID messages emission interval. Normally it is equal to TcInterval.",
166  TimeValue (Seconds (5)),
167  MakeTimeAccessor (&RoutingProtocol::m_midInterval),
168  MakeTimeChecker ())
169  .AddAttribute ("HnaInterval", "HNA messages emission interval. Normally it is equal to TcInterval.",
170  TimeValue (Seconds (5)),
171  MakeTimeAccessor (&RoutingProtocol::m_hnaInterval),
172  MakeTimeChecker ())
173  .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.",
177  OLSR_WILL_LOW, "low",
178  OLSR_WILL_DEFAULT, "default",
179  OLSR_WILL_HIGH, "high",
180  OLSR_WILL_ALWAYS, "always"))
181  .AddTraceSource ("Rx", "Receive OLSR packet.",
183  .AddTraceSource ("Tx", "Send OLSR packet.",
185  .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.",
187  ;
188  return tid;
189 }
190 
191 
193  : m_routingTableAssociation (0),
194  m_ipv4 (0),
195  m_helloTimer (Timer::CANCEL_ON_DESTROY),
196  m_tcTimer (Timer::CANCEL_ON_DESTROY),
197  m_midTimer (Timer::CANCEL_ON_DESTROY),
198  m_hnaTimer (Timer::CANCEL_ON_DESTROY),
199  m_queuedMessagesTimer (Timer::CANCEL_ON_DESTROY)
200 {
201  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
202 
203  m_hnaRoutingTable = Create<Ipv4StaticRouting> ();
204 }
205 
207 {
208 }
209 
210 void
212 {
213  NS_ASSERT (ipv4 != 0);
214  NS_ASSERT (m_ipv4 == 0);
215  NS_LOG_DEBUG ("Created olsr::RoutingProtocol");
221 
225 
227 
228  m_ipv4 = ipv4;
229 
230  m_hnaRoutingTable->SetIpv4 (ipv4);
231 }
232 
234 {
235  m_ipv4 = 0;
236  m_hnaRoutingTable = 0;
238 
239  for (std::map< Ptr<Socket>, Ipv4InterfaceAddress >::iterator iter = m_socketAddresses.begin ();
240  iter != m_socketAddresses.end (); iter++)
241  {
242  iter->first->Close ();
243  }
244  m_socketAddresses.clear ();
245 
247 }
248 
249 void
251 {
252  std::ostream* os = stream->GetStream ();
253  *os << "Destination\t\tNextHop\t\tInterface\tDistance\n";
254 
255  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
256  iter != m_table.end (); iter++)
257  {
258  *os << iter->first << "\t\t";
259  *os << iter->second.nextAddr << "\t\t";
260  if (Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) != "")
261  {
262  *os << Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) << "\t\t";
263  }
264  else
265  {
266  *os << iter->second.interface << "\t\t";
267  }
268  *os << iter->second.distance << "\t";
269  *os << "\n";
270  }
271  // Also print the HNA routing table
272  *os << " HNA Routing Table:\n";
273  m_hnaRoutingTable->PrintRoutingTable (stream);
274 }
275 
277 {
278  if (m_mainAddress == Ipv4Address ())
279  {
280  Ipv4Address loopback ("127.0.0.1");
281  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
282  {
283  // Use primary address, if multiple
284  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
285  if (addr != loopback)
286  {
287  m_mainAddress = addr;
288  break;
289  }
290  }
291 
293  }
294 
295  NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
296 
297  Ipv4Address loopback ("127.0.0.1");
298 
299  bool canRunOlsr = false;
300  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
301  {
302  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
303  if (addr == loopback)
304  continue;
305 
306  if (addr != m_mainAddress)
307  {
308  // Create never expiring interface association tuple entries for our
309  // own network interfaces, so that GetMainAddress () works to
310  // translate the node's own interface addresses into the main address.
311  IfaceAssocTuple tuple;
312  tuple.ifaceAddr = addr;
313  tuple.mainAddr = m_mainAddress;
314  AddIfaceAssocTuple (tuple);
316  }
317 
318  if(m_interfaceExclusions.find (i) != m_interfaceExclusions.end ())
319  continue;
320 
321  // Create a socket to listen only on this interface
322  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
324  socket->SetAllowBroadcast (true);
325  InetSocketAddress inetAddr (m_ipv4->GetAddress (i, 0).GetLocal (), OLSR_PORT_NUMBER);
327  if (socket->Bind (inetAddr))
328  {
329  NS_FATAL_ERROR ("Failed to bind() OLSR socket");
330  }
331  socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
332  m_socketAddresses[socket] = m_ipv4->GetAddress (i, 0);
333 
334  canRunOlsr = true;
335  }
336 
337  if(canRunOlsr)
338  {
339  HelloTimerExpire ();
340  TcTimerExpire ();
341  MidTimerExpire ();
342  HnaTimerExpire ();
343 
344  NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
345  }
346 }
347 
348 void RoutingProtocol::SetMainInterface (uint32_t interface)
349 {
350  m_mainAddress = m_ipv4->GetAddress (interface, 0).GetLocal ();
351 }
352 
353 void RoutingProtocol::SetInterfaceExclusions (std::set<uint32_t> exceptions)
354 {
355  m_interfaceExclusions = exceptions;
356 }
357 
358 //
359 // \brief Processes an incoming %OLSR packet following \RFC{3626} specification.
360 void
362 {
363  Ptr<Packet> receivedPacket;
364  Address sourceAddress;
365  receivedPacket = socket->RecvFrom (sourceAddress);
366 
367  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
368  Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
369  Ipv4Address receiverIfaceAddr = m_socketAddresses[socket].GetLocal ();
370  NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
371  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
372  << senderIfaceAddr << " to " << receiverIfaceAddr);
373 
374  // All routing messages are sent from and to port RT_PORT,
375  // so we check it.
376  NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER);
377 
378  Ptr<Packet> packet = receivedPacket;
379 
380  olsr::PacketHeader olsrPacketHeader;
381  packet->RemoveHeader (olsrPacketHeader);
382  NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ());
383  uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize ();
384 
385  MessageList messages;
386 
387  while (sizeLeft)
388  {
389  MessageHeader messageHeader;
390  if (packet->RemoveHeader (messageHeader) == 0)
391  NS_ASSERT (false);
392 
393  sizeLeft -= messageHeader.GetSerializedSize ();
394 
395  NS_LOG_DEBUG ("Olsr Msg received with type "
396  << std::dec << int (messageHeader.GetMessageType ())
397  << " TTL=" << int (messageHeader.GetTimeToLive ())
398  << " origAddr=" << messageHeader.GetOriginatorAddress ());
399  messages.push_back (messageHeader);
400  }
401 
402  m_rxPacketTrace (olsrPacketHeader, messages);
403 
404  for (MessageList::const_iterator messageIter = messages.begin ();
405  messageIter != messages.end (); messageIter++)
406  {
407  const MessageHeader &messageHeader = *messageIter;
408  // If ttl is less than or equal to zero, or
409  // the receiver is the same as the originator,
410  // the message must be silently dropped
411  if (messageHeader.GetTimeToLive () == 0
412  || messageHeader.GetOriginatorAddress () == m_mainAddress)
413  {
414  packet->RemoveAtStart (messageHeader.GetSerializedSize ()
415  - messageHeader.GetSerializedSize ());
416  continue;
417  }
418 
419  // If the message has been processed it must not be processed again
420  bool do_forwarding = true;
422  (messageHeader.GetOriginatorAddress (),
423  messageHeader.GetMessageSequenceNumber ());
424 
425  // Get main address of the peer, which may be different from the packet source address
426 // const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ());
427 // Ipv4Address peerMainAddress;
428 // if (ifaceAssoc != NULL)
429 // {
430 // peerMainAddress = ifaceAssoc->mainAddr;
431 // }
432 // else
433 // {
434 // peerMainAddress = inetSourceAddr.GetIpv4 () ;
435 // }
436 
437  if (duplicated == NULL)
438  {
439  switch (messageHeader.GetMessageType ())
440  {
442  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
443  << "s OLSR node " << m_mainAddress
444  << " received HELLO message of size " << messageHeader.GetSerializedSize ());
445  ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr);
446  break;
447 
449  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
450  << "s OLSR node " << m_mainAddress
451  << " received TC message of size " << messageHeader.GetSerializedSize ());
452  ProcessTc (messageHeader, senderIfaceAddr);
453  break;
454 
456  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
457  << "s OLSR node " << m_mainAddress
458  << " received MID message of size " << messageHeader.GetSerializedSize ());
459  ProcessMid (messageHeader, senderIfaceAddr);
460  break;
462  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
463  << "s OLSR node " << m_mainAddress
464  << " received HNA message of size " << messageHeader.GetSerializedSize ());
465  ProcessHna (messageHeader, senderIfaceAddr);
466  break;
467 
468  default:
469  NS_LOG_DEBUG ("OLSR message type " <<
470  int (messageHeader.GetMessageType ()) <<
471  " not implemented");
472  }
473  }
474  else
475  {
476  NS_LOG_DEBUG ("OLSR message is duplicated, not reading it.");
477 
478  // If the message has been considered for forwarding, it should
479  // not be retransmitted again
480  for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin ();
481  it != duplicated->ifaceList.end (); it++)
482  {
483  if (*it == receiverIfaceAddr)
484  {
485  do_forwarding = false;
486  break;
487  }
488  }
489  }
490 
491  if (do_forwarding)
492  {
493  // HELLO messages are never forwarded.
494  // TC and MID messages are forwarded using the default algorithm.
495  // Remaining messages are also forwarded using the default algorithm.
496  if (messageHeader.GetMessageType () != olsr::MessageHeader::HELLO_MESSAGE)
497  {
498  ForwardDefault (messageHeader, duplicated,
499  receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
500  }
501  }
502  }
503 
504  // After processing all OLSR messages, we must recompute the routing table
506 }
507 
514 int
516 {
517  int degree = 0;
518  for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin ();
519  it != m_state.GetTwoHopNeighbors ().end (); it++)
520  {
521  TwoHopNeighborTuple const &nb2hop_tuple = *it;
522  if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
523  {
524  const NeighborTuple *nb_tuple =
526  if (nb_tuple == NULL)
527  degree++;
528  }
529  }
530  return degree;
531 }
532 
533 namespace {
537 void
539 {
540  // first gather all 2-hop neighbors to be removed
541  std::set<Ipv4Address> toRemove;
542  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
543  {
544  if (twoHopNeigh->neighborMainAddr == neighborMainAddr)
545  {
546  toRemove.insert (twoHopNeigh->twoHopNeighborAddr);
547  }
548  }
549  // Now remove all matching records from N2
550  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); )
551  {
552  if (toRemove.find (twoHopNeigh->twoHopNeighborAddr) != toRemove.end ())
553  {
554  twoHopNeigh = N2.erase (twoHopNeigh);
555  }
556  else
557  {
558  twoHopNeigh++;
559  }
560  }
561 }
562 } // anonymous namespace
563 
567 void
569 {
570  NS_LOG_FUNCTION (this);
571 
572  // MPR computation should be done for each interface. See section 8.3.1
573  // (RFC 3626) for details.
574  MprSet mprSet;
575 
576  // N is the subset of neighbors of the node, which are
577  // neighbor "of the interface I"
578  NeighborSet N;
579  for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin ();
580  neighbor != m_state.GetNeighbors ().end (); neighbor++)
581  {
582  if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
583  {
584  N.push_back (*neighbor);
585  }
586  }
587 
588  // N2 is the set of 2-hop neighbors reachable from "the interface
589  // I", excluding:
590  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
591  // (ii) the node performing the computation
592  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
593  // link to this node on some interface.
595  for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin ();
596  twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++)
597  {
598  // excluding:
599  // (ii) the node performing the computation
600  if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
601  {
602  continue;
603  }
604 
605  // excluding:
606  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
607  bool ok = false;
608  for (NeighborSet::const_iterator neigh = N.begin ();
609  neigh != N.end (); neigh++)
610  {
611  if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
612  {
613  if (neigh->willingness == OLSR_WILL_NEVER)
614  {
615  ok = false;
616  break;
617  }
618  else
619  {
620  ok = true;
621  break;
622  }
623  }
624  }
625  if (!ok)
626  {
627  continue;
628  }
629 
630  // excluding:
631  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
632  // link to this node on some interface.
633  for (NeighborSet::const_iterator neigh = N.begin ();
634  neigh != N.end (); neigh++)
635  {
636  if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
637  {
638  ok = false;
639  break;
640  }
641  }
642 
643  if (ok)
644  {
645  N2.push_back (*twoHopNeigh);
646  }
647  }
648 
649 #ifdef NS3_LOG_ENABLE
650  {
651  std::ostringstream os;
652  os << "[";
653  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
654  iter != N2.end (); iter++)
655  {
656  TwoHopNeighborSet::const_iterator next = iter;
657  next++;
658  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
659  if (next != N2.end ())
660  os << ", ";
661  }
662  os << "]";
663  NS_LOG_DEBUG ("N2: " << os.str ());
664  }
665 #endif //NS3_LOG_ENABLE
666 
667  // 1. Start with an MPR set made of all members of N with
668  // N_willingness equal to WILL_ALWAYS
669  for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
670  {
671  if (neighbor->willingness == OLSR_WILL_ALWAYS)
672  {
673  mprSet.insert (neighbor->neighborMainAddr);
674  // (not in RFC but I think is needed: remove the 2-hop
675  // neighbors reachable by the MPR from N2)
676  CoverTwoHopNeighbors (neighbor->neighborMainAddr, N2);
677  }
678  }
679 
680  // 2. Calculate D(y), where y is a member of N, for all nodes in N.
681  // (we do this later)
682 
683  // 3. Add to the MPR set those nodes in N, which are the *only*
684  // nodes to provide reachability to a node in N2.
685  std::set<Ipv4Address> coveredTwoHopNeighbors;
686  for (TwoHopNeighborSet::const_iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
687  {
688  bool onlyOne = true;
689  // try to find another neighbor that can reach twoHopNeigh->twoHopNeighborAddr
690  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin (); otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
691  {
692  if (otherTwoHopNeigh->twoHopNeighborAddr == twoHopNeigh->twoHopNeighborAddr
693  && otherTwoHopNeigh->neighborMainAddr != twoHopNeigh->neighborMainAddr)
694  {
695  onlyOne = false;
696  break;
697  }
698  }
699  if (onlyOne)
700  {
701  NS_LOG_LOGIC ("Neighbor " << twoHopNeigh->neighborMainAddr
702  << " is the only that can reach 2-hop neigh. "
703  << twoHopNeigh->twoHopNeighborAddr
704  << " => select as MPR.");
705 
706  mprSet.insert (twoHopNeigh->neighborMainAddr);
707 
708  // take note of all the 2-hop neighbors reachable by the newly elected MPR
709  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin ();
710  otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
711  {
712  if (otherTwoHopNeigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
713  {
714  coveredTwoHopNeighbors.insert (otherTwoHopNeigh->twoHopNeighborAddr);
715  }
716  }
717  }
718  }
719  // Remove the nodes from N2 which are now covered by a node in the MPR set.
720  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
721  twoHopNeigh != N2.end (); )
722  {
723  if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
724  {
725  // This works correctly only because it is known that twoHopNeigh is reachable by exactly one neighbor,
726  // so only one record in N2 exists for each of them. This record is erased here.
727  NS_LOG_LOGIC ("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr << " is already covered by an MPR.");
728  twoHopNeigh = N2.erase (twoHopNeigh);
729  }
730  else
731  {
732  twoHopNeigh++;
733  }
734  }
735 
736  // 4. While there exist nodes in N2 which are not covered by at
737  // least one node in the MPR set:
738  while (N2.begin () != N2.end ())
739  {
740 
741 #ifdef NS3_LOG_ENABLE
742  {
743  std::ostringstream os;
744  os << "[";
745  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
746  iter != N2.end (); iter++)
747  {
748  TwoHopNeighborSet::const_iterator next = iter;
749  next++;
750  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
751  if (next != N2.end ())
752  os << ", ";
753  }
754  os << "]";
755  NS_LOG_DEBUG ("Step 4 iteration: N2=" << os.str ());
756  }
757 #endif //NS3_LOG_ENABLE
758 
759 
760  // 4.1. For each node in N, calculate the reachability, i.e., the
761  // number of nodes in N2 which are not yet covered by at
762  // least one node in the MPR set, and which are reachable
763  // through this 1-hop neighbor
764  std::map<int, std::vector<const NeighborTuple *> > reachability;
765  std::set<int> rs;
766  for (NeighborSet::iterator it = N.begin (); it != N.end (); it++)
767  {
768  NeighborTuple const &nb_tuple = *it;
769  int r = 0;
770  for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++)
771  {
772  TwoHopNeighborTuple const &nb2hop_tuple = *it2;
773  if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
774  r++;
775  }
776  rs.insert (r);
777  reachability[r].push_back (&nb_tuple);
778  }
779 
780  // 4.2. Select as a MPR the node with highest N_willingness among
781  // the nodes in N with non-zero reachability. In case of
782  // multiple choice select the node which provides
783  // reachability to the maximum number of nodes in N2. In
784  // case of multiple nodes providing the same amount of
785  // reachability, select the node as MPR whose D(y) is
786  // greater. Remove the nodes from N2 which are now covered
787  // by a node in the MPR set.
788  NeighborTuple const *max = NULL;
789  int max_r = 0;
790  for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++)
791  {
792  int r = *it;
793  if (r == 0)
794  {
795  continue;
796  }
797  for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin ();
798  it2 != reachability[r].end (); it2++)
799  {
800  const NeighborTuple *nb_tuple = *it2;
801  if (max == NULL || nb_tuple->willingness > max->willingness)
802  {
803  max = nb_tuple;
804  max_r = r;
805  }
806  else if (nb_tuple->willingness == max->willingness)
807  {
808  if (r > max_r)
809  {
810  max = nb_tuple;
811  max_r = r;
812  }
813  else if (r == max_r)
814  {
815  if (Degree (*nb_tuple) > Degree (*max))
816  {
817  max = nb_tuple;
818  max_r = r;
819  }
820  }
821  }
822  }
823  }
824 
825  if (max != NULL)
826  {
827  mprSet.insert (max->neighborMainAddr);
829  NS_LOG_LOGIC (N2.size () << " 2-hop neighbors left to cover!");
830  }
831  }
832 
833 #ifdef NS3_LOG_ENABLE
834  {
835  std::ostringstream os;
836  os << "[";
837  for (MprSet::const_iterator iter = mprSet.begin ();
838  iter != mprSet.end (); iter++)
839  {
840  MprSet::const_iterator next = iter;
841  next++;
842  os << *iter;
843  if (next != mprSet.end ())
844  os << ", ";
845  }
846  os << "]";
847  NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
848  }
849 #endif //NS3_LOG_ENABLE
850 
851  m_state.SetMprSet (mprSet);
852 }
853 
862 {
863  const IfaceAssocTuple *tuple =
864  m_state.FindIfaceAssocTuple (iface_addr);
865 
866  if (tuple != NULL)
867  return tuple->mainAddr;
868  else
869  return iface_addr;
870 }
871 
875 void
877 {
878  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " s: Node " << m_mainAddress
879  << ": RoutingTableComputation begin...");
880 
881  // 1. All the entries from the routing table are removed.
882  Clear ();
883 
884  // 2. The new routing entries are added starting with the
885  // symmetric neighbors (h=1) as the destination nodes.
886  const NeighborSet &neighborSet = m_state.GetNeighbors ();
887  for (NeighborSet::const_iterator it = neighborSet.begin ();
888  it != neighborSet.end (); it++)
889  {
890  NeighborTuple const &nb_tuple = *it;
891  NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple);
892  if (nb_tuple.status == NeighborTuple::STATUS_SYM)
893  {
894  bool nb_main_addr = false;
895  const LinkTuple *lt = NULL;
896  const LinkSet &linkSet = m_state.GetLinks ();
897  for (LinkSet::const_iterator it2 = linkSet.begin ();
898  it2 != linkSet.end (); it2++)
899  {
900  LinkTuple const &link_tuple = *it2;
901  NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple
902  << (link_tuple.time >= Simulator::Now () ? "" : " (expired)"));
903  if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr)
904  && link_tuple.time >= Simulator::Now ())
905  {
906  NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr
907  << " => adding routing table entry to neighbor");
908  lt = &link_tuple;
909  AddEntry (link_tuple.neighborIfaceAddr,
910  link_tuple.neighborIfaceAddr,
911  link_tuple.localIfaceAddr,
912  1);
913  if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
914  {
915  nb_main_addr = true;
916  }
917  }
918  else
919  {
920  NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr)
921  << "; neighborMainAddr = " << nb_tuple.neighborMainAddr
922  << "; expired=" << int (link_tuple.time < Simulator::Now ())
923  << " => IGNORE");
924  }
925  }
926 
927  // If, in the above, no R_dest_addr is equal to the main
928  // address of the neighbor, then another new routing entry
929  // with MUST be added, with:
930  // R_dest_addr = main address of the neighbor;
931  // R_next_addr = L_neighbor_iface_addr of one of the
932  // associated link tuple with L_time >= current time;
933  // R_dist = 1;
934  // R_iface_addr = L_local_iface_addr of the
935  // associated link tuple.
936  if (!nb_main_addr && lt != NULL)
937  {
938  NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor "
939  "=> adding additional routing entry");
940  AddEntry (nb_tuple.neighborMainAddr,
941  lt->neighborIfaceAddr,
942  lt->localIfaceAddr,
943  1);
944  }
945  }
946  }
947 
948  // 3. for each node in N2, i.e., a 2-hop neighbor which is not a
949  // neighbor node or the node itself, and such that there exist at
950  // least one entry in the 2-hop neighbor set where
951  // N_neighbor_main_addr correspond to a neighbor node with
952  // willingness different of WILL_NEVER,
953  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
954  for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin ();
955  it != twoHopNeighbors.end (); it++)
956  {
957  TwoHopNeighborTuple const &nb2hop_tuple = *it;
958 
959  NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
960 
961  // a 2-hop neighbor which is not a neighbor node or the node itself
963  {
964  NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped.");
965  continue;
966  }
967 
968  if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
969  {
970  NS_LOG_LOGIC ("Two-hop neighbor is self; skipped.");
971  continue;
972  }
973 
974  // ...and such that there exist at least one entry in the 2-hop
975  // neighbor set where N_neighbor_main_addr correspond to a
976  // neighbor node with willingness different of WILL_NEVER...
977  bool nb2hopOk = false;
978  for (NeighborSet::const_iterator neighbor = neighborSet.begin ();
979  neighbor != neighborSet.end (); neighbor++)
980  {
981  if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr
982  && neighbor->willingness != OLSR_WILL_NEVER)
983  {
984  nb2hopOk = true;
985  break;
986  }
987  }
988  if (!nb2hopOk)
989  {
990  NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor "
991  << nb2hop_tuple.twoHopNeighborAddr
992  << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr
993  << ", which was not found in the Neighbor Set.");
994  continue;
995  }
996 
997  // one selects one 2-hop tuple and creates one entry in the routing table with:
998  // R_dest_addr = the main address of the 2-hop neighbor;
999  // R_next_addr = the R_next_addr of the entry in the
1000  // routing table with:
1001  // R_dest_addr == N_neighbor_main_addr
1002  // of the 2-hop tuple;
1003  // R_dist = 2;
1004  // R_iface_addr = the R_iface_addr of the entry in the
1005  // routing table with:
1006  // R_dest_addr == N_neighbor_main_addr
1007  // of the 2-hop tuple;
1008  RoutingTableEntry entry;
1009  bool foundEntry = Lookup (nb2hop_tuple.neighborMainAddr, entry);
1010  if (foundEntry)
1011  {
1012  NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor.");
1013  AddEntry (nb2hop_tuple.twoHopNeighborAddr,
1014  entry.nextAddr,
1015  entry.interface,
1016  2);
1017  }
1018  else
1019  {
1020  NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor ("
1021  << nb2hop_tuple.twoHopNeighborAddr
1022  << " not found in the routing table)");
1023  }
1024  }
1025 
1026  for (uint32_t h = 2;; h++)
1027  {
1028  bool added = false;
1029 
1030  // 3.1. For each topology entry in the topology table, if its
1031  // T_dest_addr does not correspond to R_dest_addr of any
1032  // route entry in the routing table AND its T_last_addr
1033  // corresponds to R_dest_addr of a route entry whose R_dist
1034  // is equal to h, then a new route entry MUST be recorded in
1035  // the routing table (if it does not already exist)
1036  const TopologySet &topology = m_state.GetTopologySet ();
1037  for (TopologySet::const_iterator it = topology.begin ();
1038  it != topology.end (); it++)
1039  {
1040  const TopologyTuple &topology_tuple = *it;
1041  NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple);
1042 
1043  RoutingTableEntry destAddrEntry, lastAddrEntry;
1044  bool have_destAddrEntry = Lookup (topology_tuple.destAddr, destAddrEntry);
1045  bool have_lastAddrEntry = Lookup (topology_tuple.lastAddr, lastAddrEntry);
1046  if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
1047  {
1048  NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple.");
1049  // then a new route entry MUST be recorded in
1050  // the routing table (if it does not already exist) where:
1051  // R_dest_addr = T_dest_addr;
1052  // R_next_addr = R_next_addr of the recorded
1053  // route entry where:
1054  // R_dest_addr == T_last_addr
1055  // R_dist = h+1; and
1056  // R_iface_addr = R_iface_addr of the recorded
1057  // route entry where:
1058  // R_dest_addr == T_last_addr.
1059  AddEntry (topology_tuple.destAddr,
1060  lastAddrEntry.nextAddr,
1061  lastAddrEntry.interface,
1062  h + 1);
1063  added = true;
1064  }
1065  else
1066  {
1067  NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: "
1068  "have_destAddrEntry=" << have_destAddrEntry
1069  << " have_lastAddrEntry=" << have_lastAddrEntry
1070  << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance
1071  << " (h=" << h << ")");
1072  }
1073  }
1074 
1075  if (!added)
1076  break;
1077  }
1078 
1079  // 4. For each entry in the multiple interface association base
1080  // where there exists a routing entry such that:
1081  // R_dest_addr == I_main_addr (of the multiple interface association entry)
1082  // AND there is no routing entry such that:
1083  // R_dest_addr == I_iface_addr
1084  const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
1085  for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
1086  it != ifaceAssocSet.end (); it++)
1087  {
1088  IfaceAssocTuple const &tuple = *it;
1089  RoutingTableEntry entry1, entry2;
1090  bool have_entry1 = Lookup (tuple.mainAddr, entry1);
1091  bool have_entry2 = Lookup (tuple.ifaceAddr, entry2);
1092  if (have_entry1 && !have_entry2)
1093  {
1094  // then a route entry is created in the routing table with:
1095  // R_dest_addr = I_iface_addr (of the multiple interface
1096  // association entry)
1097  // R_next_addr = R_next_addr (of the recorded route entry)
1098  // R_dist = R_dist (of the recorded route entry)
1099  // R_iface_addr = R_iface_addr (of the recorded route entry).
1100  AddEntry (tuple.ifaceAddr,
1101  entry1.nextAddr,
1102  entry1.interface,
1103  entry1.distance);
1104  }
1105  }
1106 
1107  // 5. For each tuple in the association set,
1108  // If there is no entry in the routing table with:
1109  // R_dest_addr == A_network_addr/A_netmask
1110  // and if the announced network is not announced by the node itself,
1111  // then a new routing entry is created.
1112  const AssociationSet &associationSet = m_state.GetAssociationSet ();
1113 
1114  // Clear HNA routing table
1115  for (uint32_t i = 0; i < m_hnaRoutingTable->GetNRoutes (); i++)
1116  {
1117  m_hnaRoutingTable->RemoveRoute (0);
1118  }
1119 
1120  for (AssociationSet::const_iterator it = associationSet.begin ();
1121  it != associationSet.end (); it++)
1122  {
1123  AssociationTuple const &tuple = *it;
1124 
1125  // Test if HNA associations received from other gateways
1126  // are also announced by this node. In such a case, no route
1127  // is created for this association tuple (go to the next one).
1128  bool goToNextAssociationTuple = false;
1129  const Associations &localHnaAssociations = m_state.GetAssociations ();
1130  NS_LOG_DEBUG ("Nb local associations: " << localHnaAssociations.size ());
1131  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1132  assocIterator != localHnaAssociations.end (); assocIterator++)
1133  {
1134  Association const &localHnaAssoc = *assocIterator;
1135  if (localHnaAssoc.networkAddr == tuple.networkAddr && localHnaAssoc.netmask == tuple.netmask)
1136  {
1137  NS_LOG_DEBUG ("HNA association received from another GW is part of local HNA associations: no route added for network "
1138  << tuple.networkAddr << "/" << tuple.netmask);
1139  goToNextAssociationTuple = true;
1140  }
1141  }
1142  if (goToNextAssociationTuple)
1143  {
1144  continue;
1145  }
1146 
1147  RoutingTableEntry gatewayEntry;
1148 
1149  bool gatewayEntryExists = Lookup (tuple.gatewayAddr, gatewayEntry);
1150  bool addRoute = false;
1151 
1152  uint32_t routeIndex = 0;
1153 
1154  for (routeIndex = 0; routeIndex < m_hnaRoutingTable->GetNRoutes (); routeIndex++)
1155  {
1156  Ipv4RoutingTableEntry route = m_hnaRoutingTable->GetRoute (routeIndex);
1157  if (route.GetDestNetwork () == tuple.networkAddr &&
1158  route.GetDestNetworkMask () == tuple.netmask)
1159  {
1160  break;
1161  }
1162  }
1163 
1164  if (routeIndex == m_hnaRoutingTable->GetNRoutes ())
1165  {
1166  addRoute = true;
1167  }
1168  else if(gatewayEntryExists && m_hnaRoutingTable->GetMetric (routeIndex) > gatewayEntry.distance)
1169  {
1170  m_hnaRoutingTable->RemoveRoute (routeIndex);
1171  addRoute = true;
1172  }
1173 
1174  if(addRoute && gatewayEntryExists)
1175  {
1176  m_hnaRoutingTable->AddNetworkRouteTo (tuple.networkAddr,
1177  tuple.netmask,
1178  gatewayEntry.nextAddr,
1179  gatewayEntry.interface,
1180  gatewayEntry.distance);
1181 
1182  }
1183  }
1184 
1185  NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
1187 }
1188 
1189 
1200 void
1202  const Ipv4Address &receiverIface,
1203  const Ipv4Address &senderIface)
1204 {
1205  NS_LOG_FUNCTION (msg << receiverIface << senderIface);
1206 
1207  const olsr::MessageHeader::Hello &hello = msg.GetHello ();
1208 
1209  LinkSensing (msg, hello, receiverIface, senderIface);
1210 
1211 #ifdef NS3_LOG_ENABLE
1212  {
1213  const LinkSet &links = m_state.GetLinks ();
1214  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1215  << "s ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
1216  for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++)
1217  {
1218  NS_LOG_DEBUG (*link);
1219  }
1220  NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress);
1221 
1222  const NeighborSet &neighbors = m_state.GetNeighbors ();
1223  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1224  << "s ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
1225  for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1226  {
1227  NS_LOG_DEBUG (*neighbor);
1228  }
1229  NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
1230  }
1231 #endif // NS3_LOG_ENABLE
1232 
1233  PopulateNeighborSet (msg, hello);
1234  PopulateTwoHopNeighborSet (msg, hello);
1235 
1236 #ifdef NS3_LOG_ENABLE
1237  {
1238  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1239  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1240  << "s ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1241  for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin ();
1242  tuple != twoHopNeighbors.end (); tuple++)
1243  {
1244  NS_LOG_DEBUG (*tuple);
1245  }
1246  NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1247  }
1248 #endif // NS3_LOG_ENABLE
1249 
1250  MprComputation ();
1251  PopulateMprSelectorSet (msg, hello);
1252 }
1253 
1263 void
1265  const Ipv4Address &senderIface)
1266 {
1267  const olsr::MessageHeader::Tc &tc = msg.GetTc ();
1268  Time now = Simulator::Now ();
1269 
1270  // 1. If the sender interface of this message is not in the symmetric
1271  // 1-hop neighborhood of this node, the message MUST be discarded.
1272  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1273  if (link_tuple == NULL)
1274  return;
1275 
1276  // 2. If there exist some tuple in the topology set where:
1277  // T_last_addr == originator address AND
1278  // T_seq > ANSN,
1279  // then further processing of this TC message MUST NOT be
1280  // performed.
1281  const TopologyTuple *topologyTuple =
1283  if (topologyTuple != NULL)
1284  return;
1285 
1286  // 3. All tuples in the topology set where:
1287  // T_last_addr == originator address AND
1288  // T_seq < ANSN
1289  // MUST be removed from the topology set.
1291 
1292  // 4. For each of the advertised neighbor main address received in
1293  // the TC message:
1294  for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin ();
1295  i != tc.neighborAddresses.end (); i++)
1296  {
1297  const Ipv4Address &addr = *i;
1298  // 4.1. If there exist some tuple in the topology set where:
1299  // T_dest_addr == advertised neighbor main address, AND
1300  // T_last_addr == originator address,
1301  // then the holding time of that tuple MUST be set to:
1302  // T_time = current time + validity time.
1303  TopologyTuple *topologyTuple =
1305 
1306  if (topologyTuple != NULL)
1307  {
1308  topologyTuple->expirationTime = now + msg.GetVTime ();
1309  }
1310  else
1311  {
1312  // 4.2. Otherwise, a new tuple MUST be recorded in the topology
1313  // set where:
1314  // T_dest_addr = advertised neighbor main address,
1315  // T_last_addr = originator address,
1316  // T_seq = ANSN,
1317  // T_time = current time + validity time.
1318  TopologyTuple topologyTuple;;
1319  topologyTuple.destAddr = addr;
1320  topologyTuple.lastAddr = msg.GetOriginatorAddress ();
1321  topologyTuple.sequenceNumber = tc.ansn;
1322  topologyTuple.expirationTime = now + msg.GetVTime ();
1323  AddTopologyTuple (topologyTuple);
1324 
1325  // Schedules topology tuple deletion
1328  this,
1329  topologyTuple.destAddr,
1330  topologyTuple.lastAddr));
1331  }
1332  }
1333 
1334 #ifdef NS3_LOG_ENABLE
1335  {
1336  const TopologySet &topology = m_state.GetTopologySet ();
1337  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1338  << "s ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
1339  for (TopologySet::const_iterator tuple = topology.begin ();
1340  tuple != topology.end (); tuple++)
1341  {
1342  NS_LOG_DEBUG (*tuple);
1343  }
1344  NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
1345  }
1346 #endif // NS3_LOG_ENABLE
1347 }
1348 
1358 void
1360  const Ipv4Address &senderIface)
1361 {
1362  const olsr::MessageHeader::Mid &mid = msg.GetMid ();
1363  Time now = Simulator::Now ();
1364 
1365  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
1366  // 1. If the sender interface of this message is not in the symmetric
1367  // 1-hop neighborhood of this node, the message MUST be discarded.
1368  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
1369  if (linkTuple == NULL)
1370  {
1371  NS_LOG_LOGIC ("Node " << m_mainAddress <<
1372  ": the sender interface of this message is not in the "
1373  "symmetric 1-hop neighborhood of this node,"
1374  " the message MUST be discarded.");
1375  return;
1376  }
1377 
1378  // 2. For each interface address listed in the MID message
1379  for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
1380  i != mid.interfaceAddresses.end (); i++)
1381  {
1382  bool updated = false;
1384  for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin ();
1385  tuple != ifaceAssoc.end (); tuple++)
1386  {
1387  if (tuple->ifaceAddr == *i
1388  && tuple->mainAddr == msg.GetOriginatorAddress ())
1389  {
1390  NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple);
1391  tuple->time = now + msg.GetVTime ();
1392  updated = true;
1393  }
1394  }
1395  if (!updated)
1396  {
1397  IfaceAssocTuple tuple;
1398  tuple.ifaceAddr = *i;
1399  tuple.mainAddr = msg.GetOriginatorAddress ();
1400  tuple.time = now + msg.GetVTime ();
1401  AddIfaceAssocTuple (tuple);
1402  NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple);
1403  // Schedules iface association tuple deletion
1404  Simulator::Schedule (DELAY (tuple.time),
1406  }
1407  }
1408 
1409  // 3. (not part of the RFC) iterate over all NeighborTuple's and
1410  // TwoHopNeighborTuples, update the neighbor addresses taking into account
1411  // the new MID information.
1412  NeighborSet &neighbors = m_state.GetNeighbors ();
1413  for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1414  {
1415  neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr);
1416  }
1417 
1418  TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1419  for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin ();
1420  twoHopNeighbor != twoHopNeighbors.end (); twoHopNeighbor++)
1421  {
1422  twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr);
1423  twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr);
1424  }
1425  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
1426 }
1427 
1437 void
1439  const Ipv4Address &senderIface)
1440 {
1441 
1442  const olsr::MessageHeader::Hna &hna = msg.GetHna ();
1443  Time now = Simulator::Now ();
1444 
1445  // 1. If the sender interface of this message is not in the symmetric
1446  // 1-hop neighborhood of this node, the message MUST be discarded.
1447  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1448  if (link_tuple == NULL)
1449  return;
1450 
1451  // 2. Otherwise, for each (network address, netmask) pair in the
1452  // message:
1453 
1454  for (std::vector<olsr::MessageHeader::Hna::Association>::const_iterator it = hna.associations.begin ();
1455  it != hna.associations.end (); it++)
1456  {
1457  AssociationTuple *tuple = m_state.FindAssociationTuple (msg.GetOriginatorAddress (),it->address,it->mask);
1458 
1459  // 2.1 if an entry in the association set already exists, where:
1460  // A_gateway_addr == originator address
1461  // A_network_addr == network address
1462  // A_netmask == netmask
1463  // then the holding time for that tuple MUST be set to:
1464  // A_time = current time + validity time
1465  if(tuple != NULL)
1466  {
1467  tuple->expirationTime = now + msg.GetVTime ();
1468  }
1469 
1470  // 2.2 otherwise, a new tuple MUST be recorded with:
1471  // A_gateway_addr = originator address
1472  // A_network_addr = network address
1473  // A_netmask = netmask
1474  // A_time = current time + validity time
1475  else
1476  {
1477  AssociationTuple assocTuple = {
1478  msg.GetOriginatorAddress (),
1479  it->address,
1480  it->mask,
1481  now + msg.GetVTime ()
1482  };
1483  AddAssociationTuple (assocTuple);
1484 
1485  //Schedule Association Tuple deletion
1488  assocTuple.gatewayAddr,assocTuple.networkAddr,assocTuple.netmask);
1489  }
1490 
1491  }
1492 }
1493 
1505 void
1507  DuplicateTuple *duplicated,
1508  const Ipv4Address &localIface,
1509  const Ipv4Address &senderAddress)
1510 {
1511  Time now = Simulator::Now ();
1512 
1513  // If the sender interface address is not in the symmetric
1514  // 1-hop neighborhood the message must not be forwarded
1515  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
1516  if (linkTuple == NULL)
1517  return;
1518 
1519  // If the message has already been considered for forwarding,
1520  // it must not be retransmitted again
1521  if (duplicated != NULL && duplicated->retransmitted)
1522  {
1523  NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received"
1524  " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
1525  return;
1526  }
1527 
1528  // If the sender interface address is an interface address
1529  // of a MPR selector of this node and ttl is greater than 1,
1530  // the message must be retransmitted
1531  bool retransmitted = false;
1532  if (olsrMessage.GetTimeToLive () > 1)
1533  {
1534  const MprSelectorTuple *mprselTuple =
1535  m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
1536  if (mprselTuple != NULL)
1537  {
1538  olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1);
1539  olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1);
1540  // We have to introduce a random delay to avoid
1541  // synchronization with neighbors.
1542  QueueMessage (olsrMessage, JITTER);
1543  retransmitted = true;
1544  }
1545  }
1546 
1547  // Update duplicate tuple...
1548  if (duplicated != NULL)
1549  {
1550  duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
1551  duplicated->retransmitted = retransmitted;
1552  duplicated->ifaceList.push_back (localIface);
1553  }
1554  // ...or create a new one
1555  else
1556  {
1557  DuplicateTuple newDup;
1558  newDup.address = olsrMessage.GetOriginatorAddress ();
1559  newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber ();
1560  newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
1561  newDup.retransmitted = retransmitted;
1562  newDup.ifaceList.push_back (localIface);
1563  AddDuplicateTuple (newDup);
1564  // Schedule dup tuple deletion
1565  Simulator::Schedule (OLSR_DUP_HOLD_TIME,
1567  newDup.address, newDup.sequenceNumber);
1568  }
1569 }
1570 
1580 void
1582 {
1583  m_queuedMessages.push_back (message);
1584  if (not m_queuedMessagesTimer.IsRunning ())
1585  {
1588  }
1589 }
1590 
1591 void
1593  const MessageList &containedMessages)
1594 {
1595  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet");
1596 
1597  // Add a header
1598  olsr::PacketHeader header;
1599  header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ());
1601  packet->AddHeader (header);
1602 
1603  // Trace it
1604  m_txPacketTrace (header, containedMessages);
1605 
1606  // Send it
1607  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1608  m_socketAddresses.begin (); i != m_socketAddresses.end (); i++)
1609  {
1610  Ipv4Address bcast = i->second.GetLocal ().GetSubnetDirectedBroadcast (i->second.GetMask ());
1611  i->first->SendTo (packet, 0, InetSocketAddress (bcast, OLSR_PORT_NUMBER));
1612  }
1613 }
1614 
1622 void
1624 {
1625  Ptr<Packet> packet = Create<Packet> ();
1626  int numMessages = 0;
1627 
1628  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages");
1629 
1630  MessageList msglist;
1631 
1632  for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin ();
1633  message != m_queuedMessages.end ();
1634  message++)
1635  {
1636  Ptr<Packet> p = Create<Packet> ();
1637  p->AddHeader (*message);
1638  packet->AddAtEnd (p);
1639  msglist.push_back (*message);
1640  if (++numMessages == OLSR_MAX_MSGS)
1641  {
1642  SendPacket (packet, msglist);
1643  msglist.clear ();
1644  // Reset variables for next packet
1645  numMessages = 0;
1646  packet = Create<Packet> ();
1647  }
1648  }
1649 
1650  if (packet->GetSize ())
1651  {
1652  SendPacket (packet, msglist);
1653  }
1654 
1655  m_queuedMessages.clear ();
1656 }
1657 
1661 void
1663 {
1664  NS_LOG_FUNCTION (this);
1665 
1666  olsr::MessageHeader msg;
1667  Time now = Simulator::Now ();
1668 
1671  msg.SetTimeToLive (1);
1672  msg.SetHopCount (0);
1674  olsr::MessageHeader::Hello &hello = msg.GetHello ();
1675 
1676  hello.SetHTime (m_helloInterval);
1677  hello.willingness = m_willingness;
1678 
1679  std::vector<olsr::MessageHeader::Hello::LinkMessage>
1680  &linkMessages = hello.linkMessages;
1681 
1682  const LinkSet &links = m_state.GetLinks ();
1683  for (LinkSet::const_iterator link_tuple = links.begin ();
1684  link_tuple != links.end (); link_tuple++)
1685  {
1686  if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress
1687  && link_tuple->time >= now))
1688  {
1689  continue;
1690  }
1691 
1692  uint8_t link_type, nb_type = 0xff;
1693 
1694  // Establishes link type
1695  if (link_tuple->symTime >= now)
1696  {
1697  link_type = OLSR_SYM_LINK;
1698  }
1699  else if (link_tuple->asymTime >= now)
1700  {
1701  link_type = OLSR_ASYM_LINK;
1702  }
1703  else
1704  {
1705  link_type = OLSR_LOST_LINK;
1706  }
1707  // Establishes neighbor type.
1708  if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
1709  {
1710  nb_type = OLSR_MPR_NEIGH;
1711  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1712  << " to be MPR_NEIGH.");
1713  }
1714  else
1715  {
1716  bool ok = false;
1717  for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin ();
1718  nb_tuple != m_state.GetNeighbors ().end ();
1719  nb_tuple++)
1720  {
1721  if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr))
1722  {
1723  if (nb_tuple->status == NeighborTuple::STATUS_SYM)
1724  {
1725  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1726  << " to be SYM_NEIGH.");
1727  nb_type = OLSR_SYM_NEIGH;
1728  }
1729  else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
1730  {
1731  nb_type = OLSR_NOT_NEIGH;
1732  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1733  << " to be NOT_NEIGH.");
1734  }
1735  else
1736  {
1737  NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n");
1738  }
1739  ok = true;
1740  break;
1741  }
1742  }
1743  if (!ok)
1744  {
1745  NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
1746  continue;
1747  }
1748  }
1749 
1751  linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f);
1752  linkMessage.neighborInterfaceAddresses.push_back
1753  (link_tuple->neighborIfaceAddr);
1754 
1755  std::vector<Ipv4Address> interfaces =
1756  m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr);
1757 
1758  linkMessage.neighborInterfaceAddresses.insert
1759  (linkMessage.neighborInterfaceAddresses.end (),
1760  interfaces.begin (), interfaces.end ());
1761 
1762  linkMessages.push_back (linkMessage);
1763  }
1764  NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ())
1765  << " (with " << int (linkMessages.size ()) << " link messages)");
1766  QueueMessage (msg, JITTER);
1767 }
1768 
1772 void
1774 {
1775  NS_LOG_FUNCTION (this);
1776 
1777  olsr::MessageHeader msg;
1778 
1781  msg.SetTimeToLive (255);
1782  msg.SetHopCount (0);
1784 
1785  olsr::MessageHeader::Tc &tc = msg.GetTc ();
1786  tc.ansn = m_ansn;
1787 
1788  for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin ();
1789  mprsel_tuple != m_state.GetMprSelectors ().end (); mprsel_tuple++)
1790  {
1791  tc.neighborAddresses.push_back (mprsel_tuple->mainAddr);
1792  }
1793  QueueMessage (msg, JITTER);
1794 }
1795 
1799 void
1801 {
1802  olsr::MessageHeader msg;
1803  olsr::MessageHeader::Mid &mid = msg.GetMid ();
1804 
1805  // A node which has only a single interface address participating in
1806  // the MANET (i.e., running OLSR), MUST NOT generate any MID
1807  // message.
1808 
1809  // A node with several interfaces, where only one is participating
1810  // in the MANET and running OLSR (e.g., a node is connected to a
1811  // wired network as well as to a MANET) MUST NOT generate any MID
1812  // messages.
1813 
1814  // A node with several interfaces, where more than one is
1815  // participating in the MANET and running OLSR MUST generate MID
1816  // messages as specified.
1817 
1818  // [ Note: assuming here that all interfaces participate in the
1819  // MANET; later we may want to make this configurable. ]
1820 
1821  Ipv4Address loopback ("127.0.0.1");
1822  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
1823  {
1824  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
1825  if (addr != m_mainAddress && addr != loopback && m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
1826  mid.interfaceAddresses.push_back (addr);
1827  }
1828  if (mid.interfaceAddresses.size () == 0)
1829  return;
1830 
1833  msg.SetTimeToLive (255);
1834  msg.SetHopCount (0);
1836 
1837  QueueMessage (msg, JITTER);
1838 }
1839 
1843 void
1845 {
1846 
1847  olsr::MessageHeader msg;
1848 
1851  msg.SetTimeToLive (255);
1852  msg.SetHopCount (0);
1854  olsr::MessageHeader::Hna &hna = msg.GetHna ();
1855 
1856  std::vector<olsr::MessageHeader::Hna::Association> &associations = hna.associations;
1857 
1858  // Add all local HNA associations to the HNA message
1859  const Associations &localHnaAssociations = m_state.GetAssociations ();
1860  for (Associations::const_iterator it = localHnaAssociations.begin ();
1861  it != localHnaAssociations.end (); it++)
1862  {
1863  olsr::MessageHeader::Hna::Association assoc = { it->networkAddr, it->netmask};
1864  associations.push_back (assoc);
1865  }
1866  // If there is no HNA associations to send, return without queuing the message
1867  if (associations.size () == 0)
1868  {
1869  return;
1870  }
1871 
1872  // Else, queue the message to be sent later on
1873  QueueMessage (msg, JITTER);
1874 }
1875 
1881 void
1883 {
1884  // Check if the (networkAddr, netmask) tuple already exist
1885  // in the list of local HNA associations
1886  const Associations &localHnaAssociations = m_state.GetAssociations ();
1887  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1888  assocIterator != localHnaAssociations.end (); assocIterator++)
1889  {
1890  Association const &localHnaAssoc = *assocIterator;
1891  if (localHnaAssoc.networkAddr == networkAddr && localHnaAssoc.netmask == netmask)
1892  {
1893  NS_LOG_INFO ("HNA association for network " << networkAddr << "/" << netmask << " already exists.");
1894  return;
1895  }
1896  }
1897  // If the tuple does not already exist, add it to the list of local HNA associations.
1898  NS_LOG_INFO ("Adding HNA association for network " << networkAddr << "/" << netmask << ".");
1899  m_state.InsertAssociation ( (Association) { networkAddr, netmask} );
1900 }
1901 
1907 void
1909 {
1910  NS_LOG_INFO ("Removing HNA association for network " << networkAddr << "/" << netmask << ".");
1911  m_state.EraseAssociation ( (Association) { networkAddr, netmask} );
1912 }
1913 
1924 void
1926 {
1927  // If a routing table has already been associated, remove
1928  // corresponding entries from the list of local HNA associations
1929  if (m_routingTableAssociation != 0)
1930  {
1931  NS_LOG_INFO ("Removing HNA entries coming from the old routing table association.");
1932  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1933  {
1934  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1935  // If the outgoing interface for this route is a non-olsr interface
1936  if (UsesNonOlsrOutgoingInterface (route))
1937  {
1938  // remove the corresponding entry
1940  }
1941  }
1942  }
1943 
1944  // Sets the routingTableAssociation to its new value
1945  m_routingTableAssociation = routingTable;
1946 
1947  // Iterate over entries of the associated routing table and
1948  // add the routes using non-olsr outgoing interfaces to the list
1949  // of local HNA associations
1950  NS_LOG_DEBUG ("Nb local associations before adding some entries from"
1951  " the associated routing table: " << m_state.GetAssociations ().size ());
1952  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1953  {
1954  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1955  Ipv4Address destNetworkAddress = route.GetDestNetwork ();
1956  Ipv4Mask destNetmask = route.GetDestNetworkMask ();
1957 
1958  // If the outgoing interface for this route is a non-olsr interface,
1959  if (UsesNonOlsrOutgoingInterface (route))
1960  {
1961  // Add this entry's network address and netmask to the list of local HNA entries
1962  AddHostNetworkAssociation (destNetworkAddress, destNetmask);
1963  }
1964  }
1965  NS_LOG_DEBUG ("Nb local associations after having added some entries from "
1966  "the associated routing table: " << m_state.GetAssociations ().size ());
1967 }
1968 
1974 bool
1976 {
1977  std::set<uint32_t>::const_iterator ci = m_interfaceExclusions.find (route.GetInterface ());
1978  // The outgoing interface is a non-OLSR interface if a match is found
1979  // before reaching the end of the list of excluded interfaces
1980  return ci != m_interfaceExclusions.end ();
1981 }
1982 
1986 void
1988  const olsr::MessageHeader::Hello &hello,
1989  const Ipv4Address &receiverIface,
1990  const Ipv4Address &senderIface)
1991 {
1992  Time now = Simulator::Now ();
1993  bool updated = false;
1994  bool created = false;
1995  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
1996  << ": LinkSensing(receiverIface=" << receiverIface
1997  << ", senderIface=" << senderIface << ") BEGIN");
1998 
1999  NS_ASSERT (msg.GetVTime () > Seconds (0));
2000  LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
2001  if (link_tuple == NULL)
2002  {
2003  LinkTuple newLinkTuple;
2004  // We have to create a new tuple
2005  newLinkTuple.neighborIfaceAddr = senderIface;
2006  newLinkTuple.localIfaceAddr = receiverIface;
2007  newLinkTuple.symTime = now - Seconds (1);
2008  newLinkTuple.time = now + msg.GetVTime ();
2009  link_tuple = &m_state.InsertLinkTuple (newLinkTuple);
2010  created = true;
2011  NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one");
2012  }
2013  else
2014  {
2015  NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
2016  updated = true;
2017  }
2018 
2019  link_tuple->asymTime = now + msg.GetVTime ();
2020  for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
2021  hello.linkMessages.begin ();
2022  linkMessage != hello.linkMessages.end ();
2023  linkMessage++)
2024  {
2025  int lt = linkMessage->linkCode & 0x03; // Link Type
2026  int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type
2027 
2028 #ifdef NS3_LOG_ENABLE
2029  const char *linkTypeName;
2030  switch (lt)
2031  {
2032  case OLSR_UNSPEC_LINK: linkTypeName = "UNSPEC_LINK"; break;
2033  case OLSR_ASYM_LINK: linkTypeName = "ASYM_LINK"; break;
2034  case OLSR_SYM_LINK: linkTypeName = "SYM_LINK"; break;
2035  case OLSR_LOST_LINK: linkTypeName = "LOST_LINK"; break;
2036  /* no default, since lt must be in 0..3, covered above
2037  default: linkTypeName = "(invalid value!)";
2038  */
2039  }
2040 
2041  const char *neighborTypeName;
2042  switch (nt)
2043  {
2044  case OLSR_NOT_NEIGH: neighborTypeName = "NOT_NEIGH"; break;
2045  case OLSR_SYM_NEIGH: neighborTypeName = "SYM_NEIGH"; break;
2046  case OLSR_MPR_NEIGH: neighborTypeName = "MPR_NEIGH"; break;
2047  default: neighborTypeName = "(invalid value!)";
2048  }
2049 
2050  NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type "
2051  << lt << " (" << linkTypeName
2052  << ") and Neighbor Type " << nt
2053  << " (" << neighborTypeName << ")");
2054 #endif // NS3_LOG_ENABLE
2055 
2056  // We must not process invalid advertised links
2057  if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) ||
2058  (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH
2059  && nt != OLSR_NOT_NEIGH))
2060  {
2061  NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING");
2062  continue;
2063  }
2064 
2065  for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr =
2066  linkMessage->neighborInterfaceAddresses.begin ();
2067  neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end ();
2068  neighIfaceAddr++)
2069  {
2070  NS_LOG_DEBUG (" -> Neighbor: " << *neighIfaceAddr);
2071  if (*neighIfaceAddr == receiverIface)
2072  {
2073  if (lt == OLSR_LOST_LINK)
2074  {
2075  NS_LOG_LOGIC ("link is LOST => expiring it");
2076  link_tuple->symTime = now - Seconds (1);
2077  updated = true;
2078  }
2079  else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK)
2080  {
2081  NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now"
2082  " (symTime being increased to " << now + msg.GetVTime ());
2083  link_tuple->symTime = now + msg.GetVTime ();
2084  link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
2085  updated = true;
2086  }
2087  else
2088  {
2089  NS_FATAL_ERROR ("bad link type");
2090  }
2091  break;
2092  }
2093  else
2094  {
2095  NS_LOG_DEBUG (" \\-> *neighIfaceAddr (" << *neighIfaceAddr
2096  << " != receiverIface (" << receiverIface << ") => IGNORING!");
2097  }
2098  }
2099  NS_LOG_DEBUG ("Link tuple updated: " << int (updated));
2100  }
2101  link_tuple->time = std::max (link_tuple->time, link_tuple->asymTime);
2102 
2103  if (updated)
2104  {
2105  LinkTupleUpdated (*link_tuple, hello.willingness);
2106  }
2107 
2108  // Schedules link tuple deletion
2109  if (created)
2110  {
2111  LinkTupleAdded (*link_tuple, hello.willingness);
2112  m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
2114  link_tuple->neighborIfaceAddr));
2115  }
2116  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
2117  << ": LinkSensing END");
2118 }
2119 
2123 void
2125  const olsr::MessageHeader::Hello &hello)
2126 {
2128  if (nb_tuple != NULL)
2129  {
2130  nb_tuple->willingness = hello.willingness;
2131  }
2132 }
2133 
2134 
2138 void
2140  const olsr::MessageHeader::Hello &hello)
2141 {
2142  Time now = Simulator::Now ();
2143 
2144  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
2145 
2146  for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
2147  link_tuple != m_state.GetLinks ().end (); link_tuple++)
2148  {
2149  NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple);
2150  if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ())
2151  {
2152  NS_LOG_LOGIC ("Link tuple ignored: "
2153  "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
2154  NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): "
2155  << GetMainAddress (link_tuple->neighborIfaceAddr)
2156  << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ());
2157  continue;
2158  }
2159 
2160  if (link_tuple->symTime < now)
2161  {
2162  NS_LOG_LOGIC ("Link tuple ignored: expired.");
2163  continue;
2164  }
2165 
2166  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2167  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2168  linkMessage != hello.linkMessages.end (); linkMessage++)
2169  {
2170  int neighborType = (linkMessage->linkCode >> 2) & 0x3;
2171 #ifdef NS3_LOG_ENABLE
2172  const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" };
2173  const char *neighborTypeName = ((neighborType < 3) ?
2174  neighborTypeNames[neighborType]
2175  : "(invalid value)");
2176  NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType="
2177  << neighborType << " (" << neighborTypeName << ")");
2178 #endif // NS3_LOG_ENABLE
2179 
2180  for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter =
2181  linkMessage->neighborInterfaceAddresses.begin ();
2182  nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end ();
2183  nb2hop_addr_iter++)
2184  {
2185  Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter);
2186  NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: "
2187  << *nb2hop_addr_iter
2188  << " (main address is " << nb2hop_addr << ")");
2189  if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH)
2190  {
2191  // If the main address of the 2-hop neighbor address == main address
2192  // of the receiving node, silently discard the 2-hop
2193  // neighbor address.
2194  if (nb2hop_addr == m_mainAddress)
2195  {
2196  NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)");
2197  continue;
2198  }
2199 
2200  // Otherwise, a 2-hop tuple is created
2201  TwoHopNeighborTuple *nb2hop_tuple =
2203  NS_LOG_LOGIC ("Adding the 2-hop neighbor"
2204  << (nb2hop_tuple ? " (refreshing existing entry)" : ""));
2205  if (nb2hop_tuple == NULL)
2206  {
2207  TwoHopNeighborTuple new_nb2hop_tuple;
2208  new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress ();
2209  new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
2210  new_nb2hop_tuple.expirationTime = now + msg.GetVTime ();
2211  AddTwoHopNeighborTuple (new_nb2hop_tuple);
2212  // Schedules nb2hop tuple deletion
2213  m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime),
2215  new_nb2hop_tuple.neighborMainAddr,
2216  new_nb2hop_tuple.twoHopNeighborAddr));
2217  }
2218  else
2219  {
2220  nb2hop_tuple->expirationTime = now + msg.GetVTime ();
2221  }
2222  }
2223  else if (neighborType == OLSR_NOT_NEIGH)
2224  {
2225  // For each 2-hop node listed in the HELLO message
2226  // with Neighbor Type equal to NOT_NEIGH all 2-hop
2227  // tuples where: N_neighbor_main_addr == Originator
2228  // Address AND N_2hop_addr == main address of the
2229  // 2-hop neighbor are deleted.
2230  NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
2232  }
2233  else
2234  {
2235  NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad"
2236  " neighbor type value: " << neighborType);
2237  }
2238  }
2239  }
2240  }
2241 
2242  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
2243 }
2244 
2245 
2246 
2250 void
2252  const olsr::MessageHeader::Hello &hello)
2253 {
2254  NS_LOG_FUNCTION (this);
2255 
2256  Time now = Simulator::Now ();
2257 
2258  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2259  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2260  linkMessage != hello.linkMessages.end ();
2261  linkMessage++)
2262  {
2263  int nt = linkMessage->linkCode >> 2;
2264  if (nt == OLSR_MPR_NEIGH)
2265  {
2266  NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
2267 
2268  for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
2269  linkMessage->neighborInterfaceAddresses.begin ();
2270  nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
2271  nb_iface_addr++)
2272  {
2273  if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
2274  {
2275  NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
2276 
2277  // We must create a new entry into the mpr selector set
2278  MprSelectorTuple *existing_mprsel_tuple =
2280  if (existing_mprsel_tuple == NULL)
2281  {
2282  MprSelectorTuple mprsel_tuple;
2283 
2284  mprsel_tuple.mainAddr = msg.GetOriginatorAddress ();
2285  mprsel_tuple.expirationTime = now + msg.GetVTime ();
2286  AddMprSelectorTuple (mprsel_tuple);
2287 
2288  // Schedules mpr selector tuple deletion
2290  (DELAY (mprsel_tuple.expirationTime),
2292  mprsel_tuple.mainAddr));
2293  }
2294  else
2295  {
2296  existing_mprsel_tuple->expirationTime = now + msg.GetVTime ();
2297  }
2298  }
2299  }
2300  }
2301  }
2302  NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
2303 }
2304 
2305 
2306 #if 0
2307 void
2315 OLSR::mac_failed (Ptr<Packet> p) {
2316  double now = Simulator::Now ();
2317  struct hdr_ip* ih = HDR_IP (p);
2318  struct hdr_cmn* ch = HDR_CMN (p);
2319 
2320  debug ("%f: Node %d MAC Layer detects a breakage on link to %d\n",
2321  now,
2322  OLSR::node_id (ra_addr ()),
2323  OLSR::node_id (ch->next_hop ()));
2324 
2325  if ((u_int32_t)ih->daddr () == IP_BROADCAST) {
2326  drop (p, DROP_RTR_MAC_CALLBACK);
2327  return;
2328  }
2329 
2330  OLSR_link_tuple* link_tuple = state_.find_link_tuple (ch->next_hop ());
2331  if (link_tuple != NULL) {
2332  link_tuple->lost_time () = now + OLSR_NEIGHB_HOLD_TIME;
2333  link_tuple->time () = now + OLSR_NEIGHB_HOLD_TIME;
2334  nb_loss (link_tuple);
2335  }
2336  drop (p, DROP_RTR_MAC_CALLBACK);
2337 }
2338 #endif
2339 
2340 
2341 
2342 
2350 void
2352 {
2353  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2354  << "s: OLSR Node " << m_mainAddress
2355  << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
2359 
2360  MprComputation ();
2362 }
2363 
2369 void
2371 {
2372  /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
2373  Simulator::Now (),
2374  OLSR::node_id(ra_addr()),
2375  OLSR::node_id(tuple->addr()),
2376  tuple->seq_num());*/
2377  m_state.InsertDuplicateTuple (tuple);
2378 }
2379 
2385 void
2387 {
2388  /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
2389  Simulator::Now (),
2390  OLSR::node_id(ra_addr()),
2391  OLSR::node_id(tuple->addr()),
2392  tuple->seq_num());*/
2393  m_state.EraseDuplicateTuple (tuple);
2394 }
2395 
2396 void
2397 RoutingProtocol::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness)
2398 {
2399  // Creates associated neighbor tuple
2400  NeighborTuple nb_tuple;
2402  nb_tuple.willingness = willingness;
2403 
2404  if (tuple.symTime >= Simulator::Now ())
2405  {
2406  nb_tuple.status = NeighborTuple::STATUS_SYM;
2407  }
2408  else
2409  {
2411  }
2412 
2413  AddNeighborTuple (nb_tuple);
2414 }
2415 
2421 void
2423 {
2424  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2425  << "s: OLSR Node " << m_mainAddress
2426  << " LinkTuple " << tuple << " REMOVED.");
2427 
2428  m_state.EraseLinkTuple (tuple);
2430 
2431 }
2432 
2439 void
2440 RoutingProtocol::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
2441 {
2442  // Each time a link tuple changes, the associated neighbor tuple must be recomputed
2443 
2444  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2445  << "s: OLSR Node " << m_mainAddress
2446  << " LinkTuple " << tuple << " UPDATED.");
2447 
2448  NeighborTuple *nb_tuple =
2450 
2451  if (nb_tuple == NULL)
2452  {
2453  LinkTupleAdded (tuple, willingness);
2455  }
2456 
2457  if (nb_tuple != NULL)
2458  {
2459 #ifdef NS3_LOG_ENABLE
2460  int statusBefore = nb_tuple->status;
2461 #endif // NS3_LOG_ENABLE
2462 
2463  bool hasSymmetricLink = false;
2464 
2465  const LinkSet &linkSet = m_state.GetLinks ();
2466  for (LinkSet::const_iterator it = linkSet.begin ();
2467  it != linkSet.end (); it++)
2468  {
2469  const LinkTuple &link_tuple = *it;
2470  if (GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple->neighborMainAddr
2471  && link_tuple.symTime >= Simulator::Now ())
2472  {
2473  hasSymmetricLink = true;
2474  break;
2475  }
2476  }
2477 
2478  if (hasSymmetricLink)
2479  {
2480  nb_tuple->status = NeighborTuple::STATUS_SYM;
2481  NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_SYM; changed:"
2482  << int (statusBefore != nb_tuple->status));
2483  }
2484  else
2485  {
2487  NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_NOT_SYM; changed:"
2488  << int (statusBefore != nb_tuple->status));
2489  }
2490  }
2491  else
2492  {
2493  NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!");
2494  }
2495 }
2496 
2502 void
2504 {
2505 // debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n",
2506 // Simulator::Now (),
2507 // OLSR::node_id(ra_addr()),
2508 // OLSR::node_id(tuple->neighborMainAddr),
2509 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2510 
2511  m_state.InsertNeighborTuple (tuple);
2512  IncrementAnsn ();
2513 }
2514 
2520 void
2522 {
2523 // debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n",
2524 // Simulator::Now (),
2525 // OLSR::node_id(ra_addr()),
2526 // OLSR::node_id(tuple->neighborMainAddr),
2527 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2528 
2529  m_state.EraseNeighborTuple (tuple);
2530  IncrementAnsn ();
2531 }
2532 
2538 void
2540 {
2541 // debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2542 // Simulator::Now (),
2543 // OLSR::node_id(ra_addr()),
2544 // OLSR::node_id(tuple->neighborMainAddr),
2545 // OLSR::node_id(tuple->twoHopNeighborAddr));
2546 
2548 }
2549 
2555 void
2557 {
2558 // debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2559 // Simulator::Now (),
2560 // OLSR::node_id(ra_addr()),
2561 // OLSR::node_id(tuple->neighborMainAddr),
2562 // OLSR::node_id(tuple->twoHopNeighborAddr));
2563 
2565 }
2566 
2567 void
2569 {
2570  m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1);
2571 }
2572 
2580 void
2582 {
2583 // debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n",
2584 // Simulator::Now (),
2585 // OLSR::node_id(ra_addr()),
2586 // OLSR::node_id(tuple->main_addr()));
2587 
2589  IncrementAnsn ();
2590 }
2591 
2599 void
2601 {
2602 // debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n",
2603 // Simulator::Now (),
2604 // OLSR::node_id(ra_addr()),
2605 // OLSR::node_id(tuple->main_addr()));
2606 
2608  IncrementAnsn ();
2609 }
2610 
2616 void
2618 {
2619 // debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2620 // Simulator::Now (),
2621 // OLSR::node_id(ra_addr()),
2622 // OLSR::node_id(tuple->dest_addr()),
2623 // OLSR::node_id(tuple->last_addr()),
2624 // tuple->seq());
2625 
2626  m_state.InsertTopologyTuple (tuple);
2627 }
2628 
2634 void
2636 {
2637 // debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2638 // Simulator::Now (),
2639 // OLSR::node_id(ra_addr()),
2640 // OLSR::node_id(tuple->dest_addr()),
2641 // OLSR::node_id(tuple->last_addr()),
2642 // tuple->seq());
2643 
2644  m_state.EraseTopologyTuple (tuple);
2645 }
2646 
2652 void
2654 {
2655 // debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n",
2656 // Simulator::Now (),
2657 // OLSR::node_id(ra_addr()),
2658 // OLSR::node_id(tuple->main_addr()),
2659 // OLSR::node_id(tuple->iface_addr()));
2660 
2662 }
2663 
2669 void
2671 {
2672 // debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n",
2673 // Simulator::Now (),
2674 // OLSR::node_id(ra_addr()),
2675 // OLSR::node_id(tuple->main_addr()),
2676 // OLSR::node_id(tuple->iface_addr()));
2677 
2678  m_state.EraseIfaceAssocTuple (tuple);
2679 }
2680 
2686 void
2688 {
2690 }
2691 
2697 void
2699 {
2701 }
2702 
2703 
2704 
2706 {
2708  return m_packetSequenceNumber;
2709 }
2710 
2713 {
2715  return m_messageSequenceNumber;
2716 }
2717 
2718 
2723 void
2725 {
2726  SendHello ();
2728 }
2729 
2734 void
2736 {
2737  if (m_state.GetMprSelectors ().size () > 0)
2738  {
2739  SendTc ();
2740  }
2741  else
2742  {
2743  NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR.");
2744  }
2746 }
2747 
2752 void
2754 {
2755  SendMid ();
2757 }
2758 
2762 void
2764 {
2765  if (m_state.GetAssociations ().size () > 0)
2766  {
2767  SendHna ();
2768  }
2769  else
2770  {
2771  NS_LOG_DEBUG ("Not sending any HNA, no associations to advertise.");
2772  }
2774 }
2775 
2783 void
2785 {
2786  DuplicateTuple *tuple =
2787  m_state.FindDuplicateTuple (address, sequenceNumber);
2788  if (tuple == NULL)
2789  {
2790  return;
2791  }
2792  if (tuple->expirationTime < Simulator::Now ())
2793  {
2794  RemoveDuplicateTuple (*tuple);
2795  }
2796  else
2797  {
2800  address, sequenceNumber));
2801  }
2802 }
2803 
2815 void
2817 {
2818  Time now = Simulator::Now ();
2819 
2820  // the tuple parameter may be a stale copy; get a newer version from m_state
2821  LinkTuple *tuple = m_state.FindLinkTuple (neighborIfaceAddr);
2822  if (tuple == NULL)
2823  {
2824  return;
2825  }
2826  if (tuple->time < now)
2827  {
2828  RemoveLinkTuple (*tuple);
2829  }
2830  else if (tuple->symTime < now)
2831  {
2833  m_linkTupleTimerFirstTime = false;
2834  else
2835  NeighborLoss (*tuple);
2836 
2839  neighborIfaceAddr));
2840  }
2841  else
2842  {
2843  m_events.Track (Simulator::Schedule (DELAY (std::min (tuple->time, tuple->symTime)),
2845  neighborIfaceAddr));
2846  }
2847 }
2848 
2856 void
2858 {
2859  TwoHopNeighborTuple *tuple;
2860  tuple = m_state.FindTwoHopNeighborTuple (neighborMainAddr, twoHopNeighborAddr);
2861  if (tuple == NULL)
2862  {
2863  return;
2864  }
2865  if (tuple->expirationTime < Simulator::Now ())
2866  {
2867  RemoveTwoHopNeighborTuple (*tuple);
2868  }
2869  else
2870  {
2873  this, neighborMainAddr, twoHopNeighborAddr));
2874  }
2875 }
2876 
2884 void
2886 {
2887  MprSelectorTuple *tuple = m_state.FindMprSelectorTuple (mainAddr);
2888  if (tuple == NULL)
2889  {
2890  return;
2891  }
2892  if (tuple->expirationTime < Simulator::Now ())
2893  {
2894  RemoveMprSelectorTuple (*tuple);
2895  }
2896  else
2897  {
2900  this, mainAddr));
2901  }
2902 }
2903 
2911 void
2913 {
2914  TopologyTuple *tuple = m_state.FindTopologyTuple (destAddr, lastAddr);
2915  if (tuple == NULL)
2916  {
2917  return;
2918  }
2919  if (tuple->expirationTime < Simulator::Now ())
2920  {
2921  RemoveTopologyTuple (*tuple);
2922  }
2923  else
2924  {
2927  this, tuple->destAddr, tuple->lastAddr));
2928  }
2929 }
2930 
2935 void
2937 {
2938  IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (ifaceAddr);
2939  if (tuple == NULL)
2940  {
2941  return;
2942  }
2943  if (tuple->time < Simulator::Now ())
2944  {
2945  RemoveIfaceAssocTuple (*tuple);
2946  }
2947  else
2948  {
2951  this, ifaceAddr));
2952  }
2953 }
2954 
2958 void
2960 {
2961  AssociationTuple *tuple = m_state.FindAssociationTuple (gatewayAddr, networkAddr, netmask);
2962  if (tuple == NULL)
2963  {
2964  return;
2965  }
2966  if (tuple->expirationTime < Simulator::Now ())
2967  {
2968  RemoveAssociationTuple (*tuple);
2969  }
2970  else
2971  {
2974  this, gatewayAddr, networkAddr, netmask));
2975  }
2976 }
2977 
2981 void
2983 {
2985  m_table.clear ();
2986 }
2987 
2992 void
2994 {
2995  m_table.erase (dest);
2996 }
2997 
3004 bool
3006  RoutingTableEntry &outEntry) const
3007 {
3008  // Get the iterator at "dest" position
3009  std::map<Ipv4Address, RoutingTableEntry>::const_iterator it =
3010  m_table.find (dest);
3011  // If there is no route to "dest", return NULL
3012  if (it == m_table.end ())
3013  return false;
3014  outEntry = it->second;
3015  return true;
3016 }
3017 
3034 bool
3036  RoutingTableEntry &outEntry) const
3037 {
3038  outEntry = entry;
3039  while (outEntry.destAddr != outEntry.nextAddr)
3040  {
3041  if (not Lookup (outEntry.nextAddr, outEntry))
3042  return false;
3043  }
3044  return true;
3045 }
3046 
3049 {
3050  NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination () << " " << oif);
3051  Ptr<Ipv4Route> rtentry;
3052  RoutingTableEntry entry1, entry2;
3053  bool found = false;
3054 
3055  if (Lookup (header.GetDestination (), entry1) != 0)
3056  {
3057  bool foundSendEntry = FindSendEntry (entry1, entry2);
3058  if (!foundSendEntry)
3059  {
3060  NS_FATAL_ERROR ("FindSendEntry failure");
3061  }
3062  uint32_t interfaceIdx = entry2.interface;
3063  if (oif && m_ipv4->GetInterfaceForDevice (oif) != static_cast<int> (interfaceIdx))
3064  {
3065  // We do not attempt to perform a constrained routing search
3066  // if the caller specifies the oif; we just enforce that
3067  // that the found route matches the requested outbound interface
3068  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3069  << ": RouteOutput for dest=" << header.GetDestination ()
3070  << " Route interface " << interfaceIdx
3071  << " does not match requested output interface "
3072  << m_ipv4->GetInterfaceForDevice (oif));
3073  sockerr = Socket::ERROR_NOROUTETOHOST;
3074  return rtentry;
3075  }
3076  rtentry = Create<Ipv4Route> ();
3077  rtentry->SetDestination (header.GetDestination ());
3078  // the source address is the interface address that matches
3079  // the destination address (when multiple are present on the
3080  // outgoing interface, one is selected via scoping rules)
3081  NS_ASSERT (m_ipv4);
3082  uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
3083  NS_ASSERT (numOifAddresses > 0);
3084  Ipv4InterfaceAddress ifAddr;
3085  if (numOifAddresses == 1) {
3086  ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
3087  } else {
3089  NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and OLSR");
3090  }
3091  rtentry->SetSource (ifAddr.GetLocal ());
3092  rtentry->SetGateway (entry2.nextAddr);
3093  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
3094  sockerr = Socket::ERROR_NOTERROR;
3095  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3096  << ": RouteOutput for dest=" << header.GetDestination ()
3097  << " --> nextHop=" << entry2.nextAddr
3098  << " interface=" << entry2.interface);
3099  NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
3100  found = true;
3101  }
3102  else
3103  {
3104  rtentry = m_hnaRoutingTable->RouteOutput (p, header, oif, sockerr);
3105 
3106  if (rtentry)
3107  {
3108  found = true;
3109  NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
3110  }
3111  }
3112 
3113  if (!found)
3114  {
3115  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3116  << ": RouteOutput for dest=" << header.GetDestination ()
3117  << " No route to host");
3118  sockerr = Socket::ERROR_NOROUTETOHOST;
3119  }
3120  return rtentry;
3121 }
3122 
3124  const Ipv4Header &header, Ptr<const NetDevice> idev,
3127 {
3128  NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination ());
3129 
3130  Ipv4Address dst = header.GetDestination ();
3131  Ipv4Address origin = header.GetSource ();
3132 
3133  // Consume self-originated packets
3134  if (IsMyOwnAddress (origin) == true)
3135  {
3136  return true;
3137  }
3138 
3139  // Local delivery
3140  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
3141  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
3142  if (m_ipv4->IsDestinationAddress (dst, iif))
3143  {
3144  if (!lcb.IsNull ())
3145  {
3146  NS_LOG_LOGIC ("Local delivery to " << dst);
3147  lcb (p, header, iif);
3148  return true;
3149  }
3150  else
3151  {
3152  // The local delivery callback is null. This may be a multicast
3153  // or broadcast packet, so return false so that another
3154  // multicast routing protocol can handle it. It should be possible
3155  // to extend this to explicitly check whether it is a unicast
3156  // packet, and invoke the error callback if so
3157  return false;
3158  }
3159  }
3160 
3161  // Forwarding
3162  Ptr<Ipv4Route> rtentry;
3163  RoutingTableEntry entry1, entry2;
3164  if (Lookup (header.GetDestination (), entry1))
3165  {
3166  bool foundSendEntry = FindSendEntry (entry1, entry2);
3167  if (!foundSendEntry)
3168  NS_FATAL_ERROR ("FindSendEntry failure");
3169  rtentry = Create<Ipv4Route> ();
3170  rtentry->SetDestination (header.GetDestination ());
3171  uint32_t interfaceIdx = entry2.interface;
3172  // the source address is the interface address that matches
3173  // the destination address (when multiple are present on the
3174  // outgoing interface, one is selected via scoping rules)
3175  NS_ASSERT (m_ipv4);
3176  uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
3177  NS_ASSERT (numOifAddresses > 0);
3178  Ipv4InterfaceAddress ifAddr;
3179  if (numOifAddresses == 1) {
3180  ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
3181  } else {
3183  NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and OLSR");
3184  }
3185  rtentry->SetSource (ifAddr.GetLocal ());
3186  rtentry->SetGateway (entry2.nextAddr);
3187  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
3188 
3189  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3190  << ": RouteInput for dest=" << header.GetDestination ()
3191  << " --> nextHop=" << entry2.nextAddr
3192  << " interface=" << entry2.interface);
3193 
3194  ucb (rtentry, p, header);
3195  return true;
3196  }
3197  else
3198  {
3199  if(m_hnaRoutingTable->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
3200  {
3201  return true;
3202  }
3203  else
3204  {
3205 
3206 #ifdef NS3_LOG_ENABLE
3207  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3208  << ": RouteInput for dest=" << header.GetDestination ()
3209  << " --> NOT FOUND; ** Dumping routing table...");
3210 
3211  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3212  iter != m_table.end (); iter++)
3213  {
3214  NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
3215  << " via interface " << iter->second.interface);
3216  }
3217 
3218  NS_LOG_DEBUG ("** Routing table dump end.");
3219 #endif // NS3_LOG_ENABLE
3220 
3221  return false;
3222  }
3223  }
3224 }
3225 void
3227 {}
3228 void
3230 {}
3231 void
3233 {}
3234 void
3236 {}
3237 
3238 
3249 void
3251  Ipv4Address const &next,
3252  uint32_t interface,
3253  uint32_t distance)
3254 {
3255  NS_LOG_FUNCTION (this << dest << next << interface << distance << m_mainAddress);
3256 
3257  NS_ASSERT (distance > 0);
3258 
3259  // Creates a new rt entry with specified values
3260  RoutingTableEntry &entry = m_table[dest];
3261 
3262  entry.destAddr = dest;
3263  entry.nextAddr = next;
3264  entry.interface = interface;
3265  entry.distance = distance;
3266 }
3267 
3268 void
3270  Ipv4Address const &next,
3271  Ipv4Address const &interfaceAddress,
3272  uint32_t distance)
3273 {
3274  NS_LOG_FUNCTION (this << dest << next << interfaceAddress << distance << m_mainAddress);
3275 
3276  NS_ASSERT (distance > 0);
3277  NS_ASSERT (m_ipv4);
3278 
3279  RoutingTableEntry entry;
3280  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
3281  {
3282  for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
3283  {
3284  if (m_ipv4->GetAddress (i,j).GetLocal () == interfaceAddress)
3285  {
3286  AddEntry (dest, next, i, distance);
3287  return;
3288  }
3289  }
3290  }
3291  NS_ASSERT (false); // should not be reached
3292  AddEntry (dest, next, 0, distance);
3293 }
3294 
3295 
3296 std::vector<RoutingTableEntry>
3298 {
3299  std::vector<RoutingTableEntry> retval;
3300  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3301  iter != m_table.end (); iter++)
3302  {
3303  retval.push_back (iter->second);
3304  }
3305  return retval;
3306 }
3307 
3308 int64_t
3310 {
3311  NS_LOG_FUNCTION (this << stream);
3313  return 1;
3314 }
3315 
3316 bool
3318 {
3319  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
3320  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
3321  {
3322  Ipv4InterfaceAddress iface = j->second;
3323  if (a == iface.GetLocal ())
3324  {
3325  return true;
3326  }
3327  }
3328  return false;
3329 }
3330 
3331 void
3333 {
3334 #ifdef NS3_LOG_ENABLE
3335  Time now = Simulator::Now ();
3336  NS_LOG_DEBUG ("Dumping for node with main address " << m_mainAddress);
3337  NS_LOG_DEBUG (" Neighbor set");
3338  for (NeighborSet::const_iterator iter = m_state.GetNeighbors ().begin ();
3339  iter != m_state.GetNeighbors ().end (); iter++)
3340  {
3341  NS_LOG_DEBUG (" " << *iter);
3342  }
3343  NS_LOG_DEBUG (" Two-hop neighbor set");
3344  for (TwoHopNeighborSet::const_iterator iter = m_state.GetTwoHopNeighbors ().begin ();
3345  iter != m_state.GetTwoHopNeighbors ().end (); iter++)
3346  {
3347  if (now < iter->expirationTime)
3348  {
3349  NS_LOG_DEBUG (" " << *iter);
3350  }
3351  }
3352  NS_LOG_DEBUG (" Routing table");
3353  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin (); iter != m_table.end (); iter++)
3354  {
3355  NS_LOG_DEBUG (" dest=" << iter->first << " --> next=" << iter->second.nextAddr << " via interface " << iter->second.interface);
3356  }
3357  NS_LOG_DEBUG ("");
3358 #endif //NS3_LOG_ENABLE
3359 }
3360 
3361 } // namespace olsr
3362 } // namespace ns3
3363 
3364 
std::vector< TopologyTuple > TopologySet
Topology Set type.
An MPR-Selector Tuple.
Ipv4Address networkAddr
Network Address of network reachable through gatewayAddr.
static TypeId GetTypeId(void)
#define OLSR_PORT_NUMBER
std::set< uint32_t > m_interfaceExclusions
#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.
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
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.
void EraseDuplicateTuple(const DuplicateTuple &tuple)
Definition: olsr-state.cc:296
Ipv4Address GetIpv4(void) const
#define OLSR_MAX_SEQ_NUM
Maximum allowed sequence number.
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
Ipv4Address GetOriginatorAddress() const
Definition: olsr-header.h:152
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
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)
Definition: enum.cc:178
void IfaceAssocTupleTimerExpire(Ipv4Address ifaceAddr)
Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time(). ...
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:920
#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:45
#define OLSR_DUP_HOLD_TIME
Dup holding time.
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:125
Ipv4Address GetLocal(void) const
uint16_t m_messageSequenceNumber
Messages sequence number counter.
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
void InsertAssociation(const Association &tuple)
Definition: olsr-state.cc:541
LinkTuple * FindSymLinkTuple(const Ipv4Address &ifaceAddr, Time time)
Definition: olsr-state.cc:330
Ipv4Address destAddr
Address of the destination node.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
NS_LOG_COMPONENT_DEFINE("OlsrHeader")
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. Its aim is to also update the corresponding ne...
void SetPacketSequenceNumber(uint16_t seqnum)
Definition: olsr-header.h:84
void LinkSensing(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello, const Ipv4Address &receiverIface, const Ipv4Address &sender_iface)
Updates Link Set according to a new received HELLO message (following RFC 3626 specification). Neighbor Set is also updated if needed.
uint16_t m_ansn
Advertised Neighbor Set sequence number.
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:303
bool IsNull(void) const
Definition: callback.h:1014
#define NS_ASSERT(condition)
Definition: assert.h:64
Ipv4Address GetDestNetwork(void) const
#define OLSR_WILL_ALWAYS
Willingness for forwarding packets from other nodes: always.
void AddEntry(const Ipv4Address &dest, const Ipv4Address &next, uint32_t interface, uint32_t distance)
Adds a new entry into the routing table.
uint32_t GetSize(void) const
Definition: packet.h:650
virtual void NotifyInterfaceUp(uint32_t interface)
void SendTc()
Creates a new OLSR TC message which is buffered for being sent later on.
void EraseAssociationTuple(const AssociationTuple &tuple)
Definition: olsr-state.cc:507
int64_t AssignStreams(int64_t stream)
virtual void DoDispose(void)
Definition: object.cc:335
void DupTupleTimerExpire(Ipv4Address address, uint16_t sequenceNumber)
Removes tuple if expired. Else timer is rescheduled to expire at tuple.expirationTime.
#define NS_LOG_INFO(msg)
Definition: log.h:264
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:290
IfaceAssocTuple * FindIfaceAssocTuple(const Ipv4Address &ifaceAddr)
Definition: olsr-state.cc:434
enum ns3::olsr::NeighborTuple::Status status
void AddHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Inject Association to be sent in HNA message.
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
std::vector< LinkMessage > linkMessages
Definition: olsr-header.h:276
uint16_t GetMessageSequenceNumber() const
Definition: olsr-header.h:179
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:824
Time expirationTime
Time at which this tuple expires and must be removed.
#define OLSR_WILL_LOW
Willingness for forwarding packets from other nodes: low.
void EraseOlderTopologyTuples(const Ipv4Address &lastAddr, uint16_t ansn)
Definition: olsr-state.cc:409
void LinkTupleTimerExpire(Ipv4Address neighborIfaceAddr)
Removes tuple_ if expired. Else if symmetric time has expired then it is assumed a neighbor loss and ...
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)
Definition: olsr-header.h:166
void InsertTopologyTuple(const TopologyTuple &tuple)
Definition: olsr-state.cc:426
MessageType GetMessageType() const
Definition: olsr-header.h:134
void EraseTopologyTuple(const TopologyTuple &tuple)
Definition: olsr-state.cc:395
const LinkSet & GetLinks() const
Definition: olsr-state.h:115
Time GetVTime() const
Definition: olsr-header.h:143
void Nb2hopTupleTimerExpire(Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr)
Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
void RemoveAssociationTuple(const AssociationTuple &tuple)
Removes a host network association tuple from the Association Set.
DuplicateTuple * FindDuplicateTuple(const Ipv4Address &address, uint16_t sequenceNumber)
Definition: olsr-state.cc:284
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
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.
a polymophic address class
Definition: address.h:86
bool IsRunning(void) const
Definition: timer.cc:121
void SetVTime(Time time)
Definition: olsr-header.h:139
NS_OBJECT_ENSURE_REGISTERED(PacketHeader)
void MprSelTupleTimerExpire(Ipv4Address mainAddr)
Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
#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
Definition: olsr-header.h:225
std::vector< Ipv4Address > neighborAddresses
Definition: olsr-header.h:302
void SetTimeToLive(uint8_t timeToLive)
Definition: olsr-header.h:157
TracedCallback< const PacketHeader &, const MessageList & > m_rxPacketTrace
void RemoveIfaceAssocTuple(const IfaceAssocTuple &tuple)
Removes an interface association tuple from the Interface Association Set.
uint32_t GetInterface(void) const
Packet header for IPv4.
Definition: ipv4-header.h:31
EventGarbageCollector m_events
double GetSeconds(void) const
Definition: nstime.h:266
void AddAtEnd(Ptr< const Packet > packet)
Definition: packet.cc:317
Ipv4Address lastAddr
Main address of a node which is a neighbor of the destination.
void EraseTwoHopNeighborTuples(const Ipv4Address &neighbor)
Definition: olsr-state.cc:239
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 RemoveHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Removes Association sent in HNA message.
hold variables of type 'enum'
Definition: enum.h:37
Ipv4Address mainAddr
Main address of the node.
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].
hold objects of type ns3::Time
Definition: nstime.h:828
Ipv4Address mainAddr
Main address of a node which have selected this node as a MPR.
void SendPacket(Ptr< Packet > packet, const MessageList &containedMessages)
void Schedule(void)
Definition: timer.cc:152
TopologyTuple * FindTopologyTuple(const Ipv4Address &destAddr, const Ipv4Address &lastAddr)
Definition: olsr-state.cc:370
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
void SetFunction(FN fn)
Definition: timer.h:254
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.
void InsertTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Definition: olsr-state.cc:256
tuple interfaces
Definition: first.py:40
void AddAssociationTuple(const AssociationTuple &tuple)
Adds a host network association tuple to the Association Set.
void SetPacketLength(uint16_t length)
Definition: olsr-header.h:75
Ptr< Ipv4StaticRouting > m_hnaRoutingTable
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)
uint8_t GetHopCount() const
Definition: olsr-header.h:170
void MprComputation()
Computates MPR set of a node following RFC 3626 hints.
std::vector< LinkTuple > LinkSet
Link Set type.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
void RemoveDuplicateTuple(const DuplicateTuple &tuple)
Removes a duplicate tuple from the Duplicate Set.
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:127
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
Definition: socket.cc:70
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
void EraseAssociation(const Association &tuple)
Definition: olsr-state.cc:527
const Associations & GetAssociations() const
Definition: olsr-state.h:158
uint8_t GetTimeToLive() const
Definition: olsr-header.h:161
void CoverTwoHopNeighbors(Ipv4Address neighborMainAddr, TwoHopNeighborSet &N2)
Remove all covered 2-hop neighbors from N2 set. This is a helper function used by MprComputation algo...
Time m_helloInterval
HELLO messages' emission interval.
LinkTuple & InsertLinkTuple(const LinkTuple &tuple)
Definition: olsr-state.cc:361
void SetDelay(const Time &delay)
Definition: timer.cc:69
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
#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)
Inject Associations from an Ipv4StaticRouting instance.
Ipv4Address destAddr
Main address of the destination.
std::vector< IfaceAssocTuple > IfaceAssocSet
Interface Association Set type.
void SetMprSet(MprSet mprSet)
MprSet is set by routing protocol after MprCompute.
Definition: olsr-state.cc:271
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
void TopologyTupleTimerExpire(Ipv4Address destAddr, Ipv4Address lastAddr)
Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
Time m_tcInterval
TC messages' emission interval.
const IfaceAssocSet & GetIfaceAssocSet() const
Definition: olsr-state.h:139
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 tuple_ if expired. Else timer is rescheduled to expire at tuple_->time(). ...
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)
Definition: olsr-header.h:148
void RemoveTopologyTuple(const TopologyTuple &tuple)
Removes a topology tuple from 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.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
void InsertDuplicateTuple(const DuplicateTuple &tuple)
Definition: olsr-state.cc:310
static InetSocketAddress ConvertFrom(const Address &address)
void RecvOlsr(Ptr< Socket > socket)
Ipv4Address neighborMainAddr
Main address of a neighbor node.
std::vector< Association > associations
Definition: olsr-header.h:338
Ipv4Address twoHopNeighborAddr
Main address of a 2-hop neighbor with a symmetric link to nb_main_addr.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
TopologyTuple * FindNewerTopologyTuple(const Ipv4Address &lastAddr, uint16_t ansn)
Definition: olsr-state.cc:383
AssociationTuple * FindAssociationTuple(const Ipv4Address &gatewayAddr, const Ipv4Address &networkAddr, const Ipv4Mask &netmask)
Definition: olsr-state.cc:493
void MidTimerExpire()
Sends a MID message (if the node has more than one interface) and resets the MID timer.
Ptr< Ipv4StaticRouting > m_routingTableAssociation
void EraseTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Definition: olsr-state.cc:206
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.
std::vector< Ipv4Address > FindNeighborInterfaces(const Ipv4Address &neighborMainAddr) const
Definition: olsr-state.cc:478
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. Returns true if the outg...
LinkTuple * FindLinkTuple(const Ipv4Address &ifaceAddr)
Definition: olsr-state.cc:318
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:450
static Time Now(void)
Definition: simulator.cc:180
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Definition: ipv4-route.cc:77
Time time
Time at which this tuple expires and must be removed.
virtual void NotifyInterfaceDown(uint32_t interface)
uint16_t m_packetSequenceNumber
Packets sequence number counter.
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition: enum.h:118
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:329
void PopulateTwoHopNeighborSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the 2-hop Neighbor Set according to the information contained in a new received HELLO message...
void InsertMprSelectorTuple(const MprSelectorTuple &tuple)
Definition: olsr-state.cc:81
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 EraseIfaceAssocTuple(const IfaceAssocTuple &tuple)
Definition: olsr-state.cc:458
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.
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.
#define OLSR_WILL_HIGH
Willingness for forwarding packets from other nodes: high.
uint32_t interface
Interface index.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
std::vector< NeighborTuple > NeighborSet
Neighbor Set type.
bool IsMyOwnAddress(const Ipv4Address &a) const
Check that address is one of my interfaces.
uint32_t GetId(void) const
Definition: node.cc:103
void EraseLinkTuple(const LinkTuple &tuple)
Definition: olsr-state.cc:347
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)
Definition: log.h:246
Ipv4Address ifaceAddr
Interface address of a node.
#define OLSR_LOST_LINK
Lost link type.
Ipv4Address nextAddr
Address of the next hop.
TracedCallback< const PacketHeader &, const MessageList & > m_txPacketTrace
void EraseMprSelectorTuple(const MprSelectorTuple &tuple)
Definition: olsr-state.cc:50
A network Node.
Definition: node.h:55
std::set< Ipv4Address > MprSet
MPR Set type.
#define OLSR_SYM_NEIGH
Symmetric neighbor type.
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
bool FindMprAddress(const Ipv4Address &address)
Definition: olsr-state.cc:264
void SendHna()
Creates a new OLSR HNA message which is buffered for being sent later on.
const TwoHopNeighborSet & GetTwoHopNeighbors() const
Definition: olsr-state.h:85
#define OLSR_MID_HOLD_TIME
MID holding time.
std::vector< TwoHopNeighborTuple > TwoHopNeighborSet
2-hop Neighbor Set type.
void Track(EventId event)
Tracks a new event.
const AssociationSet & GetAssociationSet() const
Definition: olsr-state.h:153
static std::string FindName(Ptr< Object > object)
Definition: names.cc:664
MprSelectorTuple * FindMprSelectorTuple(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:38
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.
TwoHopNeighborTuple * FindTwoHopNeighborTuple(const Ipv4Address &neighbor, const Ipv4Address &twoHopNeighbor)
Definition: olsr-state.cc:190
void LinkTupleAdded(const LinkTuple &tuple, uint8_t willingness)
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Time m_hnaInterval
HNA messages' emission interval.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range. Both limits are inclusive.
Definition: time.cc:404
const NeighborSet & GetNeighbors() const
Definition: olsr-state.h:68
void EraseMprSelectorTuples(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:64
uint16_t GetPort(void) const
Ipv4Address neighborMainAddr
Main address of a neighbor.
std::vector< RoutingTableEntry > GetRoutingTableEntries() const
void InsertNeighborTuple(const NeighborTuple &tuple)
Definition: olsr-state.cc:172
tuple address
Definition: first.py:37
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)
Definition: olsr-header.h:175
void TcTimerExpire()
Sends a TC message (if there exists any MPR selector) and reschedules the TC timer.
Ipv4Address address
Originator address of the message.
const MprSelectorSet & GetMprSelectors() const
Definition: olsr-state.h:57
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.
IfaceAssocSet & GetIfaceAssocSetMutable()
Definition: olsr-state.h:143
void EraseNeighborTuple(const NeighborTuple &neighborTuple)
Definition: olsr-state.cc:144
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:183
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
NeighborTuple * FindNeighborTuple(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:108
#define OLSR_HNA_HOLD_TIME
HNA holding time.
std::string PrintMprSelectorSet() const
Definition: olsr-state.cc:87
Ipv4Mask GetDestNetworkMask(void) const
a unique identifier for an interface.
Definition: type-id.h:49
An Interface Association Tuple.
bool retransmitted
Indicates whether the message has been retransmitted or not.
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
The type "list of interface addresses".
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
std::ostream * GetStream(void)
uint16_t sequenceNumber
Message sequence number.
std::vector< AssociationTuple > AssociationSet
Association Set type.
void AddHeader(const Header &header)
Definition: packet.cc:253
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
const NeighborTuple * FindSymNeighborTuple(const Ipv4Address &mainAddr) const
Definition: olsr-state.cc:120
bool FindSendEntry(const RoutingTableEntry &entry, RoutingTableEntry &outEntry) const
Finds the appropiate entry which must be used in order to forward a data packet to a next hop (given ...
const TopologySet & GetTopologySet() const
Definition: olsr-state.h:125
uint16_t GetPacketLength() const
Definition: olsr-header.h:79
void InsertIfaceAssocTuple(const IfaceAssocTuple &tuple)
Definition: olsr-state.cc:472
Time expirationTime
Time at which this tuple expires and must be removed.
std::vector< Ipv4Address > ifaceList
List of interfaces which the message has been received on.
void InsertAssociationTuple(const AssociationTuple &tuple)
Definition: olsr-state.cc:521
void ProcessMid(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a MID message following RFC 3626 specification.