A Discrete-Event Network Simulator
API
olsr-routing-protocol.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2004 Francisco J. Ros
4  * Copyright (c) 2007 INESC Porto
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Authors: Francisco J. Ros <fjrm@dif.um.es>
20  * Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
21  */
22 
23 
30 
31 #define NS_LOG_APPEND_CONTEXT \
32  if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
33 
34 
35 #include "olsr-routing-protocol.h"
36 #include "ns3/socket-factory.h"
37 #include "ns3/udp-socket-factory.h"
38 #include "ns3/simulator.h"
39 #include "ns3/log.h"
40 #include "ns3/names.h"
41 #include "ns3/inet-socket-address.h"
42 #include "ns3/ipv4-routing-protocol.h"
43 #include "ns3/ipv4-routing-table-entry.h"
44 #include "ns3/ipv4-route.h"
45 #include "ns3/boolean.h"
46 #include "ns3/uinteger.h"
47 #include "ns3/enum.h"
48 #include "ns3/trace-source-accessor.h"
49 #include "ns3/ipv4-header.h"
50 
51 /********** Useful macros **********/
52 
59 #define DELAY(time) (((time) < (Simulator::Now ())) ? Seconds (0.000001) : \
60  (time - Simulator::Now () + Seconds (0.000001)))
61 
62 
63 
69 #define OLSR_REFRESH_INTERVAL m_helloInterval
70 
71 
72 /********** Holding times **********/
73 
75 #define OLSR_NEIGHB_HOLD_TIME Time (3 * OLSR_REFRESH_INTERVAL)
76 #define OLSR_TOP_HOLD_TIME Time (3 * m_tcInterval)
78 #define OLSR_DUP_HOLD_TIME Seconds (30)
80 #define OLSR_MID_HOLD_TIME Time (3 * m_midInterval)
82 #define OLSR_HNA_HOLD_TIME Time (3 * m_hnaInterval)
84 
85 /********** Link types **********/
86 
88 #define OLSR_UNSPEC_LINK 0
89 #define OLSR_ASYM_LINK 1
91 #define OLSR_SYM_LINK 2
93 #define OLSR_LOST_LINK 3
95 
96 /********** Neighbor types **********/
97 
99 #define OLSR_NOT_NEIGH 0
100 #define OLSR_SYM_NEIGH 1
102 #define OLSR_MPR_NEIGH 2
104 
105 
106 /********** Willingness **********/
107 
109 #define OLSR_WILL_NEVER 0
110 #define OLSR_WILL_LOW 1
112 #define OLSR_WILL_DEFAULT 3
114 #define OLSR_WILL_HIGH 6
116 #define OLSR_WILL_ALWAYS 7
118 
119 
120 /********** Miscellaneous constants **********/
121 
123 #define OLSR_MAXJITTER (m_helloInterval.GetSeconds () / 4)
124 #define OLSR_MAX_SEQ_NUM 65535
126 #define JITTER (Seconds (m_uniformRandomVariable->GetValue (0, OLSR_MAXJITTER)))
128 
129 
130 #define OLSR_PORT_NUMBER 698
131 #define OLSR_MAX_MSGS 64
133 
135 #define OLSR_MAX_HELLOS 12
136 
138 #define OLSR_MAX_ADDRS 64
139 
140 
141 namespace ns3 {
142 
143 NS_LOG_COMPONENT_DEFINE ("OlsrRoutingProtocol");
144 
145 namespace olsr {
146 
147 /********** OLSR class **********/
148 
149 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
150 
151 TypeId
153 {
154  static TypeId tid = TypeId ("ns3::olsr::RoutingProtocol")
156  .SetGroupName ("Olsr")
157  .AddConstructor<RoutingProtocol> ()
158  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
159  TimeValue (Seconds (2)),
161  MakeTimeChecker ())
162  .AddAttribute ("TcInterval", "TC messages emission interval.",
163  TimeValue (Seconds (5)),
165  MakeTimeChecker ())
166  .AddAttribute ("MidInterval", "MID messages emission interval. Normally it is equal to TcInterval.",
167  TimeValue (Seconds (5)),
169  MakeTimeChecker ())
170  .AddAttribute ("HnaInterval", "HNA messages emission interval. Normally it is equal to TcInterval.",
171  TimeValue (Seconds (5)),
173  MakeTimeChecker ())
174  .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.",
178  OLSR_WILL_LOW, "low",
179  OLSR_WILL_DEFAULT, "default",
180  OLSR_WILL_HIGH, "high",
181  OLSR_WILL_ALWAYS, "always"))
182  .AddTraceSource ("Rx", "Receive OLSR packet.",
184  "ns3::olsr::RoutingProtocol::PacketTxRxTracedCallback")
185  .AddTraceSource ("Tx", "Send OLSR packet.",
187  "ns3::olsr::RoutingProtocol::PacketTxRxTracedCallback")
188  .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.",
190  "ns3::olsr::RoutingProtocol::TableChangeTracedCallback")
191  ;
192  return tid;
193 }
194 
195 
197  : m_routingTableAssociation (0),
198  m_ipv4 (0),
199  m_helloTimer (Timer::CANCEL_ON_DESTROY),
200  m_tcTimer (Timer::CANCEL_ON_DESTROY),
201  m_midTimer (Timer::CANCEL_ON_DESTROY),
202  m_hnaTimer (Timer::CANCEL_ON_DESTROY),
203  m_queuedMessagesTimer (Timer::CANCEL_ON_DESTROY)
204 {
205  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
206 
207  m_hnaRoutingTable = Create<Ipv4StaticRouting> ();
208 }
209 
211 {
212 }
213 
214 void
216 {
217  NS_ASSERT (ipv4 != 0);
218  NS_ASSERT (m_ipv4 == 0);
219  NS_LOG_DEBUG ("Created olsr::RoutingProtocol");
225 
229 
231 
232  m_ipv4 = ipv4;
233 
234  m_hnaRoutingTable->SetIpv4 (ipv4);
235 }
236 
238 {
239  m_ipv4 = 0;
240  m_hnaRoutingTable = 0;
242 
243  for (std::map< Ptr<Socket>, Ipv4InterfaceAddress >::iterator iter = m_socketAddresses.begin ();
244  iter != m_socketAddresses.end (); iter++)
245  {
246  iter->first->Close ();
247  }
248  m_socketAddresses.clear ();
249 
251 }
252 
253 void
255 {
256  std::ostream* os = stream->GetStream ();
257  *os << "Destination\t\tNextHop\t\tInterface\tDistance\n";
258 
259  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
260  iter != m_table.end (); iter++)
261  {
262  *os << iter->first << "\t\t";
263  *os << iter->second.nextAddr << "\t\t";
264  if (Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) != "")
265  {
266  *os << Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) << "\t\t";
267  }
268  else
269  {
270  *os << iter->second.interface << "\t\t";
271  }
272  *os << iter->second.distance << "\t";
273  *os << "\n";
274  }
275  // Also print the HNA routing table
276  *os << " HNA Routing Table:\n";
277  m_hnaRoutingTable->PrintRoutingTable (stream);
278 }
279 
281 {
282  if (m_mainAddress == Ipv4Address ())
283  {
284  Ipv4Address loopback ("127.0.0.1");
285  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
286  {
287  // Use primary address, if multiple
288  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
289  if (addr != loopback)
290  {
291  m_mainAddress = addr;
292  break;
293  }
294  }
295 
297  }
298 
299  NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
300 
301  Ipv4Address loopback ("127.0.0.1");
302 
303  bool canRunOlsr = false;
304  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
305  {
306  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
307  if (addr == loopback)
308  continue;
309 
310  if (addr != m_mainAddress)
311  {
312  // Create never expiring interface association tuple entries for our
313  // own network interfaces, so that GetMainAddress () works to
314  // translate the node's own interface addresses into the main address.
315  IfaceAssocTuple tuple;
316  tuple.ifaceAddr = addr;
317  tuple.mainAddr = m_mainAddress;
318  AddIfaceAssocTuple (tuple);
320  }
321 
322  if(m_interfaceExclusions.find (i) != m_interfaceExclusions.end ())
323  continue;
324 
325  // Create a socket to listen only on this interface
326  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
328  socket->SetAllowBroadcast (true);
329  InetSocketAddress inetAddr (m_ipv4->GetAddress (i, 0).GetLocal (), OLSR_PORT_NUMBER);
331  if (socket->Bind (inetAddr))
332  {
333  NS_FATAL_ERROR ("Failed to bind() OLSR socket");
334  }
335  socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
336  m_socketAddresses[socket] = m_ipv4->GetAddress (i, 0);
337 
338  canRunOlsr = true;
339  }
340 
341  if(canRunOlsr)
342  {
343  HelloTimerExpire ();
344  TcTimerExpire ();
345  MidTimerExpire ();
346  HnaTimerExpire ();
347 
348  NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
349  }
350 }
351 
352 void RoutingProtocol::SetMainInterface (uint32_t interface)
353 {
354  m_mainAddress = m_ipv4->GetAddress (interface, 0).GetLocal ();
355 }
356 
357 void RoutingProtocol::SetInterfaceExclusions (std::set<uint32_t> exceptions)
358 {
359  m_interfaceExclusions = exceptions;
360 }
361 
362 //
363 // \brief Processes an incoming %OLSR packet following \RFC{3626} specification.
364 void
366 {
367  Ptr<Packet> receivedPacket;
368  Address sourceAddress;
369  receivedPacket = socket->RecvFrom (sourceAddress);
370 
371  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
372  Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
373  Ipv4Address receiverIfaceAddr = m_socketAddresses[socket].GetLocal ();
374  NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
375  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
376  << senderIfaceAddr << " to " << receiverIfaceAddr);
377 
378  // All routing messages are sent from and to port RT_PORT,
379  // so we check it.
380  NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER);
381 
382  Ptr<Packet> packet = receivedPacket;
383 
384  olsr::PacketHeader olsrPacketHeader;
385  packet->RemoveHeader (olsrPacketHeader);
386  NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ());
387  uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize ();
388 
389  MessageList messages;
390 
391  while (sizeLeft)
392  {
393  MessageHeader messageHeader;
394  if (packet->RemoveHeader (messageHeader) == 0)
395  NS_ASSERT (false);
396 
397  sizeLeft -= messageHeader.GetSerializedSize ();
398 
399  NS_LOG_DEBUG ("Olsr Msg received with type "
400  << std::dec << int (messageHeader.GetMessageType ())
401  << " TTL=" << int (messageHeader.GetTimeToLive ())
402  << " origAddr=" << messageHeader.GetOriginatorAddress ());
403  messages.push_back (messageHeader);
404  }
405 
406  m_rxPacketTrace (olsrPacketHeader, messages);
407 
408  for (MessageList::const_iterator messageIter = messages.begin ();
409  messageIter != messages.end (); messageIter++)
410  {
411  const MessageHeader &messageHeader = *messageIter;
412  // If ttl is less than or equal to zero, or
413  // the receiver is the same as the originator,
414  // the message must be silently dropped
415  if (messageHeader.GetTimeToLive () == 0
416  || messageHeader.GetOriginatorAddress () == m_mainAddress)
417  {
418  packet->RemoveAtStart (messageHeader.GetSerializedSize ()
419  - messageHeader.GetSerializedSize ());
420  continue;
421  }
422 
423  // If the message has been processed it must not be processed again
424  bool do_forwarding = true;
426  (messageHeader.GetOriginatorAddress (),
427  messageHeader.GetMessageSequenceNumber ());
428 
429  // Get main address of the peer, which may be different from the packet source address
430 // const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ());
431 // Ipv4Address peerMainAddress;
432 // if (ifaceAssoc != NULL)
433 // {
434 // peerMainAddress = ifaceAssoc->mainAddr;
435 // }
436 // else
437 // {
438 // peerMainAddress = inetSourceAddr.GetIpv4 () ;
439 // }
440 
441  if (duplicated == NULL)
442  {
443  switch (messageHeader.GetMessageType ())
444  {
446  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
447  << "s OLSR node " << m_mainAddress
448  << " received HELLO message of size " << messageHeader.GetSerializedSize ());
449  ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr);
450  break;
451 
453  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
454  << "s OLSR node " << m_mainAddress
455  << " received TC message of size " << messageHeader.GetSerializedSize ());
456  ProcessTc (messageHeader, senderIfaceAddr);
457  break;
458 
460  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
461  << "s OLSR node " << m_mainAddress
462  << " received MID message of size " << messageHeader.GetSerializedSize ());
463  ProcessMid (messageHeader, senderIfaceAddr);
464  break;
466  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
467  << "s OLSR node " << m_mainAddress
468  << " received HNA message of size " << messageHeader.GetSerializedSize ());
469  ProcessHna (messageHeader, senderIfaceAddr);
470  break;
471 
472  default:
473  NS_LOG_DEBUG ("OLSR message type " <<
474  int (messageHeader.GetMessageType ()) <<
475  " not implemented");
476  }
477  }
478  else
479  {
480  NS_LOG_DEBUG ("OLSR message is duplicated, not reading it.");
481 
482  // If the message has been considered for forwarding, it should
483  // not be retransmitted again
484  for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin ();
485  it != duplicated->ifaceList.end (); it++)
486  {
487  if (*it == receiverIfaceAddr)
488  {
489  do_forwarding = false;
490  break;
491  }
492  }
493  }
494 
495  if (do_forwarding)
496  {
497  // HELLO messages are never forwarded.
498  // TC and MID messages are forwarded using the default algorithm.
499  // Remaining messages are also forwarded using the default algorithm.
500  if (messageHeader.GetMessageType () != olsr::MessageHeader::HELLO_MESSAGE)
501  {
502  ForwardDefault (messageHeader, duplicated,
503  receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
504  }
505  }
506  }
507 
508  // After processing all OLSR messages, we must recompute the routing table
510 }
511 
518 int
520 {
521  int degree = 0;
522  for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin ();
523  it != m_state.GetTwoHopNeighbors ().end (); it++)
524  {
525  TwoHopNeighborTuple const &nb2hop_tuple = *it;
526  if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
527  {
528  const NeighborTuple *nb_tuple =
530  if (nb_tuple == NULL)
531  degree++;
532  }
533  }
534  return degree;
535 }
536 
537 namespace {
541 void
543 {
544  // first gather all 2-hop neighbors to be removed
545  std::set<Ipv4Address> toRemove;
546  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
547  {
548  if (twoHopNeigh->neighborMainAddr == neighborMainAddr)
549  {
550  toRemove.insert (twoHopNeigh->twoHopNeighborAddr);
551  }
552  }
553  // Now remove all matching records from N2
554  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); )
555  {
556  if (toRemove.find (twoHopNeigh->twoHopNeighborAddr) != toRemove.end ())
557  {
558  twoHopNeigh = N2.erase (twoHopNeigh);
559  }
560  else
561  {
562  twoHopNeigh++;
563  }
564  }
565 }
566 } // anonymous namespace
567 
571 void
573 {
574  NS_LOG_FUNCTION (this);
575 
576  // MPR computation should be done for each interface. See section 8.3.1
577  // (RFC 3626) for details.
578  MprSet mprSet;
579 
580  // N is the subset of neighbors of the node, which are
581  // neighbor "of the interface I"
582  NeighborSet N;
583  for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin ();
584  neighbor != m_state.GetNeighbors ().end (); neighbor++)
585  {
586  if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
587  {
588  N.push_back (*neighbor);
589  }
590  }
591 
592  // N2 is the set of 2-hop neighbors reachable from "the interface
593  // I", excluding:
594  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
595  // (ii) the node performing the computation
596  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
597  // link to this node on some interface.
599  for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin ();
600  twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++)
601  {
602  // excluding:
603  // (ii) the node performing the computation
604  if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
605  {
606  continue;
607  }
608 
609  // excluding:
610  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
611  bool ok = false;
612  for (NeighborSet::const_iterator neigh = N.begin ();
613  neigh != N.end (); neigh++)
614  {
615  if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
616  {
617  if (neigh->willingness == OLSR_WILL_NEVER)
618  {
619  ok = false;
620  break;
621  }
622  else
623  {
624  ok = true;
625  break;
626  }
627  }
628  }
629  if (!ok)
630  {
631  continue;
632  }
633 
634  // excluding:
635  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
636  // link to this node on some interface.
637  for (NeighborSet::const_iterator neigh = N.begin ();
638  neigh != N.end (); neigh++)
639  {
640  if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
641  {
642  ok = false;
643  break;
644  }
645  }
646 
647  if (ok)
648  {
649  N2.push_back (*twoHopNeigh);
650  }
651  }
652 
653 #ifdef NS3_LOG_ENABLE
654  {
655  std::ostringstream os;
656  os << "[";
657  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
658  iter != N2.end (); iter++)
659  {
660  TwoHopNeighborSet::const_iterator next = iter;
661  next++;
662  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
663  if (next != N2.end ())
664  os << ", ";
665  }
666  os << "]";
667  NS_LOG_DEBUG ("N2: " << os.str ());
668  }
669 #endif //NS3_LOG_ENABLE
670 
671  // 1. Start with an MPR set made of all members of N with
672  // N_willingness equal to WILL_ALWAYS
673  for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
674  {
675  if (neighbor->willingness == OLSR_WILL_ALWAYS)
676  {
677  mprSet.insert (neighbor->neighborMainAddr);
678  // (not in RFC but I think is needed: remove the 2-hop
679  // neighbors reachable by the MPR from N2)
680  CoverTwoHopNeighbors (neighbor->neighborMainAddr, N2);
681  }
682  }
683 
684  // 2. Calculate D(y), where y is a member of N, for all nodes in N.
685  // (we do this later)
686 
687  // 3. Add to the MPR set those nodes in N, which are the *only*
688  // nodes to provide reachability to a node in N2.
689  std::set<Ipv4Address> coveredTwoHopNeighbors;
690  for (TwoHopNeighborSet::const_iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
691  {
692  bool onlyOne = true;
693  // try to find another neighbor that can reach twoHopNeigh->twoHopNeighborAddr
694  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin (); otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
695  {
696  if (otherTwoHopNeigh->twoHopNeighborAddr == twoHopNeigh->twoHopNeighborAddr
697  && otherTwoHopNeigh->neighborMainAddr != twoHopNeigh->neighborMainAddr)
698  {
699  onlyOne = false;
700  break;
701  }
702  }
703  if (onlyOne)
704  {
705  NS_LOG_LOGIC ("Neighbor " << twoHopNeigh->neighborMainAddr
706  << " is the only that can reach 2-hop neigh. "
707  << twoHopNeigh->twoHopNeighborAddr
708  << " => select as MPR.");
709 
710  mprSet.insert (twoHopNeigh->neighborMainAddr);
711 
712  // take note of all the 2-hop neighbors reachable by the newly elected MPR
713  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin ();
714  otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
715  {
716  if (otherTwoHopNeigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
717  {
718  coveredTwoHopNeighbors.insert (otherTwoHopNeigh->twoHopNeighborAddr);
719  }
720  }
721  }
722  }
723  // Remove the nodes from N2 which are now covered by a node in the MPR set.
724  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
725  twoHopNeigh != N2.end (); )
726  {
727  if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
728  {
729  // This works correctly only because it is known that twoHopNeigh is reachable by exactly one neighbor,
730  // so only one record in N2 exists for each of them. This record is erased here.
731  NS_LOG_LOGIC ("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr << " is already covered by an MPR.");
732  twoHopNeigh = N2.erase (twoHopNeigh);
733  }
734  else
735  {
736  twoHopNeigh++;
737  }
738  }
739 
740  // 4. While there exist nodes in N2 which are not covered by at
741  // least one node in the MPR set:
742  while (N2.begin () != N2.end ())
743  {
744 
745 #ifdef NS3_LOG_ENABLE
746  {
747  std::ostringstream os;
748  os << "[";
749  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
750  iter != N2.end (); iter++)
751  {
752  TwoHopNeighborSet::const_iterator next = iter;
753  next++;
754  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
755  if (next != N2.end ())
756  os << ", ";
757  }
758  os << "]";
759  NS_LOG_DEBUG ("Step 4 iteration: N2=" << os.str ());
760  }
761 #endif //NS3_LOG_ENABLE
762 
763 
764  // 4.1. For each node in N, calculate the reachability, i.e., the
765  // number of nodes in N2 which are not yet covered by at
766  // least one node in the MPR set, and which are reachable
767  // through this 1-hop neighbor
768  std::map<int, std::vector<const NeighborTuple *> > reachability;
769  std::set<int> rs;
770  for (NeighborSet::iterator it = N.begin (); it != N.end (); it++)
771  {
772  NeighborTuple const &nb_tuple = *it;
773  int r = 0;
774  for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++)
775  {
776  TwoHopNeighborTuple const &nb2hop_tuple = *it2;
777  if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
778  r++;
779  }
780  rs.insert (r);
781  reachability[r].push_back (&nb_tuple);
782  }
783 
784  // 4.2. Select as a MPR the node with highest N_willingness among
785  // the nodes in N with non-zero reachability. In case of
786  // multiple choice select the node which provides
787  // reachability to the maximum number of nodes in N2. In
788  // case of multiple nodes providing the same amount of
789  // reachability, select the node as MPR whose D(y) is
790  // greater. Remove the nodes from N2 which are now covered
791  // by a node in the MPR set.
792  NeighborTuple const *max = NULL;
793  int max_r = 0;
794  for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++)
795  {
796  int r = *it;
797  if (r == 0)
798  {
799  continue;
800  }
801  for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin ();
802  it2 != reachability[r].end (); it2++)
803  {
804  const NeighborTuple *nb_tuple = *it2;
805  if (max == NULL || nb_tuple->willingness > max->willingness)
806  {
807  max = nb_tuple;
808  max_r = r;
809  }
810  else if (nb_tuple->willingness == max->willingness)
811  {
812  if (r > max_r)
813  {
814  max = nb_tuple;
815  max_r = r;
816  }
817  else if (r == max_r)
818  {
819  if (Degree (*nb_tuple) > Degree (*max))
820  {
821  max = nb_tuple;
822  max_r = r;
823  }
824  }
825  }
826  }
827  }
828 
829  if (max != NULL)
830  {
831  mprSet.insert (max->neighborMainAddr);
833  NS_LOG_LOGIC (N2.size () << " 2-hop neighbors left to cover!");
834  }
835  }
836 
837 #ifdef NS3_LOG_ENABLE
838  {
839  std::ostringstream os;
840  os << "[";
841  for (MprSet::const_iterator iter = mprSet.begin ();
842  iter != mprSet.end (); iter++)
843  {
844  MprSet::const_iterator next = iter;
845  next++;
846  os << *iter;
847  if (next != mprSet.end ())
848  os << ", ";
849  }
850  os << "]";
851  NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
852  }
853 #endif //NS3_LOG_ENABLE
854 
855  m_state.SetMprSet (mprSet);
856 }
857 
866 {
867  const IfaceAssocTuple *tuple =
868  m_state.FindIfaceAssocTuple (iface_addr);
869 
870  if (tuple != NULL)
871  return tuple->mainAddr;
872  else
873  return iface_addr;
874 }
875 
879 void
881 {
882  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " s: Node " << m_mainAddress
883  << ": RoutingTableComputation begin...");
884 
885  // 1. All the entries from the routing table are removed.
886  Clear ();
887 
888  // 2. The new routing entries are added starting with the
889  // symmetric neighbors (h=1) as the destination nodes.
890  const NeighborSet &neighborSet = m_state.GetNeighbors ();
891  for (NeighborSet::const_iterator it = neighborSet.begin ();
892  it != neighborSet.end (); it++)
893  {
894  NeighborTuple const &nb_tuple = *it;
895  NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple);
896  if (nb_tuple.status == NeighborTuple::STATUS_SYM)
897  {
898  bool nb_main_addr = false;
899  const LinkTuple *lt = NULL;
900  const LinkSet &linkSet = m_state.GetLinks ();
901  for (LinkSet::const_iterator it2 = linkSet.begin ();
902  it2 != linkSet.end (); it2++)
903  {
904  LinkTuple const &link_tuple = *it2;
905  NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple
906  << (link_tuple.time >= Simulator::Now () ? "" : " (expired)"));
907  if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr)
908  && link_tuple.time >= Simulator::Now ())
909  {
910  NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr
911  << " => adding routing table entry to neighbor");
912  lt = &link_tuple;
913  AddEntry (link_tuple.neighborIfaceAddr,
914  link_tuple.neighborIfaceAddr,
915  link_tuple.localIfaceAddr,
916  1);
917  if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
918  {
919  nb_main_addr = true;
920  }
921  }
922  else
923  {
924  NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr)
925  << "; neighborMainAddr = " << nb_tuple.neighborMainAddr
926  << "; expired=" << int (link_tuple.time < Simulator::Now ())
927  << " => IGNORE");
928  }
929  }
930 
931  // If, in the above, no R_dest_addr is equal to the main
932  // address of the neighbor, then another new routing entry
933  // with MUST be added, with:
934  // R_dest_addr = main address of the neighbor;
935  // R_next_addr = L_neighbor_iface_addr of one of the
936  // associated link tuple with L_time >= current time;
937  // R_dist = 1;
938  // R_iface_addr = L_local_iface_addr of the
939  // associated link tuple.
940  if (!nb_main_addr && lt != NULL)
941  {
942  NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor "
943  "=> adding additional routing entry");
944  AddEntry (nb_tuple.neighborMainAddr,
945  lt->neighborIfaceAddr,
946  lt->localIfaceAddr,
947  1);
948  }
949  }
950  }
951 
952  // 3. for each node in N2, i.e., a 2-hop neighbor which is not a
953  // neighbor node or the node itself, and such that there exist at
954  // least one entry in the 2-hop neighbor set where
955  // N_neighbor_main_addr correspond to a neighbor node with
956  // willingness different of WILL_NEVER,
957  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
958  for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin ();
959  it != twoHopNeighbors.end (); it++)
960  {
961  TwoHopNeighborTuple const &nb2hop_tuple = *it;
962 
963  NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
964 
965  // a 2-hop neighbor which is not a neighbor node or the node itself
967  {
968  NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped.");
969  continue;
970  }
971 
972  if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
973  {
974  NS_LOG_LOGIC ("Two-hop neighbor is self; skipped.");
975  continue;
976  }
977 
978  // ...and such that there exist at least one entry in the 2-hop
979  // neighbor set where N_neighbor_main_addr correspond to a
980  // neighbor node with willingness different of WILL_NEVER...
981  bool nb2hopOk = false;
982  for (NeighborSet::const_iterator neighbor = neighborSet.begin ();
983  neighbor != neighborSet.end (); neighbor++)
984  {
985  if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr
986  && neighbor->willingness != OLSR_WILL_NEVER)
987  {
988  nb2hopOk = true;
989  break;
990  }
991  }
992  if (!nb2hopOk)
993  {
994  NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor "
995  << nb2hop_tuple.twoHopNeighborAddr
996  << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr
997  << ", which was not found in the Neighbor Set.");
998  continue;
999  }
1000 
1001  // one selects one 2-hop tuple and creates one entry in the routing table with:
1002  // R_dest_addr = the main address of the 2-hop neighbor;
1003  // R_next_addr = the R_next_addr of the entry in the
1004  // routing table with:
1005  // R_dest_addr == N_neighbor_main_addr
1006  // of the 2-hop tuple;
1007  // R_dist = 2;
1008  // R_iface_addr = the R_iface_addr of the entry in the
1009  // routing table with:
1010  // R_dest_addr == N_neighbor_main_addr
1011  // of the 2-hop tuple;
1012  RoutingTableEntry entry;
1013  bool foundEntry = Lookup (nb2hop_tuple.neighborMainAddr, entry);
1014  if (foundEntry)
1015  {
1016  NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor.");
1017  AddEntry (nb2hop_tuple.twoHopNeighborAddr,
1018  entry.nextAddr,
1019  entry.interface,
1020  2);
1021  }
1022  else
1023  {
1024  NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor ("
1025  << nb2hop_tuple.twoHopNeighborAddr
1026  << " not found in the routing table)");
1027  }
1028  }
1029 
1030  for (uint32_t h = 2;; h++)
1031  {
1032  bool added = false;
1033 
1034  // 3.1. For each topology entry in the topology table, if its
1035  // T_dest_addr does not correspond to R_dest_addr of any
1036  // route entry in the routing table AND its T_last_addr
1037  // corresponds to R_dest_addr of a route entry whose R_dist
1038  // is equal to h, then a new route entry MUST be recorded in
1039  // the routing table (if it does not already exist)
1040  const TopologySet &topology = m_state.GetTopologySet ();
1041  for (TopologySet::const_iterator it = topology.begin ();
1042  it != topology.end (); it++)
1043  {
1044  const TopologyTuple &topology_tuple = *it;
1045  NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple);
1046 
1047  RoutingTableEntry destAddrEntry, lastAddrEntry;
1048  bool have_destAddrEntry = Lookup (topology_tuple.destAddr, destAddrEntry);
1049  bool have_lastAddrEntry = Lookup (topology_tuple.lastAddr, lastAddrEntry);
1050  if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
1051  {
1052  NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple.");
1053  // then a new route entry MUST be recorded in
1054  // the routing table (if it does not already exist) where:
1055  // R_dest_addr = T_dest_addr;
1056  // R_next_addr = R_next_addr of the recorded
1057  // route entry where:
1058  // R_dest_addr == T_last_addr
1059  // R_dist = h+1; and
1060  // R_iface_addr = R_iface_addr of the recorded
1061  // route entry where:
1062  // R_dest_addr == T_last_addr.
1063  AddEntry (topology_tuple.destAddr,
1064  lastAddrEntry.nextAddr,
1065  lastAddrEntry.interface,
1066  h + 1);
1067  added = true;
1068  }
1069  else
1070  {
1071  NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: "
1072  "have_destAddrEntry=" << have_destAddrEntry
1073  << " have_lastAddrEntry=" << have_lastAddrEntry
1074  << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance
1075  << " (h=" << h << ")");
1076  }
1077  }
1078 
1079  if (!added)
1080  break;
1081  }
1082 
1083  // 4. For each entry in the multiple interface association base
1084  // where there exists a routing entry such that:
1085  // R_dest_addr == I_main_addr (of the multiple interface association entry)
1086  // AND there is no routing entry such that:
1087  // R_dest_addr == I_iface_addr
1088  const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
1089  for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
1090  it != ifaceAssocSet.end (); it++)
1091  {
1092  IfaceAssocTuple const &tuple = *it;
1093  RoutingTableEntry entry1, entry2;
1094  bool have_entry1 = Lookup (tuple.mainAddr, entry1);
1095  bool have_entry2 = Lookup (tuple.ifaceAddr, entry2);
1096  if (have_entry1 && !have_entry2)
1097  {
1098  // then a route entry is created in the routing table with:
1099  // R_dest_addr = I_iface_addr (of the multiple interface
1100  // association entry)
1101  // R_next_addr = R_next_addr (of the recorded route entry)
1102  // R_dist = R_dist (of the recorded route entry)
1103  // R_iface_addr = R_iface_addr (of the recorded route entry).
1104  AddEntry (tuple.ifaceAddr,
1105  entry1.nextAddr,
1106  entry1.interface,
1107  entry1.distance);
1108  }
1109  }
1110 
1111  // 5. For each tuple in the association set,
1112  // If there is no entry in the routing table with:
1113  // R_dest_addr == A_network_addr/A_netmask
1114  // and if the announced network is not announced by the node itself,
1115  // then a new routing entry is created.
1116  const AssociationSet &associationSet = m_state.GetAssociationSet ();
1117 
1118  // Clear HNA routing table
1119  for (uint32_t i = 0; i < m_hnaRoutingTable->GetNRoutes (); i++)
1120  {
1121  m_hnaRoutingTable->RemoveRoute (0);
1122  }
1123 
1124  for (AssociationSet::const_iterator it = associationSet.begin ();
1125  it != associationSet.end (); it++)
1126  {
1127  AssociationTuple const &tuple = *it;
1128 
1129  // Test if HNA associations received from other gateways
1130  // are also announced by this node. In such a case, no route
1131  // is created for this association tuple (go to the next one).
1132  bool goToNextAssociationTuple = false;
1133  const Associations &localHnaAssociations = m_state.GetAssociations ();
1134  NS_LOG_DEBUG ("Nb local associations: " << localHnaAssociations.size ());
1135  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1136  assocIterator != localHnaAssociations.end (); assocIterator++)
1137  {
1138  Association const &localHnaAssoc = *assocIterator;
1139  if (localHnaAssoc.networkAddr == tuple.networkAddr && localHnaAssoc.netmask == tuple.netmask)
1140  {
1141  NS_LOG_DEBUG ("HNA association received from another GW is part of local HNA associations: no route added for network "
1142  << tuple.networkAddr << "/" << tuple.netmask);
1143  goToNextAssociationTuple = true;
1144  }
1145  }
1146  if (goToNextAssociationTuple)
1147  {
1148  continue;
1149  }
1150 
1151  RoutingTableEntry gatewayEntry;
1152 
1153  bool gatewayEntryExists = Lookup (tuple.gatewayAddr, gatewayEntry);
1154  bool addRoute = false;
1155 
1156  uint32_t routeIndex = 0;
1157 
1158  for (routeIndex = 0; routeIndex < m_hnaRoutingTable->GetNRoutes (); routeIndex++)
1159  {
1160  Ipv4RoutingTableEntry route = m_hnaRoutingTable->GetRoute (routeIndex);
1161  if (route.GetDestNetwork () == tuple.networkAddr &&
1162  route.GetDestNetworkMask () == tuple.netmask)
1163  {
1164  break;
1165  }
1166  }
1167 
1168  if (routeIndex == m_hnaRoutingTable->GetNRoutes ())
1169  {
1170  addRoute = true;
1171  }
1172  else if(gatewayEntryExists && m_hnaRoutingTable->GetMetric (routeIndex) > gatewayEntry.distance)
1173  {
1174  m_hnaRoutingTable->RemoveRoute (routeIndex);
1175  addRoute = true;
1176  }
1177 
1178  if(addRoute && gatewayEntryExists)
1179  {
1180  m_hnaRoutingTable->AddNetworkRouteTo (tuple.networkAddr,
1181  tuple.netmask,
1182  gatewayEntry.nextAddr,
1183  gatewayEntry.interface,
1184  gatewayEntry.distance);
1185 
1186  }
1187  }
1188 
1189  NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
1191 }
1192 
1193 
1204 void
1206  const Ipv4Address &receiverIface,
1207  const Ipv4Address &senderIface)
1208 {
1209  NS_LOG_FUNCTION (msg << receiverIface << senderIface);
1210 
1211  const olsr::MessageHeader::Hello &hello = msg.GetHello ();
1212 
1213  LinkSensing (msg, hello, receiverIface, senderIface);
1214 
1215 #ifdef NS3_LOG_ENABLE
1216  {
1217  const LinkSet &links = m_state.GetLinks ();
1218  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1219  << "s ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
1220  for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++)
1221  {
1222  NS_LOG_DEBUG (*link);
1223  }
1224  NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress);
1225 
1226  const NeighborSet &neighbors = m_state.GetNeighbors ();
1227  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1228  << "s ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
1229  for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1230  {
1231  NS_LOG_DEBUG (*neighbor);
1232  }
1233  NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
1234  }
1235 #endif // NS3_LOG_ENABLE
1236 
1237  PopulateNeighborSet (msg, hello);
1238  PopulateTwoHopNeighborSet (msg, hello);
1239 
1240 #ifdef NS3_LOG_ENABLE
1241  {
1242  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1243  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1244  << "s ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1245  for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin ();
1246  tuple != twoHopNeighbors.end (); tuple++)
1247  {
1248  NS_LOG_DEBUG (*tuple);
1249  }
1250  NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1251  }
1252 #endif // NS3_LOG_ENABLE
1253 
1254  MprComputation ();
1255  PopulateMprSelectorSet (msg, hello);
1256 }
1257 
1267 void
1269  const Ipv4Address &senderIface)
1270 {
1271  const olsr::MessageHeader::Tc &tc = msg.GetTc ();
1272  Time now = Simulator::Now ();
1273 
1274  // 1. If the sender interface of this message is not in the symmetric
1275  // 1-hop neighborhood of this node, the message MUST be discarded.
1276  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1277  if (link_tuple == NULL)
1278  return;
1279 
1280  // 2. If there exist some tuple in the topology set where:
1281  // T_last_addr == originator address AND
1282  // T_seq > ANSN,
1283  // then further processing of this TC message MUST NOT be
1284  // performed.
1285  const TopologyTuple *topologyTuple =
1287  if (topologyTuple != NULL)
1288  return;
1289 
1290  // 3. All tuples in the topology set where:
1291  // T_last_addr == originator address AND
1292  // T_seq < ANSN
1293  // MUST be removed from the topology set.
1295 
1296  // 4. For each of the advertised neighbor main address received in
1297  // the TC message:
1298  for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin ();
1299  i != tc.neighborAddresses.end (); i++)
1300  {
1301  const Ipv4Address &addr = *i;
1302  // 4.1. If there exist some tuple in the topology set where:
1303  // T_dest_addr == advertised neighbor main address, AND
1304  // T_last_addr == originator address,
1305  // then the holding time of that tuple MUST be set to:
1306  // T_time = current time + validity time.
1307  TopologyTuple *topologyTuple =
1309 
1310  if (topologyTuple != NULL)
1311  {
1312  topologyTuple->expirationTime = now + msg.GetVTime ();
1313  }
1314  else
1315  {
1316  // 4.2. Otherwise, a new tuple MUST be recorded in the topology
1317  // set where:
1318  // T_dest_addr = advertised neighbor main address,
1319  // T_last_addr = originator address,
1320  // T_seq = ANSN,
1321  // T_time = current time + validity time.
1322  TopologyTuple topologyTuple;;
1323  topologyTuple.destAddr = addr;
1324  topologyTuple.lastAddr = msg.GetOriginatorAddress ();
1325  topologyTuple.sequenceNumber = tc.ansn;
1326  topologyTuple.expirationTime = now + msg.GetVTime ();
1327  AddTopologyTuple (topologyTuple);
1328 
1329  // Schedules topology tuple deletion
1332  this,
1333  topologyTuple.destAddr,
1334  topologyTuple.lastAddr));
1335  }
1336  }
1337 
1338 #ifdef NS3_LOG_ENABLE
1339  {
1340  const TopologySet &topology = m_state.GetTopologySet ();
1341  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1342  << "s ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
1343  for (TopologySet::const_iterator tuple = topology.begin ();
1344  tuple != topology.end (); tuple++)
1345  {
1346  NS_LOG_DEBUG (*tuple);
1347  }
1348  NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
1349  }
1350 #endif // NS3_LOG_ENABLE
1351 }
1352 
1362 void
1364  const Ipv4Address &senderIface)
1365 {
1366  const olsr::MessageHeader::Mid &mid = msg.GetMid ();
1367  Time now = Simulator::Now ();
1368 
1369  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
1370  // 1. If the sender interface of this message is not in the symmetric
1371  // 1-hop neighborhood of this node, the message MUST be discarded.
1372  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
1373  if (linkTuple == NULL)
1374  {
1375  NS_LOG_LOGIC ("Node " << m_mainAddress <<
1376  ": the sender interface of this message is not in the "
1377  "symmetric 1-hop neighborhood of this node,"
1378  " the message MUST be discarded.");
1379  return;
1380  }
1381 
1382  // 2. For each interface address listed in the MID message
1383  for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
1384  i != mid.interfaceAddresses.end (); i++)
1385  {
1386  bool updated = false;
1388  for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin ();
1389  tuple != ifaceAssoc.end (); tuple++)
1390  {
1391  if (tuple->ifaceAddr == *i
1392  && tuple->mainAddr == msg.GetOriginatorAddress ())
1393  {
1394  NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple);
1395  tuple->time = now + msg.GetVTime ();
1396  updated = true;
1397  }
1398  }
1399  if (!updated)
1400  {
1401  IfaceAssocTuple tuple;
1402  tuple.ifaceAddr = *i;
1403  tuple.mainAddr = msg.GetOriginatorAddress ();
1404  tuple.time = now + msg.GetVTime ();
1405  AddIfaceAssocTuple (tuple);
1406  NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple);
1407  // Schedules iface association tuple deletion
1408  Simulator::Schedule (DELAY (tuple.time),
1410  }
1411  }
1412 
1413  // 3. (not part of the RFC) iterate over all NeighborTuple's and
1414  // TwoHopNeighborTuples, update the neighbor addresses taking into account
1415  // the new MID information.
1416  NeighborSet &neighbors = m_state.GetNeighbors ();
1417  for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1418  {
1419  neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr);
1420  }
1421 
1422  TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1423  for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin ();
1424  twoHopNeighbor != twoHopNeighbors.end (); twoHopNeighbor++)
1425  {
1426  twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr);
1427  twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr);
1428  }
1429  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
1430 }
1431 
1441 void
1443  const Ipv4Address &senderIface)
1444 {
1445 
1446  const olsr::MessageHeader::Hna &hna = msg.GetHna ();
1447  Time now = Simulator::Now ();
1448 
1449  // 1. If the sender interface of this message is not in the symmetric
1450  // 1-hop neighborhood of this node, the message MUST be discarded.
1451  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1452  if (link_tuple == NULL)
1453  return;
1454 
1455  // 2. Otherwise, for each (network address, netmask) pair in the
1456  // message:
1457 
1458  for (std::vector<olsr::MessageHeader::Hna::Association>::const_iterator it = hna.associations.begin ();
1459  it != hna.associations.end (); it++)
1460  {
1461  AssociationTuple *tuple = m_state.FindAssociationTuple (msg.GetOriginatorAddress (),it->address,it->mask);
1462 
1463  // 2.1 if an entry in the association set already exists, where:
1464  // A_gateway_addr == originator address
1465  // A_network_addr == network address
1466  // A_netmask == netmask
1467  // then the holding time for that tuple MUST be set to:
1468  // A_time = current time + validity time
1469  if(tuple != NULL)
1470  {
1471  tuple->expirationTime = now + msg.GetVTime ();
1472  }
1473 
1474  // 2.2 otherwise, a new tuple MUST be recorded with:
1475  // A_gateway_addr = originator address
1476  // A_network_addr = network address
1477  // A_netmask = netmask
1478  // A_time = current time + validity time
1479  else
1480  {
1481  AssociationTuple assocTuple = {
1482  msg.GetOriginatorAddress (),
1483  it->address,
1484  it->mask,
1485  now + msg.GetVTime ()
1486  };
1487  AddAssociationTuple (assocTuple);
1488 
1489  //Schedule Association Tuple deletion
1492  assocTuple.gatewayAddr,assocTuple.networkAddr,assocTuple.netmask);
1493  }
1494 
1495  }
1496 }
1497 
1509 void
1511  DuplicateTuple *duplicated,
1512  const Ipv4Address &localIface,
1513  const Ipv4Address &senderAddress)
1514 {
1515  Time now = Simulator::Now ();
1516 
1517  // If the sender interface address is not in the symmetric
1518  // 1-hop neighborhood the message must not be forwarded
1519  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
1520  if (linkTuple == NULL)
1521  return;
1522 
1523  // If the message has already been considered for forwarding,
1524  // it must not be retransmitted again
1525  if (duplicated != NULL && duplicated->retransmitted)
1526  {
1527  NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received"
1528  " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
1529  return;
1530  }
1531 
1532  // If the sender interface address is an interface address
1533  // of a MPR selector of this node and ttl is greater than 1,
1534  // the message must be retransmitted
1535  bool retransmitted = false;
1536  if (olsrMessage.GetTimeToLive () > 1)
1537  {
1538  const MprSelectorTuple *mprselTuple =
1539  m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
1540  if (mprselTuple != NULL)
1541  {
1542  olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1);
1543  olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1);
1544  // We have to introduce a random delay to avoid
1545  // synchronization with neighbors.
1546  QueueMessage (olsrMessage, JITTER);
1547  retransmitted = true;
1548  }
1549  }
1550 
1551  // Update duplicate tuple...
1552  if (duplicated != NULL)
1553  {
1554  duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
1555  duplicated->retransmitted = retransmitted;
1556  duplicated->ifaceList.push_back (localIface);
1557  }
1558  // ...or create a new one
1559  else
1560  {
1561  DuplicateTuple newDup;
1562  newDup.address = olsrMessage.GetOriginatorAddress ();
1563  newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber ();
1564  newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
1565  newDup.retransmitted = retransmitted;
1566  newDup.ifaceList.push_back (localIface);
1567  AddDuplicateTuple (newDup);
1568  // Schedule dup tuple deletion
1569  Simulator::Schedule (OLSR_DUP_HOLD_TIME,
1571  newDup.address, newDup.sequenceNumber);
1572  }
1573 }
1574 
1584 void
1586 {
1587  m_queuedMessages.push_back (message);
1588  if (not m_queuedMessagesTimer.IsRunning ())
1589  {
1592  }
1593 }
1594 
1595 void
1597  const MessageList &containedMessages)
1598 {
1599  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet");
1600 
1601  // Add a header
1602  olsr::PacketHeader header;
1603  header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ());
1605  packet->AddHeader (header);
1606 
1607  // Trace it
1608  m_txPacketTrace (header, containedMessages);
1609 
1610  // Send it
1611  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1612  m_socketAddresses.begin (); i != m_socketAddresses.end (); i++)
1613  {
1614  Ipv4Address bcast = i->second.GetLocal ().GetSubnetDirectedBroadcast (i->second.GetMask ());
1615  i->first->SendTo (packet, 0, InetSocketAddress (bcast, OLSR_PORT_NUMBER));
1616  }
1617 }
1618 
1626 void
1628 {
1629  Ptr<Packet> packet = Create<Packet> ();
1630  int numMessages = 0;
1631 
1632  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages");
1633 
1634  MessageList msglist;
1635 
1636  for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin ();
1637  message != m_queuedMessages.end ();
1638  message++)
1639  {
1640  Ptr<Packet> p = Create<Packet> ();
1641  p->AddHeader (*message);
1642  packet->AddAtEnd (p);
1643  msglist.push_back (*message);
1644  if (++numMessages == OLSR_MAX_MSGS)
1645  {
1646  SendPacket (packet, msglist);
1647  msglist.clear ();
1648  // Reset variables for next packet
1649  numMessages = 0;
1650  packet = Create<Packet> ();
1651  }
1652  }
1653 
1654  if (packet->GetSize ())
1655  {
1656  SendPacket (packet, msglist);
1657  }
1658 
1659  m_queuedMessages.clear ();
1660 }
1661 
1665 void
1667 {
1668  NS_LOG_FUNCTION (this);
1669 
1670  olsr::MessageHeader msg;
1671  Time now = Simulator::Now ();
1672 
1675  msg.SetTimeToLive (1);
1676  msg.SetHopCount (0);
1678  olsr::MessageHeader::Hello &hello = msg.GetHello ();
1679 
1680  hello.SetHTime (m_helloInterval);
1681  hello.willingness = m_willingness;
1682 
1683  std::vector<olsr::MessageHeader::Hello::LinkMessage>
1684  &linkMessages = hello.linkMessages;
1685 
1686  const LinkSet &links = m_state.GetLinks ();
1687  for (LinkSet::const_iterator link_tuple = links.begin ();
1688  link_tuple != links.end (); link_tuple++)
1689  {
1690  if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress
1691  && link_tuple->time >= now))
1692  {
1693  continue;
1694  }
1695 
1696  uint8_t link_type, nb_type = 0xff;
1697 
1698  // Establishes link type
1699  if (link_tuple->symTime >= now)
1700  {
1701  link_type = OLSR_SYM_LINK;
1702  }
1703  else if (link_tuple->asymTime >= now)
1704  {
1705  link_type = OLSR_ASYM_LINK;
1706  }
1707  else
1708  {
1709  link_type = OLSR_LOST_LINK;
1710  }
1711  // Establishes neighbor type.
1712  if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
1713  {
1714  nb_type = OLSR_MPR_NEIGH;
1715  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1716  << " to be MPR_NEIGH.");
1717  }
1718  else
1719  {
1720  bool ok = false;
1721  for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin ();
1722  nb_tuple != m_state.GetNeighbors ().end ();
1723  nb_tuple++)
1724  {
1725  if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr))
1726  {
1727  if (nb_tuple->status == NeighborTuple::STATUS_SYM)
1728  {
1729  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1730  << " to be SYM_NEIGH.");
1731  nb_type = OLSR_SYM_NEIGH;
1732  }
1733  else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
1734  {
1735  nb_type = OLSR_NOT_NEIGH;
1736  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1737  << " to be NOT_NEIGH.");
1738  }
1739  else
1740  {
1741  NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n");
1742  }
1743  ok = true;
1744  break;
1745  }
1746  }
1747  if (!ok)
1748  {
1749  NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
1750  continue;
1751  }
1752  }
1753 
1755  linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f);
1756  linkMessage.neighborInterfaceAddresses.push_back
1757  (link_tuple->neighborIfaceAddr);
1758 
1759  std::vector<Ipv4Address> interfaces =
1760  m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr);
1761 
1762  linkMessage.neighborInterfaceAddresses.insert
1763  (linkMessage.neighborInterfaceAddresses.end (),
1764  interfaces.begin (), interfaces.end ());
1765 
1766  linkMessages.push_back (linkMessage);
1767  }
1768  NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ())
1769  << " (with " << int (linkMessages.size ()) << " link messages)");
1770  QueueMessage (msg, JITTER);
1771 }
1772 
1776 void
1778 {
1779  NS_LOG_FUNCTION (this);
1780 
1781  olsr::MessageHeader msg;
1782 
1785  msg.SetTimeToLive (255);
1786  msg.SetHopCount (0);
1788 
1789  olsr::MessageHeader::Tc &tc = msg.GetTc ();
1790  tc.ansn = m_ansn;
1791 
1792  for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin ();
1793  mprsel_tuple != m_state.GetMprSelectors ().end (); mprsel_tuple++)
1794  {
1795  tc.neighborAddresses.push_back (mprsel_tuple->mainAddr);
1796  }
1797  QueueMessage (msg, JITTER);
1798 }
1799 
1803 void
1805 {
1806  olsr::MessageHeader msg;
1807  olsr::MessageHeader::Mid &mid = msg.GetMid ();
1808 
1809  // A node which has only a single interface address participating in
1810  // the MANET (i.e., running OLSR), MUST NOT generate any MID
1811  // message.
1812 
1813  // A node with several interfaces, where only one is participating
1814  // in the MANET and running OLSR (e.g., a node is connected to a
1815  // wired network as well as to a MANET) MUST NOT generate any MID
1816  // messages.
1817 
1818  // A node with several interfaces, where more than one is
1819  // participating in the MANET and running OLSR MUST generate MID
1820  // messages as specified.
1821 
1822  // [ Note: assuming here that all interfaces participate in the
1823  // MANET; later we may want to make this configurable. ]
1824 
1825  Ipv4Address loopback ("127.0.0.1");
1826  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
1827  {
1828  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
1829  if (addr != m_mainAddress && addr != loopback && m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
1830  mid.interfaceAddresses.push_back (addr);
1831  }
1832  if (mid.interfaceAddresses.size () == 0)
1833  return;
1834 
1837  msg.SetTimeToLive (255);
1838  msg.SetHopCount (0);
1840 
1841  QueueMessage (msg, JITTER);
1842 }
1843 
1847 void
1849 {
1850 
1851  olsr::MessageHeader msg;
1852 
1855  msg.SetTimeToLive (255);
1856  msg.SetHopCount (0);
1858  olsr::MessageHeader::Hna &hna = msg.GetHna ();
1859 
1860  std::vector<olsr::MessageHeader::Hna::Association> &associations = hna.associations;
1861 
1862  // Add all local HNA associations to the HNA message
1863  const Associations &localHnaAssociations = m_state.GetAssociations ();
1864  for (Associations::const_iterator it = localHnaAssociations.begin ();
1865  it != localHnaAssociations.end (); it++)
1866  {
1867  olsr::MessageHeader::Hna::Association assoc = { it->networkAddr, it->netmask};
1868  associations.push_back (assoc);
1869  }
1870  // If there is no HNA associations to send, return without queuing the message
1871  if (associations.size () == 0)
1872  {
1873  return;
1874  }
1875 
1876  // Else, queue the message to be sent later on
1877  QueueMessage (msg, JITTER);
1878 }
1879 
1885 void
1887 {
1888  // Check if the (networkAddr, netmask) tuple already exist
1889  // in the list of local HNA associations
1890  const Associations &localHnaAssociations = m_state.GetAssociations ();
1891  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1892  assocIterator != localHnaAssociations.end (); assocIterator++)
1893  {
1894  Association const &localHnaAssoc = *assocIterator;
1895  if (localHnaAssoc.networkAddr == networkAddr && localHnaAssoc.netmask == netmask)
1896  {
1897  NS_LOG_INFO ("HNA association for network " << networkAddr << "/" << netmask << " already exists.");
1898  return;
1899  }
1900  }
1901  // If the tuple does not already exist, add it to the list of local HNA associations.
1902  NS_LOG_INFO ("Adding HNA association for network " << networkAddr << "/" << netmask << ".");
1903  m_state.InsertAssociation ( (Association) { networkAddr, netmask} );
1904 }
1905 
1911 void
1913 {
1914  NS_LOG_INFO ("Removing HNA association for network " << networkAddr << "/" << netmask << ".");
1915  m_state.EraseAssociation ( (Association) { networkAddr, netmask} );
1916 }
1917 
1928 void
1930 {
1931  // If a routing table has already been associated, remove
1932  // corresponding entries from the list of local HNA associations
1933  if (m_routingTableAssociation != 0)
1934  {
1935  NS_LOG_INFO ("Removing HNA entries coming from the old routing table association.");
1936  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1937  {
1938  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1939  // If the outgoing interface for this route is a non-olsr interface
1940  if (UsesNonOlsrOutgoingInterface (route))
1941  {
1942  // remove the corresponding entry
1944  }
1945  }
1946  }
1947 
1948  // Sets the routingTableAssociation to its new value
1949  m_routingTableAssociation = routingTable;
1950 
1951  // Iterate over entries of the associated routing table and
1952  // add the routes using non-olsr outgoing interfaces to the list
1953  // of local HNA associations
1954  NS_LOG_DEBUG ("Nb local associations before adding some entries from"
1955  " the associated routing table: " << m_state.GetAssociations ().size ());
1956  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1957  {
1958  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1959  Ipv4Address destNetworkAddress = route.GetDestNetwork ();
1960  Ipv4Mask destNetmask = route.GetDestNetworkMask ();
1961 
1962  // If the outgoing interface for this route is a non-olsr interface,
1963  if (UsesNonOlsrOutgoingInterface (route))
1964  {
1965  // Add this entry's network address and netmask to the list of local HNA entries
1966  AddHostNetworkAssociation (destNetworkAddress, destNetmask);
1967  }
1968  }
1969  NS_LOG_DEBUG ("Nb local associations after having added some entries from "
1970  "the associated routing table: " << m_state.GetAssociations ().size ());
1971 }
1972 
1978 bool
1980 {
1981  std::set<uint32_t>::const_iterator ci = m_interfaceExclusions.find (route.GetInterface ());
1982  // The outgoing interface is a non-OLSR interface if a match is found
1983  // before reaching the end of the list of excluded interfaces
1984  return ci != m_interfaceExclusions.end ();
1985 }
1986 
1990 void
1992  const olsr::MessageHeader::Hello &hello,
1993  const Ipv4Address &receiverIface,
1994  const Ipv4Address &senderIface)
1995 {
1996  Time now = Simulator::Now ();
1997  bool updated = false;
1998  bool created = false;
1999  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
2000  << ": LinkSensing(receiverIface=" << receiverIface
2001  << ", senderIface=" << senderIface << ") BEGIN");
2002 
2003  NS_ASSERT (msg.GetVTime () > Seconds (0));
2004  LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
2005  if (link_tuple == NULL)
2006  {
2007  LinkTuple newLinkTuple;
2008  // We have to create a new tuple
2009  newLinkTuple.neighborIfaceAddr = senderIface;
2010  newLinkTuple.localIfaceAddr = receiverIface;
2011  newLinkTuple.symTime = now - Seconds (1);
2012  newLinkTuple.time = now + msg.GetVTime ();
2013  link_tuple = &m_state.InsertLinkTuple (newLinkTuple);
2014  created = true;
2015  NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one");
2016  }
2017  else
2018  {
2019  NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
2020  updated = true;
2021  }
2022 
2023  link_tuple->asymTime = now + msg.GetVTime ();
2024  for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
2025  hello.linkMessages.begin ();
2026  linkMessage != hello.linkMessages.end ();
2027  linkMessage++)
2028  {
2029  int lt = linkMessage->linkCode & 0x03; // Link Type
2030  int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type
2031 
2032 #ifdef NS3_LOG_ENABLE
2033  const char *linkTypeName;
2034  switch (lt)
2035  {
2036  case OLSR_UNSPEC_LINK: linkTypeName = "UNSPEC_LINK"; break;
2037  case OLSR_ASYM_LINK: linkTypeName = "ASYM_LINK"; break;
2038  case OLSR_SYM_LINK: linkTypeName = "SYM_LINK"; break;
2039  case OLSR_LOST_LINK: linkTypeName = "LOST_LINK"; break;
2040  /* no default, since lt must be in 0..3, covered above
2041  default: linkTypeName = "(invalid value!)";
2042  */
2043  }
2044 
2045  const char *neighborTypeName;
2046  switch (nt)
2047  {
2048  case OLSR_NOT_NEIGH: neighborTypeName = "NOT_NEIGH"; break;
2049  case OLSR_SYM_NEIGH: neighborTypeName = "SYM_NEIGH"; break;
2050  case OLSR_MPR_NEIGH: neighborTypeName = "MPR_NEIGH"; break;
2051  default: neighborTypeName = "(invalid value!)";
2052  }
2053 
2054  NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type "
2055  << lt << " (" << linkTypeName
2056  << ") and Neighbor Type " << nt
2057  << " (" << neighborTypeName << ")");
2058 #endif // NS3_LOG_ENABLE
2059 
2060  // We must not process invalid advertised links
2061  if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) ||
2062  (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH
2063  && nt != OLSR_NOT_NEIGH))
2064  {
2065  NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING");
2066  continue;
2067  }
2068 
2069  for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr =
2070  linkMessage->neighborInterfaceAddresses.begin ();
2071  neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end ();
2072  neighIfaceAddr++)
2073  {
2074  NS_LOG_DEBUG (" -> Neighbor: " << *neighIfaceAddr);
2075  if (*neighIfaceAddr == receiverIface)
2076  {
2077  if (lt == OLSR_LOST_LINK)
2078  {
2079  NS_LOG_LOGIC ("link is LOST => expiring it");
2080  link_tuple->symTime = now - Seconds (1);
2081  updated = true;
2082  }
2083  else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK)
2084  {
2085  NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now"
2086  " (symTime being increased to " << now + msg.GetVTime ());
2087  link_tuple->symTime = now + msg.GetVTime ();
2088  link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
2089  updated = true;
2090  }
2091  else
2092  {
2093  NS_FATAL_ERROR ("bad link type");
2094  }
2095  break;
2096  }
2097  else
2098  {
2099  NS_LOG_DEBUG (" \\-> *neighIfaceAddr (" << *neighIfaceAddr
2100  << " != receiverIface (" << receiverIface << ") => IGNORING!");
2101  }
2102  }
2103  NS_LOG_DEBUG ("Link tuple updated: " << int (updated));
2104  }
2105  link_tuple->time = std::max (link_tuple->time, link_tuple->asymTime);
2106 
2107  if (updated)
2108  {
2109  LinkTupleUpdated (*link_tuple, hello.willingness);
2110  }
2111 
2112  // Schedules link tuple deletion
2113  if (created)
2114  {
2115  LinkTupleAdded (*link_tuple, hello.willingness);
2116  m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
2118  link_tuple->neighborIfaceAddr));
2119  }
2120  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
2121  << ": LinkSensing END");
2122 }
2123 
2127 void
2129  const olsr::MessageHeader::Hello &hello)
2130 {
2132  if (nb_tuple != NULL)
2133  {
2134  nb_tuple->willingness = hello.willingness;
2135  }
2136 }
2137 
2138 
2142 void
2144  const olsr::MessageHeader::Hello &hello)
2145 {
2146  Time now = Simulator::Now ();
2147 
2148  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
2149 
2150  for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
2151  link_tuple != m_state.GetLinks ().end (); link_tuple++)
2152  {
2153  NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple);
2154  if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ())
2155  {
2156  NS_LOG_LOGIC ("Link tuple ignored: "
2157  "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
2158  NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): "
2159  << GetMainAddress (link_tuple->neighborIfaceAddr)
2160  << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ());
2161  continue;
2162  }
2163 
2164  if (link_tuple->symTime < now)
2165  {
2166  NS_LOG_LOGIC ("Link tuple ignored: expired.");
2167  continue;
2168  }
2169 
2170  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2171  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2172  linkMessage != hello.linkMessages.end (); linkMessage++)
2173  {
2174  int neighborType = (linkMessage->linkCode >> 2) & 0x3;
2175 #ifdef NS3_LOG_ENABLE
2176  const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" };
2177  const char *neighborTypeName = ((neighborType < 3) ?
2178  neighborTypeNames[neighborType]
2179  : "(invalid value)");
2180  NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType="
2181  << neighborType << " (" << neighborTypeName << ")");
2182 #endif // NS3_LOG_ENABLE
2183 
2184  for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter =
2185  linkMessage->neighborInterfaceAddresses.begin ();
2186  nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end ();
2187  nb2hop_addr_iter++)
2188  {
2189  Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter);
2190  NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: "
2191  << *nb2hop_addr_iter
2192  << " (main address is " << nb2hop_addr << ")");
2193  if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH)
2194  {
2195  // If the main address of the 2-hop neighbor address == main address
2196  // of the receiving node, silently discard the 2-hop
2197  // neighbor address.
2198  if (nb2hop_addr == m_mainAddress)
2199  {
2200  NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)");
2201  continue;
2202  }
2203 
2204  // Otherwise, a 2-hop tuple is created
2205  TwoHopNeighborTuple *nb2hop_tuple =
2207  NS_LOG_LOGIC ("Adding the 2-hop neighbor"
2208  << (nb2hop_tuple ? " (refreshing existing entry)" : ""));
2209  if (nb2hop_tuple == NULL)
2210  {
2211  TwoHopNeighborTuple new_nb2hop_tuple;
2212  new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress ();
2213  new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
2214  new_nb2hop_tuple.expirationTime = now + msg.GetVTime ();
2215  AddTwoHopNeighborTuple (new_nb2hop_tuple);
2216  // Schedules nb2hop tuple deletion
2217  m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime),
2219  new_nb2hop_tuple.neighborMainAddr,
2220  new_nb2hop_tuple.twoHopNeighborAddr));
2221  }
2222  else
2223  {
2224  nb2hop_tuple->expirationTime = now + msg.GetVTime ();
2225  }
2226  }
2227  else if (neighborType == OLSR_NOT_NEIGH)
2228  {
2229  // For each 2-hop node listed in the HELLO message
2230  // with Neighbor Type equal to NOT_NEIGH all 2-hop
2231  // tuples where: N_neighbor_main_addr == Originator
2232  // Address AND N_2hop_addr == main address of the
2233  // 2-hop neighbor are deleted.
2234  NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
2236  }
2237  else
2238  {
2239  NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad"
2240  " neighbor type value: " << neighborType);
2241  }
2242  }
2243  }
2244  }
2245 
2246  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
2247 }
2248 
2249 
2250 
2254 void
2256  const olsr::MessageHeader::Hello &hello)
2257 {
2258  NS_LOG_FUNCTION (this);
2259 
2260  Time now = Simulator::Now ();
2261 
2262  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2263  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2264  linkMessage != hello.linkMessages.end ();
2265  linkMessage++)
2266  {
2267  int nt = linkMessage->linkCode >> 2;
2268  if (nt == OLSR_MPR_NEIGH)
2269  {
2270  NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
2271 
2272  for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
2273  linkMessage->neighborInterfaceAddresses.begin ();
2274  nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
2275  nb_iface_addr++)
2276  {
2277  if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
2278  {
2279  NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
2280 
2281  // We must create a new entry into the mpr selector set
2282  MprSelectorTuple *existing_mprsel_tuple =
2284  if (existing_mprsel_tuple == NULL)
2285  {
2286  MprSelectorTuple mprsel_tuple;
2287 
2288  mprsel_tuple.mainAddr = msg.GetOriginatorAddress ();
2289  mprsel_tuple.expirationTime = now + msg.GetVTime ();
2290  AddMprSelectorTuple (mprsel_tuple);
2291 
2292  // Schedules mpr selector tuple deletion
2294  (DELAY (mprsel_tuple.expirationTime),
2296  mprsel_tuple.mainAddr));
2297  }
2298  else
2299  {
2300  existing_mprsel_tuple->expirationTime = now + msg.GetVTime ();
2301  }
2302  }
2303  }
2304  }
2305  }
2306  NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
2307 }
2308 
2309 
2310 #if 0
2311 void
2319 OLSR::mac_failed (Ptr<Packet> p) {
2320  double now = Simulator::Now ();
2321  struct hdr_ip* ih = HDR_IP (p);
2322  struct hdr_cmn* ch = HDR_CMN (p);
2323 
2324  debug ("%f: Node %d MAC Layer detects a breakage on link to %d\n",
2325  now,
2326  OLSR::node_id (ra_addr ()),
2327  OLSR::node_id (ch->next_hop ()));
2328 
2329  if ((u_int32_t)ih->daddr () == IP_BROADCAST) {
2330  drop (p, DROP_RTR_MAC_CALLBACK);
2331  return;
2332  }
2333 
2334  OLSR_link_tuple* link_tuple = state_.find_link_tuple (ch->next_hop ());
2335  if (link_tuple != NULL) {
2336  link_tuple->lost_time () = now + OLSR_NEIGHB_HOLD_TIME;
2337  link_tuple->time () = now + OLSR_NEIGHB_HOLD_TIME;
2338  nb_loss (link_tuple);
2339  }
2340  drop (p, DROP_RTR_MAC_CALLBACK);
2341 }
2342 #endif
2343 
2344 
2345 
2346 
2354 void
2356 {
2357  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2358  << "s: OLSR Node " << m_mainAddress
2359  << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
2363 
2364  MprComputation ();
2366 }
2367 
2373 void
2375 {
2376  /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
2377  Simulator::Now (),
2378  OLSR::node_id(ra_addr()),
2379  OLSR::node_id(tuple->addr()),
2380  tuple->seq_num());*/
2381  m_state.InsertDuplicateTuple (tuple);
2382 }
2383 
2389 void
2391 {
2392  /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
2393  Simulator::Now (),
2394  OLSR::node_id(ra_addr()),
2395  OLSR::node_id(tuple->addr()),
2396  tuple->seq_num());*/
2397  m_state.EraseDuplicateTuple (tuple);
2398 }
2399 
2400 void
2401 RoutingProtocol::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness)
2402 {
2403  // Creates associated neighbor tuple
2404  NeighborTuple nb_tuple;
2406  nb_tuple.willingness = willingness;
2407 
2408  if (tuple.symTime >= Simulator::Now ())
2409  {
2410  nb_tuple.status = NeighborTuple::STATUS_SYM;
2411  }
2412  else
2413  {
2415  }
2416 
2417  AddNeighborTuple (nb_tuple);
2418 }
2419 
2425 void
2427 {
2428  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2429  << "s: OLSR Node " << m_mainAddress
2430  << " LinkTuple " << tuple << " REMOVED.");
2431 
2433  m_state.EraseLinkTuple (tuple);
2434 }
2435 
2442 void
2443 RoutingProtocol::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
2444 {
2445  // Each time a link tuple changes, the associated neighbor tuple must be recomputed
2446 
2447  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2448  << "s: OLSR Node " << m_mainAddress
2449  << " LinkTuple " << tuple << " UPDATED.");
2450 
2451  NeighborTuple *nb_tuple =
2453 
2454  if (nb_tuple == NULL)
2455  {
2456  LinkTupleAdded (tuple, willingness);
2458  }
2459 
2460  if (nb_tuple != NULL)
2461  {
2462  int statusBefore = nb_tuple->status;
2463 
2464  bool hasSymmetricLink = false;
2465 
2466  const LinkSet &linkSet = m_state.GetLinks ();
2467  for (LinkSet::const_iterator it = linkSet.begin ();
2468  it != linkSet.end (); it++)
2469  {
2470  const LinkTuple &link_tuple = *it;
2471  if (GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple->neighborMainAddr
2472  && link_tuple.symTime >= Simulator::Now ())
2473  {
2474  hasSymmetricLink = true;
2475  break;
2476  }
2477  }
2478 
2479  if (hasSymmetricLink)
2480  {
2481  nb_tuple->status = NeighborTuple::STATUS_SYM;
2482  NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_SYM; changed:"
2483  << int (statusBefore != nb_tuple->status));
2484  }
2485  else
2486  {
2488  NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_NOT_SYM; changed:"
2489  << int (statusBefore != nb_tuple->status));
2490  }
2491  }
2492  else
2493  {
2494  NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!");
2495  }
2496 }
2497 
2503 void
2505 {
2506 // debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n",
2507 // Simulator::Now (),
2508 // OLSR::node_id(ra_addr()),
2509 // OLSR::node_id(tuple->neighborMainAddr),
2510 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2511 
2512  m_state.InsertNeighborTuple (tuple);
2513  IncrementAnsn ();
2514 }
2515 
2521 void
2523 {
2524 // debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n",
2525 // Simulator::Now (),
2526 // OLSR::node_id(ra_addr()),
2527 // OLSR::node_id(tuple->neighborMainAddr),
2528 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2529 
2530  m_state.EraseNeighborTuple (tuple);
2531  IncrementAnsn ();
2532 }
2533 
2539 void
2541 {
2542 // debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2543 // Simulator::Now (),
2544 // OLSR::node_id(ra_addr()),
2545 // OLSR::node_id(tuple->neighborMainAddr),
2546 // OLSR::node_id(tuple->twoHopNeighborAddr));
2547 
2549 }
2550 
2556 void
2558 {
2559 // debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2560 // Simulator::Now (),
2561 // OLSR::node_id(ra_addr()),
2562 // OLSR::node_id(tuple->neighborMainAddr),
2563 // OLSR::node_id(tuple->twoHopNeighborAddr));
2564 
2566 }
2567 
2568 void
2570 {
2571  m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1);
2572 }
2573 
2581 void
2583 {
2584 // debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n",
2585 // Simulator::Now (),
2586 // OLSR::node_id(ra_addr()),
2587 // OLSR::node_id(tuple->main_addr()));
2588 
2590  IncrementAnsn ();
2591 }
2592 
2600 void
2602 {
2603 // debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n",
2604 // Simulator::Now (),
2605 // OLSR::node_id(ra_addr()),
2606 // OLSR::node_id(tuple->main_addr()));
2607 
2609  IncrementAnsn ();
2610 }
2611 
2617 void
2619 {
2620 // debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2621 // Simulator::Now (),
2622 // OLSR::node_id(ra_addr()),
2623 // OLSR::node_id(tuple->dest_addr()),
2624 // OLSR::node_id(tuple->last_addr()),
2625 // tuple->seq());
2626 
2627  m_state.InsertTopologyTuple (tuple);
2628 }
2629 
2635 void
2637 {
2638 // debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2639 // Simulator::Now (),
2640 // OLSR::node_id(ra_addr()),
2641 // OLSR::node_id(tuple->dest_addr()),
2642 // OLSR::node_id(tuple->last_addr()),
2643 // tuple->seq());
2644 
2645  m_state.EraseTopologyTuple (tuple);
2646 }
2647 
2653 void
2655 {
2656 // debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n",
2657 // Simulator::Now (),
2658 // OLSR::node_id(ra_addr()),
2659 // OLSR::node_id(tuple->main_addr()),
2660 // OLSR::node_id(tuple->iface_addr()));
2661 
2663 }
2664 
2670 void
2672 {
2673 // debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n",
2674 // Simulator::Now (),
2675 // OLSR::node_id(ra_addr()),
2676 // OLSR::node_id(tuple->main_addr()),
2677 // OLSR::node_id(tuple->iface_addr()));
2678 
2679  m_state.EraseIfaceAssocTuple (tuple);
2680 }
2681 
2687 void
2689 {
2691 }
2692 
2698 void
2700 {
2702 }
2703 
2704 
2705 
2707 {
2709  return m_packetSequenceNumber;
2710 }
2711 
2714 {
2716  return m_messageSequenceNumber;
2717 }
2718 
2719 
2724 void
2726 {
2727  SendHello ();
2729 }
2730 
2735 void
2737 {
2738  if (m_state.GetMprSelectors ().size () > 0)
2739  {
2740  SendTc ();
2741  }
2742  else
2743  {
2744  NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR.");
2745  }
2747 }
2748 
2753 void
2755 {
2756  SendMid ();
2758 }
2759 
2763 void
2765 {
2766  if (m_state.GetAssociations ().size () > 0)
2767  {
2768  SendHna ();
2769  }
2770  else
2771  {
2772  NS_LOG_DEBUG ("Not sending any HNA, no associations to advertise.");
2773  }
2775 }
2776 
2784 void
2786 {
2787  DuplicateTuple *tuple =
2788  m_state.FindDuplicateTuple (address, sequenceNumber);
2789  if (tuple == NULL)
2790  {
2791  return;
2792  }
2793  if (tuple->expirationTime < Simulator::Now ())
2794  {
2795  RemoveDuplicateTuple (*tuple);
2796  }
2797  else
2798  {
2801  address, sequenceNumber));
2802  }
2803 }
2804 
2816 void
2818 {
2819  Time now = Simulator::Now ();
2820 
2821  // the tuple parameter may be a stale copy; get a newer version from m_state
2822  LinkTuple *tuple = m_state.FindLinkTuple (neighborIfaceAddr);
2823  if (tuple == NULL)
2824  {
2825  return;
2826  }
2827  if (tuple->time < now)
2828  {
2829  RemoveLinkTuple (*tuple);
2830  }
2831  else if (tuple->symTime < now)
2832  {
2834  m_linkTupleTimerFirstTime = false;
2835  else
2836  NeighborLoss (*tuple);
2837 
2840  neighborIfaceAddr));
2841  }
2842  else
2843  {
2844  m_events.Track (Simulator::Schedule (DELAY (std::min (tuple->time, tuple->symTime)),
2846  neighborIfaceAddr));
2847  }
2848 }
2849 
2857 void
2859 {
2860  TwoHopNeighborTuple *tuple;
2861  tuple = m_state.FindTwoHopNeighborTuple (neighborMainAddr, twoHopNeighborAddr);
2862  if (tuple == NULL)
2863  {
2864  return;
2865  }
2866  if (tuple->expirationTime < Simulator::Now ())
2867  {
2868  RemoveTwoHopNeighborTuple (*tuple);
2869  }
2870  else
2871  {
2874  this, neighborMainAddr, twoHopNeighborAddr));
2875  }
2876 }
2877 
2885 void
2887 {
2888  MprSelectorTuple *tuple = m_state.FindMprSelectorTuple (mainAddr);
2889  if (tuple == NULL)
2890  {
2891  return;
2892  }
2893  if (tuple->expirationTime < Simulator::Now ())
2894  {
2895  RemoveMprSelectorTuple (*tuple);
2896  }
2897  else
2898  {
2901  this, mainAddr));
2902  }
2903 }
2904 
2912 void
2914 {
2915  TopologyTuple *tuple = m_state.FindTopologyTuple (destAddr, lastAddr);
2916  if (tuple == NULL)
2917  {
2918  return;
2919  }
2920  if (tuple->expirationTime < Simulator::Now ())
2921  {
2922  RemoveTopologyTuple (*tuple);
2923  }
2924  else
2925  {
2928  this, tuple->destAddr, tuple->lastAddr));
2929  }
2930 }
2931 
2936 void
2938 {
2939  IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (ifaceAddr);
2940  if (tuple == NULL)
2941  {
2942  return;
2943  }
2944  if (tuple->time < Simulator::Now ())
2945  {
2946  RemoveIfaceAssocTuple (*tuple);
2947  }
2948  else
2949  {
2952  this, ifaceAddr));
2953  }
2954 }
2955 
2959 void
2961 {
2962  AssociationTuple *tuple = m_state.FindAssociationTuple (gatewayAddr, networkAddr, netmask);
2963  if (tuple == NULL)
2964  {
2965  return;
2966  }
2967  if (tuple->expirationTime < Simulator::Now ())
2968  {
2969  RemoveAssociationTuple (*tuple);
2970  }
2971  else
2972  {
2975  this, gatewayAddr, networkAddr, netmask));
2976  }
2977 }
2978 
2982 void
2984 {
2986  m_table.clear ();
2987 }
2988 
2993 void
2995 {
2996  m_table.erase (dest);
2997 }
2998 
3005 bool
3007  RoutingTableEntry &outEntry) const
3008 {
3009  // Get the iterator at "dest" position
3010  std::map<Ipv4Address, RoutingTableEntry>::const_iterator it =
3011  m_table.find (dest);
3012  // If there is no route to "dest", return NULL
3013  if (it == m_table.end ())
3014  return false;
3015  outEntry = it->second;
3016  return true;
3017 }
3018 
3035 bool
3037  RoutingTableEntry &outEntry) const
3038 {
3039  outEntry = entry;
3040  while (outEntry.destAddr != outEntry.nextAddr)
3041  {
3042  if (not Lookup (outEntry.nextAddr, outEntry))
3043  return false;
3044  }
3045  return true;
3046 }
3047 
3050 {
3051  NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination () << " " << oif);
3052  Ptr<Ipv4Route> rtentry;
3053  RoutingTableEntry entry1, entry2;
3054  bool found = false;
3055 
3056  if (Lookup (header.GetDestination (), entry1) != 0)
3057  {
3058  bool foundSendEntry = FindSendEntry (entry1, entry2);
3059  if (!foundSendEntry)
3060  {
3061  NS_FATAL_ERROR ("FindSendEntry failure");
3062  }
3063  uint32_t interfaceIdx = entry2.interface;
3064  if (oif && m_ipv4->GetInterfaceForDevice (oif) != static_cast<int> (interfaceIdx))
3065  {
3066  // We do not attempt to perform a constrained routing search
3067  // if the caller specifies the oif; we just enforce that
3068  // that the found route matches the requested outbound interface
3069  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3070  << ": RouteOutput for dest=" << header.GetDestination ()
3071  << " Route interface " << interfaceIdx
3072  << " does not match requested output interface "
3073  << m_ipv4->GetInterfaceForDevice (oif));
3074  sockerr = Socket::ERROR_NOROUTETOHOST;
3075  return rtentry;
3076  }
3077  rtentry = Create<Ipv4Route> ();
3078  rtentry->SetDestination (header.GetDestination ());
3079  // the source address is the interface address that matches
3080  // the destination address (when multiple are present on the
3081  // outgoing interface, one is selected via scoping rules)
3082  NS_ASSERT (m_ipv4);
3083  uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
3084  NS_ASSERT (numOifAddresses > 0);
3085  Ipv4InterfaceAddress ifAddr;
3086  if (numOifAddresses == 1) {
3087  ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
3088  } else {
3090  NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and OLSR");
3091  }
3092  rtentry->SetSource (ifAddr.GetLocal ());
3093  rtentry->SetGateway (entry2.nextAddr);
3094  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
3095  sockerr = Socket::ERROR_NOTERROR;
3096  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3097  << ": RouteOutput for dest=" << header.GetDestination ()
3098  << " --> nextHop=" << entry2.nextAddr
3099  << " interface=" << entry2.interface);
3100  NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
3101  found = true;
3102  }
3103  else
3104  {
3105  rtentry = m_hnaRoutingTable->RouteOutput (p, header, oif, sockerr);
3106 
3107  if (rtentry)
3108  {
3109  found = true;
3110  NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
3111  }
3112  }
3113 
3114  if (!found)
3115  {
3116  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3117  << ": RouteOutput for dest=" << header.GetDestination ()
3118  << " No route to host");
3119  sockerr = Socket::ERROR_NOROUTETOHOST;
3120  }
3121  return rtentry;
3122 }
3123 
3125  const Ipv4Header &header, Ptr<const NetDevice> idev,
3128 {
3129  NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination ());
3130 
3131  Ipv4Address dst = header.GetDestination ();
3132  Ipv4Address origin = header.GetSource ();
3133 
3134  // Consume self-originated packets
3135  if (IsMyOwnAddress (origin) == true)
3136  {
3137  return true;
3138  }
3139 
3140  // Local delivery
3141  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
3142  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
3143  if (m_ipv4->IsDestinationAddress (dst, iif))
3144  {
3145  if (!lcb.IsNull ())
3146  {
3147  NS_LOG_LOGIC ("Local delivery to " << dst);
3148  lcb (p, header, iif);
3149  return true;
3150  }
3151  else
3152  {
3153  // The local delivery callback is null. This may be a multicast
3154  // or broadcast packet, so return false so that another
3155  // multicast routing protocol can handle it. It should be possible
3156  // to extend this to explicitly check whether it is a unicast
3157  // packet, and invoke the error callback if so
3158  return false;
3159  }
3160  }
3161 
3162  // Forwarding
3163  Ptr<Ipv4Route> rtentry;
3164  RoutingTableEntry entry1, entry2;
3165  if (Lookup (header.GetDestination (), entry1))
3166  {
3167  bool foundSendEntry = FindSendEntry (entry1, entry2);
3168  if (!foundSendEntry)
3169  NS_FATAL_ERROR ("FindSendEntry failure");
3170  rtentry = Create<Ipv4Route> ();
3171  rtentry->SetDestination (header.GetDestination ());
3172  uint32_t interfaceIdx = entry2.interface;
3173  // the source address is the interface address that matches
3174  // the destination address (when multiple are present on the
3175  // outgoing interface, one is selected via scoping rules)
3176  NS_ASSERT (m_ipv4);
3177  uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
3178  NS_ASSERT (numOifAddresses > 0);
3179  Ipv4InterfaceAddress ifAddr;
3180  if (numOifAddresses == 1) {
3181  ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
3182  } else {
3184  NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and OLSR");
3185  }
3186  rtentry->SetSource (ifAddr.GetLocal ());
3187  rtentry->SetGateway (entry2.nextAddr);
3188  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
3189 
3190  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3191  << ": RouteInput for dest=" << header.GetDestination ()
3192  << " --> nextHop=" << entry2.nextAddr
3193  << " interface=" << entry2.interface);
3194 
3195  ucb (rtentry, p, header);
3196  return true;
3197  }
3198  else
3199  {
3200  if(m_hnaRoutingTable->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
3201  {
3202  return true;
3203  }
3204  else
3205  {
3206 
3207 #ifdef NS3_LOG_ENABLE
3208  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3209  << ": RouteInput for dest=" << header.GetDestination ()
3210  << " --> NOT FOUND; ** Dumping routing table...");
3211 
3212  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3213  iter != m_table.end (); iter++)
3214  {
3215  NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
3216  << " via interface " << iter->second.interface);
3217  }
3218 
3219  NS_LOG_DEBUG ("** Routing table dump end.");
3220 #endif // NS3_LOG_ENABLE
3221 
3222  return false;
3223  }
3224  }
3225 }
3226 void
3228 {}
3229 void
3231 {}
3232 void
3234 {}
3235 void
3237 {}
3238 
3239 
3250 void
3252  Ipv4Address const &next,
3253  uint32_t interface,
3254  uint32_t distance)
3255 {
3256  NS_LOG_FUNCTION (this << dest << next << interface << distance << m_mainAddress);
3257 
3258  NS_ASSERT (distance > 0);
3259 
3260  // Creates a new rt entry with specified values
3261  RoutingTableEntry &entry = m_table[dest];
3262 
3263  entry.destAddr = dest;
3264  entry.nextAddr = next;
3265  entry.interface = interface;
3266  entry.distance = distance;
3267 }
3268 
3269 void
3271  Ipv4Address const &next,
3272  Ipv4Address const &interfaceAddress,
3273  uint32_t distance)
3274 {
3275  NS_LOG_FUNCTION (this << dest << next << interfaceAddress << distance << m_mainAddress);
3276 
3277  NS_ASSERT (distance > 0);
3278  NS_ASSERT (m_ipv4);
3279 
3280  RoutingTableEntry entry;
3281  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
3282  {
3283  for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
3284  {
3285  if (m_ipv4->GetAddress (i,j).GetLocal () == interfaceAddress)
3286  {
3287  AddEntry (dest, next, i, distance);
3288  return;
3289  }
3290  }
3291  }
3292  NS_ASSERT (false); // should not be reached
3293  AddEntry (dest, next, 0, distance);
3294 }
3295 
3296 
3297 std::vector<RoutingTableEntry>
3299 {
3300  std::vector<RoutingTableEntry> retval;
3301  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3302  iter != m_table.end (); iter++)
3303  {
3304  retval.push_back (iter->second);
3305  }
3306  return retval;
3307 }
3308 
3309 int64_t
3311 {
3312  NS_LOG_FUNCTION (this << stream);
3314  return 1;
3315 }
3316 
3317 bool
3319 {
3320  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
3321  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
3322  {
3323  Ipv4InterfaceAddress iface = j->second;
3324  if (a == iface.GetLocal ())
3325  {
3326  return true;
3327  }
3328  }
3329  return false;
3330 }
3331 
3332 void
3334 {
3335 #ifdef NS3_LOG_ENABLE
3336  Time now = Simulator::Now ();
3337  NS_LOG_DEBUG ("Dumping for node with main address " << m_mainAddress);
3338  NS_LOG_DEBUG (" Neighbor set");
3339  for (NeighborSet::const_iterator iter = m_state.GetNeighbors ().begin ();
3340  iter != m_state.GetNeighbors ().end (); iter++)
3341  {
3342  NS_LOG_DEBUG (" " << *iter);
3343  }
3344  NS_LOG_DEBUG (" Two-hop neighbor set");
3345  for (TwoHopNeighborSet::const_iterator iter = m_state.GetTwoHopNeighbors ().begin ();
3346  iter != m_state.GetTwoHopNeighbors ().end (); iter++)
3347  {
3348  if (now < iter->expirationTime)
3349  {
3350  NS_LOG_DEBUG (" " << *iter);
3351  }
3352  }
3353  NS_LOG_DEBUG (" Routing table");
3354  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin (); iter != m_table.end (); iter++)
3355  {
3356  NS_LOG_DEBUG (" dest=" << iter->first << " --> next=" << iter->second.nextAddr << " via interface " << iter->second.interface);
3357  }
3358  NS_LOG_DEBUG ("");
3359 #endif //NS3_LOG_ENABLE
3360 }
3361 
3364 {
3365  return m_hnaRoutingTable;
3366 }
3367 
3368 } // namespace olsr
3369 } // namespace ns3
3370 
3371 
std::vector< TopologyTuple > TopologySet
Topology Set type.
An MPR-Selector Tuple.
Ipv4Address networkAddr
Network Address of network reachable through gatewayAddr.
static TypeId GetTypeId(void)
Get the type ID.
#define OLSR_PORT_NUMBER
std::set< uint32_t > m_interfaceExclusions
const MprSelectorSet & GetMprSelectors() const
Definition: olsr-state.h:56
#define JITTER
Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission. ...
An OLSR's routing table entry.
uint32_t distance
Distance in hops to the destination.
#define OLSR_MPR_NEIGH
Asymmetric neighbor type.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
IfaceAssocSet & GetIfaceAssocSetMutable()
Definition: olsr-state.h:142
void HelloTimerExpire()
Sends a HELLO message and reschedules the HELLO timer.
an Inet address class
void AddTopologyTuple(const TopologyTuple &tuple)
Adds a topology tuple to the Topology Set.
Ipv4Address GetIpv4(void) const
#define OLSR_MAX_SEQ_NUM
Maximum allowed sequence number.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
void DoDispose()
Destructor implementation.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Ipv4Address GetOriginatorAddress() const
Definition: olsr-header.h:152
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
TwoHopNeighborTuple * FindTwoHopNeighborTuple(const Ipv4Address &neighbor, const Ipv4Address &twoHopNeighbor)
Definition: olsr-state.cc:190
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
void IfaceAssocTupleTimerExpire(Ipv4Address ifaceAddr)
Removes tuple_ if expired.
uint16_t sequenceNumber
Sequence number.
void RemoveMprSelectorTuple(const MprSelectorTuple &tuple)
Removes an MPR selector tuple from the MPR Selector Set.
Callback template class.
Definition: callback.h:1164
#define OLSR_WILL_DEFAULT
Willingness for forwarding packets from other nodes: medium.
uint16_t GetPacketSequenceNumber()
Increments packet sequence number and returns the new value.
std::vector< Association > Associations
Association Set type.
Time m_midInterval
MID messages' emission interval.
A simple Timer class.
Definition: timer.h:73
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
#define OLSR_DUP_HOLD_TIME
Dup holding time.
void EraseMprSelectorTuples(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:64
Introspection did not find any typical Config paths.
Definition: olsr-header.h:116
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:127
Ipv4Address GetLocal(void) const
Get the local address.
uint16_t m_messageSequenceNumber
Messages sequence number counter.
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
void InsertAssociationTuple(const AssociationTuple &tuple)
Definition: olsr-state.cc:521
const Associations & GetAssociations() const
Definition: olsr-state.h:157
Ipv4Address destAddr
Address of the destination node.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:226
const NeighborTuple * FindSymNeighborTuple(const Ipv4Address &mainAddr) const
Definition: olsr-state.cc:120
std::string PrintMprSelectorSet() const
Definition: olsr-state.cc:87
void HnaTimerExpire()
Sends an HNA message (if the node has associated hosts/networks) and reschedules the HNA timer...
#define OLSR_TOP_HOLD_TIME
Top holding time.
void LinkTupleUpdated(const LinkTuple &tuple, uint8_t willingness)
This function is invoked when a link tuple is updated.
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: enum.h:209
void InsertNeighborTuple(const NeighborTuple &tuple)
Definition: olsr-state.cc:172
std::vector< Ipv4Address > FindNeighborInterfaces(const Ipv4Address &neighborMainAddr) const
Definition: olsr-state.cc:478
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).
uint16_t m_ansn
Advertised Neighbor Set sequence number.
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1258
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
Ipv4Address GetDestNetwork(void) const
#define OLSR_WILL_ALWAYS
Willingness for forwarding packets from other nodes: always.
void SetMprSet(MprSet mprSet)
MprSet is set by routing protocol after MprCompute.
Definition: olsr-state.cc:271
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
void AddEntry(const Ipv4Address &dest, const Ipv4Address &next, uint32_t interface, uint32_t distance)
Adds a new entry into the routing table.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:786
virtual void NotifyInterfaceUp(uint32_t interface)
void SendTc()
Creates a new OLSR TC message which is buffered for being sent later on.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
void DupTupleTimerExpire(Ipv4Address address, uint16_t sequenceNumber)
Removes tuple if expired.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:145
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
bool FindMprAddress(const Ipv4Address &address)
Definition: olsr-state.cc:264
enum ns3::olsr::NeighborTuple::Status status
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:339
void InsertMprSelectorTuple(const MprSelectorTuple &tuple)
Definition: olsr-state.cc:81
void AddHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Inject Association to be sent in HNA message.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
std::vector< LinkMessage > linkMessages
Definition: olsr-header.h:276
uint16_t GetMessageSequenceNumber() const
Definition: olsr-header.h:179
Time expirationTime
Time at which this tuple expires and must be removed.
NeighborTuple * FindNeighborTuple(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:108
#define OLSR_WILL_LOW
Willingness for forwarding packets from other nodes: low.
void LinkTupleTimerExpire(Ipv4Address neighborIfaceAddr)
Removes tuple_ if expired.
void EraseIfaceAssocTuple(const IfaceAssocTuple &tuple)
Definition: olsr-state.cc:458
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
MessageType GetMessageType() const
Definition: olsr-header.h:134
Time GetVTime() const
Definition: olsr-header.h:143
void Nb2hopTupleTimerExpire(Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr)
Removes tuple_ if expired.
void RemoveAssociationTuple(const AssociationTuple &tuple)
Removes a host network association tuple from the Association Set.
void ProcessTc(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a TC message following RFC 3626 specification.
Ipv4Address GetSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
#define OLSR_NEIGHB_HOLD_TIME
Neighbor holding time.
LinkTuple * FindSymLinkTuple(const Ipv4Address &ifaceAddr, Time time)
Definition: olsr-state.cc:330
a polymophic address class
Definition: address.h:90
LinkTuple * FindLinkTuple(const Ipv4Address &ifaceAddr)
Definition: olsr-state.cc:318
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
bool IsRunning(void) const
Definition: timer.cc:127
void SetVTime(Time time)
Definition: olsr-header.h:139
void EraseDuplicateTuple(const DuplicateTuple &tuple)
Definition: olsr-state.cc:296
void EraseTopologyTuple(const TopologyTuple &tuple)
Definition: olsr-state.cc:395
void MprSelTupleTimerExpire(Ipv4Address mainAddr)
Removes tuple_ if expired.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
#define OLSR_SYM_LINK
Symmetric link type.
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
std::map< Ipv4Address, RoutingTableEntry > m_table
Data structure for the routing table.
std::vector< Ipv4Address > interfaceAddresses
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
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:311
Ipv4Address lastAddr
Main address of a node which is a neighbor of the destination.
A record of an IPv4 routing table entry for Ipv4GlobalRouting and Ipv4StaticRouting.
uint8_t m_willingness
Willingness for forwarding packets on behalf of other nodes.
void PopulateNeighborSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the Neighbor Set according to the information contained in a new received HELLO message (foll...
Time expirationTime
Time at which this tuple expires and must be removed.
void EraseOlderTopologyTuples(const Ipv4Address &lastAddr, uint16_t ansn)
Definition: olsr-state.cc:409
void RemoveHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Removes Association sent in HNA message.
Hold variables of type enum.
Definition: enum.h:54
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1216
const TopologySet & GetTopologySet() const
Definition: olsr-state.h:124
Ipv4Address mainAddr
Main address of the node.
TopologyTuple * FindTopologyTuple(const Ipv4Address &destAddr, const Ipv4Address &lastAddr)
Definition: olsr-state.cc:370
void AddIfaceAssocTuple(const IfaceAssocTuple &tuple)
Adds an interface association tuple to the Interface Association Set.
void QueueMessage(const olsr::MessageHeader &message, Time delay)
Enques an OLSR message which will be sent with a delay of (0, delay].
AttributeValue implementation for Time.
Definition: nstime.h:957
Ipv4Address mainAddr
Main address of a node which have selected this node as a MPR.
void SendPacket(Ptr< Packet > packet, const MessageList &containedMessages)
void Schedule(void)
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:158
const AssociationSet & GetAssociationSet() const
Definition: olsr-state.h:152
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
OLSR routing protocol for IPv4.
void SetFunction(FN fn)
Definition: timer.h:309
An Association Tuple.
void ProcessHello(const olsr::MessageHeader &msg, const Ipv4Address &receiverIface, const Ipv4Address &senderIface)
Processes a HELLO message following RFC 3626 specification.
#define DELAY(time)
Gets the delay between a given time and the current time.
tuple interfaces
Definition: first.py:41
IfaceAssocTuple * FindIfaceAssocTuple(const Ipv4Address &ifaceAddr)
Definition: olsr-state.cc:434
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.
void InsertDuplicateTuple(const DuplicateTuple &tuple)
Definition: olsr-state.cc:310
std::vector< LinkTuple > LinkSet
Link Set type.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1480
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:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
void EraseLinkTuple(const LinkTuple &tuple)
Definition: olsr-state.cc:347
uint8_t GetTimeToLive() const
Definition: olsr-header.h:161
void CoverTwoHopNeighbors(Ipv4Address neighborMainAddr, TwoHopNeighborSet &N2)
Remove all covered 2-hop neighbors from N2 set.
Time m_helloInterval
HELLO messages' emission interval.
void SetDelay(const Time &delay)
Definition: timer.cc:75
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
#define OLSR_UNSPEC_LINK
Unspecified link type.
#define OLSR_NOT_NEIGH
Not neighbor type.
#define OLSR_ASYM_LINK
Asymmetric link type.
void SetRoutingTableAssociation(Ptr< Ipv4StaticRouting > routingTable)
Inject Associations from an Ipv4StaticRouting instance.
Ipv4Address destAddr
Main address of the destination.
std::vector< IfaceAssocTuple > IfaceAssocSet
Interface Association Set type.
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
AssociationTuple * FindAssociationTuple(const Ipv4Address &gatewayAddr, const Ipv4Address &networkAddr, const Ipv4Mask &netmask)
Definition: olsr-state.cc:493
void TopologyTupleTimerExpire(Ipv4Address destAddr, Ipv4Address lastAddr)
Removes tuple_ if expired.
Time m_tcInterval
TC messages' emission interval.
void AddTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Adds a 2-hop neighbor tuple to the 2-hop Neighbor Set.
void AssociationTupleTimerExpire(Ipv4Address gatewayAddr, Ipv4Address networkAddr, Ipv4Mask netmask)
Removes tuple_ if expired.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
void NeighborLoss(const LinkTuple &tuple)
Performs all actions needed when a neighbor loss occurs.
void SetOriginatorAddress(Ipv4Address originatorAddress)
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.
void InsertIfaceAssocTuple(const IfaceAssocTuple &tuple)
Definition: olsr-state.cc:472
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
void RecvOlsr(Ptr< Socket > socket)
Ipv4Address neighborMainAddr
Main address of a neighbor node.
const NeighborSet & GetNeighbors() const
Definition: olsr-state.h:67
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.
void MidTimerExpire()
Sends a MID message (if the node has more than one interface) and resets the MID timer.
Ptr< Ipv4StaticRouting > m_routingTableAssociation
Ptr< const Ipv4StaticRouting > GetRoutingTableAssociation() const
Returns the internal HNA table.
void AddNeighborTuple(const NeighborTuple &tuple)
Adds a neighbor tuple to the Neighbor Set.
void SendHello()
Creates a new OLSR HELLO message which is buffered for being sent later on.
MprSelectorTuple * FindMprSelectorTuple(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:38
void RemoveLinkTuple(const LinkTuple &tuple)
Removes a link tuple from the Link Set.
bool UsesNonOlsrOutgoingInterface(const Ipv4RoutingTableEntry &route)
Tests whether or not the specified route uses a non-OLSR outgoing interface.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:958
bool Lookup(const Ipv4Address &dest, RoutingTableEntry &outEntry) const
Looks up an entry for the specified destination address.
std::vector< MessageHeader > MessageList
Definition: olsr-header.h:450
Definition: olsr.py:1
void EraseAssociationTuple(const AssociationTuple &tuple)
Definition: olsr-state.cc:507
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
Definition: ipv4-route.cc:77
Time time
Time at which this tuple expires and must be removed.
virtual void NotifyInterfaceDown(uint32_t interface)
Introspection did not find any typical Config paths.
Definition: olsr-header.h:69
uint16_t m_packetSequenceNumber
Packets sequence number counter.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
void PopulateTwoHopNeighborSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the 2-hop Neighbor Set according to the information contained in a new received HELLO message...
Ipv4Address GetMainAddress(Ipv4Address iface_addr) const
Gets the main address associated with a given interface address.
void RoutingTableComputation()
Creates the routing table of the node following RFC 3626 hints.
void RemoveTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Removes a 2-hop neighbor tuple from the 2-hop Neighbor Set.
void RemoveEntry(const Ipv4Address &dest)
Deletes the entry whose destination address is given.
void ForwardDefault(olsr::MessageHeader olsrMessage, DuplicateTuple *duplicated, const Ipv4Address &localIface, const Ipv4Address &senderAddress)
OLSR's default forwarding algorithm.
void ProcessHna(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a HNA message following RFC 3626 specification.
virtual Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
int Degree(NeighborTuple const &tuple)
This auxiliary function (defined in RFC 3626) is used for calculating the MPR Set.
Ptr< const AttributeChecker > MakeEnumChecker(int v1, std::string n1, int v2, std::string n2, int v3, std::string n3, int v4, std::string n4, int v5, std::string n5, int v6, std::string n6, int v7, std::string n7, int v8, std::string n8, int v9, std::string n9, int v10, std::string n10, int v11, std::string n11, int v12, std::string n12, int v13, std::string n13, int v14, std::string n14, int v15, std::string n15, int v16, std::string n16, int v17, std::string n17, int v18, std::string n18, int v19, std::string n19, int v20, std::string n20, int v21, std::string n21, int v22, std::string n22)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.cc:184
#define OLSR_WILL_HIGH
Willingness for forwarding packets from other nodes: high.
uint32_t interface
Interface index.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
std::vector< NeighborTuple > NeighborSet
Neighbor Set type.
bool IsMyOwnAddress(const Ipv4Address &a) const
Check that address is one of my interfaces.
void EraseAssociation(const Association &tuple)
Definition: olsr-state.cc:527
uint32_t GetId(void) const
Definition: node.cc:107
a class to store IPv4 address information on an interface
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
void PopulateMprSelectorSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the MPR Selector Set according to the information contained in a new received HELLO message (...
void SendQueuedMessages()
Creates as many OLSR packets as needed in order to send all buffered OLSR messages.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
DuplicateTuple * FindDuplicateTuple(const Ipv4Address &address, uint16_t sequenceNumber)
Definition: olsr-state.cc:284
void InsertTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Definition: olsr-state.cc:256
Ipv4Address ifaceAddr
Interface address of a node.
const IfaceAssocSet & GetIfaceAssocSet() const
Definition: olsr-state.h:138
#define OLSR_LOST_LINK
Lost link type.
Ipv4Address nextAddr
Address of the next hop.
TracedCallback< const PacketHeader &, const MessageList & > m_txPacketTrace
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)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
const LinkSet & GetLinks() const
Definition: olsr-state.h:114
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
void SendHna()
Creates a new OLSR HNA message which is buffered for being sent later on.
#define OLSR_MID_HOLD_TIME
MID holding time.
std::vector< TwoHopNeighborTuple > TwoHopNeighborSet
2-hop Neighbor Set type.
void EraseTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Definition: olsr-state.cc:206
void Track(EventId event)
Tracks a new event.
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and...
Definition: names.cc:743
Abstract base class for IPv4 routing protocols.
#define OLSR_WILL_NEVER
Willingness for forwarding packets from other nodes: never.
#define OLSR_MAX_MSGS
Maximum number of messages per packet.
void LinkTupleAdded(const LinkTuple &tuple, uint8_t willingness)
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
LinkTuple & InsertLinkTuple(const LinkTuple &tuple)
Definition: olsr-state.cc:361
Time m_hnaInterval
HNA messages' emission interval.
void Dump(void)
Dump the neighbor table, two-hop neighbor table, and routing table to logging output (NS_LOG_DEBUG lo...
uint16_t GetPort(void) const
Ipv4Address neighborMainAddr
Main address of a neighbor.
virtual void DoInitialize(void)
Initialize() implementation.
std::vector< RoutingTableEntry > GetRoutingTableEntries() const
Return the list of routing table entries discovered by OLSR.
void EraseNeighborTuple(const NeighborTuple &neighborTuple)
Definition: olsr-state.cc:144
tuple address
Definition: first.py:37
const TwoHopNeighborSet & GetTwoHopNeighbors() const
Definition: olsr-state.h:84
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.
TopologyTuple * FindNewerTopologyTuple(const Ipv4Address &lastAddr, uint16_t ansn)
Definition: olsr-state.cc:383
void RemoveNeighborTuple(const NeighborTuple &tuple)
Removes a neighbor tuple from the Neighbor Set.
uint16_t GetMessageSequenceNumber()
Increments message sequence number and returns the new value.
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:186
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
#define OLSR_HNA_HOLD_TIME
HNA holding time.
Ipv4Mask GetDestNetworkMask(void) const
a unique identifier for an interface.
Definition: type-id.h:58
An Interface Association Tuple.
bool retransmitted
Indicates whether the message has been retransmitted or not.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:826
The type "list of interface addresses".
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
void EraseMprSelectorTuple(const MprSelectorTuple &tuple)
Definition: olsr-state.cc:50
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
void InsertAssociation(const Association &tuple)
Definition: olsr-state.cc:541
uint16_t sequenceNumber
Message sequence number.
std::vector< AssociationTuple > AssociationSet
Association Set type.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:255
olsr::MessageList m_queuedMessages
A list of pending messages which are buffered awaiting for being sent.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
bool FindSendEntry(const RoutingTableEntry &entry, RoutingTableEntry &outEntry) const
Finds the appropiate entry which must be used in order to forward a data packet to a next hop (given ...
uint16_t GetPacketLength() const
Definition: olsr-header.h:79
Time expirationTime
Time at which this tuple expires and must be removed.
void EraseTwoHopNeighborTuples(const Ipv4Address &neighbor)
Definition: olsr-state.cc:239
void InsertTopologyTuple(const TopologyTuple &tuple)
Definition: olsr-state.cc:426
std::vector< Ipv4Address > ifaceList
List of interfaces which the message has been received on.
void ProcessMid(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a MID message following RFC 3626 specification.