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