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