A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
olsr-routing-protocol.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2004 Francisco J. Ros
4  * Copyright (c) 2007 INESC Porto
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Authors: Francisco J. Ros <fjrm@dif.um.es>
20  * Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
21  */
22 
23 
30 
31 #define NS_LOG_APPEND_CONTEXT \
32  if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
33 
34 
35 #include "olsr-routing-protocol.h"
36 #include "ns3/socket-factory.h"
37 #include "ns3/udp-socket-factory.h"
38 #include "ns3/simulator.h"
39 #include "ns3/log.h"
40 #include "ns3/names.h"
41 #include "ns3/inet-socket-address.h"
42 #include "ns3/ipv4-routing-protocol.h"
43 #include "ns3/ipv4-routing-table-entry.h"
44 #include "ns3/ipv4-route.h"
45 #include "ns3/boolean.h"
46 #include "ns3/uinteger.h"
47 #include "ns3/enum.h"
48 #include "ns3/trace-source-accessor.h"
49 #include "ns3/ipv4-header.h"
50 
51 /********** Useful macros **********/
52 
59 #define DELAY(time) (((time) < (Simulator::Now ())) ? Seconds (0.000001) : \
60  (time - Simulator::Now () + Seconds (0.000001)))
61 
62 
63 
69 #define OLSR_REFRESH_INTERVAL m_helloInterval
70 
71 
72 /********** Holding times **********/
73 
75 #define OLSR_NEIGHB_HOLD_TIME Time (3 * OLSR_REFRESH_INTERVAL)
76 #define OLSR_TOP_HOLD_TIME Time (3 * m_tcInterval)
78 #define OLSR_DUP_HOLD_TIME Seconds (30)
80 #define OLSR_MID_HOLD_TIME Time (3 * m_midInterval)
82 #define OLSR_HNA_HOLD_TIME Time (3 * m_hnaInterval)
84 
85 /********** Link types **********/
86 
88 #define OLSR_UNSPEC_LINK 0
89 #define OLSR_ASYM_LINK 1
91 #define OLSR_SYM_LINK 2
93 #define OLSR_LOST_LINK 3
95 
96 /********** Neighbor types **********/
97 
99 #define OLSR_NOT_NEIGH 0
100 #define OLSR_SYM_NEIGH 1
102 #define OLSR_MPR_NEIGH 2
104 
105 
106 /********** Willingness **********/
107 
109 #define OLSR_WILL_NEVER 0
110 #define OLSR_WILL_LOW 1
112 #define OLSR_WILL_DEFAULT 3
114 #define OLSR_WILL_HIGH 6
116 #define OLSR_WILL_ALWAYS 7
118 
119 
120 /********** Miscellaneous constants **********/
121 
123 #define OLSR_MAXJITTER (m_helloInterval.GetSeconds () / 4)
124 #define OLSR_MAX_SEQ_NUM 65535
126 #define JITTER (Seconds (m_uniformRandomVariable->GetValue (0, OLSR_MAXJITTER)))
128 
129 
130 #define OLSR_PORT_NUMBER 698
131 #define OLSR_MAX_MSGS 64
133 
135 #define OLSR_MAX_HELLOS 12
136 
138 #define OLSR_MAX_ADDRS 64
139 
140 
141 namespace ns3 {
142 namespace olsr {
143 
144 NS_LOG_COMPONENT_DEFINE ("OlsrRoutingProtocol");
145 
146 
147 /********** OLSR class **********/
148 
149 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol)
150  ;
151 
152 TypeId
154 {
155  static TypeId tid = TypeId ("ns3::olsr::RoutingProtocol")
157  .AddConstructor<RoutingProtocol> ()
158  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
159  TimeValue (Seconds (2)),
160  MakeTimeAccessor (&RoutingProtocol::m_helloInterval),
161  MakeTimeChecker ())
162  .AddAttribute ("TcInterval", "TC messages emission interval.",
163  TimeValue (Seconds (5)),
164  MakeTimeAccessor (&RoutingProtocol::m_tcInterval),
165  MakeTimeChecker ())
166  .AddAttribute ("MidInterval", "MID messages emission interval. Normally it is equal to TcInterval.",
167  TimeValue (Seconds (5)),
168  MakeTimeAccessor (&RoutingProtocol::m_midInterval),
169  MakeTimeChecker ())
170  .AddAttribute ("HnaInterval", "HNA messages emission interval. Normally it is equal to TcInterval.",
171  TimeValue (Seconds (5)),
172  MakeTimeAccessor (&RoutingProtocol::m_hnaInterval),
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  .AddTraceSource ("Tx", "Send OLSR packet.",
186  .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.",
188  ;
189  return tid;
190 }
191 
192 
194  : m_routingTableAssociation (0),
195  m_ipv4 (0),
196  m_helloTimer (Timer::CANCEL_ON_DESTROY),
197  m_tcTimer (Timer::CANCEL_ON_DESTROY),
198  m_midTimer (Timer::CANCEL_ON_DESTROY),
199  m_hnaTimer (Timer::CANCEL_ON_DESTROY),
200  m_queuedMessagesTimer (Timer::CANCEL_ON_DESTROY)
201 {
202  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
203 
204  m_hnaRoutingTable = Create<Ipv4StaticRouting> ();
205 }
206 
208 {
209 }
210 
211 void
213 {
214  NS_ASSERT (ipv4 != 0);
215  NS_ASSERT (m_ipv4 == 0);
216  NS_LOG_DEBUG ("Created olsr::RoutingProtocol");
222 
226 
228 
229  m_ipv4 = ipv4;
230 
231  m_hnaRoutingTable->SetIpv4 (ipv4);
232 }
233 
235 {
236  m_ipv4 = 0;
237  m_hnaRoutingTable = 0;
239 
240  for (std::map< Ptr<Socket>, Ipv4InterfaceAddress >::iterator iter = m_socketAddresses.begin ();
241  iter != m_socketAddresses.end (); iter++)
242  {
243  iter->first->Close ();
244  }
245  m_socketAddresses.clear ();
246 
248 }
249 
250 void
252 {
253  std::ostream* os = stream->GetStream ();
254  *os << "Destination\t\tNextHop\t\tInterface\tDistance\n";
255 
256  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
257  iter != m_table.end (); iter++)
258  {
259  *os << iter->first << "\t\t";
260  *os << iter->second.nextAddr << "\t\t";
261  if (Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) != "")
262  {
263  *os << Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) << "\t\t";
264  }
265  else
266  {
267  *os << iter->second.interface << "\t\t";
268  }
269  *os << iter->second.distance << "\t";
270  *os << "\n";
271  }
272  // Also print the HNA routing table
273  *os << " HNA Routing Table:\n";
274  m_hnaRoutingTable->PrintRoutingTable (stream);
275 }
276 
278 {
279  if (m_mainAddress == Ipv4Address ())
280  {
281  Ipv4Address loopback ("127.0.0.1");
282  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
283  {
284  // Use primary address, if multiple
285  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
286  if (addr != loopback)
287  {
288  m_mainAddress = addr;
289  break;
290  }
291  }
292 
294  }
295 
296  NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
297 
298  Ipv4Address loopback ("127.0.0.1");
299 
300  bool canRunOlsr = false;
301  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
302  {
303  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
304  if (addr == loopback)
305  continue;
306 
307  if (addr != m_mainAddress)
308  {
309  // Create never expiring interface association tuple entries for our
310  // own network interfaces, so that GetMainAddress () works to
311  // translate the node's own interface addresses into the main address.
312  IfaceAssocTuple tuple;
313  tuple.ifaceAddr = addr;
314  tuple.mainAddr = m_mainAddress;
315  AddIfaceAssocTuple (tuple);
317  }
318 
319  if(m_interfaceExclusions.find (i) != m_interfaceExclusions.end ())
320  continue;
321 
322  // Create a socket to listen only on this interface
323  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
325  socket->SetAllowBroadcast (true);
326  InetSocketAddress inetAddr (m_ipv4->GetAddress (i, 0).GetLocal (), OLSR_PORT_NUMBER);
328  if (socket->Bind (inetAddr))
329  {
330  NS_FATAL_ERROR ("Failed to bind() OLSR socket");
331  }
332  socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
333  m_socketAddresses[socket] = m_ipv4->GetAddress (i, 0);
334 
335  canRunOlsr = true;
336  }
337 
338  if(canRunOlsr)
339  {
340  HelloTimerExpire ();
341  TcTimerExpire ();
342  MidTimerExpire ();
343  HnaTimerExpire ();
344 
345  NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
346  }
347 }
348 
349 void RoutingProtocol::SetMainInterface (uint32_t interface)
350 {
351  m_mainAddress = m_ipv4->GetAddress (interface, 0).GetLocal ();
352 }
353 
354 void RoutingProtocol::SetInterfaceExclusions (std::set<uint32_t> exceptions)
355 {
356  m_interfaceExclusions = exceptions;
357 }
358 
359 //
360 // \brief Processes an incoming %OLSR packet following \RFC{3626} specification.
361 void
363 {
364  Ptr<Packet> receivedPacket;
365  Address sourceAddress;
366  receivedPacket = socket->RecvFrom (sourceAddress);
367 
368  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
369  Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
370  Ipv4Address receiverIfaceAddr = m_socketAddresses[socket].GetLocal ();
371  NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
372  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
373  << senderIfaceAddr << " to " << receiverIfaceAddr);
374 
375  // All routing messages are sent from and to port RT_PORT,
376  // so we check it.
377  NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER);
378 
379  Ptr<Packet> packet = receivedPacket;
380 
381  olsr::PacketHeader olsrPacketHeader;
382  packet->RemoveHeader (olsrPacketHeader);
383  NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ());
384  uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize ();
385 
386  MessageList messages;
387 
388  while (sizeLeft)
389  {
390  MessageHeader messageHeader;
391  if (packet->RemoveHeader (messageHeader) == 0)
392  NS_ASSERT (false);
393 
394  sizeLeft -= messageHeader.GetSerializedSize ();
395 
396  NS_LOG_DEBUG ("Olsr Msg received with type "
397  << std::dec << int (messageHeader.GetMessageType ())
398  << " TTL=" << int (messageHeader.GetTimeToLive ())
399  << " origAddr=" << messageHeader.GetOriginatorAddress ());
400  messages.push_back (messageHeader);
401  }
402 
403  m_rxPacketTrace (olsrPacketHeader, messages);
404 
405  for (MessageList::const_iterator messageIter = messages.begin ();
406  messageIter != messages.end (); messageIter++)
407  {
408  const MessageHeader &messageHeader = *messageIter;
409  // If ttl is less than or equal to zero, or
410  // the receiver is the same as the originator,
411  // the message must be silently dropped
412  if (messageHeader.GetTimeToLive () == 0
413  || messageHeader.GetOriginatorAddress () == m_mainAddress)
414  {
415  packet->RemoveAtStart (messageHeader.GetSerializedSize ()
416  - messageHeader.GetSerializedSize ());
417  continue;
418  }
419 
420  // If the message has been processed it must not be processed again
421  bool do_forwarding = true;
423  (messageHeader.GetOriginatorAddress (),
424  messageHeader.GetMessageSequenceNumber ());
425 
426  // Get main address of the peer, which may be different from the packet source address
427 // const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ());
428 // Ipv4Address peerMainAddress;
429 // if (ifaceAssoc != NULL)
430 // {
431 // peerMainAddress = ifaceAssoc->mainAddr;
432 // }
433 // else
434 // {
435 // peerMainAddress = inetSourceAddr.GetIpv4 () ;
436 // }
437 
438  if (duplicated == NULL)
439  {
440  switch (messageHeader.GetMessageType ())
441  {
443  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
444  << "s OLSR node " << m_mainAddress
445  << " received HELLO message of size " << messageHeader.GetSerializedSize ());
446  ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr);
447  break;
448 
450  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
451  << "s OLSR node " << m_mainAddress
452  << " received TC message of size " << messageHeader.GetSerializedSize ());
453  ProcessTc (messageHeader, senderIfaceAddr);
454  break;
455 
457  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
458  << "s OLSR node " << m_mainAddress
459  << " received MID message of size " << messageHeader.GetSerializedSize ());
460  ProcessMid (messageHeader, senderIfaceAddr);
461  break;
463  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
464  << "s OLSR node " << m_mainAddress
465  << " received HNA message of size " << messageHeader.GetSerializedSize ());
466  ProcessHna (messageHeader, senderIfaceAddr);
467  break;
468 
469  default:
470  NS_LOG_DEBUG ("OLSR message type " <<
471  int (messageHeader.GetMessageType ()) <<
472  " not implemented");
473  }
474  }
475  else
476  {
477  NS_LOG_DEBUG ("OLSR message is duplicated, not reading it.");
478 
479  // If the message has been considered for forwarding, it should
480  // not be retransmitted again
481  for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin ();
482  it != duplicated->ifaceList.end (); it++)
483  {
484  if (*it == receiverIfaceAddr)
485  {
486  do_forwarding = false;
487  break;
488  }
489  }
490  }
491 
492  if (do_forwarding)
493  {
494  // HELLO messages are never forwarded.
495  // TC and MID messages are forwarded using the default algorithm.
496  // Remaining messages are also forwarded using the default algorithm.
497  if (messageHeader.GetMessageType () != olsr::MessageHeader::HELLO_MESSAGE)
498  {
499  ForwardDefault (messageHeader, duplicated,
500  receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
501  }
502  }
503  }
504 
505  // After processing all OLSR messages, we must recompute the routing table
507 }
508 
515 int
517 {
518  int degree = 0;
519  for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin ();
520  it != m_state.GetTwoHopNeighbors ().end (); it++)
521  {
522  TwoHopNeighborTuple const &nb2hop_tuple = *it;
523  if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
524  {
525  const NeighborTuple *nb_tuple =
527  if (nb_tuple == NULL)
528  degree++;
529  }
530  }
531  return degree;
532 }
533 
534 namespace {
538 void
540 {
541  // first gather all 2-hop neighbors to be removed
542  std::set<Ipv4Address> toRemove;
543  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
544  {
545  if (twoHopNeigh->neighborMainAddr == neighborMainAddr)
546  {
547  toRemove.insert (twoHopNeigh->twoHopNeighborAddr);
548  }
549  }
550  // Now remove all matching records from N2
551  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); )
552  {
553  if (toRemove.find (twoHopNeigh->twoHopNeighborAddr) != toRemove.end ())
554  {
555  twoHopNeigh = N2.erase (twoHopNeigh);
556  }
557  else
558  {
559  twoHopNeigh++;
560  }
561  }
562 }
563 } // anonymous namespace
564 
568 void
570 {
571  NS_LOG_FUNCTION (this);
572 
573  // MPR computation should be done for each interface. See section 8.3.1
574  // (RFC 3626) for details.
575  MprSet mprSet;
576 
577  // N is the subset of neighbors of the node, which are
578  // neighbor "of the interface I"
579  NeighborSet N;
580  for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin ();
581  neighbor != m_state.GetNeighbors ().end (); neighbor++)
582  {
583  if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
584  {
585  N.push_back (*neighbor);
586  }
587  }
588 
589  // N2 is the set of 2-hop neighbors reachable from "the interface
590  // I", excluding:
591  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
592  // (ii) the node performing the computation
593  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
594  // link to this node on some interface.
596  for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin ();
597  twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++)
598  {
599  // excluding:
600  // (ii) the node performing the computation
601  if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
602  {
603  continue;
604  }
605 
606  // excluding:
607  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
608  bool ok = false;
609  for (NeighborSet::const_iterator neigh = N.begin ();
610  neigh != N.end (); neigh++)
611  {
612  if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
613  {
614  if (neigh->willingness == OLSR_WILL_NEVER)
615  {
616  ok = false;
617  break;
618  }
619  else
620  {
621  ok = true;
622  break;
623  }
624  }
625  }
626  if (!ok)
627  {
628  continue;
629  }
630 
631  // excluding:
632  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
633  // link to this node on some interface.
634  for (NeighborSet::const_iterator neigh = N.begin ();
635  neigh != N.end (); neigh++)
636  {
637  if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
638  {
639  ok = false;
640  break;
641  }
642  }
643 
644  if (ok)
645  {
646  N2.push_back (*twoHopNeigh);
647  }
648  }
649 
650 #ifdef NS3_LOG_ENABLE
651  {
652  std::ostringstream os;
653  os << "[";
654  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
655  iter != N2.end (); iter++)
656  {
657  TwoHopNeighborSet::const_iterator next = iter;
658  next++;
659  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
660  if (next != N2.end ())
661  os << ", ";
662  }
663  os << "]";
664  NS_LOG_DEBUG ("N2: " << os.str ());
665  }
666 #endif //NS3_LOG_ENABLE
667 
668  // 1. Start with an MPR set made of all members of N with
669  // N_willingness equal to WILL_ALWAYS
670  for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
671  {
672  if (neighbor->willingness == OLSR_WILL_ALWAYS)
673  {
674  mprSet.insert (neighbor->neighborMainAddr);
675  // (not in RFC but I think is needed: remove the 2-hop
676  // neighbors reachable by the MPR from N2)
677  CoverTwoHopNeighbors (neighbor->neighborMainAddr, N2);
678  }
679  }
680 
681  // 2. Calculate D(y), where y is a member of N, for all nodes in N.
682  // (we do this later)
683 
684  // 3. Add to the MPR set those nodes in N, which are the *only*
685  // nodes to provide reachability to a node in N2.
686  std::set<Ipv4Address> coveredTwoHopNeighbors;
687  for (TwoHopNeighborSet::const_iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
688  {
689  bool onlyOne = true;
690  // try to find another neighbor that can reach twoHopNeigh->twoHopNeighborAddr
691  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin (); otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
692  {
693  if (otherTwoHopNeigh->twoHopNeighborAddr == twoHopNeigh->twoHopNeighborAddr
694  && otherTwoHopNeigh->neighborMainAddr != twoHopNeigh->neighborMainAddr)
695  {
696  onlyOne = false;
697  break;
698  }
699  }
700  if (onlyOne)
701  {
702  NS_LOG_LOGIC ("Neighbor " << twoHopNeigh->neighborMainAddr
703  << " is the only that can reach 2-hop neigh. "
704  << twoHopNeigh->twoHopNeighborAddr
705  << " => select as MPR.");
706 
707  mprSet.insert (twoHopNeigh->neighborMainAddr);
708 
709  // take note of all the 2-hop neighbors reachable by the newly elected MPR
710  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin ();
711  otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
712  {
713  if (otherTwoHopNeigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
714  {
715  coveredTwoHopNeighbors.insert (otherTwoHopNeigh->twoHopNeighborAddr);
716  }
717  }
718  }
719  }
720  // Remove the nodes from N2 which are now covered by a node in the MPR set.
721  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
722  twoHopNeigh != N2.end (); )
723  {
724  if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
725  {
726  // This works correctly only because it is known that twoHopNeigh is reachable by exactly one neighbor,
727  // so only one record in N2 exists for each of them. This record is erased here.
728  NS_LOG_LOGIC ("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr << " is already covered by an MPR.");
729  twoHopNeigh = N2.erase (twoHopNeigh);
730  }
731  else
732  {
733  twoHopNeigh++;
734  }
735  }
736 
737  // 4. While there exist nodes in N2 which are not covered by at
738  // least one node in the MPR set:
739  while (N2.begin () != N2.end ())
740  {
741 
742 #ifdef NS3_LOG_ENABLE
743  {
744  std::ostringstream os;
745  os << "[";
746  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
747  iter != N2.end (); iter++)
748  {
749  TwoHopNeighborSet::const_iterator next = iter;
750  next++;
751  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
752  if (next != N2.end ())
753  os << ", ";
754  }
755  os << "]";
756  NS_LOG_DEBUG ("Step 4 iteration: N2=" << os.str ());
757  }
758 #endif //NS3_LOG_ENABLE
759 
760 
761  // 4.1. For each node in N, calculate the reachability, i.e., the
762  // number of nodes in N2 which are not yet covered by at
763  // least one node in the MPR set, and which are reachable
764  // through this 1-hop neighbor
765  std::map<int, std::vector<const NeighborTuple *> > reachability;
766  std::set<int> rs;
767  for (NeighborSet::iterator it = N.begin (); it != N.end (); it++)
768  {
769  NeighborTuple const &nb_tuple = *it;
770  int r = 0;
771  for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++)
772  {
773  TwoHopNeighborTuple const &nb2hop_tuple = *it2;
774  if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
775  r++;
776  }
777  rs.insert (r);
778  reachability[r].push_back (&nb_tuple);
779  }
780 
781  // 4.2. Select as a MPR the node with highest N_willingness among
782  // the nodes in N with non-zero reachability. In case of
783  // multiple choice select the node which provides
784  // reachability to the maximum number of nodes in N2. In
785  // case of multiple nodes providing the same amount of
786  // reachability, select the node as MPR whose D(y) is
787  // greater. Remove the nodes from N2 which are now covered
788  // by a node in the MPR set.
789  NeighborTuple const *max = NULL;
790  int max_r = 0;
791  for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++)
792  {
793  int r = *it;
794  if (r == 0)
795  {
796  continue;
797  }
798  for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin ();
799  it2 != reachability[r].end (); it2++)
800  {
801  const NeighborTuple *nb_tuple = *it2;
802  if (max == NULL || nb_tuple->willingness > max->willingness)
803  {
804  max = nb_tuple;
805  max_r = r;
806  }
807  else if (nb_tuple->willingness == max->willingness)
808  {
809  if (r > max_r)
810  {
811  max = nb_tuple;
812  max_r = r;
813  }
814  else if (r == max_r)
815  {
816  if (Degree (*nb_tuple) > Degree (*max))
817  {
818  max = nb_tuple;
819  max_r = r;
820  }
821  }
822  }
823  }
824  }
825 
826  if (max != NULL)
827  {
828  mprSet.insert (max->neighborMainAddr);
830  NS_LOG_LOGIC (N2.size () << " 2-hop neighbors left to cover!");
831  }
832  }
833 
834 #ifdef NS3_LOG_ENABLE
835  {
836  std::ostringstream os;
837  os << "[";
838  for (MprSet::const_iterator iter = mprSet.begin ();
839  iter != mprSet.end (); iter++)
840  {
841  MprSet::const_iterator next = iter;
842  next++;
843  os << *iter;
844  if (next != mprSet.end ())
845  os << ", ";
846  }
847  os << "]";
848  NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
849  }
850 #endif //NS3_LOG_ENABLE
851 
852  m_state.SetMprSet (mprSet);
853 }
854 
863 {
864  const IfaceAssocTuple *tuple =
865  m_state.FindIfaceAssocTuple (iface_addr);
866 
867  if (tuple != NULL)
868  return tuple->mainAddr;
869  else
870  return iface_addr;
871 }
872 
876 void
878 {
879  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " s: Node " << m_mainAddress
880  << ": RoutingTableComputation begin...");
881 
882  // 1. All the entries from the routing table are removed.
883  Clear ();
884 
885  // 2. The new routing entries are added starting with the
886  // symmetric neighbors (h=1) as the destination nodes.
887  const NeighborSet &neighborSet = m_state.GetNeighbors ();
888  for (NeighborSet::const_iterator it = neighborSet.begin ();
889  it != neighborSet.end (); it++)
890  {
891  NeighborTuple const &nb_tuple = *it;
892  NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple);
893  if (nb_tuple.status == NeighborTuple::STATUS_SYM)
894  {
895  bool nb_main_addr = false;
896  const LinkTuple *lt = NULL;
897  const LinkSet &linkSet = m_state.GetLinks ();
898  for (LinkSet::const_iterator it2 = linkSet.begin ();
899  it2 != linkSet.end (); it2++)
900  {
901  LinkTuple const &link_tuple = *it2;
902  NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple
903  << (link_tuple.time >= Simulator::Now () ? "" : " (expired)"));
904  if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr)
905  && link_tuple.time >= Simulator::Now ())
906  {
907  NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr
908  << " => adding routing table entry to neighbor");
909  lt = &link_tuple;
910  AddEntry (link_tuple.neighborIfaceAddr,
911  link_tuple.neighborIfaceAddr,
912  link_tuple.localIfaceAddr,
913  1);
914  if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
915  {
916  nb_main_addr = true;
917  }
918  }
919  else
920  {
921  NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr)
922  << "; neighborMainAddr = " << nb_tuple.neighborMainAddr
923  << "; expired=" << int (link_tuple.time < Simulator::Now ())
924  << " => IGNORE");
925  }
926  }
927 
928  // If, in the above, no R_dest_addr is equal to the main
929  // address of the neighbor, then another new routing entry
930  // with MUST be added, with:
931  // R_dest_addr = main address of the neighbor;
932  // R_next_addr = L_neighbor_iface_addr of one of the
933  // associated link tuple with L_time >= current time;
934  // R_dist = 1;
935  // R_iface_addr = L_local_iface_addr of the
936  // associated link tuple.
937  if (!nb_main_addr && lt != NULL)
938  {
939  NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor "
940  "=> adding additional routing entry");
941  AddEntry (nb_tuple.neighborMainAddr,
942  lt->neighborIfaceAddr,
943  lt->localIfaceAddr,
944  1);
945  }
946  }
947  }
948 
949  // 3. for each node in N2, i.e., a 2-hop neighbor which is not a
950  // neighbor node or the node itself, and such that there exist at
951  // least one entry in the 2-hop neighbor set where
952  // N_neighbor_main_addr correspond to a neighbor node with
953  // willingness different of WILL_NEVER,
954  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
955  for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin ();
956  it != twoHopNeighbors.end (); it++)
957  {
958  TwoHopNeighborTuple const &nb2hop_tuple = *it;
959 
960  NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
961 
962  // a 2-hop neighbor which is not a neighbor node or the node itself
964  {
965  NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped.");
966  continue;
967  }
968 
969  if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
970  {
971  NS_LOG_LOGIC ("Two-hop neighbor is self; skipped.");
972  continue;
973  }
974 
975  // ...and such that there exist at least one entry in the 2-hop
976  // neighbor set where N_neighbor_main_addr correspond to a
977  // neighbor node with willingness different of WILL_NEVER...
978  bool nb2hopOk = false;
979  for (NeighborSet::const_iterator neighbor = neighborSet.begin ();
980  neighbor != neighborSet.end (); neighbor++)
981  {
982  if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr
983  && neighbor->willingness != OLSR_WILL_NEVER)
984  {
985  nb2hopOk = true;
986  break;
987  }
988  }
989  if (!nb2hopOk)
990  {
991  NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor "
992  << nb2hop_tuple.twoHopNeighborAddr
993  << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr
994  << ", which was not found in the Neighbor Set.");
995  continue;
996  }
997 
998  // one selects one 2-hop tuple and creates one entry in the routing table with:
999  // R_dest_addr = the main address of the 2-hop neighbor;
1000  // R_next_addr = the R_next_addr of the entry in the
1001  // routing table with:
1002  // R_dest_addr == N_neighbor_main_addr
1003  // of the 2-hop tuple;
1004  // R_dist = 2;
1005  // R_iface_addr = the R_iface_addr of the entry in the
1006  // routing table with:
1007  // R_dest_addr == N_neighbor_main_addr
1008  // of the 2-hop tuple;
1009  RoutingTableEntry entry;
1010  bool foundEntry = Lookup (nb2hop_tuple.neighborMainAddr, entry);
1011  if (foundEntry)
1012  {
1013  NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor.");
1014  AddEntry (nb2hop_tuple.twoHopNeighborAddr,
1015  entry.nextAddr,
1016  entry.interface,
1017  2);
1018  }
1019  else
1020  {
1021  NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor ("
1022  << nb2hop_tuple.twoHopNeighborAddr
1023  << " not found in the routing table)");
1024  }
1025  }
1026 
1027  for (uint32_t h = 2;; h++)
1028  {
1029  bool added = false;
1030 
1031  // 3.1. For each topology entry in the topology table, if its
1032  // T_dest_addr does not correspond to R_dest_addr of any
1033  // route entry in the routing table AND its T_last_addr
1034  // corresponds to R_dest_addr of a route entry whose R_dist
1035  // is equal to h, then a new route entry MUST be recorded in
1036  // the routing table (if it does not already exist)
1037  const TopologySet &topology = m_state.GetTopologySet ();
1038  for (TopologySet::const_iterator it = topology.begin ();
1039  it != topology.end (); it++)
1040  {
1041  const TopologyTuple &topology_tuple = *it;
1042  NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple);
1043 
1044  RoutingTableEntry destAddrEntry, lastAddrEntry;
1045  bool have_destAddrEntry = Lookup (topology_tuple.destAddr, destAddrEntry);
1046  bool have_lastAddrEntry = Lookup (topology_tuple.lastAddr, lastAddrEntry);
1047  if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
1048  {
1049  NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple.");
1050  // then a new route entry MUST be recorded in
1051  // the routing table (if it does not already exist) where:
1052  // R_dest_addr = T_dest_addr;
1053  // R_next_addr = R_next_addr of the recorded
1054  // route entry where:
1055  // R_dest_addr == T_last_addr
1056  // R_dist = h+1; and
1057  // R_iface_addr = R_iface_addr of the recorded
1058  // route entry where:
1059  // R_dest_addr == T_last_addr.
1060  AddEntry (topology_tuple.destAddr,
1061  lastAddrEntry.nextAddr,
1062  lastAddrEntry.interface,
1063  h + 1);
1064  added = true;
1065  }
1066  else
1067  {
1068  NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: "
1069  "have_destAddrEntry=" << have_destAddrEntry
1070  << " have_lastAddrEntry=" << have_lastAddrEntry
1071  << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance
1072  << " (h=" << h << ")");
1073  }
1074  }
1075 
1076  if (!added)
1077  break;
1078  }
1079 
1080  // 4. For each entry in the multiple interface association base
1081  // where there exists a routing entry such that:
1082  // R_dest_addr == I_main_addr (of the multiple interface association entry)
1083  // AND there is no routing entry such that:
1084  // R_dest_addr == I_iface_addr
1085  const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
1086  for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
1087  it != ifaceAssocSet.end (); it++)
1088  {
1089  IfaceAssocTuple const &tuple = *it;
1090  RoutingTableEntry entry1, entry2;
1091  bool have_entry1 = Lookup (tuple.mainAddr, entry1);
1092  bool have_entry2 = Lookup (tuple.ifaceAddr, entry2);
1093  if (have_entry1 && !have_entry2)
1094  {
1095  // then a route entry is created in the routing table with:
1096  // R_dest_addr = I_iface_addr (of the multiple interface
1097  // association entry)
1098  // R_next_addr = R_next_addr (of the recorded route entry)
1099  // R_dist = R_dist (of the recorded route entry)
1100  // R_iface_addr = R_iface_addr (of the recorded route entry).
1101  AddEntry (tuple.ifaceAddr,
1102  entry1.nextAddr,
1103  entry1.interface,
1104  entry1.distance);
1105  }
1106  }
1107 
1108  // 5. For each tuple in the association set,
1109  // If there is no entry in the routing table with:
1110  // R_dest_addr == A_network_addr/A_netmask
1111  // and if the announced network is not announced by the node itself,
1112  // then a new routing entry is created.
1113  const AssociationSet &associationSet = m_state.GetAssociationSet ();
1114 
1115  // Clear HNA routing table
1116  for (uint32_t i = 0; i < m_hnaRoutingTable->GetNRoutes (); i++)
1117  {
1118  m_hnaRoutingTable->RemoveRoute (0);
1119  }
1120 
1121  for (AssociationSet::const_iterator it = associationSet.begin ();
1122  it != associationSet.end (); it++)
1123  {
1124  AssociationTuple const &tuple = *it;
1125 
1126  // Test if HNA associations received from other gateways
1127  // are also announced by this node. In such a case, no route
1128  // is created for this association tuple (go to the next one).
1129  bool goToNextAssociationTuple = false;
1130  const Associations &localHnaAssociations = m_state.GetAssociations ();
1131  NS_LOG_DEBUG ("Nb local associations: " << localHnaAssociations.size ());
1132  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1133  assocIterator != localHnaAssociations.end (); assocIterator++)
1134  {
1135  Association const &localHnaAssoc = *assocIterator;
1136  if (localHnaAssoc.networkAddr == tuple.networkAddr && localHnaAssoc.netmask == tuple.netmask)
1137  {
1138  NS_LOG_DEBUG ("HNA association received from another GW is part of local HNA associations: no route added for network "
1139  << tuple.networkAddr << "/" << tuple.netmask);
1140  goToNextAssociationTuple = true;
1141  }
1142  }
1143  if (goToNextAssociationTuple)
1144  {
1145  continue;
1146  }
1147 
1148  RoutingTableEntry gatewayEntry;
1149 
1150  bool gatewayEntryExists = Lookup (tuple.gatewayAddr, gatewayEntry);
1151  bool addRoute = false;
1152 
1153  uint32_t routeIndex = 0;
1154 
1155  for (routeIndex = 0; routeIndex < m_hnaRoutingTable->GetNRoutes (); routeIndex++)
1156  {
1157  Ipv4RoutingTableEntry route = m_hnaRoutingTable->GetRoute (routeIndex);
1158  if (route.GetDestNetwork () == tuple.networkAddr &&
1159  route.GetDestNetworkMask () == tuple.netmask)
1160  {
1161  break;
1162  }
1163  }
1164 
1165  if (routeIndex == m_hnaRoutingTable->GetNRoutes ())
1166  {
1167  addRoute = true;
1168  }
1169  else if(gatewayEntryExists && m_hnaRoutingTable->GetMetric (routeIndex) > gatewayEntry.distance)
1170  {
1171  m_hnaRoutingTable->RemoveRoute (routeIndex);
1172  addRoute = true;
1173  }
1174 
1175  if(addRoute && gatewayEntryExists)
1176  {
1177  m_hnaRoutingTable->AddNetworkRouteTo (tuple.networkAddr,
1178  tuple.netmask,
1179  gatewayEntry.nextAddr,
1180  gatewayEntry.interface,
1181  gatewayEntry.distance);
1182 
1183  }
1184  }
1185 
1186  NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
1188 }
1189 
1190 
1201 void
1203  const Ipv4Address &receiverIface,
1204  const Ipv4Address &senderIface)
1205 {
1206  NS_LOG_FUNCTION (msg << receiverIface << senderIface);
1207 
1208  const olsr::MessageHeader::Hello &hello = msg.GetHello ();
1209 
1210  LinkSensing (msg, hello, receiverIface, senderIface);
1211 
1212 #ifdef NS3_LOG_ENABLE
1213  {
1214  const LinkSet &links = m_state.GetLinks ();
1215  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1216  << "s ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
1217  for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++)
1218  {
1219  NS_LOG_DEBUG (*link);
1220  }
1221  NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress);
1222 
1223  const NeighborSet &neighbors = m_state.GetNeighbors ();
1224  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1225  << "s ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
1226  for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1227  {
1228  NS_LOG_DEBUG (*neighbor);
1229  }
1230  NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
1231  }
1232 #endif // NS3_LOG_ENABLE
1233 
1234  PopulateNeighborSet (msg, hello);
1235  PopulateTwoHopNeighborSet (msg, hello);
1236 
1237 #ifdef NS3_LOG_ENABLE
1238  {
1239  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1240  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1241  << "s ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1242  for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin ();
1243  tuple != twoHopNeighbors.end (); tuple++)
1244  {
1245  NS_LOG_DEBUG (*tuple);
1246  }
1247  NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1248  }
1249 #endif // NS3_LOG_ENABLE
1250 
1251  MprComputation ();
1252  PopulateMprSelectorSet (msg, hello);
1253 }
1254 
1264 void
1266  const Ipv4Address &senderIface)
1267 {
1268  const olsr::MessageHeader::Tc &tc = msg.GetTc ();
1269  Time now = Simulator::Now ();
1270 
1271  // 1. If the sender interface of this message is not in the symmetric
1272  // 1-hop neighborhood of this node, the message MUST be discarded.
1273  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1274  if (link_tuple == NULL)
1275  return;
1276 
1277  // 2. If there exist some tuple in the topology set where:
1278  // T_last_addr == originator address AND
1279  // T_seq > ANSN,
1280  // then further processing of this TC message MUST NOT be
1281  // performed.
1282  const TopologyTuple *topologyTuple =
1284  if (topologyTuple != NULL)
1285  return;
1286 
1287  // 3. All tuples in the topology set where:
1288  // T_last_addr == originator address AND
1289  // T_seq < ANSN
1290  // MUST be removed from the topology set.
1292 
1293  // 4. For each of the advertised neighbor main address received in
1294  // the TC message:
1295  for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin ();
1296  i != tc.neighborAddresses.end (); i++)
1297  {
1298  const Ipv4Address &addr = *i;
1299  // 4.1. If there exist some tuple in the topology set where:
1300  // T_dest_addr == advertised neighbor main address, AND
1301  // T_last_addr == originator address,
1302  // then the holding time of that tuple MUST be set to:
1303  // T_time = current time + validity time.
1304  TopologyTuple *topologyTuple =
1306 
1307  if (topologyTuple != NULL)
1308  {
1309  topologyTuple->expirationTime = now + msg.GetVTime ();
1310  }
1311  else
1312  {
1313  // 4.2. Otherwise, a new tuple MUST be recorded in the topology
1314  // set where:
1315  // T_dest_addr = advertised neighbor main address,
1316  // T_last_addr = originator address,
1317  // T_seq = ANSN,
1318  // T_time = current time + validity time.
1319  TopologyTuple topologyTuple;;
1320  topologyTuple.destAddr = addr;
1321  topologyTuple.lastAddr = msg.GetOriginatorAddress ();
1322  topologyTuple.sequenceNumber = tc.ansn;
1323  topologyTuple.expirationTime = now + msg.GetVTime ();
1324  AddTopologyTuple (topologyTuple);
1325 
1326  // Schedules topology tuple deletion
1329  this,
1330  topologyTuple.destAddr,
1331  topologyTuple.lastAddr));
1332  }
1333  }
1334 
1335 #ifdef NS3_LOG_ENABLE
1336  {
1337  const TopologySet &topology = m_state.GetTopologySet ();
1338  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1339  << "s ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
1340  for (TopologySet::const_iterator tuple = topology.begin ();
1341  tuple != topology.end (); tuple++)
1342  {
1343  NS_LOG_DEBUG (*tuple);
1344  }
1345  NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
1346  }
1347 #endif // NS3_LOG_ENABLE
1348 }
1349 
1359 void
1361  const Ipv4Address &senderIface)
1362 {
1363  const olsr::MessageHeader::Mid &mid = msg.GetMid ();
1364  Time now = Simulator::Now ();
1365 
1366  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
1367  // 1. If the sender interface of this message is not in the symmetric
1368  // 1-hop neighborhood of this node, the message MUST be discarded.
1369  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
1370  if (linkTuple == NULL)
1371  {
1372  NS_LOG_LOGIC ("Node " << m_mainAddress <<
1373  ": the sender interface of this message is not in the "
1374  "symmetric 1-hop neighborhood of this node,"
1375  " the message MUST be discarded.");
1376  return;
1377  }
1378 
1379  // 2. For each interface address listed in the MID message
1380  for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
1381  i != mid.interfaceAddresses.end (); i++)
1382  {
1383  bool updated = false;
1385  for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin ();
1386  tuple != ifaceAssoc.end (); tuple++)
1387  {
1388  if (tuple->ifaceAddr == *i
1389  && tuple->mainAddr == msg.GetOriginatorAddress ())
1390  {
1391  NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple);
1392  tuple->time = now + msg.GetVTime ();
1393  updated = true;
1394  }
1395  }
1396  if (!updated)
1397  {
1398  IfaceAssocTuple tuple;
1399  tuple.ifaceAddr = *i;
1400  tuple.mainAddr = msg.GetOriginatorAddress ();
1401  tuple.time = now + msg.GetVTime ();
1402  AddIfaceAssocTuple (tuple);
1403  NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple);
1404  // Schedules iface association tuple deletion
1405  Simulator::Schedule (DELAY (tuple.time),
1407  }
1408  }
1409 
1410  // 3. (not part of the RFC) iterate over all NeighborTuple's and
1411  // TwoHopNeighborTuples, update the neighbor addresses taking into account
1412  // the new MID information.
1413  NeighborSet &neighbors = m_state.GetNeighbors ();
1414  for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1415  {
1416  neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr);
1417  }
1418 
1419  TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1420  for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin ();
1421  twoHopNeighbor != twoHopNeighbors.end (); twoHopNeighbor++)
1422  {
1423  twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr);
1424  twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr);
1425  }
1426  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
1427 }
1428 
1438 void
1440  const Ipv4Address &senderIface)
1441 {
1442 
1443  const olsr::MessageHeader::Hna &hna = msg.GetHna ();
1444  Time now = Simulator::Now ();
1445 
1446  // 1. If the sender interface of this message is not in the symmetric
1447  // 1-hop neighborhood of this node, the message MUST be discarded.
1448  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1449  if (link_tuple == NULL)
1450  return;
1451 
1452  // 2. Otherwise, for each (network address, netmask) pair in the
1453  // message:
1454 
1455  for (std::vector<olsr::MessageHeader::Hna::Association>::const_iterator it = hna.associations.begin ();
1456  it != hna.associations.end (); it++)
1457  {
1458  AssociationTuple *tuple = m_state.FindAssociationTuple (msg.GetOriginatorAddress (),it->address,it->mask);
1459 
1460  // 2.1 if an entry in the association set already exists, where:
1461  // A_gateway_addr == originator address
1462  // A_network_addr == network address
1463  // A_netmask == netmask
1464  // then the holding time for that tuple MUST be set to:
1465  // A_time = current time + validity time
1466  if(tuple != NULL)
1467  {
1468  tuple->expirationTime = now + msg.GetVTime ();
1469  }
1470 
1471  // 2.2 otherwise, a new tuple MUST be recorded with:
1472  // A_gateway_addr = originator address
1473  // A_network_addr = network address
1474  // A_netmask = netmask
1475  // A_time = current time + validity time
1476  else
1477  {
1478  AssociationTuple assocTuple = {
1479  msg.GetOriginatorAddress (),
1480  it->address,
1481  it->mask,
1482  now + msg.GetVTime ()
1483  };
1484  AddAssociationTuple (assocTuple);
1485 
1486  //Schedule Association Tuple deletion
1489  assocTuple.gatewayAddr,assocTuple.networkAddr,assocTuple.netmask);
1490  }
1491 
1492  }
1493 }
1494 
1506 void
1508  DuplicateTuple *duplicated,
1509  const Ipv4Address &localIface,
1510  const Ipv4Address &senderAddress)
1511 {
1512  Time now = Simulator::Now ();
1513 
1514  // If the sender interface address is not in the symmetric
1515  // 1-hop neighborhood the message must not be forwarded
1516  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
1517  if (linkTuple == NULL)
1518  return;
1519 
1520  // If the message has already been considered for forwarding,
1521  // it must not be retransmitted again
1522  if (duplicated != NULL && duplicated->retransmitted)
1523  {
1524  NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received"
1525  " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
1526  return;
1527  }
1528 
1529  // If the sender interface address is an interface address
1530  // of a MPR selector of this node and ttl is greater than 1,
1531  // the message must be retransmitted
1532  bool retransmitted = false;
1533  if (olsrMessage.GetTimeToLive () > 1)
1534  {
1535  const MprSelectorTuple *mprselTuple =
1536  m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
1537  if (mprselTuple != NULL)
1538  {
1539  olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1);
1540  olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1);
1541  // We have to introduce a random delay to avoid
1542  // synchronization with neighbors.
1543  QueueMessage (olsrMessage, JITTER);
1544  retransmitted = true;
1545  }
1546  }
1547 
1548  // Update duplicate tuple...
1549  if (duplicated != NULL)
1550  {
1551  duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
1552  duplicated->retransmitted = retransmitted;
1553  duplicated->ifaceList.push_back (localIface);
1554  }
1555  // ...or create a new one
1556  else
1557  {
1558  DuplicateTuple newDup;
1559  newDup.address = olsrMessage.GetOriginatorAddress ();
1560  newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber ();
1561  newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
1562  newDup.retransmitted = retransmitted;
1563  newDup.ifaceList.push_back (localIface);
1564  AddDuplicateTuple (newDup);
1565  // Schedule dup tuple deletion
1566  Simulator::Schedule (OLSR_DUP_HOLD_TIME,
1568  newDup.address, newDup.sequenceNumber);
1569  }
1570 }
1571 
1581 void
1583 {
1584  m_queuedMessages.push_back (message);
1585  if (not m_queuedMessagesTimer.IsRunning ())
1586  {
1589  }
1590 }
1591 
1592 void
1594  const MessageList &containedMessages)
1595 {
1596  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet");
1597 
1598  // Add a header
1599  olsr::PacketHeader header;
1600  header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ());
1602  packet->AddHeader (header);
1603 
1604  // Trace it
1605  m_txPacketTrace (header, containedMessages);
1606 
1607  // Send it
1608  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1609  m_socketAddresses.begin (); i != m_socketAddresses.end (); i++)
1610  {
1611  Ipv4Address bcast = i->second.GetLocal ().GetSubnetDirectedBroadcast (i->second.GetMask ());
1612  i->first->SendTo (packet, 0, InetSocketAddress (bcast, OLSR_PORT_NUMBER));
1613  }
1614 }
1615 
1623 void
1625 {
1626  Ptr<Packet> packet = Create<Packet> ();
1627  int numMessages = 0;
1628 
1629  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages");
1630 
1631  MessageList msglist;
1632 
1633  for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin ();
1634  message != m_queuedMessages.end ();
1635  message++)
1636  {
1637  Ptr<Packet> p = Create<Packet> ();
1638  p->AddHeader (*message);
1639  packet->AddAtEnd (p);
1640  msglist.push_back (*message);
1641  if (++numMessages == OLSR_MAX_MSGS)
1642  {
1643  SendPacket (packet, msglist);
1644  msglist.clear ();
1645  // Reset variables for next packet
1646  numMessages = 0;
1647  packet = Create<Packet> ();
1648  }
1649  }
1650 
1651  if (packet->GetSize ())
1652  {
1653  SendPacket (packet, msglist);
1654  }
1655 
1656  m_queuedMessages.clear ();
1657 }
1658 
1662 void
1664 {
1665  NS_LOG_FUNCTION (this);
1666 
1667  olsr::MessageHeader msg;
1668  Time now = Simulator::Now ();
1669 
1672  msg.SetTimeToLive (1);
1673  msg.SetHopCount (0);
1675  olsr::MessageHeader::Hello &hello = msg.GetHello ();
1676 
1677  hello.SetHTime (m_helloInterval);
1678  hello.willingness = m_willingness;
1679 
1680  std::vector<olsr::MessageHeader::Hello::LinkMessage>
1681  &linkMessages = hello.linkMessages;
1682 
1683  const LinkSet &links = m_state.GetLinks ();
1684  for (LinkSet::const_iterator link_tuple = links.begin ();
1685  link_tuple != links.end (); link_tuple++)
1686  {
1687  if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress
1688  && link_tuple->time >= now))
1689  {
1690  continue;
1691  }
1692 
1693  uint8_t link_type, nb_type = 0xff;
1694 
1695  // Establishes link type
1696  if (link_tuple->symTime >= now)
1697  {
1698  link_type = OLSR_SYM_LINK;
1699  }
1700  else if (link_tuple->asymTime >= now)
1701  {
1702  link_type = OLSR_ASYM_LINK;
1703  }
1704  else
1705  {
1706  link_type = OLSR_LOST_LINK;
1707  }
1708  // Establishes neighbor type.
1709  if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
1710  {
1711  nb_type = OLSR_MPR_NEIGH;
1712  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1713  << " to be MPR_NEIGH.");
1714  }
1715  else
1716  {
1717  bool ok = false;
1718  for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin ();
1719  nb_tuple != m_state.GetNeighbors ().end ();
1720  nb_tuple++)
1721  {
1722  if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr))
1723  {
1724  if (nb_tuple->status == NeighborTuple::STATUS_SYM)
1725  {
1726  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1727  << " to be SYM_NEIGH.");
1728  nb_type = OLSR_SYM_NEIGH;
1729  }
1730  else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
1731  {
1732  nb_type = OLSR_NOT_NEIGH;
1733  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1734  << " to be NOT_NEIGH.");
1735  }
1736  else
1737  {
1738  NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n");
1739  }
1740  ok = true;
1741  break;
1742  }
1743  }
1744  if (!ok)
1745  {
1746  NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
1747  continue;
1748  }
1749  }
1750 
1752  linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f);
1753  linkMessage.neighborInterfaceAddresses.push_back
1754  (link_tuple->neighborIfaceAddr);
1755 
1756  std::vector<Ipv4Address> interfaces =
1757  m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr);
1758 
1759  linkMessage.neighborInterfaceAddresses.insert
1760  (linkMessage.neighborInterfaceAddresses.end (),
1761  interfaces.begin (), interfaces.end ());
1762 
1763  linkMessages.push_back (linkMessage);
1764  }
1765  NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ())
1766  << " (with " << int (linkMessages.size ()) << " link messages)");
1767  QueueMessage (msg, JITTER);
1768 }
1769 
1773 void
1775 {
1776  NS_LOG_FUNCTION (this);
1777 
1778  olsr::MessageHeader msg;
1779 
1782  msg.SetTimeToLive (255);
1783  msg.SetHopCount (0);
1785 
1786  olsr::MessageHeader::Tc &tc = msg.GetTc ();
1787  tc.ansn = m_ansn;
1788 
1789  for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin ();
1790  mprsel_tuple != m_state.GetMprSelectors ().end (); mprsel_tuple++)
1791  {
1792  tc.neighborAddresses.push_back (mprsel_tuple->mainAddr);
1793  }
1794  QueueMessage (msg, JITTER);
1795 }
1796 
1800 void
1802 {
1803  olsr::MessageHeader msg;
1804  olsr::MessageHeader::Mid &mid = msg.GetMid ();
1805 
1806  // A node which has only a single interface address participating in
1807  // the MANET (i.e., running OLSR), MUST NOT generate any MID
1808  // message.
1809 
1810  // A node with several interfaces, where only one is participating
1811  // in the MANET and running OLSR (e.g., a node is connected to a
1812  // wired network as well as to a MANET) MUST NOT generate any MID
1813  // messages.
1814 
1815  // A node with several interfaces, where more than one is
1816  // participating in the MANET and running OLSR MUST generate MID
1817  // messages as specified.
1818 
1819  // [ Note: assuming here that all interfaces participate in the
1820  // MANET; later we may want to make this configurable. ]
1821 
1822  Ipv4Address loopback ("127.0.0.1");
1823  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
1824  {
1825  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
1826  if (addr != m_mainAddress && addr != loopback && m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
1827  mid.interfaceAddresses.push_back (addr);
1828  }
1829  if (mid.interfaceAddresses.size () == 0)
1830  return;
1831 
1834  msg.SetTimeToLive (255);
1835  msg.SetHopCount (0);
1837 
1838  QueueMessage (msg, JITTER);
1839 }
1840 
1844 void
1846 {
1847 
1848  olsr::MessageHeader msg;
1849 
1852  msg.SetTimeToLive (255);
1853  msg.SetHopCount (0);
1855  olsr::MessageHeader::Hna &hna = msg.GetHna ();
1856 
1857  std::vector<olsr::MessageHeader::Hna::Association> &associations = hna.associations;
1858 
1859  // Add all local HNA associations to the HNA message
1860  const Associations &localHnaAssociations = m_state.GetAssociations ();
1861  for (Associations::const_iterator it = localHnaAssociations.begin ();
1862  it != localHnaAssociations.end (); it++)
1863  {
1864  olsr::MessageHeader::Hna::Association assoc = { it->networkAddr, it->netmask};
1865  associations.push_back (assoc);
1866  }
1867  // If there is no HNA associations to send, return without queuing the message
1868  if (associations.size () == 0)
1869  {
1870  return;
1871  }
1872 
1873  // Else, queue the message to be sent later on
1874  QueueMessage (msg, JITTER);
1875 }
1876 
1882 void
1884 {
1885  // Check if the (networkAddr, netmask) tuple already exist
1886  // in the list of local HNA associations
1887  const Associations &localHnaAssociations = m_state.GetAssociations ();
1888  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1889  assocIterator != localHnaAssociations.end (); assocIterator++)
1890  {
1891  Association const &localHnaAssoc = *assocIterator;
1892  if (localHnaAssoc.networkAddr == networkAddr && localHnaAssoc.netmask == netmask)
1893  {
1894  NS_LOG_INFO ("HNA association for network " << networkAddr << "/" << netmask << " already exists.");
1895  return;
1896  }
1897  }
1898  // If the tuple does not already exist, add it to the list of local HNA associations.
1899  NS_LOG_INFO ("Adding HNA association for network " << networkAddr << "/" << netmask << ".");
1900  m_state.InsertAssociation ( (Association) { networkAddr, netmask} );
1901 }
1902 
1908 void
1910 {
1911  NS_LOG_INFO ("Removing HNA association for network " << networkAddr << "/" << netmask << ".");
1912  m_state.EraseAssociation ( (Association) { networkAddr, netmask} );
1913 }
1914 
1925 void
1927 {
1928  // If a routing table has already been associated, remove
1929  // corresponding entries from the list of local HNA associations
1930  if (m_routingTableAssociation != 0)
1931  {
1932  NS_LOG_INFO ("Removing HNA entries coming from the old routing table association.");
1933  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1934  {
1935  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1936  // If the outgoing interface for this route is a non-olsr interface
1937  if (UsesNonOlsrOutgoingInterface (route))
1938  {
1939  // remove the corresponding entry
1941  }
1942  }
1943  }
1944 
1945  // Sets the routingTableAssociation to its new value
1946  m_routingTableAssociation = routingTable;
1947 
1948  // Iterate over entries of the associated routing table and
1949  // add the routes using non-olsr outgoing interfaces to the list
1950  // of local HNA associations
1951  NS_LOG_DEBUG ("Nb local associations before adding some entries from"
1952  " the associated routing table: " << m_state.GetAssociations ().size ());
1953  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1954  {
1955  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1956  Ipv4Address destNetworkAddress = route.GetDestNetwork ();
1957  Ipv4Mask destNetmask = route.GetDestNetworkMask ();
1958 
1959  // If the outgoing interface for this route is a non-olsr interface,
1960  if (UsesNonOlsrOutgoingInterface (route))
1961  {
1962  // Add this entry's network address and netmask to the list of local HNA entries
1963  AddHostNetworkAssociation (destNetworkAddress, destNetmask);
1964  }
1965  }
1966  NS_LOG_DEBUG ("Nb local associations after having added some entries from "
1967  "the associated routing table: " << m_state.GetAssociations ().size ());
1968 }
1969 
1975 bool
1977 {
1978  std::set<uint32_t>::const_iterator ci = m_interfaceExclusions.find (route.GetInterface ());
1979  // The outgoing interface is a non-OLSR interface if a match is found
1980  // before reaching the end of the list of excluded interfaces
1981  return ci != m_interfaceExclusions.end ();
1982 }
1983 
1987 void
1989  const olsr::MessageHeader::Hello &hello,
1990  const Ipv4Address &receiverIface,
1991  const Ipv4Address &senderIface)
1992 {
1993  Time now = Simulator::Now ();
1994  bool updated = false;
1995  bool created = false;
1996  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
1997  << ": LinkSensing(receiverIface=" << receiverIface
1998  << ", senderIface=" << senderIface << ") BEGIN");
1999 
2000  NS_ASSERT (msg.GetVTime () > Seconds (0));
2001  LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
2002  if (link_tuple == NULL)
2003  {
2004  LinkTuple newLinkTuple;
2005  // We have to create a new tuple
2006  newLinkTuple.neighborIfaceAddr = senderIface;
2007  newLinkTuple.localIfaceAddr = receiverIface;
2008  newLinkTuple.symTime = now - Seconds (1);
2009  newLinkTuple.time = now + msg.GetVTime ();
2010  link_tuple = &m_state.InsertLinkTuple (newLinkTuple);
2011  created = true;
2012  NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one");
2013  }
2014  else
2015  {
2016  NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
2017  updated = true;
2018  }
2019 
2020  link_tuple->asymTime = now + msg.GetVTime ();
2021  for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
2022  hello.linkMessages.begin ();
2023  linkMessage != hello.linkMessages.end ();
2024  linkMessage++)
2025  {
2026  int lt = linkMessage->linkCode & 0x03; // Link Type
2027  int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type
2028 
2029 #ifdef NS3_LOG_ENABLE
2030  const char *linkTypeName;
2031  switch (lt)
2032  {
2033  case OLSR_UNSPEC_LINK: linkTypeName = "UNSPEC_LINK"; break;
2034  case OLSR_ASYM_LINK: linkTypeName = "ASYM_LINK"; break;
2035  case OLSR_SYM_LINK: linkTypeName = "SYM_LINK"; break;
2036  case OLSR_LOST_LINK: linkTypeName = "LOST_LINK"; break;
2037  /* no default, since lt must be in 0..3, covered above
2038  default: linkTypeName = "(invalid value!)";
2039  */
2040  }
2041 
2042  const char *neighborTypeName;
2043  switch (nt)
2044  {
2045  case OLSR_NOT_NEIGH: neighborTypeName = "NOT_NEIGH"; break;
2046  case OLSR_SYM_NEIGH: neighborTypeName = "SYM_NEIGH"; break;
2047  case OLSR_MPR_NEIGH: neighborTypeName = "MPR_NEIGH"; break;
2048  default: neighborTypeName = "(invalid value!)";
2049  }
2050 
2051  NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type "
2052  << lt << " (" << linkTypeName
2053  << ") and Neighbor Type " << nt
2054  << " (" << neighborTypeName << ")");
2055 #endif // NS3_LOG_ENABLE
2056 
2057  // We must not process invalid advertised links
2058  if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) ||
2059  (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH
2060  && nt != OLSR_NOT_NEIGH))
2061  {
2062  NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING");
2063  continue;
2064  }
2065 
2066  for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr =
2067  linkMessage->neighborInterfaceAddresses.begin ();
2068  neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end ();
2069  neighIfaceAddr++)
2070  {
2071  NS_LOG_DEBUG (" -> Neighbor: " << *neighIfaceAddr);
2072  if (*neighIfaceAddr == receiverIface)
2073  {
2074  if (lt == OLSR_LOST_LINK)
2075  {
2076  NS_LOG_LOGIC ("link is LOST => expiring it");
2077  link_tuple->symTime = now - Seconds (1);
2078  updated = true;
2079  }
2080  else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK)
2081  {
2082  NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now"
2083  " (symTime being increased to " << now + msg.GetVTime ());
2084  link_tuple->symTime = now + msg.GetVTime ();
2085  link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
2086  updated = true;
2087  }
2088  else
2089  {
2090  NS_FATAL_ERROR ("bad link type");
2091  }
2092  break;
2093  }
2094  else
2095  {
2096  NS_LOG_DEBUG (" \\-> *neighIfaceAddr (" << *neighIfaceAddr
2097  << " != receiverIface (" << receiverIface << ") => IGNORING!");
2098  }
2099  }
2100  NS_LOG_DEBUG ("Link tuple updated: " << int (updated));
2101  }
2102  link_tuple->time = std::max (link_tuple->time, link_tuple->asymTime);
2103 
2104  if (updated)
2105  {
2106  LinkTupleUpdated (*link_tuple, hello.willingness);
2107  }
2108 
2109  // Schedules link tuple deletion
2110  if (created)
2111  {
2112  LinkTupleAdded (*link_tuple, hello.willingness);
2113  m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
2115  link_tuple->neighborIfaceAddr));
2116  }
2117  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
2118  << ": LinkSensing END");
2119 }
2120 
2124 void
2126  const olsr::MessageHeader::Hello &hello)
2127 {
2129  if (nb_tuple != NULL)
2130  {
2131  nb_tuple->willingness = hello.willingness;
2132  }
2133 }
2134 
2135 
2139 void
2141  const olsr::MessageHeader::Hello &hello)
2142 {
2143  Time now = Simulator::Now ();
2144 
2145  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
2146 
2147  for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
2148  link_tuple != m_state.GetLinks ().end (); link_tuple++)
2149  {
2150  NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple);
2151  if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ())
2152  {
2153  NS_LOG_LOGIC ("Link tuple ignored: "
2154  "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
2155  NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): "
2156  << GetMainAddress (link_tuple->neighborIfaceAddr)
2157  << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ());
2158  continue;
2159  }
2160 
2161  if (link_tuple->symTime < now)
2162  {
2163  NS_LOG_LOGIC ("Link tuple ignored: expired.");
2164  continue;
2165  }
2166 
2167  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2168  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2169  linkMessage != hello.linkMessages.end (); linkMessage++)
2170  {
2171  int neighborType = (linkMessage->linkCode >> 2) & 0x3;
2172 #ifdef NS3_LOG_ENABLE
2173  const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" };
2174  const char *neighborTypeName = ((neighborType < 3) ?
2175  neighborTypeNames[neighborType]
2176  : "(invalid value)");
2177  NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType="
2178  << neighborType << " (" << neighborTypeName << ")");
2179 #endif // NS3_LOG_ENABLE
2180 
2181  for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter =
2182  linkMessage->neighborInterfaceAddresses.begin ();
2183  nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end ();
2184  nb2hop_addr_iter++)
2185  {
2186  Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter);
2187  NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: "
2188  << *nb2hop_addr_iter
2189  << " (main address is " << nb2hop_addr << ")");
2190  if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH)
2191  {
2192  // If the main address of the 2-hop neighbor address == main address
2193  // of the receiving node, silently discard the 2-hop
2194  // neighbor address.
2195  if (nb2hop_addr == m_mainAddress)
2196  {
2197  NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)");
2198  continue;
2199  }
2200 
2201  // Otherwise, a 2-hop tuple is created
2202  TwoHopNeighborTuple *nb2hop_tuple =
2204  NS_LOG_LOGIC ("Adding the 2-hop neighbor"
2205  << (nb2hop_tuple ? " (refreshing existing entry)" : ""));
2206  if (nb2hop_tuple == NULL)
2207  {
2208  TwoHopNeighborTuple new_nb2hop_tuple;
2209  new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress ();
2210  new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
2211  new_nb2hop_tuple.expirationTime = now + msg.GetVTime ();
2212  AddTwoHopNeighborTuple (new_nb2hop_tuple);
2213  // Schedules nb2hop tuple deletion
2214  m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime),
2216  new_nb2hop_tuple.neighborMainAddr,
2217  new_nb2hop_tuple.twoHopNeighborAddr));
2218  }
2219  else
2220  {
2221  nb2hop_tuple->expirationTime = now + msg.GetVTime ();
2222  }
2223  }
2224  else if (neighborType == OLSR_NOT_NEIGH)
2225  {
2226  // For each 2-hop node listed in the HELLO message
2227  // with Neighbor Type equal to NOT_NEIGH all 2-hop
2228  // tuples where: N_neighbor_main_addr == Originator
2229  // Address AND N_2hop_addr == main address of the
2230  // 2-hop neighbor are deleted.
2231  NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
2233  }
2234  else
2235  {
2236  NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad"
2237  " neighbor type value: " << neighborType);
2238  }
2239  }
2240  }
2241  }
2242 
2243  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
2244 }
2245 
2246 
2247 
2251 void
2253  const olsr::MessageHeader::Hello &hello)
2254 {
2255  NS_LOG_FUNCTION (this);
2256 
2257  Time now = Simulator::Now ();
2258 
2259  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2260  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2261  linkMessage != hello.linkMessages.end ();
2262  linkMessage++)
2263  {
2264  int nt = linkMessage->linkCode >> 2;
2265  if (nt == OLSR_MPR_NEIGH)
2266  {
2267  NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
2268 
2269  for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
2270  linkMessage->neighborInterfaceAddresses.begin ();
2271  nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
2272  nb_iface_addr++)
2273  {
2274  if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
2275  {
2276  NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
2277 
2278  // We must create a new entry into the mpr selector set
2279  MprSelectorTuple *existing_mprsel_tuple =
2281  if (existing_mprsel_tuple == NULL)
2282  {
2283  MprSelectorTuple mprsel_tuple;
2284 
2285  mprsel_tuple.mainAddr = msg.GetOriginatorAddress ();
2286  mprsel_tuple.expirationTime = now + msg.GetVTime ();
2287  AddMprSelectorTuple (mprsel_tuple);
2288 
2289  // Schedules mpr selector tuple deletion
2291  (DELAY (mprsel_tuple.expirationTime),
2293  mprsel_tuple.mainAddr));
2294  }
2295  else
2296  {
2297  existing_mprsel_tuple->expirationTime = now + msg.GetVTime ();
2298  }
2299  }
2300  }
2301  }
2302  }
2303  NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
2304 }
2305 
2306 
2307 #if 0
2308 void
2316 OLSR::mac_failed (Ptr<Packet> p) {
2317  double now = Simulator::Now ();
2318  struct hdr_ip* ih = HDR_IP (p);
2319  struct hdr_cmn* ch = HDR_CMN (p);
2320 
2321  debug ("%f: Node %d MAC Layer detects a breakage on link to %d\n",
2322  now,
2323  OLSR::node_id (ra_addr ()),
2324  OLSR::node_id (ch->next_hop ()));
2325 
2326  if ((u_int32_t)ih->daddr () == IP_BROADCAST) {
2327  drop (p, DROP_RTR_MAC_CALLBACK);
2328  return;
2329  }
2330 
2331  OLSR_link_tuple* link_tuple = state_.find_link_tuple (ch->next_hop ());
2332  if (link_tuple != NULL) {
2333  link_tuple->lost_time () = now + OLSR_NEIGHB_HOLD_TIME;
2334  link_tuple->time () = now + OLSR_NEIGHB_HOLD_TIME;
2335  nb_loss (link_tuple);
2336  }
2337  drop (p, DROP_RTR_MAC_CALLBACK);
2338 }
2339 #endif
2340 
2341 
2342 
2343 
2351 void
2353 {
2354  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2355  << "s: OLSR Node " << m_mainAddress
2356  << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
2360 
2361  MprComputation ();
2363 }
2364 
2370 void
2372 {
2373  /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
2374  Simulator::Now (),
2375  OLSR::node_id(ra_addr()),
2376  OLSR::node_id(tuple->addr()),
2377  tuple->seq_num());*/
2378  m_state.InsertDuplicateTuple (tuple);
2379 }
2380 
2386 void
2388 {
2389  /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
2390  Simulator::Now (),
2391  OLSR::node_id(ra_addr()),
2392  OLSR::node_id(tuple->addr()),
2393  tuple->seq_num());*/
2394  m_state.EraseDuplicateTuple (tuple);
2395 }
2396 
2397 void
2398 RoutingProtocol::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness)
2399 {
2400  // Creates associated neighbor tuple
2401  NeighborTuple nb_tuple;
2403  nb_tuple.willingness = willingness;
2404 
2405  if (tuple.symTime >= Simulator::Now ())
2406  {
2407  nb_tuple.status = NeighborTuple::STATUS_SYM;
2408  }
2409  else
2410  {
2412  }
2413 
2414  AddNeighborTuple (nb_tuple);
2415 }
2416 
2422 void
2424 {
2425  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2426  << "s: OLSR Node " << m_mainAddress
2427  << " LinkTuple " << tuple << " REMOVED.");
2428 
2429  m_state.EraseLinkTuple (tuple);
2431 
2432 }
2433 
2440 void
2441 RoutingProtocol::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
2442 {
2443  // Each time a link tuple changes, the associated neighbor tuple must be recomputed
2444 
2445  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2446  << "s: OLSR Node " << m_mainAddress
2447  << " LinkTuple " << tuple << " UPDATED.");
2448 
2449  NeighborTuple *nb_tuple =
2451 
2452  if (nb_tuple == NULL)
2453  {
2454  LinkTupleAdded (tuple, willingness);
2456  }
2457 
2458  if (nb_tuple != NULL)
2459  {
2460 #ifdef NS3_LOG_ENABLE
2461  int statusBefore = nb_tuple->status;
2462 #endif // NS3_LOG_ENABLE
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 
3362 } // namespace olsr
3363 } // namespace ns3
3364 
3365 
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
#define JITTER
Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission. ...
An OLSR's routing table entry.
uint32_t distance
Distance in hops to the destination.
#define OLSR_MPR_NEIGH
Asymmetric neighbor type.
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
void HelloTimerExpire()
Sends a HELLO message and reschedules the HELLO timer.
an Inet address class
void AddTopologyTuple(const TopologyTuple &tuple)
Adds a topology tuple to the Topology Set.
void EraseDuplicateTuple(const DuplicateTuple &tuple)
Definition: olsr-state.cc:296
Ipv4Address GetIpv4(void) const
#define OLSR_MAX_SEQ_NUM
Maximum allowed sequence number.
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
void DoDispose()
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
Ipv4Address GetOriginatorAddress() const
Definition: olsr-header.h:152
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
Ptr< const AttributeChecker > MakeEnumChecker(int v1, std::string n1, int v2, std::string n2, int v3, std::string n3, int v4, std::string n4, int v5, std::string n5, int v6, std::string n6, int v7, std::string n7, int v8, std::string n8, int v9, std::string n9, int v10, std::string n10, int v11, std::string n11, int v12, std::string n12, int v13, std::string n13, int v14, std::string n14, int v15, std::string n15, int v16, std::string n16, int v17, std::string n17, int v18, std::string n18, int v19, std::string n19, int v20, std::string n20, int v21, std::string n21, int v22, std::string n22)
Definition: enum.cc:178
void IfaceAssocTupleTimerExpire(Ipv4Address ifaceAddr)
Removes tuple_ if expired.
uint16_t sequenceNumber
Sequence number.
void RemoveMprSelectorTuple(const MprSelectorTuple &tuple)
Removes an MPR selector tuple from the MPR Selector Set.
Callback template class.
Definition: callback.h:920
#define OLSR_WILL_DEFAULT
Willingness for forwarding packets from other nodes: medium.
uint16_t GetPacketSequenceNumber()
Increments packet sequence number and returns the new value.
std::vector< Association > Associations
Association Set type.
Time m_midInterval
MID messages' emission interval.
a simple Timer class
Definition: timer.h:45
#define OLSR_DUP_HOLD_TIME
Dup holding time.
Doxygen 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:126
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 InsertAssociation(const Association &tuple)
Definition: olsr-state.cc:541
LinkTuple * FindSymLinkTuple(const Ipv4Address &ifaceAddr, Time time)
Definition: olsr-state.cc:330
Ipv4Address destAddr
Address of the destination node.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
NS_LOG_COMPONENT_DEFINE("OlsrHeader")
void HnaTimerExpire()
Sends an HNA message (if the node has associated hosts/networks) and reschedules the HNA timer...
#define OLSR_TOP_HOLD_TIME
Top holding time.
void LinkTupleUpdated(const LinkTuple &tuple, uint8_t willingness)
This function is invoked when a link tuple is updated.
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:1014
#define NS_ASSERT(condition)
Definition: assert.h:64
Ipv4Address GetDestNetwork(void) const
#define OLSR_WILL_ALWAYS
Willingness for forwarding packets from other nodes: always.
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
void AddEntry(const Ipv4Address &dest, const Ipv4Address &next, uint32_t interface, uint32_t distance)
Adds a new entry into the routing table.
uint32_t GetSize(void) const
Definition: packet.h:650
virtual void NotifyInterfaceUp(uint32_t interface)
void SendTc()
Creates a new OLSR TC message which is buffered for being sent later on.
void EraseAssociationTuple(const AssociationTuple &tuple)
Definition: olsr-state.cc:507
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
void DupTupleTimerExpire(Ipv4Address address, uint16_t sequenceNumber)
Removes tuple if expired.
#define NS_LOG_INFO(msg)
Definition: log.h:298
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
IfaceAssocTuple * FindIfaceAssocTuple(const Ipv4Address &ifaceAddr)
Definition: olsr-state.cc:434
enum ns3::olsr::NeighborTuple::Status status
void AddHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Inject Association to be sent in HNA message.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
std::vector< LinkMessage > linkMessages
Definition: olsr-header.h:276
uint16_t GetMessageSequenceNumber() const
Definition: olsr-header.h:179
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:824
Time expirationTime
Time at which this tuple expires and must be removed.
#define OLSR_WILL_LOW
Willingness for forwarding packets from other nodes: low.
void EraseOlderTopologyTuples(const Ipv4Address &lastAddr, uint16_t ansn)
Definition: olsr-state.cc:409
void LinkTupleTimerExpire(Ipv4Address neighborIfaceAddr)
Removes tuple_ if expired.
void SetMainInterface(uint32_t interface)
Set the OLSR main address to the first address on the indicated interface.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Ipv4Mask netmask
Netmask of network reachable through gatewayAddr.
void SetHopCount(uint8_t hopCount)
Definition: olsr-header.h:166
void InsertTopologyTuple(const TopologyTuple &tuple)
Definition: olsr-state.cc:426
MessageType GetMessageType() const
Definition: olsr-header.h:134
void EraseTopologyTuple(const TopologyTuple &tuple)
Definition: olsr-state.cc:395
const LinkSet & GetLinks() const
Definition: olsr-state.h:115
Time GetVTime() const
Definition: olsr-header.h:143
void Nb2hopTupleTimerExpire(Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr)
Removes tuple_ if expired.
void RemoveAssociationTuple(const AssociationTuple &tuple)
Removes a host network association tuple from the Association Set.
DuplicateTuple * FindDuplicateTuple(const Ipv4Address &address, uint16_t sequenceNumber)
Definition: olsr-state.cc:284
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
void ProcessTc(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a TC message following RFC 3626 specification.
Ipv4Address GetSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
#define OLSR_NEIGHB_HOLD_TIME
Neighbor holding time.
a polymophic address class
Definition: address.h:86
bool IsRunning(void) const
Definition: timer.cc:121
void SetVTime(Time time)
Definition: olsr-header.h:139
void MprSelTupleTimerExpire(Ipv4Address mainAddr)
Removes tuple_ if expired.
#define OLSR_SYM_LINK
Symmetric link type.
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
std::map< Ipv4Address, RoutingTableEntry > m_table
Data structure for the routing table.
std::vector< Ipv4Address > interfaceAddresses
Definition: olsr-header.h:225
std::vector< Ipv4Address > neighborAddresses
Definition: olsr-header.h:302
void SetTimeToLive(uint8_t timeToLive)
Definition: olsr-header.h:157
TracedCallback< const PacketHeader &, const MessageList & > m_rxPacketTrace
void RemoveIfaceAssocTuple(const IfaceAssocTuple &tuple)
Removes an interface association tuple from the Interface Association Set.
uint32_t GetInterface(void) const
Packet header for IPv4.
Definition: ipv4-header.h:31
EventGarbageCollector m_events
double GetSeconds(void) const
Definition: nstime.h:274
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:317
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.
void EraseTwoHopNeighborTuples(const Ipv4Address &neighbor)
Definition: olsr-state.cc:239
uint8_t m_willingness
Willingness for forwarding packets on behalf of other nodes.
void PopulateNeighborSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the Neighbor Set according to the information contained in a new received HELLO message (foll...
Time expirationTime
Time at which this tuple expires and must be removed.
void RemoveHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Removes Association sent in HNA message.
hold variables of type 'enum'
Definition: enum.h:37
Ipv4Address mainAddr
Main address of the node.
void AddIfaceAssocTuple(const IfaceAssocTuple &tuple)
Adds an interface association tuple to the Interface Association Set.
void QueueMessage(const olsr::MessageHeader &message, Time delay)
Enques an OLSR message which will be sent with a delay of (0, delay].
hold objects of type ns3::Time
Definition: nstime.h:961
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:152
TopologyTuple * FindTopologyTuple(const Ipv4Address &destAddr, const Ipv4Address &lastAddr)
Definition: olsr-state.cc:370
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
void SetFunction(FN fn)
Definition: timer.h:254
An Association Tuple.
void ProcessHello(const olsr::MessageHeader &msg, const Ipv4Address &receiverIface, const Ipv4Address &senderIface)
Processes a HELLO message following RFC 3626 specification.
#define DELAY(time)
Gets the delay between a given time and the current time.
void InsertTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Definition: olsr-state.cc:256
tuple interfaces
Definition: first.py:40
void AddAssociationTuple(const AssociationTuple &tuple)
Adds a host network association tuple to the Association Set.
void SetPacketLength(uint16_t length)
Definition: olsr-header.h:75
Ptr< Ipv4StaticRouting > m_hnaRoutingTable
Time expirationTime
Time at which this tuple expires and must be removed.
virtual bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
uint8_t GetHopCount() const
Definition: olsr-header.h:170
void MprComputation()
Computates MPR set of a node following RFC 3626 hints.
std::vector< LinkTuple > LinkSet
Link Set type.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
void RemoveDuplicateTuple(const DuplicateTuple &tuple)
Removes a duplicate tuple from the Duplicate Set.
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc: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 EraseAssociation(const Association &tuple)
Definition: olsr-state.cc:527
const Associations & GetAssociations() const
Definition: olsr-state.h:158
uint8_t GetTimeToLive() const
Definition: olsr-header.h:161
void CoverTwoHopNeighbors(Ipv4Address neighborMainAddr, TwoHopNeighborSet &N2)
Remove all covered 2-hop neighbors from N2 set.
Time m_helloInterval
HELLO messages' emission interval.
LinkTuple & InsertLinkTuple(const LinkTuple &tuple)
Definition: olsr-state.cc:361
void SetDelay(const Time &delay)
Definition: timer.cc:69
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
#define OLSR_UNSPEC_LINK
Unspecified link type.
#define OLSR_NOT_NEIGH
Not neighbor type.
#define OLSR_ASYM_LINK
Asymmetric link type.
void SetRoutingTableAssociation(Ptr< Ipv4StaticRouting > routingTable)
Inject Associations from an Ipv4StaticRouting instance.
Ipv4Address destAddr
Main address of the destination.
std::vector< IfaceAssocTuple > IfaceAssocSet
Interface Association Set type.
void SetMprSet(MprSet mprSet)
MprSet is set by routing protocol after MprCompute.
Definition: olsr-state.cc:271
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
void TopologyTupleTimerExpire(Ipv4Address destAddr, Ipv4Address lastAddr)
Removes tuple_ if expired.
Time m_tcInterval
TC messages' emission interval.
const IfaceAssocSet & GetIfaceAssocSet() const
Definition: olsr-state.h:139
void AddTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Adds a 2-hop neighbor tuple to the 2-hop Neighbor Set.
void AssociationTupleTimerExpire(Ipv4Address gatewayAddr, Ipv4Address networkAddr, Ipv4Mask netmask)
Removes tuple_ if expired.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
void NeighborLoss(const LinkTuple &tuple)
Performs all actions needed when a neighbor loss occurs.
void SetOriginatorAddress(Ipv4Address originatorAddress)
Definition: olsr-header.h:148
void RemoveTopologyTuple(const TopologyTuple &tuple)
Removes a topology tuple from the Topology Set.
uint8_t willingness
A value between 0 and 7 specifying the node's willingness to carry traffic on behalf of other nodes...
Time expirationTime
Time at which this tuple expires and must be removed.
void SendMid()
Creates a new OLSR MID message which is buffered for being sent later on.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
void InsertDuplicateTuple(const DuplicateTuple &tuple)
Definition: olsr-state.cc:310
static InetSocketAddress ConvertFrom(const Address &address)
void RecvOlsr(Ptr< Socket > socket)
Ipv4Address neighborMainAddr
Main address of a neighbor node.
std::vector< Association > associations
Definition: olsr-header.h:338
Ipv4Address twoHopNeighborAddr
Main address of a 2-hop neighbor with a symmetric link to nb_main_addr.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
TopologyTuple * FindNewerTopologyTuple(const Ipv4Address &lastAddr, uint16_t ansn)
Definition: olsr-state.cc:383
AssociationTuple * FindAssociationTuple(const Ipv4Address &gatewayAddr, const Ipv4Address &networkAddr, const Ipv4Mask &netmask)
Definition: olsr-state.cc:493
void MidTimerExpire()
Sends a MID message (if the node has more than one interface) and resets the MID timer.
Ptr< Ipv4StaticRouting > m_routingTableAssociation
void EraseTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Definition: olsr-state.cc:206
void AddNeighborTuple(const NeighborTuple &tuple)
Adds a neighbor tuple to the Neighbor Set.
void SendHello()
Creates a new OLSR HELLO message which is buffered for being sent later on.
std::vector< Ipv4Address > FindNeighborInterfaces(const Ipv4Address &neighborMainAddr) const
Definition: olsr-state.cc:478
void RemoveLinkTuple(const LinkTuple &tuple)
Removes a link tuple from the Link Set.
bool UsesNonOlsrOutgoingInterface(const Ipv4RoutingTableEntry &route)
Tests whether or not the specified route uses a non-OLSR outgoing interface.
LinkTuple * FindLinkTuple(const Ipv4Address &ifaceAddr)
Definition: olsr-state.cc:318
bool Lookup(const Ipv4Address &dest, RoutingTableEntry &outEntry) const
Looks up an entry for the specified destination address.
std::vector< MessageHeader > MessageList
Definition: olsr-header.h:450
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
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)
Doxygen introspection did not find any typical Config paths.
Definition: olsr-header.h:69
uint16_t m_packetSequenceNumber
Packets sequence number counter.
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition: enum.h:118
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
void PopulateTwoHopNeighborSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the 2-hop Neighbor Set according to the information contained in a new received HELLO message...
void InsertMprSelectorTuple(const MprSelectorTuple &tuple)
Definition: olsr-state.cc:81
Ipv4Address GetMainAddress(Ipv4Address iface_addr) const
Gets the main address associated with a given interface address.
void RoutingTableComputation()
Creates the routing table of the node following RFC 3626 hints.
void RemoveTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Removes a 2-hop neighbor tuple from the 2-hop Neighbor Set.
void EraseIfaceAssocTuple(const IfaceAssocTuple &tuple)
Definition: olsr-state.cc:458
void RemoveEntry(const Ipv4Address &dest)
Deletes the entry whose destination address is given.
void ForwardDefault(olsr::MessageHeader olsrMessage, DuplicateTuple *duplicated, const Ipv4Address &localIface, const Ipv4Address &senderAddress)
OLSR's default forwarding algorithm.
void ProcessHna(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a HNA message following RFC 3626 specification.
virtual Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
int Degree(NeighborTuple const &tuple)
This auxiliary function (defined in RFC 3626) is used for calculating the MPR Set.
#define OLSR_WILL_HIGH
Willingness for forwarding packets from other nodes: high.
uint32_t interface
Interface index.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
std::vector< NeighborTuple > NeighborSet
Neighbor Set type.
bool IsMyOwnAddress(const Ipv4Address &a) const
Check that address is one of my interfaces.
uint32_t GetId(void) const
Definition: node.cc:104
void EraseLinkTuple(const LinkTuple &tuple)
Definition: olsr-state.cc:347
a class to store IPv4 address information on an interface
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
void PopulateMprSelectorSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the MPR Selector Set according to the information contained in a new received HELLO message (...
void SendQueuedMessages()
Creates as many OLSR packets as needed in order to send all buffered OLSR messages.
#define NS_LOG_WARN(msg)
Definition: log.h:280
Ipv4Address ifaceAddr
Interface address of a node.
#define OLSR_LOST_LINK
Lost link type.
Ipv4Address nextAddr
Address of the next hop.
TracedCallback< const PacketHeader &, const MessageList & > m_txPacketTrace
void EraseMprSelectorTuple(const MprSelectorTuple &tuple)
Definition: olsr-state.cc:50
A network Node.
Definition: node.h:55
std::set< Ipv4Address > MprSet
MPR Set type.
#define OLSR_SYM_NEIGH
Symmetric neighbor type.
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
bool FindMprAddress(const Ipv4Address &address)
Definition: olsr-state.cc:264
void SendHna()
Creates a new OLSR HNA message which is buffered for being sent later on.
const TwoHopNeighborSet & GetTwoHopNeighbors() const
Definition: olsr-state.h:85
#define OLSR_MID_HOLD_TIME
MID holding time.
std::vector< TwoHopNeighborTuple > TwoHopNeighborSet
2-hop Neighbor Set type.
void Track(EventId event)
Tracks a new event.
const AssociationSet & GetAssociationSet() const
Definition: olsr-state.h:153
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and...
Definition: names.cc:665
MprSelectorTuple * FindMprSelectorTuple(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:38
Abstract base class for IPv4 routing protocols.
#define OLSR_WILL_NEVER
Willingness for forwarding packets from other nodes: never.
#define OLSR_MAX_MSGS
Maximum number of messages per packet.
TwoHopNeighborTuple * FindTwoHopNeighborTuple(const Ipv4Address &neighbor, const Ipv4Address &twoHopNeighbor)
Definition: olsr-state.cc:190
void LinkTupleAdded(const LinkTuple &tuple, uint8_t willingness)
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Time m_hnaInterval
HNA messages' emission interval.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:452
const NeighborSet & GetNeighbors() const
Definition: olsr-state.h:68
void Dump(void)
Dump the neighbor table, two-hop neighbor table, and routing table to logging output (NS_LOG_DEBUG lo...
void EraseMprSelectorTuples(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:64
uint16_t GetPort(void) const
Ipv4Address neighborMainAddr
Main address of a neighbor.
virtual void DoInitialize(void)
This method is called only once by Object::Initialize.
std::vector< RoutingTableEntry > GetRoutingTableEntries() const
Return the list of routing table entries discovered by OLSR.
void InsertNeighborTuple(const NeighborTuple &tuple)
Definition: olsr-state.cc:172
tuple address
Definition: first.py:37
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
void AddDuplicateTuple(const DuplicateTuple &tuple)
Adds a duplicate tuple to the Duplicate Set.
void SetMessageSequenceNumber(uint16_t messageSequenceNumber)
Definition: olsr-header.h:175
void TcTimerExpire()
Sends a TC message (if there exists any MPR selector) and reschedules the TC timer.
Ipv4Address address
Originator address of the message.
const MprSelectorSet & GetMprSelectors() const
Definition: olsr-state.h:57
void RemoveNeighborTuple(const NeighborTuple &tuple)
Removes a neighbor tuple from the Neighbor Set.
uint16_t GetMessageSequenceNumber()
Increments message sequence number and returns the new value.
IfaceAssocSet & GetIfaceAssocSetMutable()
Definition: olsr-state.h:143
void EraseNeighborTuple(const NeighborTuple &neighborTuple)
Definition: olsr-state.cc:144
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:185
Ipv4Address gatewayAddr
Main address of the gateway.
OlsrState m_state
Internal state with all needed data structs.
void AddMprSelectorTuple(const MprSelectorTuple &tuple)
Adds an MPR selector tuple to the MPR Selector Set.
TracedCallback< uint32_t > m_routingTableChanged
NeighborTuple * FindNeighborTuple(const Ipv4Address &mainAddr)
Definition: olsr-state.cc:108
#define OLSR_HNA_HOLD_TIME
HNA holding time.
std::string PrintMprSelectorSet() const
Definition: olsr-state.cc:87
Ipv4Mask GetDestNetworkMask(void) const
a unique identifier for an interface.
Definition: type-id.h:49
An Interface Association Tuple.
bool retransmitted
Indicates whether the message has been retransmitted or not.
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
The type "list of interface addresses".
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
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:253
olsr::MessageList m_queuedMessages
A list of pending messages which are buffered awaiting for being sent.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
const NeighborTuple * FindSymNeighborTuple(const Ipv4Address &mainAddr) const
Definition: olsr-state.cc:120
bool FindSendEntry(const RoutingTableEntry &entry, RoutingTableEntry &outEntry) const
Finds the appropiate entry which must be used in order to forward a data packet to a next hop (given ...
const TopologySet & GetTopologySet() const
Definition: olsr-state.h:125
uint16_t GetPacketLength() const
Definition: olsr-header.h:79
void InsertIfaceAssocTuple(const IfaceAssocTuple &tuple)
Definition: olsr-state.cc:472
Time expirationTime
Time at which this tuple expires and must be removed.
std::vector< Ipv4Address > ifaceList
List of interfaces which the message has been received on.
void InsertAssociationTuple(const AssociationTuple &tuple)
Definition: olsr-state.cc:521
void ProcessMid(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a MID message following RFC 3626 specification.