1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
3 * Copyright (c) 2004 Francisco J. Ros
4 * Copyright (c) 2007 INESC Porto
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;
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.
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
19 * Authors: Francisco J. Ros <fjrm@dif.um.es>
20 * Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
26 /// \brief Implementation of OLSR agent and related classes.
28 /// This is the main file of this software because %OLSR's behaviour is
32 #define NS_LOG_APPEND_CONTEXT \
33 if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
36 #include "olsr-agent-impl.h"
37 #include "ns3/socket-factory.h"
38 #include "ns3/udp-socket-factory.h"
39 #include "ns3/simulator.h"
41 #include "ns3/random-variable.h"
42 #include "ns3/inet-socket-address.h"
43 #include "ns3/boolean.h"
44 #include "ns3/uinteger.h"
46 #include "ns3/trace-source-accessor.h"
48 /********** Useful macros **********/
51 /// \brief Gets the delay between a given time and the current time.
53 /// If given time is previous to the current one, then this macro returns
54 /// a number close to 0. This is used for scheduling events at a certain moment.
56 #define DELAY(time) (((time) < (Simulator::Now ())) ? Seconds (0.000001) : \
57 (time - Simulator::Now () + Seconds (0.000001)))
62 /// \brief Period at which a node must cite every link and every neighbor.
64 /// We only use this value in order to define OLSR_NEIGHB_HOLD_TIME.
66 #define OLSR_REFRESH_INTERVAL Seconds (2)
69 /********** Holding times **********/
71 /// Neighbor holding time.
72 #define OLSR_NEIGHB_HOLD_TIME (Scalar (3) * OLSR_REFRESH_INTERVAL)
74 #define OLSR_TOP_HOLD_TIME (Scalar (3) * m_tcInterval)
76 #define OLSR_DUP_HOLD_TIME Seconds (30)
78 #define OLSR_MID_HOLD_TIME (Scalar (3) * m_midInterval)
81 /********** Link types **********/
83 /// Unspecified link type.
84 #define OLSR_UNSPEC_LINK 0
85 /// Asymmetric link type.
86 #define OLSR_ASYM_LINK 1
87 /// Symmetric link type.
88 #define OLSR_SYM_LINK 2
90 #define OLSR_LOST_LINK 3
92 /********** Neighbor types **********/
94 /// Not neighbor type.
95 #define OLSR_NOT_NEIGH 0
96 /// Symmetric neighbor type.
97 #define OLSR_SYM_NEIGH 1
98 /// Asymmetric neighbor type.
99 #define OLSR_MPR_NEIGH 2
102 /********** Willingness **********/
104 /// Willingness for forwarding packets from other nodes: never.
105 #define OLSR_WILL_NEVER 0
106 /// Willingness for forwarding packets from other nodes: low.
107 #define OLSR_WILL_LOW 1
108 /// Willingness for forwarding packets from other nodes: medium.
109 #define OLSR_WILL_DEFAULT 3
110 /// Willingness for forwarding packets from other nodes: high.
111 #define OLSR_WILL_HIGH 6
112 /// Willingness for forwarding packets from other nodes: always.
113 #define OLSR_WILL_ALWAYS 7
116 /********** Miscellaneous constants **********/
118 /// Maximum allowed jitter.
119 #define OLSR_MAXJITTER (m_helloInterval.GetSeconds () / 4)
120 /// Maximum allowed sequence number.
121 #define OLSR_MAX_SEQ_NUM 65535
122 /// Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission.
123 #define JITTER (Seconds (UniformVariable::GetSingleValue (0, OLSR_MAXJITTER)))
126 #define OLSR_PORT_NUMBER 698
127 /// Maximum number of messages per packet.
128 #define OLSR_MAX_MSGS 64
130 /// Maximum number of hellos per message (4 possible link types * 3 possible nb types).
131 #define OLSR_MAX_HELLOS 12
133 /// Maximum number of addresses advertised on a message.
134 #define OLSR_MAX_ADDRS 64
140 NS_LOG_COMPONENT_DEFINE ("OlsrAgent");
143 /********** OLSR class **********/
145 NS_OBJECT_ENSURE_REGISTERED (AgentImpl);
148 AgentImpl::GetTypeId (void)
150 static TypeId tid = TypeId ("ns3::olsr::AgentImpl")
152 .AddConstructor<AgentImpl> ()
153 .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
154 TimeValue (Seconds (2)),
155 MakeTimeAccessor (&AgentImpl::m_helloInterval),
157 .AddAttribute ("TcInterval", "TC messages emission interval.",
158 TimeValue (Seconds (5)),
159 MakeTimeAccessor (&AgentImpl::m_tcInterval),
161 .AddAttribute ("MidInterval", "MID messages emission interval. Normally it is equal to TcInterval.",
162 TimeValue (Seconds (5)),
163 MakeTimeAccessor (&AgentImpl::m_midInterval),
165 .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.",
166 EnumValue (OLSR_WILL_DEFAULT),
167 MakeEnumAccessor (&AgentImpl::m_willingness),
168 MakeEnumChecker (OLSR_WILL_NEVER, "never",
169 OLSR_WILL_LOW, "low",
170 OLSR_WILL_DEFAULT, "default",
171 OLSR_WILL_HIGH, "high",
172 OLSR_WILL_ALWAYS, "always"))
173 .AddTraceSource ("Rx", "Receive OLSR packet.",
174 MakeTraceSourceAccessor (&AgentImpl::m_rxPacketTrace))
175 .AddTraceSource ("Tx", "Send OLSR packet.",
176 MakeTraceSourceAccessor (&AgentImpl::m_txPacketTrace))
177 .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.",
178 MakeTraceSourceAccessor (&AgentImpl::m_routingTableChanged))
184 AgentImpl::AgentImpl ()
186 m_helloTimer (Timer::CANCEL_ON_DESTROY),
187 m_tcTimer (Timer::CANCEL_ON_DESTROY),
188 m_midTimer (Timer::CANCEL_ON_DESTROY)
191 AgentImpl::~AgentImpl ()
195 AgentImpl::SetNode (Ptr<Node> node)
197 NS_LOG_DEBUG ("Created olsr::AgentImpl");
198 m_helloTimer.SetFunction (&AgentImpl::HelloTimerExpire, this);
199 m_tcTimer.SetFunction (&AgentImpl::TcTimerExpire, this);
200 m_midTimer.SetFunction (&AgentImpl::MidTimerExpire, this);
201 m_queuedMessagesTimer.SetFunction (&AgentImpl::SendQueuedMessages, this);
203 m_packetSequenceNumber = OLSR_MAX_SEQ_NUM;
204 m_messageSequenceNumber = OLSR_MAX_SEQ_NUM;
205 m_ansn = OLSR_MAX_SEQ_NUM;
207 m_linkTupleTimerFirstTime = true;
209 m_ipv4 = node->GetObject<Ipv4> ();
213 void AgentImpl::DoDispose ()
217 for (std::map< Ptr<Socket>, Ipv4Address >::iterator iter = m_socketAddresses.begin ();
218 iter != m_socketAddresses.end (); iter++)
220 iter->first->Dispose ();
222 m_socketAddresses.clear ();
226 m_routingTable->Dispose ();
230 Object::DoDispose ();
233 void AgentImpl::Start ()
235 if (m_mainAddress == Ipv4Address ())
237 Ipv4Address loopback ("127.0.0.1");
238 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
240 Ipv4Address addr = m_ipv4->GetAddress (i);
241 if (addr != loopback)
243 m_mainAddress = addr;
248 NS_ASSERT (m_mainAddress != Ipv4Address ());
251 NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
253 m_routingTable = CreateObject<RoutingTable> ();
254 m_routingTable->SetIpv4 (m_ipv4);
255 m_routingTable->SetMainAddress (m_mainAddress);
256 // Add OLSR as routing protocol, with slightly higher priority than
258 m_ipv4->AddRoutingProtocol (m_routingTable, 10);
260 Ipv4Address loopback ("127.0.0.1");
261 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
263 Ipv4Address addr = m_ipv4->GetAddress (i);
264 if (addr == loopback)
267 if (addr != m_mainAddress)
269 // Create never expiring interface association tuple entries for our
270 // own network interfaces, so that GetMainAddress () works to
271 // translate the node's own interface addresses into the main address.
272 IfaceAssocTuple tuple;
273 tuple.ifaceAddr = addr;
274 tuple.mainAddr = m_mainAddress;
275 AddIfaceAssocTuple (tuple);
276 NS_ASSERT (GetMainAddress (addr) == m_mainAddress);
279 // Create a socket to listen only on this interface
280 Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
281 UdpSocketFactory::GetTypeId());
282 socket->SetRecvCallback (MakeCallback (&AgentImpl::RecvOlsr, this));
283 if (socket->Bind (InetSocketAddress (addr, OLSR_PORT_NUMBER)))
285 NS_FATAL_ERROR ("Failed to bind() OLSR receive socket");
287 socket->Connect (InetSocketAddress (Ipv4Address (0xffffffff), OLSR_PORT_NUMBER));
288 m_socketAddresses[socket] = addr;
295 NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
298 void AgentImpl::SetMainInterface (uint32_t interface)
300 m_mainAddress = m_ipv4->GetAddress (interface);
305 // \brief Processes an incoming %OLSR packet following RFC 3626 specification.
307 AgentImpl::RecvOlsr (Ptr<Socket> socket)
309 Ptr<Packet> receivedPacket;
310 Address sourceAddress;
311 receivedPacket = socket->RecvFrom (sourceAddress);
313 InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
314 Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
315 Ipv4Address receiverIfaceAddr = m_socketAddresses[socket];
316 NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
317 NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
318 << senderIfaceAddr << " to " << receiverIfaceAddr);
320 // All routing messages are sent from and to port RT_PORT,
322 NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER);
324 Ptr<Packet> packet = receivedPacket;
326 olsr::PacketHeader olsrPacketHeader;
327 packet->RemoveHeader (olsrPacketHeader);
328 NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ());
329 uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize ();
331 MessageList messages;
335 MessageHeader messageHeader;
336 if (packet->RemoveHeader (messageHeader) == 0)
339 sizeLeft -= messageHeader.GetSerializedSize ();
341 NS_LOG_DEBUG ("Olsr Msg received with type "
342 << std::dec << int (messageHeader.GetMessageType ())
343 << " TTL=" << int (messageHeader.GetTimeToLive ())
344 << " origAddr=" << messageHeader.GetOriginatorAddress ());
345 messages.push_back (messageHeader);
348 m_rxPacketTrace (olsrPacketHeader, messages);
350 for (MessageList::const_iterator messageIter = messages.begin ();
351 messageIter != messages.end (); messageIter++)
353 const MessageHeader &messageHeader = *messageIter;
354 // If ttl is less than or equal to zero, or
355 // the receiver is the same as the originator,
356 // the message must be silently dropped
357 if (messageHeader.GetTimeToLive () == 0
358 || messageHeader.GetOriginatorAddress () == m_mainAddress)
360 packet->RemoveAtStart (messageHeader.GetSerializedSize ()
361 - messageHeader.GetSerializedSize ());
365 // If the message has been processed it must not be processed again
366 bool do_forwarding = true;
367 DuplicateTuple *duplicated = m_state.FindDuplicateTuple
368 (messageHeader.GetOriginatorAddress (),
369 messageHeader.GetMessageSequenceNumber ());
371 // Get main address of the peer, which may be different from the packet source address
372 // const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ());
373 // Ipv4Address peerMainAddress;
374 // if (ifaceAssoc != NULL)
376 // peerMainAddress = ifaceAssoc->mainAddr;
380 // peerMainAddress = inetSourceAddr.GetIpv4 () ;
383 if (duplicated == NULL)
385 switch (messageHeader.GetMessageType ())
387 case olsr::MessageHeader::HELLO_MESSAGE:
388 NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
389 << "s OLSR node " << m_mainAddress
390 << " received HELLO message of size " << messageHeader.GetSerializedSize ());
391 ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr);
394 case olsr::MessageHeader::TC_MESSAGE:
395 NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
396 << "s OLSR node " << m_mainAddress
397 << " received TC message of size " << messageHeader.GetSerializedSize ());
398 ProcessTc (messageHeader, senderIfaceAddr);
401 case olsr::MessageHeader::MID_MESSAGE:
402 NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
403 << "s OLSR node " << m_mainAddress
404 << " received MID message of size " << messageHeader.GetSerializedSize ());
405 ProcessMid (messageHeader, senderIfaceAddr);
409 NS_LOG_DEBUG ("OLSR message type " <<
410 int (messageHeader.GetMessageType ()) <<
416 NS_LOG_DEBUG ("OLSR message is duplicated, not reading it.");
418 // If the message has been considered for forwarding, it should
419 // not be retransmitted again
420 for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin ();
421 it != duplicated->ifaceList.end(); it++)
423 if (*it == receiverIfaceAddr)
425 do_forwarding = false;
433 // HELLO messages are never forwarded.
434 // TC and MID messages are forwarded using the default algorithm.
435 // Remaining messages are also forwarded using the default algorithm.
436 if (messageHeader.GetMessageType () != olsr::MessageHeader::HELLO_MESSAGE)
438 ForwardDefault (messageHeader, duplicated,
439 receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
445 // After processing all OLSR messages, we must recompute the routing table
446 RoutingTableComputation ();
450 /// \brief This auxiliary function (defined in RFC 3626) is used for calculating the MPR Set.
452 /// \param tuple the neighbor tuple which has the main address of the node we are going to calculate its degree to.
453 /// \return the degree of the node.
456 AgentImpl::Degree (NeighborTuple const &tuple)
459 for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin ();
460 it != m_state.GetTwoHopNeighbors ().end (); it++)
462 TwoHopNeighborTuple const &nb2hop_tuple = *it;
463 if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
465 const NeighborTuple *nb_tuple =
466 m_state.FindNeighborTuple (nb2hop_tuple.neighborMainAddr);
467 if (nb_tuple == NULL)
475 /// \brief Computates MPR set of a node following RFC 3626 hints.
478 AgentImpl::MprComputation()
480 NS_LOG_FUNCTION (this);
482 // MPR computation should be done for each interface. See section 8.3.1
483 // (RFC 3626) for details.
487 // N is the subset of neighbors of the node, which are
488 // neighbor "of the interface I"
490 for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin();
491 neighbor != m_state.GetNeighbors ().end (); neighbor++)
493 if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
495 N.push_back (*neighbor);
499 // N2 is the set of 2-hop neighbors reachable from "the interface
501 // (i) the nodes only reachable by members of N with willingness WILL_NEVER
502 // (ii) the node performing the computation
503 // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
504 // link to this node on some interface.
505 TwoHopNeighborSet N2;
506 for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin ();
507 twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++)
510 // (ii) the node performing the computation
511 if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
517 // (i) the nodes only reachable by members of N with willingness WILL_NEVER
519 for (NeighborSet::const_iterator neigh = N.begin ();
520 neigh != N.end (); neigh++)
522 if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
524 if (neigh->willingness == OLSR_WILL_NEVER)
542 // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
543 // link to this node on some interface.
544 for (NeighborSet::const_iterator neigh = N.begin ();
545 neigh != N.end (); neigh++)
547 if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
556 N2.push_back (*twoHopNeigh);
560 NS_LOG_DEBUG ("Size of N2: " << N2.size ());
562 // 1. Start with an MPR set made of all members of N with
563 // N_willingness equal to WILL_ALWAYS
564 for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
566 if (neighbor->willingness == OLSR_WILL_ALWAYS)
568 mprSet.insert (neighbor->neighborMainAddr);
569 // (not in RFC but I think is needed: remove the 2-hop
570 // neighbors reachable by the MPR from N2)
571 for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
572 twoHopNeigh != N2.end (); )
574 if (twoHopNeigh->neighborMainAddr == neighbor->neighborMainAddr)
576 twoHopNeigh = N2.erase (twoHopNeigh);
586 // 2. Calculate D(y), where y is a member of N, for all nodes in N.
587 // (we do this later)
589 // 3. Add to the MPR set those nodes in N, which are the *only*
590 // nodes to provide reachability to a node in N2.
591 std::set<Ipv4Address> coveredTwoHopNeighbors;
592 for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
594 NeighborSet::const_iterator onlyNeighbor = N.end ();
596 for (NeighborSet::const_iterator neighbor = N.begin ();
597 neighbor != N.end (); neighbor++)
599 if (neighbor->neighborMainAddr == twoHopNeigh->neighborMainAddr)
601 if (onlyNeighbor == N.end ())
603 onlyNeighbor = neighbor;
607 onlyNeighbor = N.end ();
612 if (onlyNeighbor != N.end ())
614 mprSet.insert (onlyNeighbor->neighborMainAddr);
615 coveredTwoHopNeighbors.insert (twoHopNeigh->twoHopNeighborAddr);
618 // Remove the nodes from N2 which are now covered by a node in the MPR set.
619 for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
620 twoHopNeigh != N2.end (); )
622 if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
624 twoHopNeigh = N2.erase (twoHopNeigh);
632 // 4. While there exist nodes in N2 which are not covered by at
633 // least one node in the MPR set:
634 while (N2.begin () != N2.end ())
636 // 4.1. For each node in N, calculate the reachability, i.e., the
637 // number of nodes in N2 which are not yet covered by at
638 // least one node in the MPR set, and which are reachable
639 // through this 1-hop neighbor
640 std::map<int, std::vector<const NeighborTuple *> > reachability;
642 for (NeighborSet::iterator it = N.begin(); it != N.end(); it++)
644 NeighborTuple const &nb_tuple = *it;
646 for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++)
648 TwoHopNeighborTuple const &nb2hop_tuple = *it2;
649 if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
653 reachability[r].push_back (&nb_tuple);
656 // 4.2. Select as a MPR the node with highest N_willingness among
657 // the nodes in N with non-zero reachability. In case of
658 // multiple choice select the node which provides
659 // reachability to the maximum number of nodes in N2. In
660 // case of multiple nodes providing the same amount of
661 // reachability, select the node as MPR whose D(y) is
662 // greater. Remove the nodes from N2 which are now covered
663 // by a node in the MPR set.
664 NeighborTuple const *max = NULL;
666 for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++)
673 for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin ();
674 it2 != reachability[r].end (); it2++)
676 const NeighborTuple *nb_tuple = *it2;
677 if (max == NULL || nb_tuple->willingness > max->willingness)
682 else if (nb_tuple->willingness == max->willingness)
691 if (Degree (*nb_tuple) > Degree (*max))
703 mprSet.insert (max->neighborMainAddr);
704 for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
705 twoHopNeigh != N2.end (); )
707 if (twoHopNeigh->neighborMainAddr == max->neighborMainAddr)
709 twoHopNeigh = N2.erase (twoHopNeigh);
719 #ifdef NS3_LOG_ENABLE
721 std::ostringstream os;
723 for (MprSet::const_iterator iter = mprSet.begin ();
724 iter != mprSet.end (); iter++)
726 MprSet::const_iterator next = iter;
729 if (next != mprSet.end ())
733 NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
737 m_state.SetMprSet (mprSet);
741 /// \brief Gets the main address associated with a given interface address.
743 /// \param iface_addr the interface address.
744 /// \return the corresponding main address.
747 AgentImpl::GetMainAddress (Ipv4Address iface_addr) const
749 const IfaceAssocTuple *tuple =
750 m_state.FindIfaceAssocTuple (iface_addr);
753 return tuple->mainAddr;
759 /// \brief Creates the routing table of the node following RFC 3626 hints.
762 AgentImpl::RoutingTableComputation ()
764 NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " s: Node " << m_mainAddress
765 << ": RoutingTableComputation begin...");
767 // 1. All the entries from the routing table are removed.
768 m_routingTable->Clear ();
770 // 2. The new routing entries are added starting with the
771 // symmetric neighbors (h=1) as the destination nodes.
772 const NeighborSet &neighborSet = m_state.GetNeighbors ();
773 for (NeighborSet::const_iterator it = neighborSet.begin ();
774 it != neighborSet.end(); it++)
776 NeighborTuple const &nb_tuple = *it;
777 NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple);
778 if (nb_tuple.status == NeighborTuple::STATUS_SYM)
780 bool nb_main_addr = false;
781 const LinkTuple *lt = NULL;
782 const LinkSet &linkSet = m_state.GetLinks ();
783 for (LinkSet::const_iterator it2 = linkSet.begin();
784 it2 != linkSet.end(); it2++)
786 LinkTuple const &link_tuple = *it2;
787 NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple
788 << (link_tuple.time >= Simulator::Now ()? "" : " (expired)"));
789 if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr)
790 && link_tuple.time >= Simulator::Now ())
792 NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr
793 << " => adding routing table entry to neighbor");
795 m_routingTable->AddEntry (link_tuple.neighborIfaceAddr,
796 link_tuple.neighborIfaceAddr,
797 link_tuple.localIfaceAddr,
799 if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
806 NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr)
807 << "; neighborMainAddr = " << nb_tuple.neighborMainAddr
808 << "; expired=" << int (link_tuple.time < Simulator::Now ())
813 // If, in the above, no R_dest_addr is equal to the main
814 // address of the neighbor, then another new routing entry
815 // with MUST be added, with:
816 // R_dest_addr = main address of the neighbor;
817 // R_next_addr = L_neighbor_iface_addr of one of the
818 // associated link tuple with L_time >= current time;
820 // R_iface_addr = L_local_iface_addr of the
821 // associated link tuple.
822 if (!nb_main_addr && lt != NULL)
824 NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor "
825 "=> adding additional routing entry");
826 m_routingTable->AddEntry(nb_tuple.neighborMainAddr,
827 lt->neighborIfaceAddr,
834 // 3. for each node in N2, i.e., a 2-hop neighbor which is not a
835 // neighbor node or the node itself, and such that there exist at
836 // least one entry in the 2-hop neighbor set where
837 // N_neighbor_main_addr correspond to a neighbor node with
838 // willingness different of WILL_NEVER,
839 const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
840 for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin ();
841 it != twoHopNeighbors.end (); it++)
843 TwoHopNeighborTuple const &nb2hop_tuple = *it;
845 NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
847 // a 2-hop neighbor which is not a neighbor node or the node itself
848 if (m_state.FindNeighborTuple (nb2hop_tuple.twoHopNeighborAddr))
850 NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped.");
854 if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
856 NS_LOG_LOGIC ("Two-hop neighbor is self; skipped.");
860 // ...and such that there exist at least one entry in the 2-hop
861 // neighbor set where N_neighbor_main_addr correspond to a
862 // neighbor node with willingness different of WILL_NEVER...
863 bool nb2hopOk = false;
864 for (NeighborSet::const_iterator neighbor = neighborSet.begin ();
865 neighbor != neighborSet.end(); neighbor++)
867 if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr
868 && neighbor->willingness != OLSR_WILL_NEVER)
876 NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor "
877 << nb2hop_tuple.twoHopNeighborAddr
878 << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr
879 << ", which was not found in the Neighbor Set.");
883 // one selects one 2-hop tuple and creates one entry in the routing table with:
884 // R_dest_addr = the main address of the 2-hop neighbor;
885 // R_next_addr = the R_next_addr of the entry in the
886 // routing table with:
887 // R_dest_addr == N_neighbor_main_addr
888 // of the 2-hop tuple;
890 // R_iface_addr = the R_iface_addr of the entry in the
891 // routing table with:
892 // R_dest_addr == N_neighbor_main_addr
893 // of the 2-hop tuple;
894 RoutingTableEntry entry;
895 bool foundEntry = m_routingTable->Lookup (nb2hop_tuple.neighborMainAddr, entry);
898 NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor.");
899 m_routingTable->AddEntry (nb2hop_tuple.twoHopNeighborAddr,
906 NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor ("
907 << nb2hop_tuple.twoHopNeighborAddr
908 << " not found in the routing table)");
912 for (uint32_t h = 2; ; h++)
916 // 3.1. For each topology entry in the topology table, if its
917 // T_dest_addr does not correspond to R_dest_addr of any
918 // route entry in the routing table AND its T_last_addr
919 // corresponds to R_dest_addr of a route entry whose R_dist
920 // is equal to h, then a new route entry MUST be recorded in
921 // the routing table (if it does not already exist)
922 const TopologySet &topology = m_state.GetTopologySet ();
923 for (TopologySet::const_iterator it = topology.begin ();
924 it != topology.end (); it++)
926 const TopologyTuple &topology_tuple = *it;
927 NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple);
929 RoutingTableEntry destAddrEntry, lastAddrEntry;
930 bool have_destAddrEntry = m_routingTable->Lookup (topology_tuple.destAddr, destAddrEntry);
931 bool have_lastAddrEntry = m_routingTable->Lookup (topology_tuple.lastAddr, lastAddrEntry);
932 if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
934 NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple.");
935 // then a new route entry MUST be recorded in
936 // the routing table (if it does not already exist) where:
937 // R_dest_addr = T_dest_addr;
938 // R_next_addr = R_next_addr of the recorded
939 // route entry where:
940 // R_dest_addr == T_last_addr
942 // R_iface_addr = R_iface_addr of the recorded
943 // route entry where:
944 // R_dest_addr == T_last_addr.
945 m_routingTable->AddEntry (topology_tuple.destAddr,
946 lastAddrEntry.nextAddr,
947 lastAddrEntry.interface,
953 NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: "
954 "have_destAddrEntry=" << have_destAddrEntry
955 << " have_lastAddrEntry=" << have_lastAddrEntry
956 << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance
957 << " (h=" << h << ")");
965 // 4. For each entry in the multiple interface association base
966 // where there exists a routing entry such that:
967 // R_dest_addr == I_main_addr (of the multiple interface association entry)
968 // AND there is no routing entry such that:
969 // R_dest_addr == I_iface_addr
970 const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
971 for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
972 it != ifaceAssocSet.end (); it++)
974 IfaceAssocTuple const &tuple = *it;
975 RoutingTableEntry entry1, entry2;
976 bool have_entry1 = m_routingTable->Lookup (tuple.mainAddr, entry1);
977 bool have_entry2 = m_routingTable->Lookup (tuple.ifaceAddr, entry2);
978 if (have_entry1 && !have_entry2)
980 // then a route entry is created in the routing table with:
981 // R_dest_addr = I_iface_addr (of the multiple interface
982 // association entry)
983 // R_next_addr = R_next_addr (of the recorded route entry)
984 // R_dist = R_dist (of the recorded route entry)
985 // R_iface_addr = R_iface_addr (of the recorded route entry).
986 m_routingTable->AddEntry (tuple.ifaceAddr,
993 NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
994 m_routingTableChanged (m_routingTable->GetSize ());
999 /// \brief Processes a HELLO message following RFC 3626 specification.
1001 /// Link sensing and population of the Neighbor Set, 2-hop Neighbor Set and MPR
1002 /// Selector Set are performed.
1004 /// \param msg the %OLSR message which contains the HELLO message.
1005 /// \param receiver_iface the address of the interface where the message was received from.
1006 /// \param sender_iface the address of the interface where the message was sent from.
1009 AgentImpl::ProcessHello (const olsr::MessageHeader &msg,
1010 const Ipv4Address &receiverIface,
1011 const Ipv4Address &senderIface)
1013 const olsr::MessageHeader::Hello &hello = msg.GetHello ();
1015 LinkSensing (msg, hello, receiverIface, senderIface);
1017 #ifdef NS3_LOG_ENABLE
1019 const LinkSet &links = m_state.GetLinks ();
1020 NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1021 << "s ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
1022 for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++)
1024 NS_LOG_DEBUG(*link);
1026 NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress);
1028 const NeighborSet &neighbors = m_state.GetNeighbors ();
1029 NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1030 << "s ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
1031 for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1033 NS_LOG_DEBUG(*neighbor);
1035 NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
1039 PopulateNeighborSet (msg, hello);
1040 PopulateTwoHopNeighborSet (msg, hello);
1042 #ifdef NS3_LOG_ENABLE
1044 const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1045 NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1046 << "s ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1047 for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin ();
1048 tuple != twoHopNeighbors.end (); tuple++)
1050 NS_LOG_DEBUG(*tuple);
1052 NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1057 PopulateMprSelectorSet (msg, hello);
1061 /// \brief Processes a TC message following RFC 3626 specification.
1063 /// The Topology Set is updated (if needed) with the information of
1064 /// the received TC message.
1066 /// \param msg the %OLSR message which contains the TC message.
1067 /// \param sender_iface the address of the interface where the message was sent from.
1070 AgentImpl::ProcessTc (const olsr::MessageHeader &msg,
1071 const Ipv4Address &senderIface)
1073 const olsr::MessageHeader::Tc &tc = msg.GetTc ();
1074 Time now = Simulator::Now ();
1076 // 1. If the sender interface of this message is not in the symmetric
1077 // 1-hop neighborhood of this node, the message MUST be discarded.
1078 const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1079 if (link_tuple == NULL)
1082 // 2. If there exist some tuple in the topology set where:
1083 // T_last_addr == originator address AND
1085 // then further processing of this TC message MUST NOT be
1087 const TopologyTuple *topologyTuple =
1088 m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.ansn);
1089 if (topologyTuple != NULL)
1092 // 3. All tuples in the topology set where:
1093 // T_last_addr == originator address AND
1095 // MUST be removed from the topology set.
1096 m_state.EraseOlderTopologyTuples (msg.GetOriginatorAddress (), tc.ansn);
1098 // 4. For each of the advertised neighbor main address received in
1100 for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin ();
1101 i != tc.neighborAddresses.end (); i++)
1103 const Ipv4Address &addr = *i;
1104 // 4.1. If there exist some tuple in the topology set where:
1105 // T_dest_addr == advertised neighbor main address, AND
1106 // T_last_addr == originator address,
1107 // then the holding time of that tuple MUST be set to:
1108 // T_time = current time + validity time.
1109 TopologyTuple *topologyTuple =
1110 m_state.FindTopologyTuple (addr, msg.GetOriginatorAddress ());
1112 if (topologyTuple != NULL)
1114 topologyTuple->expirationTime = now + msg.GetVTime ();
1118 // 4.2. Otherwise, a new tuple MUST be recorded in the topology
1120 // T_dest_addr = advertised neighbor main address,
1121 // T_last_addr = originator address,
1123 // T_time = current time + validity time.
1124 TopologyTuple topologyTuple;;
1125 topologyTuple.destAddr = addr;
1126 topologyTuple.lastAddr = msg.GetOriginatorAddress ();
1127 topologyTuple.sequenceNumber = tc.ansn;
1128 topologyTuple.expirationTime = now + msg.GetVTime ();
1129 AddTopologyTuple (topologyTuple);
1131 // Schedules topology tuple deletion
1132 m_events.Track (Simulator::Schedule (DELAY (topologyTuple.expirationTime),
1133 &AgentImpl::TopologyTupleTimerExpire,
1135 topologyTuple.destAddr,
1136 topologyTuple.lastAddr));
1140 #ifdef NS3_LOG_ENABLE
1142 const TopologySet &topology = m_state.GetTopologySet ();
1143 NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1144 << "s ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
1145 for (TopologySet::const_iterator tuple = topology.begin ();
1146 tuple != topology.end (); tuple++)
1148 NS_LOG_DEBUG (*tuple);
1150 NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
1156 /// \brief Processes a MID message following RFC 3626 specification.
1158 /// The Interface Association Set is updated (if needed) with the information
1159 /// of the received MID message.
1161 /// \param msg the %OLSR message which contains the MID message.
1162 /// \param sender_iface the address of the interface where the message was sent from.
1165 AgentImpl::ProcessMid (const olsr::MessageHeader &msg,
1166 const Ipv4Address &senderIface)
1168 const olsr::MessageHeader::Mid &mid = msg.GetMid ();
1169 Time now = Simulator::Now ();
1171 NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
1172 // 1. If the sender interface of this message is not in the symmetric
1173 // 1-hop neighborhood of this node, the message MUST be discarded.
1174 const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
1175 if (linkTuple == NULL)
1177 NS_LOG_LOGIC ("Node " << m_mainAddress <<
1178 ": the sender interface of this message is not in the "
1179 "symmetric 1-hop neighborhood of this node,"
1180 " the message MUST be discarded.");
1184 // 2. For each interface address listed in the MID message
1185 for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
1186 i != mid.interfaceAddresses.end (); i++)
1188 bool updated = false;
1189 IfaceAssocSet &ifaceAssoc = m_state.GetIfaceAssocSetMutable ();
1190 for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin();
1191 tuple != ifaceAssoc.end(); tuple++)
1193 if (tuple->ifaceAddr == *i
1194 && tuple->mainAddr == msg.GetOriginatorAddress ())
1196 NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple);
1197 tuple->time = now + msg.GetVTime ();
1203 IfaceAssocTuple tuple;
1204 tuple.ifaceAddr = *i;
1205 tuple.mainAddr = msg.GetOriginatorAddress ();
1206 tuple.time = now + msg.GetVTime ();
1207 AddIfaceAssocTuple (tuple);
1208 NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple);
1209 // Schedules iface association tuple deletion
1210 Simulator::Schedule (DELAY (tuple.time),
1211 &AgentImpl::IfaceAssocTupleTimerExpire, this, tuple.ifaceAddr);
1215 // 3. (not part of the RFC) iterate over all NeighborTuple's and
1216 // TwoHopNeighborTuples, update the neighbor addresses taking into account
1217 // the new MID information.
1218 NeighborSet &neighbors = m_state.GetNeighbors ();
1219 for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end(); neighbor++)
1221 neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr);
1224 TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1225 for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin ();
1226 twoHopNeighbor != twoHopNeighbors.end(); twoHopNeighbor++)
1228 twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr);
1229 twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr);
1231 NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
1236 /// \brief OLSR's default forwarding algorithm.
1238 /// See RFC 3626 for details.
1240 /// \param p the %OLSR packet which has been received.
1241 /// \param msg the %OLSR message which must be forwarded.
1242 /// \param dup_tuple NULL if the message has never been considered for forwarding,
1243 /// or a duplicate tuple in other case.
1244 /// \param local_iface the address of the interface where the message was received from.
1247 AgentImpl::ForwardDefault (olsr::MessageHeader olsrMessage,
1248 DuplicateTuple *duplicated,
1249 const Ipv4Address &localIface,
1250 const Ipv4Address &senderAddress)
1252 Time now = Simulator::Now ();
1254 // If the sender interface address is not in the symmetric
1255 // 1-hop neighborhood the message must not be forwarded
1256 const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
1257 if (linkTuple == NULL)
1260 // If the message has already been considered for forwarding,
1261 // it must not be retransmitted again
1262 if (duplicated != NULL && duplicated->retransmitted)
1264 NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received"
1265 " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
1269 // If the sender interface address is an interface address
1270 // of a MPR selector of this node and ttl is greater than 1,
1271 // the message must be retransmitted
1272 bool retransmitted = false;
1273 if (olsrMessage.GetTimeToLive () > 1)
1275 const MprSelectorTuple *mprselTuple =
1276 m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
1277 if (mprselTuple != NULL)
1279 olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1);
1280 olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1);
1281 // We have to introduce a random delay to avoid
1282 // synchronization with neighbors.
1283 QueueMessage (olsrMessage, JITTER);
1284 retransmitted = true;
1288 // Update duplicate tuple...
1289 if (duplicated != NULL)
1291 duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
1292 duplicated->retransmitted = retransmitted;
1293 duplicated->ifaceList.push_back (localIface);
1295 // ...or create a new one
1298 DuplicateTuple newDup;
1299 newDup.address = olsrMessage.GetOriginatorAddress ();
1300 newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber ();
1301 newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
1302 newDup.retransmitted = retransmitted;
1303 newDup.ifaceList.push_back (localIface);
1304 AddDuplicateTuple (newDup);
1305 // Schedule dup tuple deletion
1306 Simulator::Schedule (OLSR_DUP_HOLD_TIME,
1307 &AgentImpl::DupTupleTimerExpire, this,
1308 newDup.address, newDup.sequenceNumber);
1313 /// \brief Enques an %OLSR message which will be sent with a delay of (0, delay].
1315 /// This buffering system is used in order to piggyback several %OLSR messages in
1316 /// a same %OLSR packet.
1318 /// \param msg the %OLSR message which must be sent.
1319 /// \param delay maximum delay the %OLSR message is going to be buffered.
1322 AgentImpl::QueueMessage (const olsr::MessageHeader &message, Time delay)
1324 m_queuedMessages.push_back (message);
1325 if (not m_queuedMessagesTimer.IsRunning ())
1327 m_queuedMessagesTimer.SetDelay (delay);
1328 m_queuedMessagesTimer.Schedule ();
1333 AgentImpl::SendPacket (Ptr<Packet> packet,
1334 const MessageList &containedMessages)
1336 NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet");
1339 olsr::PacketHeader header;
1340 header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ());
1341 header.SetPacketSequenceNumber (GetPacketSequenceNumber ());
1342 packet->AddHeader (header);
1345 m_txPacketTrace (header, containedMessages);
1348 m_socketAddresses.begin ()->first->Send (packet);
1352 /// \brief Creates as many %OLSR packets as needed in order to send all buffered
1355 /// Maximum number of messages which can be contained in an %OLSR packet is
1356 /// dictated by OLSR_MAX_MSGS constant.
1359 AgentImpl::SendQueuedMessages ()
1361 Ptr<Packet> packet = Create<Packet> ();
1362 int numMessages = 0;
1364 NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages");
1366 MessageList msglist;
1368 for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin ();
1369 message != m_queuedMessages.end ();
1372 Ptr<Packet> p = Create<Packet> ();
1373 p->AddHeader (*message);
1374 packet->AddAtEnd (p);
1375 msglist.push_back (*message);
1376 if (++numMessages == OLSR_MAX_MSGS)
1378 SendPacket (packet, msglist);
1380 // Reset variables for next packet
1382 packet = Create<Packet> ();
1386 if (packet->GetSize ())
1388 SendPacket (packet, msglist);
1391 m_queuedMessages.clear ();
1395 /// \brief Creates a new %OLSR HELLO message which is buffered for being sent later on.
1398 AgentImpl::SendHello ()
1400 NS_LOG_FUNCTION (this);
1402 olsr::MessageHeader msg;
1403 Time now = Simulator::Now ();
1405 msg.SetVTime (OLSR_NEIGHB_HOLD_TIME);
1406 msg.SetOriginatorAddress (m_mainAddress);
1407 msg.SetTimeToLive (1);
1408 msg.SetHopCount (0);
1409 msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
1410 olsr::MessageHeader::Hello &hello = msg.GetHello ();
1412 hello.SetHTime (Scalar (3) * m_helloInterval);
1413 hello.willingness = m_willingness;
1415 std::vector<olsr::MessageHeader::Hello::LinkMessage>
1416 &linkMessages = hello.linkMessages;
1418 const LinkSet &links = m_state.GetLinks ();
1419 for (LinkSet::const_iterator link_tuple = links.begin ();
1420 link_tuple != links.end (); link_tuple++)
1422 if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress
1423 && link_tuple->time >= now))
1428 uint8_t link_type, nb_type = 0xff;
1430 // Establishes link type
1431 if (link_tuple->symTime >= now)
1433 link_type = OLSR_SYM_LINK;
1435 else if (link_tuple->asymTime >= now)
1437 link_type = OLSR_ASYM_LINK;
1441 link_type = OLSR_LOST_LINK;
1443 // Establishes neighbor type.
1444 if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
1446 nb_type = OLSR_MPR_NEIGH;
1447 NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1448 << " to be MPR_NEIGH.");
1453 for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin ();
1454 nb_tuple != m_state.GetNeighbors ().end ();
1457 if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr))
1459 if (nb_tuple->status == NeighborTuple::STATUS_SYM)
1461 NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1462 << " to be SYM_NEIGH.");
1463 nb_type = OLSR_SYM_NEIGH;
1465 else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
1467 nb_type = OLSR_NOT_NEIGH;
1468 NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1469 << " to be NOT_NEIGH.");
1473 NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n");
1481 NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
1486 olsr::MessageHeader::Hello::LinkMessage linkMessage;
1487 linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f);
1488 linkMessage.neighborInterfaceAddresses.push_back
1489 (link_tuple->neighborIfaceAddr);
1491 std::vector<Ipv4Address> interfaces =
1492 m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr);
1494 linkMessage.neighborInterfaceAddresses.insert
1495 (linkMessage.neighborInterfaceAddresses.end (),
1496 interfaces.begin (), interfaces.end ());
1498 linkMessages.push_back (linkMessage);
1500 NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ())
1501 << " (with " << int (linkMessages.size ()) << " link messages)");
1502 QueueMessage (msg, JITTER);
1506 /// \brief Creates a new %OLSR TC message which is buffered for being sent later on.
1509 AgentImpl::SendTc ()
1511 NS_LOG_FUNCTION (this);
1513 olsr::MessageHeader msg;
1515 msg.SetVTime (OLSR_TOP_HOLD_TIME);
1516 msg.SetOriginatorAddress (m_mainAddress);
1517 msg.SetTimeToLive (255);
1518 msg.SetHopCount (0);
1519 msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
1521 olsr::MessageHeader::Tc &tc = msg.GetTc ();
1523 for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin();
1524 mprsel_tuple != m_state.GetMprSelectors ().end(); mprsel_tuple++)
1526 tc.neighborAddresses.push_back (mprsel_tuple->mainAddr);
1528 QueueMessage (msg, JITTER);
1532 /// \brief Creates a new %OLSR MID message which is buffered for being sent later on.
1535 AgentImpl::SendMid ()
1537 olsr::MessageHeader msg;
1538 olsr::MessageHeader::Mid &mid = msg.GetMid ();
1540 // A node which has only a single interface address participating in
1541 // the MANET (i.e., running OLSR), MUST NOT generate any MID
1544 // A node with several interfaces, where only one is participating
1545 // in the MANET and running OLSR (e.g., a node is connected to a
1546 // wired network as well as to a MANET) MUST NOT generate any MID
1549 // A node with several interfaces, where more than one is
1550 // participating in the MANET and running OLSR MUST generate MID
1551 // messages as specified.
1553 // [ Note: assuming here that all interfaces participate in the
1554 // MANET; later we may want to make this configurable. ]
1556 Ipv4Address loopback ("127.0.0.1");
1557 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
1559 Ipv4Address addr = m_ipv4->GetAddress (i);
1560 if (addr != m_mainAddress && addr != loopback)
1561 mid.interfaceAddresses.push_back (addr);
1563 if (mid.interfaceAddresses.size () == 0)
1566 msg.SetVTime (OLSR_MID_HOLD_TIME);
1567 msg.SetOriginatorAddress (m_mainAddress);
1568 msg.SetTimeToLive (255);
1569 msg.SetHopCount (0);
1570 msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
1572 QueueMessage (msg, JITTER);
1576 /// \brief Updates Link Set according to a new received HELLO message (following RFC 3626
1577 /// specification). Neighbor Set is also updated if needed.
1579 AgentImpl::LinkSensing (const olsr::MessageHeader &msg,
1580 const olsr::MessageHeader::Hello &hello,
1581 const Ipv4Address &receiverIface,
1582 const Ipv4Address &senderIface)
1584 Time now = Simulator::Now ();
1585 bool updated = false;
1586 bool created = false;
1587 NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
1588 << ": LinkSensing(receiverIface=" << receiverIface
1589 << ", senderIface=" << senderIface << ") BEGIN");
1591 NS_ASSERT (msg.GetVTime () > Seconds (0));
1592 LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
1593 if (link_tuple == NULL)
1595 LinkTuple newLinkTuple;
1596 // We have to create a new tuple
1597 newLinkTuple.neighborIfaceAddr = senderIface;
1598 newLinkTuple.localIfaceAddr = receiverIface;
1599 newLinkTuple.symTime = now - Seconds (1);
1600 newLinkTuple.time = now + msg.GetVTime ();
1601 link_tuple = &m_state.InsertLinkTuple (newLinkTuple);
1603 NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one");
1607 NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
1611 link_tuple->asymTime = now + msg.GetVTime ();
1612 for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
1613 hello.linkMessages.begin ();
1614 linkMessage != hello.linkMessages.end ();
1617 int lt = linkMessage->linkCode & 0x03; // Link Type
1618 int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type
1620 #ifdef NS3_LOG_ENABLE
1621 const char *linkTypeName;
1624 case OLSR_UNSPEC_LINK: linkTypeName = "UNSPEC_LINK"; break;
1625 case OLSR_ASYM_LINK: linkTypeName = "ASYM_LINK"; break;
1626 case OLSR_SYM_LINK: linkTypeName = "SYM_LINK"; break;
1627 case OLSR_LOST_LINK: linkTypeName = "LOST_LINK"; break;
1628 default: linkTypeName = "(invalid value!)";
1631 const char *neighborTypeName;
1634 case OLSR_NOT_NEIGH: neighborTypeName = "NOT_NEIGH"; break;
1635 case OLSR_SYM_NEIGH: neighborTypeName = "SYM_NEIGH"; break;
1636 case OLSR_MPR_NEIGH: neighborTypeName = "MPR_NEIGH"; break;
1637 default: neighborTypeName = "(invalid value!)";
1640 NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type "
1641 << lt << " (" << linkTypeName
1642 << ") and Neighbor Type " << nt
1643 << " (" << neighborTypeName << ")");
1646 // We must not process invalid advertised links
1647 if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) ||
1648 (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH
1649 && nt != OLSR_NOT_NEIGH))
1651 NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING");
1655 for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr =
1656 linkMessage->neighborInterfaceAddresses.begin ();
1657 neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end ();
1660 NS_LOG_DEBUG (" -> Neighbor: " << *neighIfaceAddr);
1661 if (*neighIfaceAddr == receiverIface)
1663 if (lt == OLSR_LOST_LINK)
1665 NS_LOG_LOGIC ("link is LOST => expiring it");
1666 link_tuple->symTime = now - Seconds (1);
1669 else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK)
1671 NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now"
1672 " (symTime being increased to " << now + msg.GetVTime ());
1673 link_tuple->symTime = now + msg.GetVTime ();
1674 link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
1679 NS_FATAL_ERROR ("bad link type");
1685 NS_LOG_DEBUG (" \\-> *neighIfaceAddr (" << *neighIfaceAddr
1686 << " != receiverIface (" << receiverIface << ") => IGNORING!");
1689 NS_LOG_DEBUG ("Link tuple updated: " << int (updated));
1691 link_tuple->time = std::max(link_tuple->time, link_tuple->asymTime);
1695 LinkTupleUpdated (*link_tuple, hello.willingness);
1698 // Schedules link tuple deletion
1699 if (created && link_tuple != NULL)
1701 LinkTupleAdded (*link_tuple, hello.willingness);
1702 m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
1703 &AgentImpl::LinkTupleTimerExpire, this,
1704 link_tuple->neighborIfaceAddr));
1706 NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
1707 << ": LinkSensing END");
1711 /// \brief Updates the Neighbor Set according to the information contained in a new received
1712 /// HELLO message (following RFC 3626).
1714 AgentImpl::PopulateNeighborSet (const olsr::MessageHeader &msg,
1715 const olsr::MessageHeader::Hello &hello)
1717 NeighborTuple *nb_tuple = m_state.FindNeighborTuple (msg.GetOriginatorAddress ());
1718 if (nb_tuple != NULL)
1720 nb_tuple->willingness = hello.willingness;
1726 /// \brief Updates the 2-hop Neighbor Set according to the information contained in a new
1727 /// received HELLO message (following RFC 3626).
1729 AgentImpl::PopulateTwoHopNeighborSet (const olsr::MessageHeader &msg,
1730 const olsr::MessageHeader::Hello &hello)
1732 Time now = Simulator::Now ();
1734 NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
1736 for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
1737 link_tuple != m_state.GetLinks ().end (); link_tuple++)
1739 NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple);
1740 if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ())
1742 NS_LOG_LOGIC ("Link tuple ignored: "
1743 "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
1744 NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): "
1745 << GetMainAddress (link_tuple->neighborIfaceAddr)
1746 << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ());
1750 if (link_tuple->symTime < now)
1752 NS_LOG_LOGIC ("Link tuple ignored: expired.");
1756 typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
1757 for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
1758 linkMessage != hello.linkMessages.end (); linkMessage++)
1760 int neighborType = (linkMessage->linkCode >> 2) & 0x3;
1761 #ifdef NS3_LOG_ENABLE
1762 const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" };
1763 const char *neighborTypeName = ((neighborType < 3)?
1764 neighborTypeNames[neighborType]
1765 : "(invalid value)");
1766 NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType="
1767 << neighborType << " (" << neighborTypeName << ")");
1770 for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter =
1771 linkMessage->neighborInterfaceAddresses.begin ();
1772 nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end ();
1775 Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter);
1776 NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: "
1777 << *nb2hop_addr_iter
1778 << " (main address is " << nb2hop_addr << ")");
1779 if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH)
1781 // If the main address of the 2-hop neighbor address == main address
1782 // of the receiving node, silently discard the 2-hop
1783 // neighbor address.
1784 if (nb2hop_addr == m_routingAgentAddr)
1786 NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)");
1790 // Otherwise, a 2-hop tuple is created
1791 TwoHopNeighborTuple *nb2hop_tuple =
1792 m_state.FindTwoHopNeighborTuple (msg.GetOriginatorAddress (), nb2hop_addr);
1793 NS_LOG_LOGIC ("Adding the 2-hop neighbor"
1794 << (nb2hop_tuple? " (refreshing existing entry)" : ""));
1795 if (nb2hop_tuple == NULL)
1797 TwoHopNeighborTuple new_nb2hop_tuple;
1798 new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress ();
1799 new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
1800 new_nb2hop_tuple.expirationTime = now + msg.GetVTime ();
1801 AddTwoHopNeighborTuple (new_nb2hop_tuple);
1802 // Schedules nb2hop tuple deletion
1803 m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime),
1804 &AgentImpl::Nb2hopTupleTimerExpire, this,
1805 new_nb2hop_tuple.neighborMainAddr,
1806 new_nb2hop_tuple.twoHopNeighborAddr));
1810 nb2hop_tuple->expirationTime = now + msg.GetVTime ();
1813 else if (neighborType == OLSR_NOT_NEIGH)
1815 // For each 2-hop node listed in the HELLO message
1816 // with Neighbor Type equal to NOT_NEIGH all 2-hop
1817 // tuples where: N_neighbor_main_addr == Originator
1818 // Address AND N_2hop_addr == main address of the
1819 // 2-hop neighbor are deleted.
1820 NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
1821 m_state.EraseTwoHopNeighborTuples (msg.GetOriginatorAddress (), nb2hop_addr);
1825 NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad"
1826 " neighbor type value: " << neighborType);
1832 NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
1838 /// \brief Updates the MPR Selector Set according to the information contained in a new
1839 /// received HELLO message (following RFC 3626).
1841 AgentImpl::PopulateMprSelectorSet (const olsr::MessageHeader &msg,
1842 const olsr::MessageHeader::Hello &hello)
1844 NS_LOG_FUNCTION (this);
1846 Time now = Simulator::Now ();
1848 typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
1849 for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
1850 linkMessage != hello.linkMessages.end ();
1853 int nt = linkMessage->linkCode >> 2;
1854 if (nt == OLSR_MPR_NEIGH)
1856 NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
1858 for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
1859 linkMessage->neighborInterfaceAddresses.begin ();
1860 nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
1863 if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
1865 NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
1867 // We must create a new entry into the mpr selector set
1868 MprSelectorTuple *existing_mprsel_tuple =
1869 m_state.FindMprSelectorTuple (msg.GetOriginatorAddress ());
1870 if (existing_mprsel_tuple == NULL)
1872 MprSelectorTuple mprsel_tuple;
1874 mprsel_tuple.mainAddr = msg.GetOriginatorAddress ();
1875 mprsel_tuple.expirationTime = now + msg.GetVTime ();
1876 AddMprSelectorTuple (mprsel_tuple);
1878 // Schedules mpr selector tuple deletion
1879 m_events.Track (Simulator::Schedule
1880 (DELAY (mprsel_tuple.expirationTime),
1881 &AgentImpl::MprSelTupleTimerExpire, this,
1882 mprsel_tuple.mainAddr));
1886 existing_mprsel_tuple->expirationTime = now + msg.GetVTime ();
1892 NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
1898 /// \brief Drops a given packet because it couldn't be delivered to the corresponding
1899 /// destination by the MAC layer. This may cause a neighbor loss, and appropiate
1900 /// actions are then taken.
1902 /// \param p the packet which couldn't be delivered by the MAC layer.
1905 OLSR::mac_failed(Ptr<Packet> p) {
1906 double now = Simulator::Now ();
1907 struct hdr_ip* ih = HDR_IP(p);
1908 struct hdr_cmn* ch = HDR_CMN(p);
1910 debug("%f: Node %d MAC Layer detects a breakage on link to %d\n",
1912 OLSR::node_id(ra_addr()),
1913 OLSR::node_id(ch->next_hop()));
1915 if ((u_int32_t)ih->daddr() == IP_BROADCAST) {
1916 drop(p, DROP_RTR_MAC_CALLBACK);
1920 OLSR_link_tuple* link_tuple = state_.find_link_tuple(ch->next_hop());
1921 if (link_tuple != NULL) {
1922 link_tuple->lost_time() = now + OLSR_NEIGHB_HOLD_TIME;
1923 link_tuple->time() = now + OLSR_NEIGHB_HOLD_TIME;
1924 nb_loss(link_tuple);
1926 drop(p, DROP_RTR_MAC_CALLBACK);
1934 /// \brief Performs all actions needed when a neighbor loss occurs.
1936 /// Neighbor Set, 2-hop Neighbor Set, MPR Set and MPR Selector Set are updated.
1938 /// \param tuple link tuple with the information of the link to the neighbor which has been lost.
1941 AgentImpl::NeighborLoss (const LinkTuple &tuple)
1943 NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
1944 << "s: OLSR Node " << m_mainAddress
1945 << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
1946 LinkTupleUpdated (tuple, OLSR_WILL_DEFAULT);
1947 m_state.EraseTwoHopNeighborTuples (GetMainAddress (tuple.neighborIfaceAddr));
1948 m_state.EraseMprSelectorTuples (GetMainAddress (tuple.neighborIfaceAddr));
1951 RoutingTableComputation ();
1955 /// \brief Adds a duplicate tuple to the Duplicate Set.
1957 /// \param tuple the duplicate tuple to be added.
1960 AgentImpl::AddDuplicateTuple (const DuplicateTuple &tuple)
1962 /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
1964 OLSR::node_id(ra_addr()),
1965 OLSR::node_id(tuple->addr()),
1966 tuple->seq_num());*/
1967 m_state.InsertDuplicateTuple (tuple);
1971 /// \brief Removes a duplicate tuple from the Duplicate Set.
1973 /// \param tuple the duplicate tuple to be removed.
1976 AgentImpl::RemoveDuplicateTuple (const DuplicateTuple &tuple)
1978 /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
1980 OLSR::node_id(ra_addr()),
1981 OLSR::node_id(tuple->addr()),
1982 tuple->seq_num());*/
1983 m_state.EraseDuplicateTuple (tuple);
1987 AgentImpl::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness)
1989 // Creates associated neighbor tuple
1990 NeighborTuple nb_tuple;
1991 nb_tuple.neighborMainAddr = GetMainAddress (tuple.neighborIfaceAddr);
1992 nb_tuple.willingness = willingness;
1994 if (tuple.symTime >= Simulator::Now ())
1996 nb_tuple.status = NeighborTuple::STATUS_SYM;
2000 nb_tuple.status = NeighborTuple::STATUS_NOT_SYM;
2003 AddNeighborTuple (nb_tuple);
2007 /// \brief Removes a link tuple from the Link Set.
2009 /// \param tuple the link tuple to be removed.
2012 AgentImpl::RemoveLinkTuple (const LinkTuple &tuple)
2014 NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2015 << "s: OLSR Node " << m_mainAddress
2016 << " LinkTuple " << tuple << " REMOVED.");
2018 m_state.EraseLinkTuple (tuple);
2019 m_state.EraseNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
2024 /// \brief This function is invoked when a link tuple is updated. Its aim is to
2025 /// also update the corresponding neighbor tuple if it is needed.
2027 /// \param tuple the link tuple which has been updated.
2030 AgentImpl::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
2032 // Each time a link tuple changes, the associated neighbor tuple must be recomputed
2034 NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
2035 << "s: OLSR Node " << m_mainAddress
2036 << " LinkTuple " << tuple << " UPDATED.");
2038 NeighborTuple *nb_tuple =
2039 m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
2041 if (nb_tuple == NULL)
2043 LinkTupleAdded (tuple, willingness);
2044 nb_tuple = m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
2047 if (nb_tuple != NULL)
2049 #ifdef NS3_LOG_ENABLE
2050 int statusBefore = nb_tuple->status;
2052 if (tuple.symTime >= Simulator::Now ())
2054 nb_tuple->status = NeighborTuple::STATUS_SYM;
2055 NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_SYM; changed:"
2056 << int (statusBefore != nb_tuple->status));
2060 nb_tuple->status = NeighborTuple::STATUS_NOT_SYM;
2061 NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_NOT_SYM; changed:"
2062 << int (statusBefore != nb_tuple->status));
2067 NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!");
2072 /// \brief Adds a neighbor tuple to the Neighbor Set.
2074 /// \param tuple the neighbor tuple to be added.
2077 AgentImpl::AddNeighborTuple (const NeighborTuple &tuple)
2079 // debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n",
2080 // Simulator::Now (),
2081 // OLSR::node_id(ra_addr()),
2082 // OLSR::node_id(tuple->neighborMainAddr),
2083 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2085 m_state.InsertNeighborTuple (tuple);
2090 /// \brief Removes a neighbor tuple from the Neighbor Set.
2092 /// \param tuple the neighbor tuple to be removed.
2095 AgentImpl::RemoveNeighborTuple (const NeighborTuple &tuple)
2097 // debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n",
2098 // Simulator::Now (),
2099 // OLSR::node_id(ra_addr()),
2100 // OLSR::node_id(tuple->neighborMainAddr),
2101 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2103 m_state.EraseNeighborTuple (tuple);
2108 /// \brief Adds a 2-hop neighbor tuple to the 2-hop Neighbor Set.
2110 /// \param tuple the 2-hop neighbor tuple to be added.
2113 AgentImpl::AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
2115 // debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2116 // Simulator::Now (),
2117 // OLSR::node_id(ra_addr()),
2118 // OLSR::node_id(tuple->neighborMainAddr),
2119 // OLSR::node_id(tuple->twoHopNeighborAddr));
2121 m_state.InsertTwoHopNeighborTuple (tuple);
2125 /// \brief Removes a 2-hop neighbor tuple from the 2-hop Neighbor Set.
2127 /// \param tuple the 2-hop neighbor tuple to be removed.
2130 AgentImpl::RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
2132 // debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2133 // Simulator::Now (),
2134 // OLSR::node_id(ra_addr()),
2135 // OLSR::node_id(tuple->neighborMainAddr),
2136 // OLSR::node_id(tuple->twoHopNeighborAddr));
2138 m_state.EraseTwoHopNeighborTuple (tuple);
2142 AgentImpl::IncrementAnsn ()
2144 m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1);
2148 /// \brief Adds an MPR selector tuple to the MPR Selector Set.
2150 /// Advertised Neighbor Sequence Number (ANSN) is also updated.
2152 /// \param tuple the MPR selector tuple to be added.
2155 AgentImpl::AddMprSelectorTuple (const MprSelectorTuple &tuple)
2157 // debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n",
2158 // Simulator::Now (),
2159 // OLSR::node_id(ra_addr()),
2160 // OLSR::node_id(tuple->main_addr()));
2162 m_state.InsertMprSelectorTuple (tuple);
2167 /// \brief Removes an MPR selector tuple from the MPR Selector Set.
2169 /// Advertised Neighbor Sequence Number (ANSN) is also updated.
2171 /// \param tuple the MPR selector tuple to be removed.
2174 AgentImpl::RemoveMprSelectorTuple (const MprSelectorTuple &tuple)
2176 // debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n",
2177 // Simulator::Now (),
2178 // OLSR::node_id(ra_addr()),
2179 // OLSR::node_id(tuple->main_addr()));
2181 m_state.EraseMprSelectorTuple (tuple);
2186 /// \brief Adds a topology tuple to the Topology Set.
2188 /// \param tuple the topology tuple to be added.
2191 AgentImpl::AddTopologyTuple (const TopologyTuple &tuple)
2193 // debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2194 // Simulator::Now (),
2195 // OLSR::node_id(ra_addr()),
2196 // OLSR::node_id(tuple->dest_addr()),
2197 // OLSR::node_id(tuple->last_addr()),
2200 m_state.InsertTopologyTuple(tuple);
2204 /// \brief Removes a topology tuple from the Topology Set.
2206 /// \param tuple the topology tuple to be removed.
2209 AgentImpl::RemoveTopologyTuple (const TopologyTuple &tuple)
2211 // debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2212 // Simulator::Now (),
2213 // OLSR::node_id(ra_addr()),
2214 // OLSR::node_id(tuple->dest_addr()),
2215 // OLSR::node_id(tuple->last_addr()),
2218 m_state.EraseTopologyTuple (tuple);
2222 /// \brief Adds an interface association tuple to the Interface Association Set.
2224 /// \param tuple the interface association tuple to be added.
2227 AgentImpl::AddIfaceAssocTuple (const IfaceAssocTuple &tuple)
2229 // debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n",
2230 // Simulator::Now (),
2231 // OLSR::node_id(ra_addr()),
2232 // OLSR::node_id(tuple->main_addr()),
2233 // OLSR::node_id(tuple->iface_addr()));
2235 m_state.InsertIfaceAssocTuple (tuple);
2239 /// \brief Removes an interface association tuple from the Interface Association Set.
2241 /// \param tuple the interface association tuple to be removed.
2244 AgentImpl::RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple)
2246 // debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n",
2247 // Simulator::Now (),
2248 // OLSR::node_id(ra_addr()),
2249 // OLSR::node_id(tuple->main_addr()),
2250 // OLSR::node_id(tuple->iface_addr()));
2252 m_state.EraseIfaceAssocTuple (tuple);
2256 uint16_t AgentImpl::GetPacketSequenceNumber ()
2258 m_packetSequenceNumber = (m_packetSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1);
2259 return m_packetSequenceNumber;
2262 /// Increments message sequence number and returns the new value.
2263 uint16_t AgentImpl::GetMessageSequenceNumber ()
2265 m_messageSequenceNumber = (m_messageSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1);
2266 return m_messageSequenceNumber;
2271 /// \brief Sends a HELLO message and reschedules the HELLO timer.
2272 /// \param e The event which has expired.
2275 AgentImpl::HelloTimerExpire ()
2278 m_helloTimer.Schedule (m_helloInterval);
2282 /// \brief Sends a TC message (if there exists any MPR selector) and reschedules the TC timer.
2283 /// \param e The event which has expired.
2286 AgentImpl::TcTimerExpire ()
2288 if (m_state.GetMprSelectors ().size () > 0)
2294 NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR.");
2296 m_tcTimer.Schedule (m_tcInterval);
2300 /// \brief Sends a MID message (if the node has more than one interface) and resets the MID timer.
2301 /// \warning Currently it does nothing because there is no support for multiple interfaces.
2302 /// \param e The event which has expired.
2305 AgentImpl::MidTimerExpire ()
2308 m_midTimer.Schedule (m_midInterval);
2312 /// \brief Removes tuple if expired. Else timer is rescheduled to expire at tuple.expirationTime.
2314 /// The task of actually removing the tuple is left to the OLSR agent.
2316 /// \param tuple The tuple which has expired.
2319 AgentImpl::DupTupleTimerExpire (Ipv4Address address, uint16_t sequenceNumber)
2321 DuplicateTuple *tuple =
2322 m_state.FindDuplicateTuple (address, sequenceNumber);
2327 if (tuple->expirationTime < Simulator::Now ())
2329 RemoveDuplicateTuple (*tuple);
2333 m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
2334 &AgentImpl::DupTupleTimerExpire, this,
2335 address, sequenceNumber));
2340 /// \brief Removes tuple_ if expired. Else if symmetric time
2341 /// has expired then it is assumed a neighbor loss and agent_->nb_loss()
2342 /// is called. In this case the timer is rescheduled to expire at
2343 /// tuple_->time(). Otherwise the timer is rescheduled to expire at
2344 /// the minimum between tuple_->time() and tuple_->sym_time().
2346 /// The task of actually removing the tuple is left to the OLSR agent.
2348 /// \param e The event which has expired.
2351 AgentImpl::LinkTupleTimerExpire (Ipv4Address neighborIfaceAddr)
2353 Time now = Simulator::Now ();
2355 // the tuple parameter may be a stale copy; get a newer version from m_state
2356 LinkTuple *tuple = m_state.FindLinkTuple (neighborIfaceAddr);
2361 if (tuple->time < now)
2363 RemoveLinkTuple (*tuple);
2365 else if (tuple->symTime < now)
2367 if (m_linkTupleTimerFirstTime)
2368 m_linkTupleTimerFirstTime = false;
2370 NeighborLoss (*tuple);
2372 m_events.Track (Simulator::Schedule (DELAY (tuple->time),
2373 &AgentImpl::LinkTupleTimerExpire, this,
2374 neighborIfaceAddr));
2378 m_events.Track (Simulator::Schedule (DELAY (std::min (tuple->time, tuple->symTime)),
2379 &AgentImpl::LinkTupleTimerExpire, this,
2380 neighborIfaceAddr));
2385 /// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
2387 /// The task of actually removing the tuple is left to the OLSR agent.
2389 /// \param e The event which has expired.
2392 AgentImpl::Nb2hopTupleTimerExpire (Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr)
2394 TwoHopNeighborTuple *tuple;
2395 tuple = m_state.FindTwoHopNeighborTuple (neighborMainAddr, twoHopNeighborAddr);
2400 if (tuple->expirationTime < Simulator::Now ())
2402 RemoveTwoHopNeighborTuple (*tuple);
2406 m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
2407 &AgentImpl::Nb2hopTupleTimerExpire,
2408 this, neighborMainAddr, twoHopNeighborAddr));
2413 /// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
2415 /// The task of actually removing the tuple is left to the OLSR agent.
2417 /// \param e The event which has expired.
2420 AgentImpl::MprSelTupleTimerExpire (Ipv4Address mainAddr)
2422 MprSelectorTuple *tuple = m_state.FindMprSelectorTuple (mainAddr);
2427 if (tuple->expirationTime < Simulator::Now ())
2429 RemoveMprSelectorTuple (*tuple);
2433 m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
2434 &AgentImpl::MprSelTupleTimerExpire,
2440 /// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
2442 /// The task of actually removing the tuple is left to the OLSR agent.
2444 /// \param e The event which has expired.
2447 AgentImpl::TopologyTupleTimerExpire (Ipv4Address destAddr, Ipv4Address lastAddr)
2449 TopologyTuple *tuple = m_state.FindTopologyTuple (destAddr, lastAddr);
2454 if (tuple->expirationTime < Simulator::Now ())
2456 RemoveTopologyTuple (*tuple);
2460 m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
2461 &AgentImpl::TopologyTupleTimerExpire,
2462 this, tuple->destAddr, tuple->lastAddr));
2467 /// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time().
2468 /// \warning Actually this is never invoked because there is no support for multiple interfaces.
2469 /// \param e The event which has expired.
2472 AgentImpl::IfaceAssocTupleTimerExpire (Ipv4Address ifaceAddr)
2474 IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (ifaceAddr);
2479 if (tuple->time < Simulator::Now ())
2481 RemoveIfaceAssocTuple (*tuple);
2485 m_events.Track (Simulator::Schedule (DELAY (tuple->time),
2486 &AgentImpl::IfaceAssocTupleTimerExpire,
2491 Ptr<const olsr::RoutingTable>
2492 AgentImpl::GetRoutingTable () const
2494 return m_routingTable;
2497 }} // namespace olsr, ns3