A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
dsr-routing.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Yufei Cheng
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Yufei Cheng <yfcheng@ittc.ku.edu>
18 *
19 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
20 * ResiliNets Research Group https://resilinets.org/
21 * Information and Telecommunication Technology Center (ITTC)
22 * and Department of Electrical Engineering and Computer Science
23 * The University of Kansas Lawrence, KS USA.
24 *
25 * Work supported in part by NSF FIND (Future Internet Design) Program
26 * under grant CNS-0626918 (Postmodern Internet Architecture),
27 * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
28 * US Department of Defense (DoD), and ITTC at The University of Kansas.
29 */
30
31#define NS_LOG_APPEND_CONTEXT \
32 if (GetObject<Node>()) \
33 { \
34 std::clog << "[node " << GetObject<Node>()->GetId() << "] "; \
35 }
36
37#include "dsr-routing.h"
38
39#include "dsr-fs-header.h"
40#include "dsr-options.h"
41#include "dsr-rcache.h"
42#include "dsr-rreq-table.h"
43
44#include "ns3/adhoc-wifi-mac.h"
45#include "ns3/arp-header.h"
46#include "ns3/assert.h"
47#include "ns3/boolean.h"
48#include "ns3/config.h"
49#include "ns3/double.h"
50#include "ns3/enum.h"
51#include "ns3/icmpv4-l4-protocol.h"
52#include "ns3/inet-socket-address.h"
53#include "ns3/ipv4-address.h"
54#include "ns3/ipv4-header.h"
55#include "ns3/ipv4-l3-protocol.h"
56#include "ns3/ipv4-route.h"
57#include "ns3/ipv6-interface.h"
58#include "ns3/llc-snap-header.h"
59#include "ns3/log.h"
60#include "ns3/net-device.h"
61#include "ns3/node-list.h"
62#include "ns3/object-vector.h"
63#include "ns3/packet.h"
64#include "ns3/pointer.h"
65#include "ns3/ptr.h"
66#include "ns3/string.h"
67#include "ns3/tcp-socket-factory.h"
68#include "ns3/timer.h"
69#include "ns3/trace-source-accessor.h"
70#include "ns3/udp-l4-protocol.h"
71#include "ns3/udp-socket-factory.h"
72#include "ns3/uinteger.h"
73#include "ns3/wifi-net-device.h"
74
75#include <algorithm>
76#include <ctime>
77#include <iostream>
78#include <limits>
79#include <list>
80#include <map>
81
82namespace ns3
83{
84
85NS_LOG_COMPONENT_DEFINE("DsrRouting");
86
87namespace dsr
88{
89
91
92/* see http://www.iana.org/assignments/protocol-numbers */
93const uint8_t DsrRouting::PROT_NUMBER = 48;
94
95/*
96 * The extension header is the fixed size dsr header, it is response for recognizing DSR option
97 types
98 * and demux to right options to process the packet.
99 *
100 * The header format with neighboring layers is as follows:
101 *
102 +-+-+-+-+-+-+-+-+-+-+-
103 | Application Header |
104 +-+-+-+-+-+-+-+-+-+-+-+
105 | Transport Header |
106 +-+-+-+-+-+-+-+-+-+-+-+
107 | Fixed DSR Header |
108 +---------------------+
109 | DSR Options |
110 +-+-+-+-+-+-+-+-+-+-+-+
111 | IP Header |
112 +-+-+-+-+-+-+-+-+-+-+-+
113 */
114
115TypeId
117{
118 static TypeId tid =
119 TypeId("ns3::dsr::DsrRouting")
121 .SetGroupName("Dsr")
122 .AddConstructor<DsrRouting>()
123 .AddAttribute(
124 "RouteCache",
125 "The route cache for saving routes from "
126 "route discovery process.",
127 PointerValue(nullptr),
129 MakePointerChecker<DsrRouteCache>())
130 .AddAttribute(
131 "RreqTable",
132 "The request table to manage route requests.",
133 PointerValue(nullptr),
135 MakePointerChecker<DsrRreqTable>())
136 .AddAttribute(
137 "PassiveBuffer",
138 "The passive buffer to manage "
139 "promisucously received passive ack.",
140 PointerValue(nullptr),
142 MakePointerChecker<DsrPassiveBuffer>())
143 .AddAttribute("MaxSendBuffLen",
144 "Maximum number of packets that can be stored "
145 "in send buffer.",
146 UintegerValue(64),
148 MakeUintegerChecker<uint32_t>())
149 .AddAttribute("MaxSendBuffTime",
150 "Maximum time packets can be queued in the send buffer .",
151 TimeValue(Seconds(30)),
154 .AddAttribute("MaxMaintLen",
155 "Maximum number of packets that can be stored "
156 "in maintenance buffer.",
157 UintegerValue(50),
159 MakeUintegerChecker<uint32_t>())
160 .AddAttribute("MaxMaintTime",
161 "Maximum time packets can be queued in maintenance buffer.",
162 TimeValue(Seconds(30)),
165 .AddAttribute("MaxCacheLen",
166 "Maximum number of route entries that can be stored "
167 "in route cache.",
168 UintegerValue(64),
170 MakeUintegerChecker<uint32_t>())
171 .AddAttribute("RouteCacheTimeout",
172 "Maximum time the route cache can be queued in "
173 "route cache.",
174 TimeValue(Seconds(300)),
177 .AddAttribute("MaxEntriesEachDst",
178 "Maximum number of route entries for a "
179 "single destination to respond.",
180 UintegerValue(20),
182 MakeUintegerChecker<uint32_t>())
183 .AddAttribute("SendBuffInterval",
184 "How often to check send buffer for packet with route.",
185 TimeValue(Seconds(500)),
188 .AddAttribute("NodeTraversalTime",
189 "The time it takes to traverse two neighboring nodes.",
193 .AddAttribute("RreqRetries",
194 "Maximum number of retransmissions for "
195 "request discovery of a route.",
196 UintegerValue(16),
198 MakeUintegerChecker<uint32_t>())
199 .AddAttribute("MaintenanceRetries",
200 "Maximum number of retransmissions for "
201 "data packets from maintenance buffer.",
202 UintegerValue(2),
204 MakeUintegerChecker<uint32_t>())
205 .AddAttribute("RequestTableSize",
206 "Maximum number of request entries in the request table, "
207 "set this as the number of nodes in the simulation.",
208 UintegerValue(64),
210 MakeUintegerChecker<uint32_t>())
211 .AddAttribute("RequestIdSize",
212 "Maximum number of request source Ids in "
213 "the request table.",
214 UintegerValue(16),
216 MakeUintegerChecker<uint32_t>())
217 .AddAttribute("UniqueRequestIdSize",
218 "Maximum number of request Ids in "
219 "the request table for a single destination.",
220 UintegerValue(256),
222 MakeUintegerChecker<uint32_t>())
223 .AddAttribute("NonPropRequestTimeout",
224 "The timeout value for non-propagation request.",
228 .AddAttribute("DiscoveryHopLimit",
229 "The max discovery hop limit for route requests.",
230 UintegerValue(255),
232 MakeUintegerChecker<uint32_t>())
233 .AddAttribute("MaxSalvageCount",
234 "The max salvage count for a single data packet.",
235 UintegerValue(15),
237 MakeUintegerChecker<uint8_t>())
238 .AddAttribute("BlacklistTimeout",
239 "The time for a neighbor to stay in blacklist.",
240 TimeValue(Seconds(3)),
243 .AddAttribute("GratReplyHoldoff",
244 "The time for gratuitous reply entry to expire.",
245 TimeValue(Seconds(1)),
248 .AddAttribute("BroadcastJitter",
249 "The jitter time to avoid collision for broadcast packets.",
250 UintegerValue(10),
252 MakeUintegerChecker<uint32_t>())
253 .AddAttribute("LinkAckTimeout",
254 "The time a packet in maintenance buffer wait for "
255 "link acknowledgment.",
259 .AddAttribute("TryLinkAcks",
260 "The number of link acknowledgment to use.",
261 UintegerValue(1),
263 MakeUintegerChecker<uint32_t>())
264 .AddAttribute("PassiveAckTimeout",
265 "The time a packet in maintenance buffer wait for "
266 "passive acknowledgment.",
270 .AddAttribute("TryPassiveAcks",
271 "The number of passive acknowledgment to use.",
272 UintegerValue(1),
274 MakeUintegerChecker<uint32_t>())
275 .AddAttribute("RequestPeriod",
276 "The base time interval between route requests.",
280 .AddAttribute("MaxRequestPeriod",
281 "The max time interval between route requests.",
282 TimeValue(Seconds(10)),
285 .AddAttribute("GraReplyTableSize",
286 "The gratuitous reply table size.",
287 UintegerValue(64),
289 MakeUintegerChecker<uint32_t>())
290 .AddAttribute("CacheType",
291 "Use Link Cache or use Path Cache",
292 StringValue("LinkCache"),
295 .AddAttribute("StabilityDecrFactor",
296 "The stability decrease factor for link cache",
297 UintegerValue(2),
299 MakeUintegerChecker<uint32_t>())
300 .AddAttribute("StabilityIncrFactor",
301 "The stability increase factor for link cache",
302 UintegerValue(4),
304 MakeUintegerChecker<uint32_t>())
305 .AddAttribute("InitStability",
306 "The initial stability factor for link cache",
307 TimeValue(Seconds(25)),
310 .AddAttribute("MinLifeTime",
311 "The minimal life time for link cache",
312 TimeValue(Seconds(1)),
315 .AddAttribute("UseExtends",
316 "The extension time for link cache",
317 TimeValue(Seconds(120)),
320 .AddAttribute("EnableSubRoute",
321 "Enables saving of sub route when receiving "
322 "route error messages, only available when "
323 "using path route cache",
324 BooleanValue(true),
327 .AddAttribute("RetransIncr",
328 "The increase time for retransmission timer "
329 "when facing network congestion",
333 .AddAttribute("MaxNetworkQueueSize",
334 "The max number of packet to save in the network queue.",
335 UintegerValue(400),
337 MakeUintegerChecker<uint32_t>())
338 .AddAttribute("MaxNetworkQueueDelay",
339 "The max time for a packet to stay in the network queue.",
340 TimeValue(Seconds(30.0)),
343 .AddAttribute("NumPriorityQueues",
344 "The max number of packet to save in the network queue.",
345 UintegerValue(2),
347 MakeUintegerChecker<uint32_t>())
348 .AddAttribute("LinkAcknowledgment",
349 "Enable Link layer acknowledgment mechanism",
350 BooleanValue(true),
353 .AddTraceSource("Tx",
354 "Send DSR packet.",
356 "ns3::dsr::DsrOptionSRHeader::TracedCallback")
357 .AddTraceSource("Drop",
358 "Drop DSR packet",
360 "ns3::Packet::TracedCallback");
361 return tid;
362}
363
365{
367
368 m_uniformRandomVariable = CreateObject<UniformRandomVariable>();
369
370 /*
371 * The following Ptr statements created objects for all the options header for DSR, and each of
372 * them have distinct option number assigned, when DSR Routing received a packet from higher
373 * layer, it will find the following options based on the option number, and pass the packet to
374 * the appropriate option to process it. After the option processing, it will pass the packet
375 * back to DSR Routing to send down layer.
376 */
377 Ptr<dsr::DsrOptionPad1> pad1Option = CreateObject<dsr::DsrOptionPad1>();
378 Ptr<dsr::DsrOptionPadn> padnOption = CreateObject<dsr::DsrOptionPadn>();
379 Ptr<dsr::DsrOptionRreq> rreqOption = CreateObject<dsr::DsrOptionRreq>();
380 Ptr<dsr::DsrOptionRrep> rrepOption = CreateObject<dsr::DsrOptionRrep>();
381 Ptr<dsr::DsrOptionSR> srOption = CreateObject<dsr::DsrOptionSR>();
382 Ptr<dsr::DsrOptionRerr> rerrOption = CreateObject<dsr::DsrOptionRerr>();
383 Ptr<dsr::DsrOptionAckReq> ackReq = CreateObject<dsr::DsrOptionAckReq>();
384 Ptr<dsr::DsrOptionAck> ack = CreateObject<dsr::DsrOptionAck>();
385
386 Insert(pad1Option);
387 Insert(padnOption);
388 Insert(rreqOption);
389 Insert(rrepOption);
390 Insert(srOption);
391 Insert(rerrOption);
392 Insert(ackReq);
393 Insert(ack);
394
395 // Check the send buffer for sending packets
398}
399
401{
403}
404
405void
407{
408 NS_LOG_FUNCTION(this << "NotifyNewAggregate");
409 if (!m_node)
410 {
411 Ptr<Node> node = this->GetObject<Node>();
412 if (node)
413 {
414 m_ipv4 = this->GetObject<Ipv4L3Protocol>();
415 if (m_ipv4)
416 {
417 this->SetNode(node);
418 m_ipv4->Insert(this);
420 }
421
422 m_ip = node->GetObject<Ipv4>();
423 if (m_ip)
424 {
425 NS_LOG_DEBUG("Ipv4 started");
426 }
427 }
428 }
431}
432
433void
435{
436 NS_LOG_FUNCTION(this << "Start DSR Routing protocol");
437
438 NS_LOG_INFO("The number of network queues " << m_numPriorityQueues);
439 for (uint32_t i = 0; i < m_numPriorityQueues; i++)
440 {
441 // Set the network queue max size and the delay
442 NS_LOG_INFO("The network queue size " << m_maxNetworkSize << " and the queue delay "
445 CreateObject<dsr::DsrNetworkQueue>(m_maxNetworkSize, m_maxNetworkDelay);
446 std::pair<std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator, bool> result_i =
447 m_priorityQueue.insert(std::make_pair(i, queue_i));
448 NS_ASSERT_MSG(result_i.second, "Error in creating queues");
449 }
450 Ptr<dsr::DsrRreqTable> rreqTable = CreateObject<dsr::DsrRreqTable>();
451 // Set the initial hop limit
452 rreqTable->SetInitHopLimit(m_discoveryHopLimit);
453 // Configure the request table parameters
454 rreqTable->SetRreqTableSize(m_requestTableSize);
455 rreqTable->SetRreqIdSize(m_requestTableIds);
456 rreqTable->SetUniqueRreqIdSize(m_maxRreqId);
457 SetRequestTable(rreqTable);
458 // Set the passive buffer parameters using just the send buffer parameters
459 Ptr<dsr::DsrPassiveBuffer> passiveBuffer = CreateObject<dsr::DsrPassiveBuffer>();
460 passiveBuffer->SetMaxQueueLen(m_maxSendBuffLen);
461 passiveBuffer->SetPassiveBufferTimeout(m_sendBufferTimeout);
462 SetPassiveBuffer(passiveBuffer);
463
464 // Set the send buffer parameters
467 // Set the error buffer parameters using just the send buffer parameters
470 // Set the maintenance buffer parameters
473 // Set the gratuitous reply table size
475
476 if (m_mainAddress == Ipv4Address())
477 {
478 Ipv4Address loopback("127.0.0.1");
479 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
480 {
481 // Use primary address, if multiple
482 Ipv4Address addr = m_ipv4->GetAddress(i, 0).GetLocal();
483 m_broadcast = m_ipv4->GetAddress(i, 0).GetBroadcast();
484 if (addr != loopback)
485 {
486 /*
487 * Set dsr route cache
488 */
489 Ptr<dsr::DsrRouteCache> routeCache = CreateObject<dsr::DsrRouteCache>();
490 // Configure the path cache parameters
491 routeCache->SetCacheType(m_cacheType);
492 routeCache->SetSubRoute(m_subRoute);
493 routeCache->SetMaxCacheLen(m_maxCacheLen);
494 routeCache->SetCacheTimeout(m_maxCacheTime);
495 routeCache->SetMaxEntriesEachDst(m_maxEntriesEachDst);
496 // Parameters for link cache
497 routeCache->SetStabilityDecrFactor(m_stabilityDecrFactor);
498 routeCache->SetStabilityIncrFactor(m_stabilityIncrFactor);
499 routeCache->SetInitStability(m_initStability);
500 routeCache->SetMinLifeTime(m_minLifeTime);
501 routeCache->SetUseExtends(m_useExtends);
502 routeCache->ScheduleTimer();
503 // The call back to handle link error and send error message to appropriate nodes
505 // routeCache->SetCallback (MakeCallback
506 // (&DsrRouting::SendRerrWhenBreaksLinkToNextHop, this));
507 SetRouteCache(routeCache);
508 // Set the main address as the current ip address
509 m_mainAddress = addr;
510
511 m_ipv4->GetNetDevice(1)->SetPromiscReceiveCallback(
513
514 // Allow neighbor manager use this interface for layer 2 feedback if possible
515 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(addr));
516 Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice>();
517 if (!wifi)
518 {
519 break;
520 }
521 Ptr<WifiMac> mac = wifi->GetMac();
522 if (!mac)
523 {
524 break;
525 }
526
527 routeCache->AddArpCache(m_ipv4->GetInterface(i)->GetArpCache());
528 NS_LOG_LOGIC("Starting DSR on node " << m_mainAddress);
529 break;
530 }
531 }
533 }
534}
535
538{
539 // Use "NodeList/*/DeviceList/*/ as reference
540 // where element [1] is the Node Id
541 // element [2] is the NetDevice Id
542 std::vector<std::string> elements = GetElementsFromContext(context);
543 Ptr<Node> n = NodeList::GetNode(std::stoi(elements[1]));
544 NS_ASSERT(n);
545 return n->GetDevice(std::stoi(elements[3]));
546}
547
548std::vector<std::string>
550{
551 std::vector<std::string> elements;
552 size_t pos1 = 0;
553 size_t pos2;
554 while (pos1 != std::string::npos)
555 {
556 pos1 = context.find('/', pos1);
557 pos2 = context.find('/', pos1 + 1);
558 elements.push_back(context.substr(pos1 + 1, pos2 - (pos1 + 1)));
559 pos1 = pos2;
560 }
561 return elements;
562}
563
564void
566{
568 m_node = nullptr;
569 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
570 {
571 // Disable layer 2 link state monitoring (if possible)
572 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(i);
573 Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice>();
574 if (wifi)
575 {
576 Ptr<WifiMac> mac = wifi->GetMac();
577 if (mac)
578 {
579 Ptr<AdhocWifiMac> adhoc = mac->GetObject<AdhocWifiMac>();
580 if (adhoc)
581 {
582 m_routeCache->DelArpCache(m_ipv4->GetInterface(i)->GetArpCache());
583 }
584 }
585 }
586 }
588}
589
590void
592{
593 m_node = node;
594}
595
598{
600 return m_node;
601}
602
603void
605{
606 // / Set the route cache to use
607 m_routeCache = r;
608}
609
612{
613 // / Get the route cache to use
614 return m_routeCache;
615}
616
617void
619{
620 // / Set the request table to use
621 m_rreqTable = q;
622}
623
626{
627 // / Get the request table to use
628 return m_rreqTable;
629}
630
631void
633{
634 // / Set the request table to use
635 m_passiveBuffer = p;
636}
637
640{
641 // / Get the request table to use
642 return m_passiveBuffer;
643}
644
647{
648 NS_LOG_FUNCTION(this << ipv4Address);
649 int32_t nNodes = NodeList::GetNNodes();
650 for (int32_t i = 0; i < nNodes; ++i)
651 {
653 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
654 int32_t ifIndex = ipv4->GetInterfaceForAddress(ipv4Address);
655 if (ifIndex != -1)
656 {
657 return node;
658 }
659 }
660 return nullptr;
661}
662
663bool
665{
666 return m_routeCache->IsLinkCache();
667}
668
669void
671{
672 m_routeCache->UseExtends(rt);
673}
674
675bool
677{
678 return m_routeCache->LookupRoute(id, rt);
679}
680
681bool
683{
684 Ipv4Address nextHop = SearchNextHop(source, nodelist);
685 m_errorBuffer.DropPacketForErrLink(source, nextHop);
686 return m_routeCache->AddRoute_Link(nodelist, source);
687}
688
689bool
691{
692 std::vector<Ipv4Address> nodelist = rt.GetVector();
693 Ipv4Address nextHop = SearchNextHop(m_mainAddress, nodelist);
695 return m_routeCache->AddRoute(rt);
696}
697
698void
700 Ipv4Address unreachNode,
701 Ipv4Address node)
702{
703 m_routeCache->DeleteAllRoutesIncludeLink(errorSrc, unreachNode, node);
704}
705
706bool
708{
709 return m_routeCache->UpdateRouteEntry(dst);
710}
711
712bool
714{
715 return m_rreqTable->FindSourceEntry(src, dst, id);
716}
717
720{
721 NS_LOG_FUNCTION(this << address);
722 int32_t nNodes = NodeList::GetNNodes();
723 for (int32_t i = 0; i < nNodes; ++i)
724 {
726 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
727 Ptr<NetDevice> netDevice = ipv4->GetNetDevice(1);
728
729 if (netDevice->GetAddress() == address)
730 {
731 return ipv4->GetAddress(1, 0).GetLocal();
732 }
733 }
734 return nullptr;
735}
736
737void
738DsrRouting::PrintVector(std::vector<Ipv4Address>& vec)
739{
740 NS_LOG_FUNCTION(this);
741 /*
742 * Check elements in a route vector
743 */
744 if (vec.empty())
745 {
746 NS_LOG_DEBUG("The vector is empty");
747 }
748 else
749 {
750 NS_LOG_DEBUG("Print all the elements in a vector");
751 for (std::vector<Ipv4Address>::const_iterator i = vec.begin(); i != vec.end(); ++i)
752 {
753 NS_LOG_DEBUG("The ip address " << *i);
754 }
755 }
756}
757
759DsrRouting::SearchNextHop(Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
760{
761 NS_LOG_FUNCTION(this << ipv4Address);
762 Ipv4Address nextHop;
763 NS_LOG_DEBUG("the vector size " << vec.size());
764 if (vec.size() == 2)
765 {
766 NS_LOG_DEBUG("The two nodes are neighbors");
767 nextHop = vec[1];
768 return nextHop;
769 }
770
771 if (ipv4Address == vec.back())
772 {
773 NS_LOG_DEBUG("We have reached to the final destination " << ipv4Address << " "
774 << vec.back());
775 return ipv4Address;
776 }
777 for (std::vector<Ipv4Address>::const_iterator i = vec.begin(); i != vec.end(); ++i)
778 {
779 if (ipv4Address == (*i))
780 {
781 nextHop = *(++i);
782 return nextHop;
783 }
784 }
785
786 NS_LOG_DEBUG("Next hop address not found");
787 Ipv4Address none = "0.0.0.0";
788 return none;
789}
790
793{
794 NS_LOG_FUNCTION(this << nextHop << srcAddress);
795 m_ipv4Route = Create<Ipv4Route>();
796 m_ipv4Route->SetDestination(nextHop);
797 m_ipv4Route->SetGateway(nextHop);
798 m_ipv4Route->SetSource(srcAddress);
799 return m_ipv4Route;
800}
801
802int
804{
805 // / This is the protocol number for DSR which is 48
806 return PROT_NUMBER;
807}
808
809uint16_t
811{
812 int32_t nNodes = NodeList::GetNNodes();
813 for (int32_t i = 0; i < nNodes; ++i)
814 {
816 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
817 if (ipv4->GetAddress(1, 0).GetLocal() == address)
818 {
819 return uint16_t(i);
820 }
821 }
822 return 256;
823}
824
827{
828 if (id >= 256)
829 {
830 NS_LOG_DEBUG("Exceed the node range");
831 return "0.0.0.0";
832 }
833
835 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
836 return ipv4->GetAddress(1, 0).GetLocal();
837}
838
841{
842 if (messageType == DSR_CONTROL_PACKET)
843 {
844 return 0;
845 }
846 else
847 {
848 return 1;
849 }
850}
851
852void
854{
856 {
858 }
861}
862
863void
865{
866 NS_LOG_INFO(Simulator::Now().As(Time::S) << " Checking send buffer at " << m_mainAddress
867 << " with size " << m_sendBuffer.GetSize());
868
869 for (std::vector<DsrSendBuffEntry>::iterator i = m_sendBuffer.GetBuffer().begin();
870 i != m_sendBuffer.GetBuffer().end();)
871 {
872 NS_LOG_DEBUG("Here we try to find the data packet in the send buffer");
873 Ipv4Address destination = i->GetDestination();
874 DsrRouteCacheEntry toDst;
875 bool findRoute = m_routeCache->LookupRoute(destination, toDst);
876 if (findRoute)
877 {
878 NS_LOG_INFO("We have found a route for the packet");
879 Ptr<const Packet> packet = i->GetPacket();
880 Ptr<Packet> cleanP = packet->Copy();
881 uint8_t protocol = i->GetProtocol();
882
883 i = m_sendBuffer.GetBuffer().erase(i);
884
885 DsrRoutingHeader dsrRoutingHeader;
886 Ptr<Packet> copyP = packet->Copy();
887 Ptr<Packet> dsrPacket = packet->Copy();
888 dsrPacket->RemoveHeader(dsrRoutingHeader);
889 uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
890 copyP->RemoveAtStart(offset); // Here the processed size is 8 bytes, which is the fixed
891 // sized extension header
892 // The packet to get ipv4 header
893 Ptr<Packet> ipv4P = copyP->Copy();
894 /*
895 * Peek data to get the option type as well as length and segmentsLeft field
896 */
897 uint32_t size = copyP->GetSize();
898 uint8_t* data = new uint8_t[size];
899 copyP->CopyData(data, size);
900
901 uint8_t optionType = 0;
902 optionType = *(data);
903
904 if (optionType == 3)
905 {
906 Ptr<dsr::DsrOptions> dsrOption;
907 DsrOptionHeader dsrOptionHeader;
908 uint8_t errorType = *(data + 2);
909
910 if (errorType == 1) // This is the Route Error Option
911 {
913 copyP->RemoveHeader(rerr);
914 NS_ASSERT(copyP->GetSize() == 0);
915
917 newUnreach.SetErrorType(1);
918 newUnreach.SetErrorSrc(rerr.GetErrorSrc());
919 newUnreach.SetUnreachNode(rerr.GetUnreachNode());
920 newUnreach.SetErrorDst(rerr.GetErrorDst());
921 newUnreach.SetSalvage(rerr.GetSalvage()); // Set the value about whether to
922 // salvage a packet or not
923
924 DsrOptionSRHeader sourceRoute;
925 std::vector<Ipv4Address> errorRoute = toDst.GetVector();
926 sourceRoute.SetNodesAddress(errorRoute);
928 if (m_routeCache->IsLinkCache())
929 {
930 m_routeCache->UseExtends(errorRoute);
931 }
932 sourceRoute.SetSegmentsLeft((errorRoute.size() - 2));
933 uint8_t salvage = 0;
934 sourceRoute.SetSalvage(salvage);
935 Ipv4Address nextHop =
936 SearchNextHop(m_mainAddress, errorRoute); // Get the next hop address
937
938 if (nextHop == "0.0.0.0")
939 {
940 PacketNewRoute(dsrPacket, m_mainAddress, destination, protocol);
941 return;
942 }
943
944 SetRoute(nextHop, m_mainAddress);
945 uint8_t length = (sourceRoute.GetLength() + newUnreach.GetLength());
946 dsrRoutingHeader.SetNextHeader(protocol);
947 dsrRoutingHeader.SetMessageType(1);
948 dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
949 dsrRoutingHeader.SetDestId(255);
950 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
951 dsrRoutingHeader.AddDsrOption(newUnreach);
952 dsrRoutingHeader.AddDsrOption(sourceRoute);
953
954 Ptr<Packet> newPacket = Create<Packet>();
955 newPacket->AddHeader(dsrRoutingHeader); // Add the routing header with rerr and
956 // sourceRoute attached to it
957 Ptr<NetDevice> dev =
958 m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
959 m_ipv4Route->SetOutputDevice(dev);
960
962 std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i =
963 m_priorityQueue.find(priority);
964 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
965 NS_LOG_LOGIC("Will be inserting into priority queue number: " << priority);
966
967 // m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (),
968 // m_ipv4Route);
969
971 DsrNetworkQueueEntry newEntry(newPacket,
973 nextHop,
976
977 if (dsrNetworkQueue->Enqueue(newEntry))
978 {
979 Scheduler(priority);
980 }
981 else
982 {
983 NS_LOG_INFO("Packet dropped as dsr network queue is full");
984 }
985 }
986 }
987 else
988 {
989 dsrRoutingHeader.SetNextHeader(protocol);
990 dsrRoutingHeader.SetMessageType(2);
991 dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
992 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
993
994 DsrOptionSRHeader sourceRoute;
995 std::vector<Ipv4Address> nodeList =
996 toDst.GetVector(); // Get the route from the route entry we found
997 Ipv4Address nextHop =
999 nodeList); // Get the next hop address for the route
1000 if (nextHop == "0.0.0.0")
1001 {
1002 PacketNewRoute(dsrPacket, m_mainAddress, destination, protocol);
1003 return;
1004 }
1005 uint8_t salvage = 0;
1006 sourceRoute.SetNodesAddress(
1007 nodeList); // Save the whole route in the source route header of the packet
1008 sourceRoute.SetSegmentsLeft(
1009 (nodeList.size() - 2)); // The segmentsLeft field will indicate the hops to go
1010 sourceRoute.SetSalvage(salvage);
1012 if (m_routeCache->IsLinkCache())
1013 {
1014 m_routeCache->UseExtends(nodeList);
1015 }
1016 uint8_t length = sourceRoute.GetLength();
1017 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1018 dsrRoutingHeader.AddDsrOption(sourceRoute);
1019 cleanP->AddHeader(dsrRoutingHeader);
1020 Ptr<const Packet> mtP = cleanP->Copy();
1021 // Put the data packet in the maintenance queue for data packet retransmission
1022 DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1023 /*ourAddress=*/m_mainAddress,
1024 /*nextHop=*/nextHop,
1025 /*src=*/m_mainAddress,
1026 /*dst=*/destination,
1027 /*ackId=*/0,
1028 /*segsLeft=*/nodeList.size() - 2,
1029 /*expire=*/m_maxMaintainTime);
1030 bool result = m_maintainBuffer.Enqueue(
1031 newEntry); // Enqueue the packet the the maintenance buffer
1032 if (result)
1033 {
1034 NetworkKey networkKey;
1035 networkKey.m_ackId = newEntry.GetAckId();
1036 networkKey.m_ourAdd = newEntry.GetOurAdd();
1037 networkKey.m_nextHop = newEntry.GetNextHop();
1038 networkKey.m_source = newEntry.GetSrc();
1039 networkKey.m_destination = newEntry.GetDst();
1040
1041 PassiveKey passiveKey;
1042 passiveKey.m_ackId = 0;
1043 passiveKey.m_source = newEntry.GetSrc();
1044 passiveKey.m_destination = newEntry.GetDst();
1045 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1046
1047 LinkKey linkKey;
1048 linkKey.m_source = newEntry.GetSrc();
1049 linkKey.m_destination = newEntry.GetDst();
1050 linkKey.m_ourAdd = newEntry.GetOurAdd();
1051 linkKey.m_nextHop = newEntry.GetNextHop();
1052
1053 m_addressForwardCnt[networkKey] = 0;
1054 m_passiveCnt[passiveKey] = 0;
1055 m_linkCnt[linkKey] = 0;
1056
1057 if (m_linkAck)
1058 {
1059 ScheduleLinkPacketRetry(newEntry, protocol);
1060 }
1061 else
1062 {
1063 NS_LOG_LOGIC("Not using link acknowledgment");
1064 if (nextHop != destination)
1065 {
1066 SchedulePassivePacketRetry(newEntry, protocol);
1067 }
1068 else
1069 {
1070 // This is the first network retry
1071 ScheduleNetworkPacketRetry(newEntry, true, protocol);
1072 }
1073 }
1074 }
1075 // we need to suspend the normal timer that checks the send buffer
1076 // until we are done sending packets
1078 {
1080 }
1082 return;
1083 }
1084 }
1085 else
1086 {
1087 ++i;
1088 }
1089 }
1090 // after going through the entire send buffer and send all packets found route,
1091 // we need to resume the timer if it has been suspended
1093 {
1094 NS_LOG_DEBUG("Resume the send buffer timer");
1096 }
1097}
1098
1099bool
1101 Ptr<const Packet> packet,
1102 uint16_t protocol,
1103 const Address& from,
1104 const Address& to,
1105 NetDevice::PacketType packetType)
1106{
1107 if (protocol != Ipv4L3Protocol::PROT_NUMBER)
1108 {
1109 return false;
1110 }
1111 // Remove the ipv4 header here
1112 Ptr<Packet> pktMinusIpHdr = packet->Copy();
1113 Ipv4Header ipv4Header;
1114 pktMinusIpHdr->RemoveHeader(ipv4Header);
1115
1116 if (ipv4Header.GetProtocol() != DsrRouting::PROT_NUMBER)
1117 {
1118 return false;
1119 }
1120 // Remove the dsr routing header here
1121 Ptr<Packet> pktMinusDsrHdr = pktMinusIpHdr->Copy();
1122 DsrRoutingHeader dsrRouting;
1123 pktMinusDsrHdr->RemoveHeader(dsrRouting);
1124
1125 /*
1126 * Message type 2 means the data packet, we will further process the data
1127 * packet for delivery notification, safely ignore control packet
1128 * Another check here is our own address, if this is the data destinated for us,
1129 * process it further, otherwise, just ignore it
1130 */
1131 Ipv4Address ourAddress = m_ipv4->GetAddress(1, 0).GetLocal();
1132 // check if the message type is 2 and if the ipv4 address matches
1133 if (dsrRouting.GetMessageType() == 2 && ourAddress == m_mainAddress)
1134 {
1135 NS_LOG_DEBUG("data packet receives " << packet->GetUid());
1136 Ipv4Address sourceIp = GetIPfromID(dsrRouting.GetSourceId());
1137 Ipv4Address destinationIp = GetIPfromID(dsrRouting.GetDestId());
1140
1141 Ptr<Packet> p = Create<Packet>();
1142 // Here the segments left value need to plus one to check the earlier hop maintain buffer
1143 // entry
1144 DsrMaintainBuffEntry newEntry;
1145 newEntry.SetPacket(p);
1146 newEntry.SetSrc(sourceIp);
1147 newEntry.SetDst(destinationIp);
1149 newEntry.SetOurAdd(previousHop);
1150 newEntry.SetNextHop(ourAddress);
1152 Ptr<Node> node = GetNodeWithAddress(previousHop);
1153 NS_LOG_DEBUG("The previous node " << previousHop);
1154
1155 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1156 dsr->CancelLinkPacketTimer(newEntry);
1157 }
1158
1159 // Receive only IP packets and packets destined for other hosts
1160 if (packetType == NetDevice::PACKET_OTHERHOST)
1161 {
1162 // just to minimize debug output
1163 NS_LOG_INFO(this << from << to << packetType << *pktMinusIpHdr);
1164
1165 uint8_t offset =
1166 dsrRouting
1167 .GetDsrOptionsOffset(); // Get the offset for option header, 4 bytes in this case
1168 uint8_t nextHeader = dsrRouting.GetNextHeader();
1169 uint32_t sourceId = dsrRouting.GetSourceId();
1170 Ipv4Address source = GetIPfromID(sourceId);
1171
1172 // This packet is used to peek option type
1173 pktMinusIpHdr->RemoveAtStart(offset);
1174 /*
1175 * Peek data to get the option type as well as length and segmentsLeft field
1176 */
1177 uint32_t size = pktMinusIpHdr->GetSize();
1178 uint8_t* data = new uint8_t[size];
1179 pktMinusIpHdr->CopyData(data, size);
1180 uint8_t optionType = 0;
1181 optionType = *(data);
1182
1183 Ptr<dsr::DsrOptions> dsrOption;
1184
1185 if (optionType == 96) // This is the source route option
1186 {
1187 Ipv4Address promiscSource = GetIPfromMAC(Mac48Address::ConvertFrom(from));
1188 dsrOption = GetOption(
1189 optionType); // Get the relative DSR option and demux to the process function
1191 << " DSR node " << m_mainAddress
1192 << " overhearing packet PID: " << pktMinusIpHdr->GetUid() << " from "
1193 << promiscSource << " to " << GetIPfromMAC(Mac48Address::ConvertFrom(to))
1194 << " with source IP " << ipv4Header.GetSource() << " and destination IP "
1195 << ipv4Header.GetDestination() << " and packet : " << *pktMinusDsrHdr);
1196
1197 bool isPromisc = true; // Set the boolean value isPromisc as true
1198 dsrOption->Process(pktMinusIpHdr,
1199 pktMinusDsrHdr,
1201 source,
1202 ipv4Header,
1203 nextHeader,
1204 isPromisc,
1205 promiscSource);
1206 return true;
1207 }
1208 }
1209 return false;
1210}
1211
1212void
1214 Ipv4Address source,
1215 Ipv4Address destination,
1216 uint8_t protocol)
1217{
1218 NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)protocol);
1219 // Look up routes for the specific destination
1220 DsrRouteCacheEntry toDst;
1221 bool findRoute = m_routeCache->LookupRoute(destination, toDst);
1222 // Queue the packet if there is no route pre-existing
1223 if (!findRoute)
1224 {
1226 << " " << m_mainAddress
1227 << " there is no route for this packet, queue the packet");
1228
1229 Ptr<Packet> p = packet->Copy();
1230 DsrSendBuffEntry newEntry(p,
1231 destination,
1233 protocol); // Create a new entry for send buffer
1234 bool result = m_sendBuffer.Enqueue(newEntry); // Enqueue the packet in send buffer
1235 if (result)
1236 {
1237 NS_LOG_INFO(Simulator::Now().As(Time::S) << " Add packet PID: " << packet->GetUid()
1238 << " to queue. Packet: " << *packet);
1239
1240 NS_LOG_LOGIC("Send RREQ to" << destination);
1241 if ((m_addressReqTimer.find(destination) == m_addressReqTimer.end()) &&
1242 (m_nonPropReqTimer.find(destination) == m_nonPropReqTimer.end()))
1243 {
1244 /*
1245 * Call the send request function, it will update the request table entry and ttl
1246 * there
1247 */
1248 SendInitialRequest(source, destination, protocol);
1249 }
1250 }
1251 }
1252 else
1253 {
1254 Ptr<Packet> cleanP = packet->Copy();
1255 DsrRoutingHeader dsrRoutingHeader;
1256 dsrRoutingHeader.SetNextHeader(protocol);
1257 dsrRoutingHeader.SetMessageType(2);
1258 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1259 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1260
1261 DsrOptionSRHeader sourceRoute;
1262 std::vector<Ipv4Address> nodeList =
1263 toDst.GetVector(); // Get the route from the route entry we found
1264 Ipv4Address nextHop =
1265 SearchNextHop(m_mainAddress, nodeList); // Get the next hop address for the route
1266 if (nextHop == "0.0.0.0")
1267 {
1268 PacketNewRoute(cleanP, source, destination, protocol);
1269 return;
1270 }
1271 uint8_t salvage = 0;
1272 sourceRoute.SetNodesAddress(
1273 nodeList); // Save the whole route in the source route header of the packet
1275 if (m_routeCache->IsLinkCache())
1276 {
1277 m_routeCache->UseExtends(nodeList);
1278 }
1279 sourceRoute.SetSegmentsLeft(
1280 (nodeList.size() - 2)); // The segmentsLeft field will indicate the hops to go
1281 sourceRoute.SetSalvage(salvage);
1282
1283 uint8_t length = sourceRoute.GetLength();
1284 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1285 dsrRoutingHeader.AddDsrOption(sourceRoute);
1286 cleanP->AddHeader(dsrRoutingHeader);
1287 Ptr<const Packet> mtP = cleanP->Copy();
1288 SetRoute(nextHop, m_mainAddress);
1289 // Put the data packet in the maintenance queue for data packet retransmission
1290 DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1291 /*ourAddress=*/m_mainAddress,
1292 /*nextHop=*/nextHop,
1293 /*src=*/source,
1294 /*dst=*/destination,
1295 /*ackId=*/0,
1296 /*segsLeft=*/nodeList.size() - 2,
1297 /*expire=*/m_maxMaintainTime);
1298 bool result =
1299 m_maintainBuffer.Enqueue(newEntry); // Enqueue the packet the the maintenance buffer
1300
1301 if (result)
1302 {
1303 NetworkKey networkKey;
1304 networkKey.m_ackId = newEntry.GetAckId();
1305 networkKey.m_ourAdd = newEntry.GetOurAdd();
1306 networkKey.m_nextHop = newEntry.GetNextHop();
1307 networkKey.m_source = newEntry.GetSrc();
1308 networkKey.m_destination = newEntry.GetDst();
1309
1310 PassiveKey passiveKey;
1311 passiveKey.m_ackId = 0;
1312 passiveKey.m_source = newEntry.GetSrc();
1313 passiveKey.m_destination = newEntry.GetDst();
1314 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1315
1316 LinkKey linkKey;
1317 linkKey.m_source = newEntry.GetSrc();
1318 linkKey.m_destination = newEntry.GetDst();
1319 linkKey.m_ourAdd = newEntry.GetOurAdd();
1320 linkKey.m_nextHop = newEntry.GetNextHop();
1321
1322 m_addressForwardCnt[networkKey] = 0;
1323 m_passiveCnt[passiveKey] = 0;
1324 m_linkCnt[linkKey] = 0;
1325
1326 if (m_linkAck)
1327 {
1328 ScheduleLinkPacketRetry(newEntry, protocol);
1329 }
1330 else
1331 {
1332 NS_LOG_LOGIC("Not using link acknowledgment");
1333 if (nextHop != destination)
1334 {
1335 SchedulePassivePacketRetry(newEntry, protocol);
1336 }
1337 else
1338 {
1339 // This is the first network retry
1340 ScheduleNetworkPacketRetry(newEntry, true, protocol);
1341 }
1342 }
1343 }
1344 }
1345}
1346
1347void
1349 Ipv4Address destination,
1350 Ipv4Address originalDst,
1351 uint8_t salvage,
1352 uint8_t protocol)
1353{
1354 NS_LOG_FUNCTION(this << unreachNode << destination << originalDst << (uint32_t)salvage
1355 << (uint32_t)protocol);
1356 DsrRoutingHeader dsrRoutingHeader;
1357 dsrRoutingHeader.SetNextHeader(protocol);
1358 dsrRoutingHeader.SetMessageType(1);
1359 dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
1360 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1361
1362 DsrOptionRerrUnreachHeader rerrUnreachHeader;
1363 rerrUnreachHeader.SetErrorType(1);
1364 rerrUnreachHeader.SetErrorSrc(m_mainAddress);
1365 rerrUnreachHeader.SetUnreachNode(unreachNode);
1366 rerrUnreachHeader.SetErrorDst(destination);
1367 rerrUnreachHeader.SetOriginalDst(originalDst);
1368 rerrUnreachHeader.SetSalvage(salvage); // Set the value about whether to salvage a packet or not
1369 uint8_t rerrLength = rerrUnreachHeader.GetLength();
1370
1371 DsrRouteCacheEntry toDst;
1372 bool findRoute = m_routeCache->LookupRoute(destination, toDst);
1373 // Queue the packet if there is no route pre-existing
1374 Ptr<Packet> newPacket = Create<Packet>();
1375 if (!findRoute)
1376 {
1377 if (destination == m_mainAddress)
1378 {
1379 NS_LOG_INFO("We are the error source, send request to original dst " << originalDst);
1380 // Send error request message if we are the source node
1381 SendErrorRequest(rerrUnreachHeader, protocol);
1382 }
1383 else
1384 {
1386 << " " << m_mainAddress
1387 << " there is no route for this packet, queue the packet");
1388
1389 dsrRoutingHeader.SetPayloadLength(rerrLength + 2);
1390 dsrRoutingHeader.AddDsrOption(rerrUnreachHeader);
1391 newPacket->AddHeader(dsrRoutingHeader);
1392 Ptr<Packet> p = newPacket->Copy();
1393 // Save the error packet in the error buffer
1394 DsrErrorBuffEntry newEntry(p,
1395 destination,
1397 unreachNode,
1399 protocol);
1400 bool result = m_errorBuffer.Enqueue(newEntry); // Enqueue the packet in send buffer
1401 if (result)
1402 {
1404 << " Add packet PID: " << p->GetUid() << " to queue. Packet: " << *p);
1405 NS_LOG_LOGIC("Send RREQ to" << destination);
1406 if ((m_addressReqTimer.find(destination) == m_addressReqTimer.end()) &&
1407 (m_nonPropReqTimer.find(destination) == m_nonPropReqTimer.end()))
1408 {
1409 NS_LOG_DEBUG("When there is no existing route request for "
1410 << destination << ", initialize one");
1411 /*
1412 * Call the send request function, it will update the request table entry and
1413 * ttl there
1414 */
1415 SendInitialRequest(m_mainAddress, destination, protocol);
1416 }
1417 }
1418 }
1419 }
1420 else
1421 {
1422 std::vector<Ipv4Address> nodeList = toDst.GetVector();
1423 Ipv4Address nextHop = SearchNextHop(m_mainAddress, nodeList);
1424 if (nextHop == "0.0.0.0")
1425 {
1426 NS_LOG_DEBUG("The route is not right");
1427 PacketNewRoute(newPacket, m_mainAddress, destination, protocol);
1428 return;
1429 }
1430 DsrOptionSRHeader sourceRoute;
1431 sourceRoute.SetNodesAddress(nodeList);
1433 if (m_routeCache->IsLinkCache())
1434 {
1435 m_routeCache->UseExtends(nodeList);
1436 }
1437 sourceRoute.SetSegmentsLeft((nodeList.size() - 2));
1438 uint8_t srLength = sourceRoute.GetLength();
1439 uint8_t length = (srLength + rerrLength);
1440
1441 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
1442 dsrRoutingHeader.AddDsrOption(rerrUnreachHeader);
1443 dsrRoutingHeader.AddDsrOption(sourceRoute);
1444 newPacket->AddHeader(dsrRoutingHeader);
1445
1446 SetRoute(nextHop, m_mainAddress);
1447 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
1448 m_ipv4Route->SetOutputDevice(dev);
1449 NS_LOG_INFO("Send the packet to the next hop address " << nextHop << " from "
1450 << m_mainAddress << " with the size "
1451 << newPacket->GetSize());
1452
1454 std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
1455 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1456 NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue
1457 << " number: " << priority);
1458
1459 // m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
1460
1462 DsrNetworkQueueEntry newEntry(newPacket,
1464 nextHop,
1466 m_ipv4Route);
1467
1468 if (dsrNetworkQueue->Enqueue(newEntry))
1469 {
1470 Scheduler(priority);
1471 }
1472 else
1473 {
1474 NS_LOG_INFO("Packet dropped as dsr network queue is full");
1475 }
1476 }
1477}
1478
1479void
1481 DsrOptionSRHeader& sourceRoute,
1482 Ipv4Address nextHop,
1483 uint8_t protocol,
1484 Ptr<Ipv4Route> route)
1485{
1486 NS_LOG_FUNCTION(this << rerr << sourceRoute << nextHop << (uint32_t)protocol << route);
1487 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
1488 DsrRoutingHeader dsrRoutingHeader;
1489 dsrRoutingHeader.SetNextHeader(protocol);
1490 dsrRoutingHeader.SetMessageType(1);
1491 dsrRoutingHeader.SetSourceId(GetIDfromIP(rerr.GetErrorSrc()));
1492 dsrRoutingHeader.SetDestId(GetIDfromIP(rerr.GetErrorDst()));
1493
1494 uint8_t length = (sourceRoute.GetLength() + rerr.GetLength());
1495 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
1496 dsrRoutingHeader.AddDsrOption(rerr);
1497 dsrRoutingHeader.AddDsrOption(sourceRoute);
1498 Ptr<Packet> packet = Create<Packet>();
1499 packet->AddHeader(dsrRoutingHeader);
1500 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
1501 route->SetOutputDevice(dev);
1502
1504 std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
1505 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1506 NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue
1507 << " number: " << priority);
1508
1509 // m_downTarget (packet, m_mainAddress, nextHop, GetProtocolNumber (), route);
1510
1512 DsrNetworkQueueEntry newEntry(packet, m_mainAddress, nextHop, Simulator::Now(), route);
1513
1514 if (dsrNetworkQueue->Enqueue(newEntry))
1515 {
1516 Scheduler(priority);
1517 }
1518 else
1519 {
1520 NS_LOG_INFO("Packet dropped as dsr network queue is full");
1521 }
1522}
1523
1524void
1526 Ipv4Address source,
1527 Ipv4Address destination,
1528 uint8_t protocol,
1529 Ptr<Ipv4Route> route)
1530{
1531 NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)protocol << route);
1532 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
1533
1534 if (protocol == 1)
1535 {
1536 NS_LOG_INFO("Drop packet. Not handling ICMP packet for now");
1537 }
1538 else
1539 {
1540 // Look up routes for the specific destination
1541 DsrRouteCacheEntry toDst;
1542 bool findRoute = m_routeCache->LookupRoute(destination, toDst);
1543 // Queue the packet if there is no route pre-existing
1544 if (!findRoute)
1545 {
1547 << " " << m_mainAddress
1548 << " there is no route for this packet, queue the packet");
1549
1550 Ptr<Packet> p = packet->Copy();
1551 DsrSendBuffEntry newEntry(p,
1552 destination,
1554 protocol); // Create a new entry for send buffer
1555 bool result = m_sendBuffer.Enqueue(newEntry); // Enqueue the packet in send buffer
1556 if (result)
1557 {
1558 NS_LOG_INFO(Simulator::Now().As(Time::S) << " Add packet PID: " << packet->GetUid()
1559 << " to send buffer. Packet: " << *packet);
1560 // Only when there is no existing route request timer when new route request is
1561 // scheduled
1562 if ((m_addressReqTimer.find(destination) == m_addressReqTimer.end()) &&
1563 (m_nonPropReqTimer.find(destination) == m_nonPropReqTimer.end()))
1564 {
1565 /*
1566 * Call the send request function, it will update the request table entry and
1567 * ttl value
1568 */
1569 NS_LOG_LOGIC("Send initial RREQ to " << destination);
1570 SendInitialRequest(source, destination, protocol);
1571 }
1572 else
1573 {
1574 NS_LOG_LOGIC("There is existing route request timer with request count "
1575 << m_rreqTable->GetRreqCnt(destination));
1576 }
1577 }
1578 }
1579 else
1580 {
1581 Ptr<Packet> cleanP = packet->Copy();
1582 DsrRoutingHeader dsrRoutingHeader;
1583 dsrRoutingHeader.SetNextHeader(protocol);
1584 dsrRoutingHeader.SetMessageType(2);
1585 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1586 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1587
1588 DsrOptionSRHeader sourceRoute;
1589 std::vector<Ipv4Address> nodeList =
1590 toDst.GetVector(); // Get the route from the route entry we found
1591 Ipv4Address nextHop =
1592 SearchNextHop(m_mainAddress, nodeList); // Get the next hop address for the route
1593 if (nextHop == "0.0.0.0")
1594 {
1595 PacketNewRoute(cleanP, source, destination, protocol);
1596 return;
1597 }
1598 uint8_t salvage = 0;
1599 sourceRoute.SetNodesAddress(
1600 nodeList); // Save the whole route in the source route header of the packet
1602 if (m_routeCache->IsLinkCache())
1603 {
1604 m_routeCache->UseExtends(nodeList);
1605 }
1606 sourceRoute.SetSegmentsLeft(
1607 (nodeList.size() - 2)); // The segmentsLeft field will indicate the hops to go
1608 sourceRoute.SetSalvage(salvage);
1609
1610 uint8_t length = sourceRoute.GetLength();
1611
1612 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1613 dsrRoutingHeader.AddDsrOption(sourceRoute);
1614 cleanP->AddHeader(dsrRoutingHeader);
1615
1616 Ptr<const Packet> mtP = cleanP->Copy();
1617 NS_LOG_DEBUG("maintain packet size " << cleanP->GetSize());
1618 // Put the data packet in the maintenance queue for data packet retransmission
1619 DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1620 /*ourAddress=*/m_mainAddress,
1621 /*nextHop=*/nextHop,
1622 /*src=*/source,
1623 /*dst=*/destination,
1624 /*ackId=*/0,
1625 /*segsLeft=*/nodeList.size() - 2,
1626 /*expire=*/m_maxMaintainTime);
1627 bool result =
1628 m_maintainBuffer.Enqueue(newEntry); // Enqueue the packet the the maintenance buffer
1629 if (result)
1630 {
1631 NetworkKey networkKey;
1632 networkKey.m_ackId = newEntry.GetAckId();
1633 networkKey.m_ourAdd = newEntry.GetOurAdd();
1634 networkKey.m_nextHop = newEntry.GetNextHop();
1635 networkKey.m_source = newEntry.GetSrc();
1636 networkKey.m_destination = newEntry.GetDst();
1637
1638 PassiveKey passiveKey;
1639 passiveKey.m_ackId = 0;
1640 passiveKey.m_source = newEntry.GetSrc();
1641 passiveKey.m_destination = newEntry.GetDst();
1642 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1643
1644 LinkKey linkKey;
1645 linkKey.m_source = newEntry.GetSrc();
1646 linkKey.m_destination = newEntry.GetDst();
1647 linkKey.m_ourAdd = newEntry.GetOurAdd();
1648 linkKey.m_nextHop = newEntry.GetNextHop();
1649
1650 m_addressForwardCnt[networkKey] = 0;
1651 m_passiveCnt[passiveKey] = 0;
1652 m_linkCnt[linkKey] = 0;
1653
1654 if (m_linkAck)
1655 {
1656 ScheduleLinkPacketRetry(newEntry, protocol);
1657 }
1658 else
1659 {
1660 NS_LOG_LOGIC("Not using link acknowledgment");
1661 if (nextHop != destination)
1662 {
1663 SchedulePassivePacketRetry(newEntry, protocol);
1664 }
1665 else
1666 {
1667 // This is the first network retry
1668 ScheduleNetworkPacketRetry(newEntry, true, protocol);
1669 }
1670 }
1671 }
1672
1673 if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(destination))
1674 {
1675 // Try to send packet from *previously* queued entries from send buffer if any
1678 this,
1679 sourceRoute,
1680 nextHop,
1681 protocol);
1682 }
1683 }
1684 }
1685}
1686
1687uint16_t
1689{
1690 NS_LOG_FUNCTION(this << packet << nextHop);
1691 // This packet is used to peek option type
1692 Ptr<Packet> dsrP = packet->Copy();
1693 Ptr<Packet> tmpP = packet->Copy();
1694
1695 DsrRoutingHeader dsrRoutingHeader;
1696 dsrP->RemoveHeader(dsrRoutingHeader); // Remove the DSR header in whole
1697 uint8_t protocol = dsrRoutingHeader.GetNextHeader();
1698 uint32_t sourceId = dsrRoutingHeader.GetSourceId();
1699 uint32_t destinationId = dsrRoutingHeader.GetDestId();
1700 uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
1701 tmpP->RemoveAtStart(
1702 offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
1703
1704 // Get the number of routers' address field
1705 uint8_t buf[2];
1706 tmpP->CopyData(buf, sizeof(buf));
1707 uint8_t numberAddress = (buf[1] - 2) / 4;
1708 DsrOptionSRHeader sourceRoute;
1709 sourceRoute.SetNumberAddress(numberAddress);
1710 tmpP->RemoveHeader(sourceRoute); // this is a clean packet without any dsr involved headers
1711
1712 DsrOptionAckReqHeader ackReq;
1713 m_ackId = m_routeCache->CheckUniqueAckId(nextHop);
1714 ackReq.SetAckId(m_ackId);
1715 uint8_t length = (sourceRoute.GetLength() + ackReq.GetLength());
1716 DsrRoutingHeader newDsrRoutingHeader;
1717 newDsrRoutingHeader.SetNextHeader(protocol);
1718 newDsrRoutingHeader.SetMessageType(2);
1719 newDsrRoutingHeader.SetSourceId(sourceId);
1720 newDsrRoutingHeader.SetDestId(destinationId);
1721 newDsrRoutingHeader.SetPayloadLength(length + 4);
1722 newDsrRoutingHeader.AddDsrOption(sourceRoute);
1723 newDsrRoutingHeader.AddDsrOption(ackReq);
1724 dsrP->AddHeader(newDsrRoutingHeader);
1725 // give the dsrP value to packet and then return
1726 packet = dsrP;
1727 return m_ackId;
1728}
1729
1730void
1732 Ipv4Address source,
1733 Ipv4Address nextHop,
1734 uint8_t protocol)
1735{
1736 NS_LOG_FUNCTION(this << packet << source << nextHop << (uint32_t)protocol);
1737 // Send out the data packet
1739 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
1740 m_ipv4Route->SetOutputDevice(dev);
1741
1743 std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
1744 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1745 NS_LOG_INFO("Will be inserting into priority queue number: " << priority);
1746
1747 // m_downTarget (packet, source, nextHop, GetProtocolNumber (), m_ipv4Route);
1748
1750 DsrNetworkQueueEntry newEntry(packet, source, nextHop, Simulator::Now(), m_ipv4Route);
1751
1752 if (dsrNetworkQueue->Enqueue(newEntry))
1753 {
1754 Scheduler(priority);
1755 }
1756 else
1757 {
1758 NS_LOG_INFO("Packet dropped as dsr network queue is full");
1759 }
1760}
1761
1762void
1764{
1765 NS_LOG_FUNCTION(this);
1766 PriorityScheduler(priority, true);
1767}
1768
1769void
1770DsrRouting::PriorityScheduler(uint32_t priority, bool continueWithFirst)
1771{
1772 NS_LOG_FUNCTION(this << priority << continueWithFirst);
1773 uint32_t numPriorities;
1774 if (continueWithFirst)
1775 {
1776 numPriorities = 0;
1777 }
1778 else
1779 {
1780 numPriorities = priority;
1781 }
1782 // priorities ranging from 0 to m_numPriorityQueues, with 0 as the highest priority
1783 for (uint32_t i = priority; numPriorities < m_numPriorityQueues; numPriorities++)
1784 {
1785 std::map<uint32_t, Ptr<DsrNetworkQueue>>::iterator q = m_priorityQueue.find(i);
1786 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = q->second;
1787 uint32_t queueSize = dsrNetworkQueue->GetSize();
1788 if (queueSize == 0)
1789 {
1790 if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1791 {
1792 i = 0;
1793 }
1794 else
1795 {
1796 i++;
1797 }
1798 }
1799 else
1800 {
1801 uint32_t totalQueueSize = 0;
1802 for (std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator j =
1803 m_priorityQueue.begin();
1804 j != m_priorityQueue.end();
1805 j++)
1806 {
1807 NS_LOG_INFO("The size of the network queue for " << j->first << " is "
1808 << j->second->GetSize());
1809 totalQueueSize += j->second->GetSize();
1810 NS_LOG_INFO("The total network queue size is " << totalQueueSize);
1811 }
1812 if (totalQueueSize > 5)
1813 {
1814 // Here the queue size is larger than 5, we need to increase the retransmission
1815 // timer for each packet in the network queue
1817 }
1818 DsrNetworkQueueEntry newEntry;
1819 dsrNetworkQueue->Dequeue(newEntry);
1820 if (SendRealDown(newEntry))
1821 {
1822 NS_LOG_LOGIC("Packet sent by Dsr. Calling PriorityScheduler after some time");
1823 // packet was successfully sent down. call scheduler after some time
1826 this,
1827 i,
1828 false);
1829 }
1830 else
1831 {
1832 // packet was dropped by Dsr. Call scheduler immediately so that we can
1833 // send another packet immediately.
1834 NS_LOG_LOGIC("Packet dropped by Dsr. Calling PriorityScheduler immediately");
1836 }
1837
1838 if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1839 {
1840 i = 0;
1841 }
1842 else
1843 {
1844 i++;
1845 }
1846 }
1847 }
1848}
1849
1850void
1852{
1853 NS_LOG_FUNCTION(this);
1854 // We may want to get the queue first and then we need to save a vector of the entries here and
1855 // then find
1857 std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
1858 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1859
1860 std::vector<DsrNetworkQueueEntry> newNetworkQueue = dsrNetworkQueue->GetQueue();
1861 for (std::vector<DsrNetworkQueueEntry>::iterator i = newNetworkQueue.begin();
1862 i != newNetworkQueue.end();
1863 i++)
1864 {
1865 Ipv4Address nextHop = i->GetNextHopAddress();
1866 for (std::map<NetworkKey, Timer>::iterator j = m_addressForwardTimer.begin();
1867 j != m_addressForwardTimer.end();
1868 j++)
1869 {
1870 if (nextHop == j->first.m_nextHop)
1871 {
1872 NS_LOG_DEBUG("The network delay left is " << j->second.GetDelayLeft());
1873 j->second.SetDelay(j->second.GetDelayLeft() + m_retransIncr);
1874 }
1875 }
1876 }
1877}
1878
1879bool
1881{
1882 NS_LOG_FUNCTION(this);
1883 Ipv4Address source = newEntry.GetSourceAddress();
1884 Ipv4Address nextHop = newEntry.GetNextHopAddress();
1885 Ptr<Packet> packet = newEntry.GetPacket()->Copy();
1886 Ptr<Ipv4Route> route = newEntry.GetIpv4Route();
1887 m_downTarget(packet, source, nextHop, GetProtocolNumber(), route);
1888 return true;
1889}
1890
1891void
1893 Ipv4Address nextHop,
1894 uint8_t protocol)
1895{
1896 NS_LOG_FUNCTION(this << nextHop << (uint32_t)protocol);
1897 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
1898
1899 // Reconstruct the route and Retransmit the data packet
1900 std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
1901 Ipv4Address destination = nodeList.back();
1902 Ipv4Address source = nodeList.front(); // Get the source address
1903 NS_LOG_INFO("The nexthop address " << nextHop << " the source " << source << " the destination "
1904 << destination);
1905 /*
1906 * Here we try to find data packet from send buffer, if packet with this destination found, send
1907 * it out
1908 */
1909 if (m_sendBuffer.Find(destination))
1910 {
1911 NS_LOG_DEBUG("destination over here " << destination);
1912
1914 if (m_routeCache->IsLinkCache())
1915 {
1916 m_routeCache->UseExtends(nodeList);
1917 }
1918 DsrSendBuffEntry entry;
1919 if (m_sendBuffer.Dequeue(destination, entry))
1920 {
1921 Ptr<Packet> packet = entry.GetPacket()->Copy();
1922 Ptr<Packet> p = packet->Copy(); // get a copy of the packet
1923 // Set the source route option
1924 DsrRoutingHeader dsrRoutingHeader;
1925 dsrRoutingHeader.SetNextHeader(protocol);
1926 dsrRoutingHeader.SetMessageType(2);
1927 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1928 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1929
1930 uint8_t length = sourceRoute.GetLength();
1931 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1932 dsrRoutingHeader.AddDsrOption(sourceRoute);
1933
1934 p->AddHeader(dsrRoutingHeader);
1935
1936 Ptr<const Packet> mtP = p->Copy();
1937 // Put the data packet in the maintenance queue for data packet retransmission
1938 DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1939 /*ourAddress=*/m_mainAddress,
1940 /*nextHop=*/nextHop,
1941 /*src=*/source,
1942 /*dst=*/destination,
1943 /*ackId=*/0,
1944 /*segsLeft=*/nodeList.size() - 2,
1945 /*expire=*/m_maxMaintainTime);
1946 bool result =
1947 m_maintainBuffer.Enqueue(newEntry); // Enqueue the packet the the maintenance buffer
1948
1949 if (result)
1950 {
1951 NetworkKey networkKey;
1952 networkKey.m_ackId = newEntry.GetAckId();
1953 networkKey.m_ourAdd = newEntry.GetOurAdd();
1954 networkKey.m_nextHop = newEntry.GetNextHop();
1955 networkKey.m_source = newEntry.GetSrc();
1956 networkKey.m_destination = newEntry.GetDst();
1957
1958 PassiveKey passiveKey;
1959 passiveKey.m_ackId = 0;
1960 passiveKey.m_source = newEntry.GetSrc();
1961 passiveKey.m_destination = newEntry.GetDst();
1962 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1963
1964 LinkKey linkKey;
1965 linkKey.m_source = newEntry.GetSrc();
1966 linkKey.m_destination = newEntry.GetDst();
1967 linkKey.m_ourAdd = newEntry.GetOurAdd();
1968 linkKey.m_nextHop = newEntry.GetNextHop();
1969
1970 m_addressForwardCnt[networkKey] = 0;
1971 m_passiveCnt[passiveKey] = 0;
1972 m_linkCnt[linkKey] = 0;
1973
1974 if (m_linkAck)
1975 {
1976 ScheduleLinkPacketRetry(newEntry, protocol);
1977 }
1978 else
1979 {
1980 NS_LOG_LOGIC("Not using link acknowledgment");
1981 if (nextHop != destination)
1982 {
1983 SchedulePassivePacketRetry(newEntry, protocol);
1984 }
1985 else
1986 {
1987 // This is the first network retry
1988 ScheduleNetworkPacketRetry(newEntry, true, protocol);
1989 }
1990 }
1991 }
1992
1993 NS_LOG_DEBUG("send buffer size here and the destination " << m_sendBuffer.GetSize()
1994 << " " << destination);
1995 if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(destination))
1996 {
1997 NS_LOG_LOGIC("Schedule sending the next packet in send buffer");
2000 this,
2001 sourceRoute,
2002 nextHop,
2003 protocol);
2004 }
2005 }
2006 else
2007 {
2008 NS_LOG_LOGIC("All queued packets are out-dated for the destination in send buffer");
2009 }
2010 }
2011 /*
2012 * Here we try to find data packet from send buffer, if packet with this destination found, send
2013 * it out
2014 */
2015 else if (m_errorBuffer.Find(destination))
2016 {
2017 DsrErrorBuffEntry entry;
2018 if (m_errorBuffer.Dequeue(destination, entry))
2019 {
2020 Ptr<Packet> packet = entry.GetPacket()->Copy();
2021 NS_LOG_DEBUG("The queued packet size " << packet->GetSize());
2022
2023 DsrRoutingHeader dsrRoutingHeader;
2024 Ptr<Packet> copyP = packet->Copy();
2025 Ptr<Packet> dsrPacket = packet->Copy();
2026 dsrPacket->RemoveHeader(dsrRoutingHeader);
2027 uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
2028 copyP->RemoveAtStart(offset); // Here the processed size is 8 bytes, which is the fixed
2029 // sized extension header
2030 /*
2031 * Peek data to get the option type as well as length and segmentsLeft field
2032 */
2033 uint32_t size = copyP->GetSize();
2034 uint8_t* data = new uint8_t[size];
2035 copyP->CopyData(data, size);
2036
2037 uint8_t optionType = 0;
2038 optionType = *(data);
2039 NS_LOG_DEBUG("The option type value in send packet " << (uint32_t)optionType);
2040 if (optionType == 3)
2041 {
2042 NS_LOG_DEBUG("The packet is error packet");
2043 Ptr<dsr::DsrOptions> dsrOption;
2044 DsrOptionHeader dsrOptionHeader;
2045
2046 uint8_t errorType = *(data + 2);
2047 NS_LOG_DEBUG("The error type");
2048 if (errorType == 1)
2049 {
2050 NS_LOG_DEBUG("The packet is route error unreach packet");
2052 copyP->RemoveHeader(rerr);
2053 NS_ASSERT(copyP->GetSize() == 0);
2054 uint8_t length = (sourceRoute.GetLength() + rerr.GetLength());
2055
2056 DsrOptionRerrUnreachHeader newUnreach;
2057 newUnreach.SetErrorType(1);
2058 newUnreach.SetErrorSrc(rerr.GetErrorSrc());
2059 newUnreach.SetUnreachNode(rerr.GetUnreachNode());
2060 newUnreach.SetErrorDst(rerr.GetErrorDst());
2061 newUnreach.SetOriginalDst(rerr.GetOriginalDst());
2062 newUnreach.SetSalvage(rerr.GetSalvage()); // Set the value about whether to
2063 // salvage a packet or not
2064
2065 std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
2066 DsrRoutingHeader newRoutingHeader;
2067 newRoutingHeader.SetNextHeader(protocol);
2068 newRoutingHeader.SetMessageType(1);
2069 newRoutingHeader.SetSourceId(GetIDfromIP(rerr.GetErrorSrc()));
2070 newRoutingHeader.SetDestId(GetIDfromIP(rerr.GetErrorDst()));
2071 newRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
2072 newRoutingHeader.AddDsrOption(newUnreach);
2073 newRoutingHeader.AddDsrOption(sourceRoute);
2075 if (m_routeCache->IsLinkCache())
2076 {
2077 m_routeCache->UseExtends(nodeList);
2078 }
2079 SetRoute(nextHop, m_mainAddress);
2080 Ptr<Packet> newPacket = Create<Packet>();
2081 newPacket->AddHeader(newRoutingHeader); // Add the extension header with rerr
2082 // and sourceRoute attached to it
2083 Ptr<NetDevice> dev =
2084 m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
2085 m_ipv4Route->SetOutputDevice(dev);
2086
2088 std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i =
2089 m_priorityQueue.find(priority);
2090 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2091 NS_LOG_DEBUG("Will be inserting into priority queue "
2092 << dsrNetworkQueue << " number: " << priority);
2093
2094 // m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (),
2095 // m_ipv4Route);
2096
2098 DsrNetworkQueueEntry newEntry(newPacket,
2100 nextHop,
2102 m_ipv4Route);
2103
2104 if (dsrNetworkQueue->Enqueue(newEntry))
2105 {
2106 Scheduler(priority);
2107 }
2108 else
2109 {
2110 NS_LOG_INFO("Packet dropped as dsr network queue is full");
2111 }
2112 }
2113 }
2114
2115 if (m_errorBuffer.GetSize() != 0 && m_errorBuffer.Find(destination))
2116 {
2117 NS_LOG_LOGIC("Schedule sending the next packet in error buffer");
2120 this,
2121 sourceRoute,
2122 nextHop,
2123 protocol);
2124 }
2125 }
2126 }
2127 else
2128 {
2129 NS_LOG_DEBUG("Packet not found in either the send or error buffer");
2130 }
2131}
2132
2133bool
2135 Ipv4Address source,
2136 Ipv4Address destination,
2137 uint8_t segsLeft,
2138 uint16_t fragmentOffset,
2139 uint16_t identification,
2140 bool saveEntry)
2141{
2142 NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)segsLeft);
2143
2144 Ptr<Packet> p = packet->Copy();
2145 // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
2146 DsrPassiveBuffEntry newEntry;
2147 newEntry.SetPacket(p);
2148 newEntry.SetSource(source);
2149 newEntry.SetDestination(destination);
2150 newEntry.SetIdentification(identification);
2151 newEntry.SetFragmentOffset(fragmentOffset);
2152 newEntry.SetSegsLeft(segsLeft); // We try to make sure the segments left is larger for 1
2153
2154 NS_LOG_DEBUG("The passive buffer size " << m_passiveBuffer->GetSize());
2155
2156 if (m_passiveBuffer->AllEqual(newEntry) && (!saveEntry))
2157 {
2158 // The PromiscEqual function will remove the maintain buffer entry if equal value found
2159 // It only compares the source and destination address, ackId, and the segments left value
2160 NS_LOG_DEBUG("We get the all equal for passive buffer here");
2161
2162 DsrMaintainBuffEntry mbEntry;
2163 mbEntry.SetPacket(p);
2164 mbEntry.SetSrc(source);
2165 mbEntry.SetDst(destination);
2166 mbEntry.SetAckId(0);
2167 mbEntry.SetSegsLeft(segsLeft + 1);
2168
2169 CancelPassivePacketTimer(mbEntry);
2170 return true;
2171 }
2172 if (saveEntry)
2173 {
2175 m_passiveBuffer->Enqueue(newEntry);
2176 }
2177 return false;
2178}
2179
2180bool
2182 Ipv4Address source,
2183 Ipv4Address destination,
2184 uint8_t segsLeft)
2185{
2186 NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)segsLeft);
2187
2188 NS_LOG_DEBUG("Cancel the passive timer");
2189
2190 Ptr<Packet> p = packet->Copy();
2191 // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
2192 DsrMaintainBuffEntry newEntry;
2193 newEntry.SetPacket(p);
2194 newEntry.SetSrc(source);
2195 newEntry.SetDst(destination);
2196 newEntry.SetAckId(0);
2197 newEntry.SetSegsLeft(segsLeft + 1);
2198
2199 if (m_maintainBuffer.PromiscEqual(newEntry))
2200 {
2201 // The PromiscEqual function will remove the maintain buffer entry if equal value found
2202 // It only compares the source and destination address, ackId, and the segments left value
2203 CancelPassivePacketTimer(newEntry);
2204 return true;
2205 }
2206 return false;
2207}
2208
2209void
2211 const Ipv4Header& ipv4Header,
2212 Ipv4Address realSrc,
2213 Ipv4Address realDst)
2214{
2215 NS_LOG_FUNCTION(this << (uint32_t)ackId << ipv4Header << realSrc << realDst);
2216 Ipv4Address sender = ipv4Header.GetDestination();
2217 Ipv4Address receiver = ipv4Header.GetSource();
2218 /*
2219 * Create a packet to fill maintenance buffer, not used to compare with maintenance entry
2220 * The reason is ack header doesn't have the original packet copy
2221 */
2222 Ptr<Packet> mainP = Create<Packet>();
2223 DsrMaintainBuffEntry newEntry(/*packet=*/mainP,
2224 /*ourAddress=*/sender,
2225 /*nextHop=*/receiver,
2226 /*src=*/realSrc,
2227 /*dst=*/realDst,
2228 /*ackId=*/ackId,
2229 /*segsLeft=*/0,
2230 /*expire=*/Simulator::Now());
2231 CancelNetworkPacketTimer(newEntry); // Only need to cancel network packet timer
2232}
2233
2234void
2236{
2237 NS_LOG_FUNCTION(this);
2241}
2242
2243void
2245{
2246 NS_LOG_FUNCTION(this);
2247 LinkKey linkKey;
2248 linkKey.m_ourAdd = mb.GetOurAdd();
2249 linkKey.m_nextHop = mb.GetNextHop();
2250 linkKey.m_source = mb.GetSrc();
2251 linkKey.m_destination = mb.GetDst();
2252 /*
2253 * Here we have found the entry for send retries, so we get the value and increase it by one
2254 */
2256 m_linkCnt[linkKey] = 0;
2257 m_linkCnt.erase(linkKey);
2258
2259 // TODO if find the linkkey, we need to remove it
2260
2261 // Find the network acknowledgment timer
2262 std::map<LinkKey, Timer>::const_iterator i = m_linkAckTimer.find(linkKey);
2263 if (i == m_linkAckTimer.end())
2264 {
2265 NS_LOG_INFO("did not find the link timer");
2266 }
2267 else
2268 {
2269 NS_LOG_INFO("did find the link timer");
2270 /*
2271 * Schedule the packet retry
2272 * Push back the nextHop, source, destination address
2273 */
2274 m_linkAckTimer[linkKey].Cancel();
2275 if (m_linkAckTimer[linkKey].IsRunning())
2276 {
2277 NS_LOG_INFO("Timer not canceled");
2278 }
2279 m_linkAckTimer.erase(linkKey);
2280 }
2281
2282 // Erase the maintenance entry
2283 // yet this does not check the segments left value here
2284 NS_LOG_DEBUG("The link buffer size " << m_maintainBuffer.GetSize());
2286 {
2287 NS_LOG_INFO("Link acknowledgment received, remove same maintenance buffer entry");
2288 }
2289}
2290
2291void
2293{
2294 NS_LOG_FUNCTION(this);
2295 NetworkKey networkKey;
2296 networkKey.m_ackId = mb.GetAckId();
2297 networkKey.m_ourAdd = mb.GetOurAdd();
2298 networkKey.m_nextHop = mb.GetNextHop();
2299 networkKey.m_source = mb.GetSrc();
2300 networkKey.m_destination = mb.GetDst();
2301 /*
2302 * Here we have found the entry for send retries, so we get the value and increase it by one
2303 */
2304 m_addressForwardCnt[networkKey] = 0;
2305 m_addressForwardCnt.erase(networkKey);
2306
2307 NS_LOG_INFO("ackId " << mb.GetAckId() << " ourAdd " << mb.GetOurAdd() << " nextHop "
2308 << mb.GetNextHop() << " source " << mb.GetSrc() << " destination "
2309 << mb.GetDst() << " segsLeft " << (uint32_t)mb.GetSegsLeft());
2310 // Find the network acknowledgment timer
2311 std::map<NetworkKey, Timer>::const_iterator i = m_addressForwardTimer.find(networkKey);
2312 if (i == m_addressForwardTimer.end())
2313 {
2314 NS_LOG_INFO("did not find the packet timer");
2315 }
2316 else
2317 {
2318 NS_LOG_INFO("did find the packet timer");
2319 /*
2320 * Schedule the packet retry
2321 * Push back the nextHop, source, destination address
2322 */
2323 m_addressForwardTimer[networkKey].Cancel();
2324 if (m_addressForwardTimer[networkKey].IsRunning())
2325 {
2326 NS_LOG_INFO("Timer not canceled");
2327 }
2328 m_addressForwardTimer.erase(networkKey);
2329 }
2330 // Erase the maintenance entry
2331 // yet this does not check the segments left value here
2333 {
2334 NS_LOG_INFO("Remove same maintenance buffer entry based on network acknowledgment");
2335 }
2336}
2337
2338void
2340{
2341 NS_LOG_FUNCTION(this);
2342 PassiveKey passiveKey;
2343 passiveKey.m_ackId = 0;
2344 passiveKey.m_source = mb.GetSrc();
2345 passiveKey.m_destination = mb.GetDst();
2346 passiveKey.m_segsLeft = mb.GetSegsLeft();
2347
2348 m_passiveCnt[passiveKey] = 0;
2349 m_passiveCnt.erase(passiveKey);
2350
2351 // Find the passive acknowledgment timer
2352 std::map<PassiveKey, Timer>::const_iterator j = m_passiveAckTimer.find(passiveKey);
2353 if (j == m_passiveAckTimer.end())
2354 {
2355 NS_LOG_INFO("did not find the passive timer");
2356 }
2357 else
2358 {
2359 NS_LOG_INFO("find the passive timer");
2360 /*
2361 * Cancel passive acknowledgment timer
2362 */
2363 m_passiveAckTimer[passiveKey].Cancel();
2364 if (m_passiveAckTimer[passiveKey].IsRunning())
2365 {
2366 NS_LOG_INFO("Timer not canceled");
2367 }
2368 m_passiveAckTimer.erase(passiveKey);
2369 }
2370}
2371
2372void
2374{
2375 NS_LOG_FUNCTION(this << nextHop << (uint32_t)protocol);
2376
2378 std::vector<Ipv4Address> previousErrorDst;
2379 if (m_maintainBuffer.Dequeue(nextHop, entry))
2380 {
2381 Ipv4Address source = entry.GetSrc();
2382 Ipv4Address destination = entry.GetDst();
2383
2384 Ptr<Packet> dsrP = entry.GetPacket()->Copy();
2385 Ptr<Packet> p = dsrP->Copy();
2386 Ptr<Packet> packet = dsrP->Copy();
2387 DsrRoutingHeader dsrRoutingHeader;
2388 dsrP->RemoveHeader(dsrRoutingHeader); // Remove the dsr header in whole
2389 uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
2390 p->RemoveAtStart(offset);
2391
2392 // Get the number of routers' address field
2393 uint8_t buf[2];
2394 p->CopyData(buf, sizeof(buf));
2395 uint8_t numberAddress = (buf[1] - 2) / 4;
2396 NS_LOG_DEBUG("The number of addresses " << (uint32_t)numberAddress);
2397 DsrOptionSRHeader sourceRoute;
2398 sourceRoute.SetNumberAddress(numberAddress);
2399 p->RemoveHeader(sourceRoute);
2400 std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
2401 uint8_t salvage = sourceRoute.GetSalvage();
2402 Ipv4Address address1 = nodeList[1];
2403 PrintVector(nodeList);
2404
2405 /*
2406 * If the salvage is not 0, use the first address in the route as the error dst in error
2407 * header otherwise use the source of packet as the error destination
2408 */
2409 Ipv4Address errorDst;
2410 if (salvage)
2411 {
2412 errorDst = address1;
2413 }
2414 else
2415 {
2416 errorDst = source;
2417 }
2419 if (std::find(previousErrorDst.begin(), previousErrorDst.end(), destination) ==
2420 previousErrorDst.end())
2421 {
2422 NS_LOG_DEBUG("have not seen this dst before " << errorDst << " in "
2423 << previousErrorDst.size());
2424 SendUnreachError(nextHop, errorDst, destination, salvage, protocol);
2425 previousErrorDst.push_back(errorDst);
2426 }
2427
2428 /*
2429 * Cancel the packet timer and then salvage the data packet
2430 */
2431
2432 CancelPacketAllTimer(entry);
2433 SalvagePacket(packet, source, destination, protocol);
2434
2436 {
2437 NS_LOG_INFO("Cancel the packet timer for next maintenance entry");
2440 this,
2441 nextHop,
2442 protocol);
2443 }
2444 }
2445 else
2446 {
2447 NS_LOG_INFO("Maintenance buffer entry not found");
2448 }
2450}
2451
2452void
2454 Ipv4Address source,
2455 Ipv4Address dst,
2456 uint8_t protocol)
2457{
2458 NS_LOG_FUNCTION(this << packet << source << dst << (uint32_t)protocol);
2459 // Create two copies of packet
2460 Ptr<Packet> p = packet->Copy();
2461 Ptr<Packet> newPacket = packet->Copy();
2462 // Remove the routing header in a whole to get a clean packet
2463 DsrRoutingHeader dsrRoutingHeader;
2464 p->RemoveHeader(dsrRoutingHeader);
2465 // Remove offset of dsr routing header
2466 uint8_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
2467 newPacket->RemoveAtStart(offset);
2468
2469 // Get the number of routers' address field
2470 uint8_t buf[2];
2471 newPacket->CopyData(buf, sizeof(buf));
2472 uint8_t numberAddress = (buf[1] - 2) / 4;
2473
2474 DsrOptionSRHeader sourceRoute;
2475 sourceRoute.SetNumberAddress(numberAddress);
2476 newPacket->RemoveHeader(sourceRoute);
2477 uint8_t salvage = sourceRoute.GetSalvage();
2478 /*
2479 * Look in the route cache for other routes for this destination
2480 */
2481 DsrRouteCacheEntry toDst;
2482 bool findRoute = m_routeCache->LookupRoute(dst, toDst);
2483 if (findRoute && (salvage < m_maxSalvageCount))
2484 {
2485 NS_LOG_DEBUG("We have found a route for the packet");
2486 DsrRoutingHeader newDsrRoutingHeader;
2487 newDsrRoutingHeader.SetNextHeader(protocol);
2488 newDsrRoutingHeader.SetMessageType(2);
2489 newDsrRoutingHeader.SetSourceId(GetIDfromIP(source));
2490 newDsrRoutingHeader.SetDestId(GetIDfromIP(dst));
2491
2492 std::vector<Ipv4Address> nodeList =
2493 toDst.GetVector(); // Get the route from the route entry we found
2494 Ipv4Address nextHop =
2495 SearchNextHop(m_mainAddress, nodeList); // Get the next hop address for the route
2496 if (nextHop == "0.0.0.0")
2497 {
2498 PacketNewRoute(p, source, dst, protocol);
2499 return;
2500 }
2501 // Increase the salvage count by 1
2502 salvage++;
2503 DsrOptionSRHeader sourceRoute;
2504 sourceRoute.SetSalvage(salvage);
2505 sourceRoute.SetNodesAddress(
2506 nodeList); // Save the whole route in the source route header of the packet
2507 sourceRoute.SetSegmentsLeft(
2508 (nodeList.size() - 2)); // The segmentsLeft field will indicate the hops to go
2510 if (m_routeCache->IsLinkCache())
2511 {
2512 m_routeCache->UseExtends(nodeList);
2513 }
2514 uint8_t length = sourceRoute.GetLength();
2515 NS_LOG_INFO("length of source route header " << (uint32_t)(sourceRoute.GetLength()));
2516 newDsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
2517 newDsrRoutingHeader.AddDsrOption(sourceRoute);
2518 p->AddHeader(newDsrRoutingHeader);
2519
2520 SetRoute(nextHop, m_mainAddress);
2521 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
2522 m_ipv4Route->SetOutputDevice(dev);
2523
2524 // Send out the data packet
2526 std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
2527 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2528 NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue
2529 << " number: " << priority);
2530
2531 // m_downTarget (p, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
2532
2535
2536 if (dsrNetworkQueue->Enqueue(newEntry))
2537 {
2538 Scheduler(priority);
2539 }
2540 else
2541 {
2542 NS_LOG_INFO("Packet dropped as dsr network queue is full");
2543 }
2544
2545 /*
2546 * Mark the next hop address in blacklist
2547 */
2548 // NS_LOG_DEBUG ("Save the next hop node in blacklist");
2549 // m_rreqTable->MarkLinkAsUnidirectional (nextHop, m_blacklistTimeout);
2550 }
2551 else
2552 {
2553 NS_LOG_DEBUG("Will not salvage this packet, silently drop");
2554 }
2555}
2556
2557void
2559{
2560 NS_LOG_FUNCTION(this << (uint32_t)protocol);
2561
2562 Ptr<Packet> p = mb.GetPacket()->Copy();
2563 Ipv4Address source = mb.GetSrc();
2564 Ipv4Address nextHop = mb.GetNextHop();
2565
2566 // Send the data packet out before schedule the next packet transmission
2567 SendPacket(p, source, nextHop, protocol);
2568
2569 LinkKey linkKey;
2570 linkKey.m_source = mb.GetSrc();
2571 linkKey.m_destination = mb.GetDst();
2572 linkKey.m_ourAdd = mb.GetOurAdd();
2573 linkKey.m_nextHop = mb.GetNextHop();
2574
2575 if (m_linkAckTimer.find(linkKey) == m_linkAckTimer.end())
2576 {
2578 m_linkAckTimer[linkKey] = timer;
2579 }
2580 m_linkAckTimer[linkKey].SetFunction(&DsrRouting::LinkScheduleTimerExpire, this);
2581 m_linkAckTimer[linkKey].Cancel();
2582 m_linkAckTimer[linkKey].SetArguments(mb, protocol);
2583 m_linkAckTimer[linkKey].Schedule(m_linkAckTimeout);
2584}
2585
2586void
2588{
2589 NS_LOG_FUNCTION(this << (uint32_t)protocol);
2590
2591 Ptr<Packet> p = mb.GetPacket()->Copy();
2592 Ipv4Address source = mb.GetSrc();
2593 Ipv4Address nextHop = mb.GetNextHop();
2594
2595 // Send the data packet out before schedule the next packet transmission
2596 SendPacket(p, source, nextHop, protocol);
2597
2598 PassiveKey passiveKey;
2599 passiveKey.m_ackId = 0;
2600 passiveKey.m_source = mb.GetSrc();
2601 passiveKey.m_destination = mb.GetDst();
2602 passiveKey.m_segsLeft = mb.GetSegsLeft();
2603
2604 if (m_passiveAckTimer.find(passiveKey) == m_passiveAckTimer.end())
2605 {
2607 m_passiveAckTimer[passiveKey] = timer;
2608 }
2609 NS_LOG_DEBUG("The passive acknowledgment option for data packet");
2610 m_passiveAckTimer[passiveKey].SetFunction(&DsrRouting::PassiveScheduleTimerExpire, this);
2611 m_passiveAckTimer[passiveKey].Cancel();
2612 m_passiveAckTimer[passiveKey].SetArguments(mb, protocol);
2613 m_passiveAckTimer[passiveKey].Schedule(m_passiveAckTimeout);
2614}
2615
2616void
2618{
2619 Ptr<Packet> p = Create<Packet>();
2620 Ptr<Packet> dsrP = Create<Packet>();
2621 // The new entry will be used for retransmission
2622 NetworkKey networkKey;
2623 Ipv4Address nextHop = mb.GetNextHop();
2624 NS_LOG_DEBUG("is the first retry or not " << isFirst);
2625 if (isFirst)
2626 {
2627 // This is the very first network packet retry
2628 p = mb.GetPacket()->Copy();
2629 // Here we add the ack request header to the data packet for network acknowledgement
2630 uint16_t ackId = AddAckReqHeader(p, nextHop);
2631
2632 Ipv4Address source = mb.GetSrc();
2633 Ipv4Address nextHop = mb.GetNextHop();
2634 // Send the data packet out before schedule the next packet transmission
2635 SendPacket(p, source, nextHop, protocol);
2636
2637 dsrP = p->Copy();
2638 DsrMaintainBuffEntry newEntry = mb;
2639 // The function AllEqual will find the exact entry and delete it if found
2641 newEntry.SetPacket(dsrP);
2642 newEntry.SetAckId(ackId);
2644
2645 networkKey.m_ackId = newEntry.GetAckId();
2646 networkKey.m_ourAdd = newEntry.GetOurAdd();
2647 networkKey.m_nextHop = newEntry.GetNextHop();
2648 networkKey.m_source = newEntry.GetSrc();
2649 networkKey.m_destination = newEntry.GetDst();
2650
2651 m_addressForwardCnt[networkKey] = 0;
2652 if (!m_maintainBuffer.Enqueue(newEntry))
2653 {
2654 NS_LOG_ERROR("Failed to enqueue packet retry");
2655 }
2656
2657 if (m_addressForwardTimer.find(networkKey) == m_addressForwardTimer.end())
2658 {
2660 m_addressForwardTimer[networkKey] = timer;
2661 }
2662
2663 // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment
2664 // option
2666 this);
2667 m_addressForwardTimer[networkKey].Cancel();
2668 m_addressForwardTimer[networkKey].SetArguments(newEntry, protocol);
2669 NS_LOG_DEBUG("The packet retries time for " << newEntry.GetAckId() << " is "
2670 << m_sendRetries << " and the delay time is "
2671 << Time(2 * m_nodeTraversalTime).As(Time::S));
2672 // Back-off mechanism
2673 m_addressForwardTimer[networkKey].Schedule(Time(2 * m_nodeTraversalTime));
2674 }
2675 else
2676 {
2677 networkKey.m_ackId = mb.GetAckId();
2678 networkKey.m_ourAdd = mb.GetOurAdd();
2679 networkKey.m_nextHop = mb.GetNextHop();
2680 networkKey.m_source = mb.GetSrc();
2681 networkKey.m_destination = mb.GetDst();
2682 /*
2683 * Here we have found the entry for send retries, so we get the value and increase it by one
2684 */
2685 m_sendRetries = m_addressForwardCnt[networkKey];
2686 NS_LOG_DEBUG("The packet retry we have done " << m_sendRetries);
2687
2688 p = mb.GetPacket()->Copy();
2689 dsrP = mb.GetPacket()->Copy();
2690
2691 Ipv4Address source = mb.GetSrc();
2692 Ipv4Address nextHop = mb.GetNextHop();
2693 // Send the data packet out before schedule the next packet transmission
2694 SendPacket(p, source, nextHop, protocol);
2695
2696 NS_LOG_DEBUG("The packet with dsr header " << dsrP->GetSize());
2697 networkKey.m_ackId = mb.GetAckId();
2698 networkKey.m_ourAdd = mb.GetOurAdd();
2699 networkKey.m_nextHop = mb.GetNextHop();
2700 networkKey.m_source = mb.GetSrc();
2701 networkKey.m_destination = mb.GetDst();
2702 /*
2703 * If a data packet has been attempted SendRetries times at the maximum TTL without
2704 * receiving any ACK, all data packets destined for the corresponding destination SHOULD be
2705 * dropped from the send buffer
2706 *
2707 * The maxMaintRexmt also needs to decrease one for the passive ack packet
2708 */
2709 /*
2710 * Check if the send retry time for a certain packet has already passed max maintenance
2711 * retransmission time or not
2712 */
2713
2714 // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment
2715 // option
2717 this);
2718 m_addressForwardTimer[networkKey].Cancel();
2719 m_addressForwardTimer[networkKey].SetArguments(mb, protocol);
2720 NS_LOG_DEBUG("The packet retries time for "
2721 << mb.GetAckId() << " is " << m_sendRetries << " and the delay time is "
2723 // Back-off mechanism
2724 m_addressForwardTimer[networkKey].Schedule(Time(2 * m_sendRetries * m_nodeTraversalTime));
2725 }
2726}
2727
2728void
2730{
2731 NS_LOG_FUNCTION(this << (uint32_t)protocol);
2732 Ipv4Address nextHop = mb.GetNextHop();
2733 Ptr<const Packet> packet = mb.GetPacket();
2734 SetRoute(nextHop, m_mainAddress);
2735 Ptr<Packet> p = packet->Copy();
2736
2737 LinkKey lk;
2738 lk.m_source = mb.GetSrc();
2739 lk.m_destination = mb.GetDst();
2740 lk.m_ourAdd = mb.GetOurAdd();
2741 lk.m_nextHop = mb.GetNextHop();
2742
2743 // Cancel passive ack timer
2744 m_linkAckTimer[lk].Cancel();
2745 if (m_linkAckTimer[lk].IsRunning())
2746 {
2747 NS_LOG_DEBUG("Timer not canceled");
2748 }
2749 m_linkAckTimer.erase(lk);
2750
2751 // Increase the send retry times
2754 {
2755 m_linkCnt[lk] = ++m_linkRetries;
2756 ScheduleLinkPacketRetry(mb, protocol);
2757 }
2758 else
2759 {
2760 NS_LOG_INFO("We need to send error messages now");
2761
2762 // Delete all the routes including the links
2763 m_routeCache->DeleteAllRoutesIncludeLink(m_mainAddress, nextHop, m_mainAddress);
2764 /*
2765 * here we cancel the packet retransmission time for all the packets have next hop address
2766 * as nextHop Also salvage the packet for the all the packet destined for the nextHop
2767 * address this is also responsible for send unreachable error back to source
2768 */
2769 CancelPacketTimerNextHop(nextHop, protocol);
2770 }
2771}
2772
2773void
2775{
2776 NS_LOG_FUNCTION(this << (uint32_t)protocol);
2777 Ipv4Address nextHop = mb.GetNextHop();
2778 Ptr<const Packet> packet = mb.GetPacket();
2779 SetRoute(nextHop, m_mainAddress);
2780 Ptr<Packet> p = packet->Copy();
2781
2782 PassiveKey pk;
2783 pk.m_ackId = 0;
2784 pk.m_source = mb.GetSrc();
2785 pk.m_destination = mb.GetDst();
2786 pk.m_segsLeft = mb.GetSegsLeft();
2787
2788 // Cancel passive ack timer
2789 m_passiveAckTimer[pk].Cancel();
2790 if (m_passiveAckTimer[pk].IsRunning())
2791 {
2792 NS_LOG_DEBUG("Timer not canceled");
2793 }
2794 m_passiveAckTimer.erase(pk);
2795
2796 // Increase the send retry times
2799 {
2801 SchedulePassivePacketRetry(mb, protocol);
2802 }
2803 else
2804 {
2805 // This is the first network acknowledgement retry
2806 // Cancel the passive packet timer now and remove maintenance buffer entry for it
2808 ScheduleNetworkPacketRetry(mb, true, protocol);
2809 }
2810}
2811
2812int64_t
2814{
2815 NS_LOG_FUNCTION(this << stream);
2817 return 1;
2818}
2819
2820void
2822{
2823 Ptr<Packet> p = mb.GetPacket()->Copy();
2824 Ipv4Address source = mb.GetSrc();
2825 Ipv4Address nextHop = mb.GetNextHop();
2826 Ipv4Address dst = mb.GetDst();
2827
2828 NetworkKey networkKey;
2829 networkKey.m_ackId = mb.GetAckId();
2830 networkKey.m_ourAdd = mb.GetOurAdd();
2831 networkKey.m_nextHop = nextHop;
2832 networkKey.m_source = source;
2833 networkKey.m_destination = dst;
2834
2835 // Increase the send retry times
2836 m_sendRetries = m_addressForwardCnt[networkKey];
2837
2839 {
2840 // Delete all the routes including the links
2841 m_routeCache->DeleteAllRoutesIncludeLink(m_mainAddress, nextHop, m_mainAddress);
2842 /*
2843 * here we cancel the packet retransmission time for all the packets have next hop address
2844 * as nextHop Also salvage the packet for the all the packet destined for the nextHop
2845 * address
2846 */
2847 CancelPacketTimerNextHop(nextHop, protocol);
2848 }
2849 else
2850 {
2851 m_addressForwardCnt[networkKey] = ++m_sendRetries;
2852 ScheduleNetworkPacketRetry(mb, false, protocol);
2853 }
2854}
2855
2856void
2858 DsrOptionSRHeader& sourceRoute,
2859 const Ipv4Header& ipv4Header,
2860 Ipv4Address source,
2861 Ipv4Address nextHop,
2862 Ipv4Address targetAddress,
2863 uint8_t protocol,
2864 Ptr<Ipv4Route> route)
2865{
2866 NS_LOG_FUNCTION(this << packet << sourceRoute << source << nextHop << targetAddress
2867 << (uint32_t)protocol << route);
2868 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
2869
2870 DsrRoutingHeader dsrRoutingHeader;
2871 dsrRoutingHeader.SetNextHeader(protocol);
2872 dsrRoutingHeader.SetMessageType(2);
2873 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
2874 dsrRoutingHeader.SetDestId(GetIDfromIP(targetAddress));
2875
2876 // We get the salvage value in sourceRoute header and set it to route error header if triggered
2877 // error
2878 Ptr<Packet> p = packet->Copy();
2879 uint8_t length = sourceRoute.GetLength();
2880 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
2881 dsrRoutingHeader.AddDsrOption(sourceRoute);
2882 p->AddHeader(dsrRoutingHeader);
2883
2884 Ptr<const Packet> mtP = p->Copy();
2885
2886 DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
2887 /*ourAddress=*/m_mainAddress,
2888 /*nextHop=*/nextHop,
2889 /*src=*/source,
2890 /*dst=*/targetAddress,
2891 /*ackId=*/m_ackId,
2892 /*segsLeft=*/sourceRoute.GetSegmentsLeft(),
2893 /*expire=*/m_maxMaintainTime);
2894 bool result = m_maintainBuffer.Enqueue(newEntry);
2895
2896 if (result)
2897 {
2898 NetworkKey networkKey;
2899 networkKey.m_ackId = newEntry.GetAckId();
2900 networkKey.m_ourAdd = newEntry.GetOurAdd();
2901 networkKey.m_nextHop = newEntry.GetNextHop();
2902 networkKey.m_source = newEntry.GetSrc();
2903 networkKey.m_destination = newEntry.GetDst();
2904
2905 PassiveKey passiveKey;
2906 passiveKey.m_ackId = 0;
2907 passiveKey.m_source = newEntry.GetSrc();
2908 passiveKey.m_destination = newEntry.GetDst();
2909 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
2910
2911 LinkKey linkKey;
2912 linkKey.m_source = newEntry.GetSrc();
2913 linkKey.m_destination = newEntry.GetDst();
2914 linkKey.m_ourAdd = newEntry.GetOurAdd();
2915 linkKey.m_nextHop = newEntry.GetNextHop();
2916
2917 m_addressForwardCnt[networkKey] = 0;
2918 m_passiveCnt[passiveKey] = 0;
2919 m_linkCnt[linkKey] = 0;
2920
2921 if (m_linkAck)
2922 {
2923 ScheduleLinkPacketRetry(newEntry, protocol);
2924 }
2925 else
2926 {
2927 NS_LOG_LOGIC("Not using link acknowledgment");
2928 if (nextHop != targetAddress)
2929 {
2930 SchedulePassivePacketRetry(newEntry, protocol);
2931 }
2932 else
2933 {
2934 // This is the first network retry
2935 ScheduleNetworkPacketRetry(newEntry, true, protocol);
2936 }
2937 }
2938 }
2939}
2940
2941void
2942DsrRouting::SendInitialRequest(Ipv4Address source, Ipv4Address destination, uint8_t protocol)
2943{
2944 NS_LOG_FUNCTION(this << source << destination << (uint32_t)protocol);
2945 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
2946 Ptr<Packet> packet = Create<Packet>();
2947 // Create an empty Ipv4 route ptr
2948 Ptr<Ipv4Route> route;
2949 /*
2950 * Construct the route request option header
2951 */
2952 DsrRoutingHeader dsrRoutingHeader;
2953 dsrRoutingHeader.SetNextHeader(protocol);
2954 dsrRoutingHeader.SetMessageType(1);
2955 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
2956 dsrRoutingHeader.SetDestId(255);
2957
2958 DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
2959 rreqHeader.AddNodeAddress(m_mainAddress); // Add our own address in the header
2960 rreqHeader.SetTarget(destination);
2961 m_requestId =
2962 m_rreqTable->CheckUniqueRreqId(destination); // Check the Id cache for duplicate ones
2963 rreqHeader.SetId(m_requestId);
2964
2965 dsrRoutingHeader.AddDsrOption(rreqHeader); // Add the rreqHeader to the dsr extension header
2966 uint8_t length = rreqHeader.GetLength();
2967 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
2968 packet->AddHeader(dsrRoutingHeader);
2969
2970 // Schedule the route requests retry with non-propagation set true
2971 bool nonProp = true;
2972 std::vector<Ipv4Address> address;
2973 address.push_back(source);
2974 address.push_back(destination);
2975 /*
2976 * Add the socket ip ttl tag to the packet to limit the scope of route requests
2977 */
2978 SocketIpTtlTag tag;
2979 tag.SetTtl(0);
2980 Ptr<Packet> nonPropPacket = packet->Copy();
2981 nonPropPacket->AddPacketTag(tag);
2982 // Increase the request count
2983 m_rreqTable->FindAndUpdate(destination);
2984 SendRequest(nonPropPacket, source);
2985 // Schedule the next route request
2986 ScheduleRreqRetry(packet, address, nonProp, m_requestId, protocol);
2987}
2988
2989void
2991{
2992 NS_LOG_FUNCTION(this << (uint32_t)protocol);
2993 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
2994 uint8_t salvage = rerr.GetSalvage();
2995 Ipv4Address dst = rerr.GetOriginalDst();
2996 NS_LOG_DEBUG("our own address here " << m_mainAddress << " error source " << rerr.GetErrorSrc()
2997 << " error destination " << rerr.GetErrorDst()
2998 << " error next hop " << rerr.GetUnreachNode()
2999 << " original dst " << rerr.GetOriginalDst());
3000 DsrRouteCacheEntry toDst;
3001 if (m_routeCache->LookupRoute(dst, toDst))
3002 {
3003 /*
3004 * Found a route the dst, construct the source route option header
3005 */
3006 DsrOptionSRHeader sourceRoute;
3007 std::vector<Ipv4Address> ip = toDst.GetVector();
3008 sourceRoute.SetNodesAddress(ip);
3010 if (m_routeCache->IsLinkCache())
3011 {
3012 m_routeCache->UseExtends(ip);
3013 }
3014 sourceRoute.SetSegmentsLeft((ip.size() - 2));
3015 sourceRoute.SetSalvage(salvage);
3016 Ipv4Address nextHop = SearchNextHop(m_mainAddress, ip); // Get the next hop address
3017 NS_LOG_DEBUG("The nextHop address " << nextHop);
3018 Ptr<Packet> packet = Create<Packet>();
3019 if (nextHop == "0.0.0.0")
3020 {
3021 NS_LOG_DEBUG("Error next hop address");
3022 PacketNewRoute(packet, m_mainAddress, dst, protocol);
3023 return;
3024 }
3025 SetRoute(nextHop, m_mainAddress);
3026 CancelRreqTimer(dst, true);
3028 if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(dst))
3029 {
3030 SendPacketFromBuffer(sourceRoute, nextHop, protocol);
3031 }
3032 NS_LOG_LOGIC("Route to " << dst << " found");
3033 }
3034 else
3035 {
3036 NS_LOG_INFO("No route found, initiate route error request");
3037 Ptr<Packet> packet = Create<Packet>();
3038 Ipv4Address originalDst = rerr.GetOriginalDst();
3039 // Create an empty route ptr
3040 Ptr<Ipv4Route> route = nullptr;
3041 /*
3042 * Construct the route request option header
3043 */
3044 DsrRoutingHeader dsrRoutingHeader;
3045 dsrRoutingHeader.SetNextHeader(protocol);
3046 dsrRoutingHeader.SetMessageType(1);
3047 dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
3048 dsrRoutingHeader.SetDestId(255);
3049
3050 Ptr<Packet> dstP = Create<Packet>();
3051 DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
3052 rreqHeader.AddNodeAddress(m_mainAddress); // Add our own address in the header
3053 rreqHeader.SetTarget(originalDst);
3054 m_requestId =
3055 m_rreqTable->CheckUniqueRreqId(originalDst); // Check the Id cache for duplicate ones
3056 rreqHeader.SetId(m_requestId);
3057
3058 dsrRoutingHeader.AddDsrOption(rreqHeader); // Add the rreqHeader to the dsr extension header
3059 dsrRoutingHeader.AddDsrOption(rerr);
3060 uint8_t length = rreqHeader.GetLength() + rerr.GetLength();
3061 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
3062 dstP->AddHeader(dsrRoutingHeader);
3063 // Schedule the route requests retry, propagate the route request message as it contains
3064 // error
3065 bool nonProp = false;
3066 std::vector<Ipv4Address> address;
3067 address.push_back(m_mainAddress);
3068 address.push_back(originalDst);
3069 /*
3070 * Add the socket ip ttl tag to the packet to limit the scope of route requests
3071 */
3072 SocketIpTtlTag tag;
3073 tag.SetTtl((uint8_t)m_discoveryHopLimit);
3074 Ptr<Packet> propPacket = dstP->Copy();
3075 propPacket->AddPacketTag(tag);
3076
3077 if ((m_addressReqTimer.find(originalDst) == m_addressReqTimer.end()) &&
3078 (m_nonPropReqTimer.find(originalDst) == m_nonPropReqTimer.end()))
3079 {
3080 NS_LOG_INFO("Only when there is no existing route request time when the initial route "
3081 "request is scheduled");
3082 SendRequest(propPacket, m_mainAddress);
3083 ScheduleRreqRetry(dstP, address, nonProp, m_requestId, protocol);
3084 }
3085 else
3086 {
3087 NS_LOG_INFO("There is existing route request, find the existing route request entry");
3088 /*
3089 * Cancel the route request timer first before scheduling the route request
3090 * in this case, we do not want to remove the route request entry, so the isRemove value
3091 * is false
3092 */
3093 CancelRreqTimer(originalDst, false);
3094 ScheduleRreqRetry(dstP, address, nonProp, m_requestId, protocol);
3095 }
3096 }
3097}
3098
3099void
3101{
3102 NS_LOG_FUNCTION(this << dst << isRemove);
3103 // Cancel the non propagation request timer if found
3104 if (m_nonPropReqTimer.find(dst) == m_nonPropReqTimer.end())
3105 {
3106 NS_LOG_DEBUG("Did not find the non-propagation timer");
3107 }
3108 else
3109 {
3110 NS_LOG_DEBUG("did find the non-propagation timer");
3111 }
3112 m_nonPropReqTimer[dst].Cancel();
3113
3114 if (m_nonPropReqTimer[dst].IsRunning())
3115 {
3116 NS_LOG_DEBUG("Timer not canceled");
3117 }
3118 m_nonPropReqTimer.erase(dst);
3119
3120 // Cancel the address request timer if found
3121 if (m_addressReqTimer.find(dst) == m_addressReqTimer.end())
3122 {
3123 NS_LOG_DEBUG("Did not find the propagation timer");
3124 }
3125 else
3126 {
3127 NS_LOG_DEBUG("did find the propagation timer");
3128 }
3129 m_addressReqTimer[dst].Cancel();
3130 if (m_addressReqTimer[dst].IsRunning())
3131 {
3132 NS_LOG_DEBUG("Timer not canceled");
3133 }
3134 m_addressReqTimer.erase(dst);
3135 /*
3136 * If the route request is scheduled to remove the route request entry
3137 * Remove the route request entry with the route retry times done for certain destination
3138 */
3139 if (isRemove)
3140 {
3141 // remove the route request entry from route request table
3142 m_rreqTable->RemoveRreqEntry(dst);
3143 }
3144}
3145
3146void
3148 std::vector<Ipv4Address> address,
3149 bool nonProp,
3150 uint32_t requestId,
3151 uint8_t protocol)
3152{
3153 NS_LOG_FUNCTION(this << packet << nonProp << requestId << (uint32_t)protocol);
3154 Ipv4Address source = address[0];
3155 Ipv4Address dst = address[1];
3156 if (nonProp)
3157 {
3158 // The nonProp route request is only sent out only and is already used
3159 if (m_nonPropReqTimer.find(dst) == m_nonPropReqTimer.end())
3160 {
3162 m_nonPropReqTimer[dst] = timer;
3163 }
3164 std::vector<Ipv4Address> address;
3165 address.push_back(source);
3166 address.push_back(dst);
3168 m_nonPropReqTimer[dst].Cancel();
3169 m_nonPropReqTimer[dst].SetArguments(packet, address, requestId, protocol);
3171 }
3172 else
3173 {
3174 // Cancel the non propagation request timer if found
3175 m_nonPropReqTimer[dst].Cancel();
3176 if (m_nonPropReqTimer[dst].IsRunning())
3177 {
3178 NS_LOG_DEBUG("Timer not canceled");
3179 }
3180 m_nonPropReqTimer.erase(dst);
3181
3182 if (m_addressReqTimer.find(dst) == m_addressReqTimer.end())
3183 {
3185 m_addressReqTimer[dst] = timer;
3186 }
3187 std::vector<Ipv4Address> address;
3188 address.push_back(source);
3189 address.push_back(dst);
3191 m_addressReqTimer[dst].Cancel();
3192 m_addressReqTimer[dst].SetArguments(packet, address, requestId, protocol);
3193 Time rreqDelay;
3194 // back off mechanism for sending route requests
3195 if (m_rreqTable->GetRreqCnt(dst))
3196 {
3197 // When the route request count is larger than 0
3198 // This is the exponential back-off mechanism for route request
3199 rreqDelay = Time(std::pow(static_cast<double>(m_rreqTable->GetRreqCnt(dst)), 2.0) *
3201 }
3202 else
3203 {
3204 // This is the first route request retry
3205 rreqDelay = m_requestPeriod;
3206 }
3207 NS_LOG_LOGIC("Request count for " << dst << " " << m_rreqTable->GetRreqCnt(dst)
3208 << " with delay time " << rreqDelay.As(Time::S));
3209 if (rreqDelay > m_maxRequestPeriod)
3210 {
3211 // use the max request period
3212 NS_LOG_LOGIC("The max request delay time " << m_maxRequestPeriod.As(Time::S));
3214 }
3215 else
3216 {
3217 NS_LOG_LOGIC("The request delay time " << rreqDelay.As(Time::S));
3218 m_addressReqTimer[dst].Schedule(rreqDelay);
3219 }
3220 }
3221}
3222
3223void
3225 std::vector<Ipv4Address> address,
3226 uint32_t requestId,
3227 uint8_t protocol)
3228{
3229 NS_LOG_FUNCTION(this << packet << requestId << (uint32_t)protocol);
3230 // Get a clean packet without dsr header
3231 Ptr<Packet> dsrP = packet->Copy();
3232 DsrRoutingHeader dsrRoutingHeader;
3233 dsrP->RemoveHeader(dsrRoutingHeader); // Remove the dsr header in whole
3234
3235 Ipv4Address source = address[0];
3236 Ipv4Address dst = address[1];
3237 DsrRouteCacheEntry toDst;
3238 if (m_routeCache->LookupRoute(dst, toDst))
3239 {
3240 /*
3241 * Found a route the dst, construct the source route option header
3242 */
3243 DsrOptionSRHeader sourceRoute;
3244 std::vector<Ipv4Address> ip = toDst.GetVector();
3245 sourceRoute.SetNodesAddress(ip);
3246 // When we found the route and use it, UseExtends for the link cache
3247 if (m_routeCache->IsLinkCache())
3248 {
3249 m_routeCache->UseExtends(ip);
3250 }
3251 sourceRoute.SetSegmentsLeft((ip.size() - 2));
3253 sourceRoute.SetSalvage(0);
3254 Ipv4Address nextHop = SearchNextHop(m_mainAddress, ip); // Get the next hop address
3255 NS_LOG_INFO("The nextHop address is " << nextHop);
3256 if (nextHop == "0.0.0.0")
3257 {
3258 NS_LOG_DEBUG("Error next hop address");
3259 PacketNewRoute(dsrP, source, dst, protocol);
3260 return;
3261 }
3262 SetRoute(nextHop, m_mainAddress);
3263 CancelRreqTimer(dst, true);
3265 if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(dst))
3266 {
3267 SendPacketFromBuffer(sourceRoute, nextHop, protocol);
3268 }
3269 NS_LOG_LOGIC("Route to " << dst << " found");
3270 return;
3271 }
3272 /*
3273 * If a route discovery has been attempted m_rreqRetries times at the maximum TTL without
3274 * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
3275 * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the
3276 * application.
3277 */
3278 NS_LOG_LOGIC("The new request count for " << dst << " is " << m_rreqTable->GetRreqCnt(dst)
3279 << " the max " << m_rreqRetries);
3280 if (m_rreqTable->GetRreqCnt(dst) >= m_rreqRetries)
3281 {
3282 NS_LOG_LOGIC("Route discovery to " << dst << " has been attempted " << m_rreqRetries
3283 << " times");
3284 CancelRreqTimer(dst, true);
3285 NS_LOG_DEBUG("Route not found. Drop packet with dst " << dst);
3287 }
3288 else
3289 {
3290 SocketIpTtlTag tag;
3291 tag.SetTtl((uint8_t)m_discoveryHopLimit);
3292 Ptr<Packet> propPacket = packet->Copy();
3293 propPacket->AddPacketTag(tag);
3294 // Increase the request count
3295 m_rreqTable->FindAndUpdate(dst);
3296 SendRequest(propPacket, source);
3297 NS_LOG_DEBUG("Check the route request entry " << source << " " << dst);
3298 ScheduleRreqRetry(packet, address, false, requestId, protocol);
3299 }
3300}
3301
3302void
3304{
3305 NS_LOG_FUNCTION(this << packet << source);
3306
3307 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
3308 /*
3309 * The destination address here is directed broadcast address
3310 */
3312 std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
3313 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3314 NS_LOG_LOGIC("Inserting into priority queue number: " << priority);
3315
3316 // m_downTarget (packet, source, m_broadcast, GetProtocolNumber (), 0);
3317
3319 DsrNetworkQueueEntry newEntry(packet, source, m_broadcast, Simulator::Now(), nullptr);
3320 if (dsrNetworkQueue->Enqueue(newEntry))
3321 {
3322 Scheduler(priority);
3323 }
3324 else
3325 {
3326 NS_LOG_INFO("Packet dropped as dsr network queue is full");
3327 }
3328}
3329
3330void
3332{
3333 NS_LOG_FUNCTION(this << packet);
3334 /*
3335 * This is a forwarding case when sending route requests, a random delay time [0,
3336 * m_broadcastJitter] used before forwarding as link-layer broadcast
3337 */
3340 this,
3341 packet,
3343}
3344
3345void
3347 Ipv4Address srcAddress,
3348 std::vector<Ipv4Address>& nodeList,
3349 uint8_t protocol)
3350{
3351 NS_LOG_FUNCTION(this << source << srcAddress << (uint32_t)protocol);
3352 if (!(m_graReply.FindAndUpdate(source,
3353 srcAddress,
3354 m_gratReplyHoldoff))) // Find the gratuitous reply entry
3355 {
3356 NS_LOG_LOGIC("Update gratuitous reply " << source);
3357 GraReplyEntry graReplyEntry(source, srcAddress, m_gratReplyHoldoff + Simulator::Now());
3358 m_graReply.AddEntry(graReplyEntry);
3359 /*
3360 * Automatic route shortening
3361 */
3362 m_finalRoute.clear(); // Clear the final route vector
3366 std::vector<Ipv4Address>::iterator before =
3367 find(nodeList.begin(), nodeList.end(), srcAddress);
3368 for (std::vector<Ipv4Address>::iterator i = nodeList.begin(); i != before; ++i)
3369 {
3370 m_finalRoute.push_back(*i);
3371 }
3372 m_finalRoute.push_back(srcAddress);
3373 std::vector<Ipv4Address>::iterator after =
3374 find(nodeList.begin(), nodeList.end(), m_mainAddress);
3375 for (std::vector<Ipv4Address>::iterator j = after; j != nodeList.end(); ++j)
3376 {
3377 m_finalRoute.push_back(*j);
3378 }
3380 rrep.SetNodesAddress(m_finalRoute); // Set the node addresses in the route reply header
3381 // Get the real reply source and destination
3382 Ipv4Address replySrc = m_finalRoute.back();
3383 Ipv4Address replyDst = m_finalRoute.front();
3384 /*
3385 * Set the route and use it in send back route reply
3386 */
3387 m_ipv4Route = SetRoute(srcAddress, m_mainAddress);
3388 /*
3389 * This part adds DSR header to the packet and send reply
3390 */
3391 DsrRoutingHeader dsrRoutingHeader;
3392 dsrRoutingHeader.SetNextHeader(protocol);
3393 dsrRoutingHeader.SetMessageType(1);
3394 dsrRoutingHeader.SetSourceId(GetIDfromIP(replySrc));
3395 dsrRoutingHeader.SetDestId(GetIDfromIP(replyDst));
3396
3397 uint8_t length =
3398 rrep.GetLength(); // Get the length of the rrep header excluding the type header
3399 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
3400 dsrRoutingHeader.AddDsrOption(rrep);
3401 Ptr<Packet> newPacket = Create<Packet>();
3402 newPacket->AddHeader(dsrRoutingHeader);
3403 /*
3404 * Send gratuitous reply
3405 */
3406 NS_LOG_INFO("Send back gratuitous route reply");
3407 SendReply(newPacket, m_mainAddress, srcAddress, m_ipv4Route);
3408 }
3409 else
3410 {
3411 NS_LOG_INFO("The same gratuitous route reply has already sent");
3412 }
3413}
3414
3415void
3417 Ipv4Address source,
3418 Ipv4Address nextHop,
3419 Ptr<Ipv4Route> route)
3420{
3421 NS_LOG_FUNCTION(this << packet << source << nextHop);
3422 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
3423
3424 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(m_mainAddress));
3425 route->SetOutputDevice(dev);
3426 NS_LOG_INFO("The output device " << dev << " packet is: " << *packet);
3427
3429 std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
3430 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3431 NS_LOG_INFO("Inserting into priority queue number: " << priority);
3432
3433 // m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
3434
3436 DsrNetworkQueueEntry newEntry(packet, source, nextHop, Simulator::Now(), route);
3437 if (dsrNetworkQueue->Enqueue(newEntry))
3438 {
3439 Scheduler(priority);
3440 }
3441 else
3442 {
3443 NS_LOG_INFO("Packet dropped as dsr network queue is full");
3444 }
3445}
3446
3447void
3449 Ipv4Address source,
3450 Ipv4Address nextHop,
3451 Ptr<Ipv4Route> route)
3452{
3453 NS_LOG_FUNCTION(this << packet << source << nextHop);
3454 Simulator::ScheduleNow(&DsrRouting::SendReply, this, packet, source, nextHop, route);
3455}
3456
3457void
3459 Ipv4Address source,
3460 Ipv4Address destination,
3461 Ptr<Ipv4Route> route,
3462 double hops)
3463{
3464 NS_LOG_FUNCTION(this << packet << source << destination);
3466 Time(2 * m_nodeTraversalTime * (hops - 1 + m_uniformRandomVariable->GetValue(0, 1))),
3468 this,
3469 packet,
3470 source,
3471 destination,
3472 route);
3473}
3474
3475void
3476DsrRouting::SendAck(uint16_t ackId,
3477 Ipv4Address destination,
3478 Ipv4Address realSrc,
3479 Ipv4Address realDst,
3480 uint8_t protocol,
3481 Ptr<Ipv4Route> route)
3482{
3483 NS_LOG_FUNCTION(this << ackId << destination << realSrc << realDst << (uint32_t)protocol
3484 << route);
3485 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
3486
3487 // This is a route reply option header
3488 DsrRoutingHeader dsrRoutingHeader;
3489 dsrRoutingHeader.SetNextHeader(protocol);
3490 dsrRoutingHeader.SetMessageType(1);
3491 dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
3492 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
3493
3495 /*
3496 * Set the ack Id and set the ack source address and destination address
3497 */
3498 ack.SetAckId(ackId);
3499 ack.SetRealSrc(realSrc);
3500 ack.SetRealDst(realDst);
3501
3502 uint8_t length = ack.GetLength();
3503 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
3504 dsrRoutingHeader.AddDsrOption(ack);
3505
3506 Ptr<Packet> packet = Create<Packet>();
3507 packet->AddHeader(dsrRoutingHeader);
3508 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
3509 route->SetOutputDevice(dev);
3510
3512 std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
3513 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3514
3515 NS_LOG_LOGIC("Will be inserting into priority queue " << dsrNetworkQueue
3516 << " number: " << priority);
3517
3518 // m_downTarget (packet, m_mainAddress, destination, GetProtocolNumber (), route);
3519
3521 DsrNetworkQueueEntry newEntry(packet, m_mainAddress, destination, Simulator::Now(), route);
3522 if (dsrNetworkQueue->Enqueue(newEntry))
3523 {
3524 Scheduler(priority);
3525 }
3526 else
3527 {
3528 NS_LOG_INFO("Packet dropped as dsr network queue is full");
3529 }
3530}
3531
3534{
3535 NS_LOG_FUNCTION(this << p << ip << incomingInterface);
3536
3537 NS_LOG_INFO("Our own IP address " << m_mainAddress << " The incoming interface address "
3538 << incomingInterface);
3539 m_node = GetNode(); // Get the node
3540 Ptr<Packet> packet = p->Copy(); // Save a copy of the received packet
3541 /*
3542 * When forwarding or local deliver packets, this one should be used always!!
3543 */
3544 DsrRoutingHeader dsrRoutingHeader;
3545 packet->RemoveHeader(dsrRoutingHeader); // Remove the DSR header in whole
3546 Ptr<Packet> copy = packet->Copy();
3547
3548 uint8_t protocol = dsrRoutingHeader.GetNextHeader();
3549 uint32_t sourceId = dsrRoutingHeader.GetSourceId();
3550 Ipv4Address source = GetIPfromID(sourceId);
3551 NS_LOG_INFO("The source address " << source << " with source id " << sourceId);
3552 /*
3553 * Get the IP source and destination address
3554 */
3555 Ipv4Address src = ip.GetSource();
3556
3557 bool isPromisc = false;
3558 uint32_t offset =
3559 dsrRoutingHeader
3560 .GetDsrOptionsOffset(); // Get the offset for option header, 8 bytes in this case
3561
3562 // This packet is used to peek option type
3563 p->RemoveAtStart(offset);
3564
3565 Ptr<dsr::DsrOptions> dsrOption;
3566 DsrOptionHeader dsrOptionHeader;
3567 /*
3568 * Peek data to get the option type as well as length and segmentsLeft field
3569 */
3570 uint32_t size = p->GetSize();
3571 uint8_t* data = new uint8_t[size];
3572 p->CopyData(data, size);
3573
3574 uint8_t optionType = 0;
3575 uint8_t optionLength = 0;
3576 uint8_t segmentsLeft = 0;
3577
3578 optionType = *(data);
3579 NS_LOG_LOGIC("The option type value " << (uint32_t)optionType << " with packet id "
3580 << p->GetUid());
3581 dsrOption =
3582 GetOption(optionType); // Get the relative dsr option and demux to the process function
3583 Ipv4Address promiscSource;
3584 if (optionType == 1) // This is the request option
3585 {
3586 BlackList* blackList = m_rreqTable->FindUnidirectional(src);
3587 if (blackList)
3588 {
3589 NS_LOG_INFO("Discard this packet due to unidirectional link");
3590 m_dropTrace(p);
3591 }
3592
3593 dsrOption = GetOption(optionType);
3594 optionLength =
3595 dsrOption
3596 ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3597
3598 if (optionLength == 0)
3599 {
3600 NS_LOG_INFO("Discard this packet");
3601 m_dropTrace(p);
3602 }
3603 }
3604 else if (optionType == 2)
3605 {
3606 dsrOption = GetOption(optionType);
3607 optionLength =
3608 dsrOption
3609 ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3610
3611 if (optionLength == 0)
3612 {
3613 NS_LOG_INFO("Discard this packet");
3614 m_dropTrace(p);
3615 }
3616 }
3617
3618 else if (optionType == 32) // This is the ACK option
3619 {
3620 NS_LOG_INFO("This is the ack option");
3621 dsrOption = GetOption(optionType);
3622 optionLength =
3623 dsrOption
3624 ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3625
3626 if (optionLength == 0)
3627 {
3628 NS_LOG_INFO("Discard this packet");
3629 m_dropTrace(p);
3630 }
3631 }
3632
3633 else if (optionType == 3) // This is a route error header
3634 {
3635 // populate this route error
3636 NS_LOG_INFO("The option type value " << (uint32_t)optionType);
3637
3638 dsrOption = GetOption(optionType);
3639 optionLength =
3640 dsrOption
3641 ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3642
3643 if (optionLength == 0)
3644 {
3645 NS_LOG_INFO("Discard this packet");
3646 m_dropTrace(p);
3647 }
3648 NS_LOG_INFO("The option Length " << (uint32_t)optionLength);
3649 }
3650
3651 else if (optionType == 96) // This is the source route option
3652 {
3653 dsrOption = GetOption(optionType);
3654 optionLength =
3655 dsrOption
3656 ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3657 segmentsLeft = data[3];
3658 if (optionLength == 0)
3659 {
3660 NS_LOG_INFO("Discard this packet");
3661 m_dropTrace(p);
3662 }
3663 else
3664 {
3665 if (segmentsLeft == 0)
3666 {
3667 // / Get the next header
3668 uint8_t nextHeader = dsrRoutingHeader.GetNextHeader();
3670 Ptr<IpL4Protocol> nextProto = l3proto->GetProtocol(nextHeader);
3671 if (!nextProto)
3672 {
3673 NS_FATAL_ERROR("Should not have 0 next protocol value");
3674 }
3675
3676 // we need to make a copy in the unlikely event we hit the
3677 // RX_ENDPOINT_UNREACH code path
3678 // Here we can use the packet that has been get off whole DSR header
3679 IpL4Protocol::RxStatus status = nextProto->Receive(copy, ip, incomingInterface);
3680 NS_LOG_DEBUG("The receive status " << status);
3681 switch (status)
3682 {
3684 // fall through
3686 // fall through
3688 break;
3691 {
3692 break; // Do not reply to broadcast or multicast
3693 }
3694 // Another case to suppress ICMP is a subnet-directed broadcast
3695 }
3696 return status;
3697 }
3698 else
3699 {
3700 NS_LOG_INFO("This is not the final destination, the packet has already been "
3701 "forward to next hop");
3702 }
3703 }
3704 }
3705 else
3706 {
3707 NS_LOG_LOGIC("Unknown Option. Drop!");
3708 /*
3709 * Initialize the salvage value to 0
3710 */
3711 uint8_t salvage = 0;
3712
3713 DsrOptionRerrUnsupportedHeader rerrUnsupportedHeader;
3714 rerrUnsupportedHeader.SetErrorType(3); // The error type 3 means Option not supported
3715 rerrUnsupportedHeader.SetErrorSrc(
3716 m_mainAddress); // The error source address is our own address
3717 rerrUnsupportedHeader.SetUnsupported(optionType); // The unsupported option type number
3718 rerrUnsupportedHeader.SetErrorDst(
3719 src); // Error destination address is the destination of the data packet
3720 rerrUnsupportedHeader.SetSalvage(
3721 salvage); // Set the value about whether to salvage a packet or not
3722
3723 /*
3724 * The unknown option error is not supported currently in this implementation, and it's also
3725 * not likely to happen in simulations
3726 */
3727 // SendError (rerrUnsupportedHeader, 0, protocol); // Send the error packet
3728 }
3729 return IpL4Protocol::RX_OK;
3730}
3731
3734{
3735 NS_LOG_FUNCTION(this << p << ip.GetSource() << ip.GetDestination() << incomingInterface);
3737}
3738
3739void
3741{
3742 m_downTarget = callback;
3743}
3744
3745void
3747{
3748 NS_FATAL_ERROR("Unimplemented");
3749}
3750
3753{
3754 return m_downTarget;
3755}
3756
3759{
3760 NS_FATAL_ERROR("Unimplemented");
3761 return MakeNullCallback<void, Ptr<Packet>, Ipv6Address, Ipv6Address, uint8_t, Ptr<Ipv6Route>>();
3762}
3763
3764void
3766{
3767 m_options.push_back(option);
3768}
3769
3771DsrRouting::GetOption(int optionNumber)
3772{
3773 for (DsrOptionList_t::iterator i = m_options.begin(); i != m_options.end(); ++i)
3774 {
3775 if ((*i)->GetOptionNumber() == optionNumber)
3776 {
3777 return *i;
3778 }
3779 }
3780 return nullptr;
3781}
3782} /* namespace dsr */
3783} /* namespace ns3 */
a polymophic address class
Definition: address.h:100
Wifi MAC high model for an ad-hoc Wifi MAC.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
L4 Protocol abstract base class.
RxStatus
Rx status codes.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
bool IsMulticast() const
bool IsBroadcast() const
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetSource() const
Definition: ipv4-header.cc:302
uint8_t GetProtocol() const
Definition: ipv4-header.cc:281
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:79
Implement the IPv4 layer.
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route) override
Describes an IPv6 address.
Definition: ipv6-address.h:49
Packet header for IPv6.
Definition: ipv6-header.h:35
Ipv6Address GetDestination() const
Get the "Destination address" field.
Definition: ipv6-header.cc:124
Ipv6Address GetSource() const
Get the "Source address" field.
Definition: ipv6-header.cc:112
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address ConvertFrom(const Address &address)
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition: net-device.h:307
static uint32_t GetNNodes()
Definition: node-list.cc:258
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:251
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:332
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
Maintain the event list.
Definition: scheduler.h:157
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:606
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition: socket.h:1122
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:602
Hold variables of type string.
Definition: string.h:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
@ S
second
Definition: nstime.h:116
AttributeValue implementation for Time.
Definition: nstime.h:1423
A simple virtual Timer class.
Definition: timer.h:74
void SetFunction(FN fn)
Definition: timer.h:275
@ CANCEL_ON_DESTROY
This policy cancels the event from the destructor of the Timer or from Suspend().
Definition: timer.h:93
void Cancel()
Cancel the currently-running event if there is one.
Definition: timer.cc:108
bool IsSuspended() const
Definition: timer.cc:136
void Schedule()
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:162
void Resume()
Restart the timer to expire within the amount of time left saved during Suspend.
Definition: timer.cc:198
bool IsRunning() const
Definition: timer.cc:129
void Suspend()
Pause the timer and save the amount of time left until it was set to expire.
Definition: timer.cc:181
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value drawn from the distribution.
Hold together all Wifi-related objects.
DSR Error Buffer Entry.
Definition: dsr-errorbuff.h:48
Ptr< const Packet > GetPacket() const
Get packet from entry.
Definition: dsr-errorbuff.h:91
void SetMaxQueueLen(uint32_t len)
Set maximum queue length.
bool Enqueue(DsrErrorBuffEntry &entry)
Push entry in queue, if there is no entry with the same packet and destination address in queue.
bool Dequeue(Ipv4Address dst, DsrErrorBuffEntry &entry)
Return first found (the earliest) entry for given destination.
bool Find(Ipv4Address dst)
Finds whether a packet with destination dst exists in the queue.
void DropPacketForErrLink(Ipv4Address source, Ipv4Address nextHop)
Remove all packets with the error link.
void SetErrorBufferTimeout(Time t)
Set error buffer timeout.
uint32_t GetSize()
Returns the number of entries in the queue.
void SetSourceId(uint16_t sourceId)
brief Set the source ID of the header.
void SetNextHeader(uint8_t protocol)
Set the "Next header" field.
void SetDestId(uint16_t destId)
brief Set the dest ID of the header.
uint8_t GetMessageType() const
brief Get the message type of the header.
uint8_t GetNextHeader() const
Get the next header.
uint16_t GetSourceId() const
brief Get the source ID of the header.
uint16_t GetDestId() const
brief Get the dest ID of the header.
void SetMessageType(uint8_t messageType)
brief Set the message type of the header.
void SetPayloadLength(uint16_t length)
brief Set the payload length of the header.
bool AddEntry(GraReplyEntry &graTableEntry)
Add a new gratuitous reply entry.
void SetGraTableSize(uint32_t g)
Set the gratuitous reply table size.
bool FindAndUpdate(Ipv4Address replyTo, Ipv4Address replyFrom, Time gratReplyHoldoff)
Update the route entry if found.
DSR Maintain Buffer Entry.
uint8_t GetSegsLeft() const
Get segments left.
void SetDst(Ipv4Address n)
Set destination address.
void SetExpireTime(Time exp)
Set expiration time.
void SetNextHop(Ipv4Address n)
Set next hop of entry.
Ipv4Address GetSrc() const
Get source address.
void SetSegsLeft(uint8_t segs)
Set segments left.
void SetPacket(Ptr< const Packet > p)
Set packet.
Ptr< const Packet > GetPacket() const
Get packet.
void SetOurAdd(Ipv4Address us)
Set local address of entry.
void SetSrc(Ipv4Address s)
Set source address.
uint16_t GetAckId() const
Get acknowledge ID.
Ipv4Address GetOurAdd() const
Get local address of entry.
void SetAckId(uint16_t ackId)
Set acknowledge ID.
Ipv4Address GetNextHop() const
Get next hop of entry.
Ipv4Address GetDst() const
Get destination address.
bool Dequeue(Ipv4Address dst, DsrMaintainBuffEntry &entry)
Return first found (the earliest) entry for given destination.
void SetMaxQueueLen(uint32_t len)
Set maximum queue length.
bool AllEqual(DsrMaintainBuffEntry &entry)
Verify if all the elements in the maintenance buffer entry is the same.
bool LinkEqual(DsrMaintainBuffEntry &entry)
Verify if the maintain buffer entry is the same in every field for link ack.
bool Find(Ipv4Address nextHop)
Finds whether a packet with next hop dst exists in the queue.
void SetMaintainBufferTimeout(Time t)
Set maintain buffer timeout.
uint32_t GetSize()
Number of entries.
bool PromiscEqual(DsrMaintainBuffEntry &entry)
Verify if the maintain buffer entry is the same in every field for promiscuous ack.
bool NetworkEqual(DsrMaintainBuffEntry &entry)
Verify if the maintain buffer entry is the same in every field for network ack.
bool Enqueue(DsrMaintainBuffEntry &entry)
Push entry in queue, if there is no entry with the same packet and destination address in queue.
DSR Network Queue Entry.
Ptr< Ipv4Route > GetIpv4Route() const
Get IP route function.
Ptr< const Packet > GetPacket() const
Get packet function.
Ipv4Address GetSourceAddress() const
Get source address function.
Ipv4Address GetNextHopAddress() const
Get next hop address function.
Acknowledgement (ACK) Message Format.
void SetAckId(uint16_t identification)
Set the Ack id number.
void SetRealSrc(Ipv4Address realSrcAddress)
Set Error source ip address.
void SetRealDst(Ipv4Address realDstAddress)
Set Error source ip address.
Acknowledgement Request (ACK_RREQ) Message Format.
void SetAckId(uint16_t identification)
Set the Ack request id number.
void AddDsrOption(const DsrOptionHeader &option)
Serialize the option, prepending pad1 or padn option as necessary.
uint32_t GetDsrOptionsOffset() const
Get the offset where the options begin, measured from the start of the extension header.
Header for Dsr Options.
uint8_t GetLength() const
Get the option length.
void SetErrorType(uint8_t errorType)
Set the route error type.
Route Error (RERR) Unreachable node address option Message Format.
void SetOriginalDst(Ipv4Address originalDst)
Set the unreachable node ip address.
Ipv4Address GetErrorSrc() const override
Get the route error source address.
void SetErrorDst(Ipv4Address errorDstAddress) override
Set the error destination ip address.
void SetErrorSrc(Ipv4Address errorSrcAddress) override
Set the route error source address.
uint8_t GetSalvage() const override
Get the salvage value of the packet.
Ipv4Address GetOriginalDst() const
Get the unreachable node ip address.
void SetUnreachNode(Ipv4Address unreachNode)
Set the unreachable node ip address.
void SetSalvage(uint8_t salvage) override
Set the salvage value of the packet.
Ipv4Address GetUnreachNode() const
Get the unreachable node ip address.
Ipv4Address GetErrorDst() const override
Get the error destination ip address.
Route Error (RERR) Unsupported option Message Format.
void SetErrorSrc(Ipv4Address errorSrcAddress) override
Set the route error source address.
void SetSalvage(uint8_t salvage) override
Set the salvage value of the packet.
void SetUnsupported(uint16_t optionType)
Set the unsupported option type value.
void SetErrorDst(Ipv4Address errorDstAddress) override
Set the error destination ip address.
Route Reply (RREP) Message Format.
void SetNodesAddress(std::vector< Ipv4Address > ipv4Address)
Set the vector of ipv4 address.
Route Request (RREQ) Message Format.
void SetTarget(Ipv4Address target)
Set the target ipv4 address.
void AddNodeAddress(Ipv4Address ipv4)
Add one node address.
void SetId(uint16_t identification)
Set the request id number.
Source Route (SR) Message Format.
std::vector< Ipv4Address > GetNodesAddress() const
Get the vector of ipv4 address.
void SetNumberAddress(uint8_t n)
Set the number of ipv4 address.
void SetSalvage(uint8_t salvage)
Set the salvage value for a packet.
void SetSegmentsLeft(uint8_t segmentsLeft)
Set the number of segments left to send.
uint8_t GetSalvage() const
Get the salvage value for a packet.
void SetNodesAddress(std::vector< Ipv4Address > ipv4Address)
Set the vector of ipv4 address.
uint8_t GetSegmentsLeft() const
Get the number of segments left to send.
DSR Passive Buffer Entry.
void SetIdentification(uint16_t i)
Set identification function.
void SetDestination(Ipv4Address d)
Set destination address function.
void SetSegsLeft(uint8_t seg)
Set segments left.
void SetSource(Ipv4Address s)
Set surce address function.
void SetPacket(Ptr< const Packet > p)
Set packet function.
void SetFragmentOffset(uint16_t f)
Set fragment offset function.
DsrRouteCacheEntry class for entries in the route cache.
Definition: dsr-rcache.h:229
IP_VECTOR GetVector() const
Get the IP vector.
Definition: dsr-rcache.h:309
std::vector< Ipv4Address > IP_VECTOR
Define the vector to hold Ip address.
Definition: dsr-rcache.h:231
Header of Dsr Routing.
Dsr Routing base.
Definition: dsr-routing.h:98
Ptr< dsr::DsrRreqTable > GetRequestTable() const
Get the request table.
Definition: dsr-routing.cc:625
void ScheduleInterRequest(Ptr< Packet > packet)
Schedule the intermediate route request.
void CheckSendBuffer()
Check the send buffer of packets with route when send buffer timer expire.
Definition: dsr-routing.cc:864
Ptr< Ipv4 > m_ip
The ip ptr.
Definition: dsr-routing.h:794
void ScheduleRreqRetry(Ptr< Packet > packet, std::vector< Ipv4Address > address, bool nonProp, uint32_t requestId, uint8_t protocol)
Schedule the route request retry.
void NotifyNewAggregate() override
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: dsr-routing.cc:406
Time m_blacklistTimeout
The black list time out.
Definition: dsr-routing.h:863
std::string m_cacheType
The type of route cache.
Definition: dsr-routing.h:888
std::map< Ipv4Address, Timer > m_nonPropReqTimer
Map IP address + RREQ timer.
Definition: dsr-routing.h:910
IpL4Protocol::DownTargetCallback GetDownTarget() const override
This method allows a caller to get the current down target callback set for this L4 protocol (IPv4 ca...
void SetNode(Ptr< Node > node)
Set the node.
Definition: dsr-routing.cc:591
void SendBuffTimerExpire()
The send buffer timer expire.
Definition: dsr-routing.cc:853
void SetPassiveBuffer(Ptr< dsr::DsrPassiveBuffer > r)
Set the node.
Definition: dsr-routing.cc:632
std::vector< std::string > GetElementsFromContext(std::string context)
Get the elements from the tracing context.
Definition: dsr-routing.cc:549
void UseExtends(DsrRouteCacheEntry::IP_VECTOR rt)
Extends the lifetime of a route cache entry.
Definition: dsr-routing.cc:670
uint32_t m_maxRreqId
The max number of request ids for a single destination.
Definition: dsr-routing.h:861
bool SendRealDown(DsrNetworkQueueEntry &newEntry)
This function is called to send packets down stack.
Time m_sendBufferTimeout
The maximum period of time that a routing protocol is allowed to buffer a packet for.
Definition: dsr-routing.h:832
uint8_t segsLeft
The segment left value from SR header.
Definition: dsr-routing.h:800
void SendRequest(Ptr< Packet > packet, Ipv4Address source)
Forward the route request if the node is not the destination.
void CancelPacketTimerNextHop(Ipv4Address nextHop, uint8_t protocol)
Cancel the packet retransmission timer for a all maintenance entries with nextHop address.
bool m_linkAck
define if we use link acknowledgement or not
Definition: dsr-routing.h:935
void PrintVector(std::vector< Ipv4Address > &vec)
Print the route vector.
Definition: dsr-routing.cc:738
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
Definition: dsr-routing.h:950
void ForwardErrPacket(DsrOptionRerrUnreachHeader &rerr, DsrOptionSRHeader &sourceRoute, Ipv4Address nextHop, uint8_t protocol, Ptr< Ipv4Route > route)
This function is responsible for forwarding error packets along the route.
bool CancelPassiveTimer(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t segsLeft)
Cancel the passive timer.
IpL4Protocol::RxStatus Receive(Ptr< Packet > p, const Ipv4Header &header, Ptr< Ipv4Interface > incomingInterface) override
void PassiveScheduleTimerExpire(DsrMaintainBuffEntry &mb, uint8_t protocol)
This function deals with packet retransmission timer expire using passive acknowledgment.
bool AddRoute_Link(DsrRouteCacheEntry::IP_VECTOR nodelist, Ipv4Address source)
dd route link to cache See also DsrRouteCache::AddRoute_Link
Definition: dsr-routing.cc:682
uint16_t m_ackId
The ack id assigned to each acknowledge.
Definition: dsr-routing.h:855
DsrRouting()
Constructor.
Definition: dsr-routing.cc:364
void CancelLinkPacketTimer(DsrMaintainBuffEntry &mb)
Cancel the link packet retransmission timer for a specific maintenance entry.
Time m_nonpropRequestTimeout
The non-propagation request timeout.
Definition: dsr-routing.h:814
Time m_gratReplyHoldoff
The max gratuitous reply hold off time.
Definition: dsr-routing.h:882
uint16_t GetIDfromIP(Ipv4Address address)
Get the node id from ip address.
Definition: dsr-routing.cc:810
std::map< uint32_t, Ptr< dsr::DsrNetworkQueue > > m_priorityQueue
priority queues
Definition: dsr-routing.h:937
uint32_t m_maxEntriesEachDst
Max number of route entries to save for each destination.
Definition: dsr-routing.h:849
std::map< Ipv4Address, Timer > m_addressReqTimer
Map IP address + RREQ timer.
Definition: dsr-routing.h:908
Time m_retransIncr
the increase time for retransmission timer when face network congestion
Definition: dsr-routing.h:904
std::map< NetworkKey, Timer > m_addressForwardTimer
Map network key + forward timer.
Definition: dsr-routing.h:912
uint32_t m_stabilityDecrFactor
The initial decrease factor for link cache.
Definition: dsr-routing.h:892
Time m_nodeTraversalTime
Time estimated for packet to travel between two nodes.
Definition: dsr-routing.h:827
uint32_t m_requestId
The id assigned to each route request.
Definition: dsr-routing.h:853
std::map< NetworkKey, uint32_t > m_addressForwardCnt
Map network key + forward counts.
Definition: dsr-routing.h:914
Ptr< NetDevice > GetNetDeviceFromContext(std::string context)
Get the netdevice from the context.
Definition: dsr-routing.cc:537
bool FindSourceEntry(Ipv4Address src, Ipv4Address dst, uint16_t id)
Find the source request entry in the route request queue, return false if not found.
Definition: dsr-routing.cc:713
Ipv4Address m_broadcast
The broadcast IP address.
Definition: dsr-routing.h:865
Ptr< dsr::DsrPassiveBuffer > GetPassiveBuffer() const
Get the passive buffer.
Definition: dsr-routing.cc:639
Ipv4Address GetIPfromMAC(Mac48Address address)
Get the Ip address from mac address.
Definition: dsr-routing.cc:719
Ptr< dsr::DsrRouteCache > GetRouteCache() const
Get the route cache.
Definition: dsr-routing.cc:611
Time m_maxNetworkDelay
Maximum network delay.
Definition: dsr-routing.h:806
Ptr< dsr::DsrOptions > GetOption(int optionNumber)
Get the option corresponding to optionNumber.
uint32_t m_maxSendBuffLen
The maximum number of packets that we allow a routing protocol to buffer.
Definition: dsr-routing.h:829
Time m_passiveAckTimeout
The timeout value for passive acknowledge.
Definition: dsr-routing.h:869
void SetRequestTable(Ptr< dsr::DsrRreqTable > r)
Set the node.
Definition: dsr-routing.cc:618
uint32_t m_maxMaintainLen
Max # of entries for maintenance buffer.
Definition: dsr-routing.h:839
static const uint8_t PROT_NUMBER
Define the dsr protocol number.
Definition: dsr-routing.h:108
uint32_t GetPriority(DsrMessageType messageType)
Set the priority of the packet in network queue.
Definition: dsr-routing.cc:840
void SendReply(Ptr< Packet > packet, Ipv4Address source, Ipv4Address nextHop, Ptr< Ipv4Route > route)
Send the route reply back to the request originator with the cumulated route.
void ScheduleNetworkPacketRetry(DsrMaintainBuffEntry &mb, bool isFirst, uint8_t protocol)
Schedule the packet retransmission based on network layer acknowledgment.
Ipv4Address m_mainAddress
Our own Ip address.
Definition: dsr-routing.h:798
void SendInitialRequest(Ipv4Address source, Ipv4Address destination, uint8_t protocol)
Broadcast the route request packet in subnet.
Timer m_sendBuffTimer
The send buffer timer.
Definition: dsr-routing.h:878
Time m_maxCacheTime
Max time for caching the route cache entry.
Definition: dsr-routing.h:845
void SendGratuitousReply(Ipv4Address replyTo, Ipv4Address replyFrom, std::vector< Ipv4Address > &nodeList, uint8_t protocol)
Send the gratuitous reply.
void DeleteAllRoutesIncludeLink(Ipv4Address errorSrc, Ipv4Address unreachNode, Ipv4Address node)
Delete all the routes which includes the link from next hop address that has just been notified as un...
Definition: dsr-routing.cc:699
DsrOptionList_t m_options
List of DSR Options supported.
Definition: dsr-routing.h:788
std::map< PassiveKey, uint32_t > m_passiveCnt
Map packet key + passive forward counts.
Definition: dsr-routing.h:916
DsrErrorBuffer m_errorBuffer
The error buffer to save the error messages.
Definition: dsr-routing.h:837
void SalvagePacket(Ptr< const Packet > packet, Ipv4Address source, Ipv4Address dst, uint8_t protocol)
Salvage the packet which has been transmitted for 3 times.
bool m_subRoute
Whether to save sub route or not.
Definition: dsr-routing.h:902
void SendPacket(Ptr< Packet > packet, Ipv4Address source, Ipv4Address nextHop, uint8_t protocol)
This function is called by when really sending out the packet.
void SetDownTarget(IpL4Protocol::DownTargetCallback callback) override
This method allows a caller to set the current down target callback set for this L4 protocol (IPv4 ca...
bool IsLinkCache()
Checks if the link is cached in the route cache See also DsrRouteCache::IsLinkCache.
Definition: dsr-routing.cc:664
std::map< LinkKey, uint32_t > m_linkCnt
Map packet key + link forward counts.
Definition: dsr-routing.h:920
~DsrRouting() override
Destructor.
Definition: dsr-routing.cc:400
DsrSendBuffer m_sendBuffer
The send buffer.
Definition: dsr-routing.h:835
uint32_t m_passiveRetries
Definition: dsr-routing.h:818
uint32_t m_rreqRetries
Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route.
Definition: dsr-routing.h:822
uint8_t m_maxSalvageCount
Maximum # times to salvage a packet.
Definition: dsr-routing.h:810
Ptr< Ipv4Route > SetRoute(Ipv4Address nextHop, Ipv4Address srcAddress)
Set the route to use for data packets, used by the option headers when sending data/control packets.
Definition: dsr-routing.cc:792
uint16_t AddAckReqHeader(Ptr< Packet > &packet, Ipv4Address nextHop)
This function is called to add ack request header for network acknowledgement.
uint32_t m_requestTableSize
The max size of the request table size.
Definition: dsr-routing.h:857
DsrGraReply m_graReply
The gratuitous route reply.
Definition: dsr-routing.h:939
void ScheduleLinkPacketRetry(DsrMaintainBuffEntry &mb, uint8_t protocol)
Schedule the packet retransmission based on link-layer acknowledgment.
bool PromiscReceive(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Promiscuous receive data packets destined to some other node.
Time m_sendBuffInterval
how often to check send buffer
Definition: dsr-routing.h:880
TracedCallback< const DsrOptionSRHeader & > m_txPacketTrace
packet trace callback
Definition: dsr-routing.h:755
void ScheduleInitialReply(Ptr< Packet > packet, Ipv4Address source, Ipv4Address nextHop, Ptr< Ipv4Route > route)
this is a generating the initial route reply from the destination address, a random delay time [0,...
bool LookupRoute(Ipv4Address id, DsrRouteCacheEntry &rt)
Lookup route cache entry with destination address dst See also DsrRouteCache::LookupRoute.
Definition: dsr-routing.cc:676
Time m_initStability
The initial stability value for link cache.
Definition: dsr-routing.h:896
uint32_t m_stabilityIncrFactor
The initial increase factor for link cache.
Definition: dsr-routing.h:894
void SetDownTarget6(IpL4Protocol::DownTargetCallback6 callback) override
This method allows a caller to set the current down target callback set for this L4 protocol (IPv6 ca...
Time m_useExtends
The use extension of the life time for link cache.
Definition: dsr-routing.h:900
uint32_t m_numPriorityQueues
The number of priority queues used.
Definition: dsr-routing.h:933
Ipv4Address SearchNextHop(Ipv4Address ipv4Address, std::vector< Ipv4Address > &vec)
Get the next hop of the route.
Definition: dsr-routing.cc:759
IpL4Protocol::DownTargetCallback m_downTarget
The callback for down layer.
Definition: dsr-routing.h:802
uint32_t m_graReplyTableSize
Set the gratuitous reply table size.
Definition: dsr-routing.h:886
bool PassiveEntryCheck(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t segsLeft, uint16_t fragmentOffset, uint16_t identification, bool saveEntry)
Find the same passive entry.
Ptr< Node > GetNodeWithAddress(Ipv4Address ipv4Address)
Get the node with give ip address.
Definition: dsr-routing.cc:646
Ptr< Ipv4L3Protocol > m_ipv4
Ipv4l3Protocol.
Definition: dsr-routing.h:790
void Scheduler(uint32_t priority)
This function is called to schedule sending packets from the network queue.
void RouteRequestTimerExpire(Ptr< Packet > packet, std::vector< Ipv4Address > address, uint32_t requestId, uint8_t protocol)
Handle route discovery timer.
void NetworkScheduleTimerExpire(DsrMaintainBuffEntry &mb, uint8_t protocol)
This function deals with packet retransmission timer expire using network acknowledgment.
uint32_t m_requestTableIds
The request table identifiers.
Definition: dsr-routing.h:859
TracedCallback< Ptr< const Packet > > m_dropTrace
The trace for drop, receive and send data packets.
Definition: dsr-routing.h:754
void SendPacketFromBuffer(const DsrOptionSRHeader &sourceRoute, Ipv4Address nextHop, uint8_t protocol)
This function is responsible for sending out data packets when have route, if no route found,...
uint32_t m_tryPassiveAcks
Maximum number of packet transmission using passive acknowledgment.
Definition: dsr-routing.h:872
void LinkScheduleTimerExpire(DsrMaintainBuffEntry &mb, uint8_t protocol)
This function deals with packet retransmission timer expire using link acknowledgment.
bool UpdateRouteEntry(Ipv4Address dst)
Update route cache entry if it has been recently used and successfully delivered the data packet.
Definition: dsr-routing.cc:707
uint32_t m_maxNetworkSize
Maximum network queue size.
Definition: dsr-routing.h:804
Ptr< Ipv4Route > m_ipv4Route
Ipv4 Route.
Definition: dsr-routing.h:792
Ptr< Node > GetNode() const
Get the node.
Definition: dsr-routing.cc:597
Ipv4Address GetIPfromID(uint16_t id)
Get the ip address from id.
Definition: dsr-routing.cc:826
Time m_maxRequestPeriod
The max request period.
Definition: dsr-routing.h:884
void SchedulePassivePacketRetry(DsrMaintainBuffEntry &mb, uint8_t protocol)
Schedule the packet retransmission based on passive acknowledgment.
Ptr< dsr::DsrPassiveBuffer > m_passiveBuffer
A "drop-front" queue used by the routing layer to cache route request sent.
Definition: dsr-routing.h:930
Ptr< Node > m_node
The node ptr.
Definition: dsr-routing.h:796
Ptr< dsr::DsrRouteCache > m_routeCache
A "drop-front" queue used by the routing layer to cache routes found.
Definition: dsr-routing.h:925
std::map< PassiveKey, Timer > m_passiveAckTimer
The timer for passive acknowledgment.
Definition: dsr-routing.h:918
bool AddRoute(DsrRouteCacheEntry &rt)
Add route cache entry if it doesn't yet exist in route cache See also DsrRouteCache::AddRoute.
Definition: dsr-routing.cc:690
Time m_maxMaintainTime
Time out for maintenance buffer.
Definition: dsr-routing.h:841
DsrMaintainBuffer m_maintainBuffer
The declaration of maintain buffer.
Definition: dsr-routing.h:851
uint32_t m_maxMaintRexmt
Maximum number of retransmissions of data packets.
Definition: dsr-routing.h:825
void CallCancelPacketTimer(uint16_t ackId, const Ipv4Header &ipv4Header, Ipv4Address realSrc, Ipv4Address realDst)
Call the cancel packet retransmission timer function.
Time m_requestPeriod
The base time interval between route requests.
Definition: dsr-routing.h:812
Time m_linkAckTimeout
The timeout value for link acknowledge.
Definition: dsr-routing.h:874
void SendUnreachError(Ipv4Address unreachNode, Ipv4Address destination, Ipv4Address originalDst, uint8_t salvage, uint8_t protocol)
This function is responsible for sending error packets in case of break link to next hop.
uint32_t m_tryLinkAcks
Maximum number of packet transmission using link acknowledgment.
Definition: dsr-routing.h:876
uint32_t m_discoveryHopLimit
Maximum hops to go for route request.
Definition: dsr-routing.h:808
void CancelRreqTimer(Ipv4Address dst, bool isRemove)
Cancel the route request timer.
std::map< LinkKey, Timer > m_linkAckTimer
The timer for link acknowledgment.
Definition: dsr-routing.h:922
IpL4Protocol::DownTargetCallback6 GetDownTarget6() const override
This method allows a caller to get the current down target callback set for this L4 protocol (IPv6 ca...
Time m_minLifeTime
The min life time.
Definition: dsr-routing.h:898
void ForwardPacket(Ptr< const Packet > packet, DsrOptionSRHeader &sourceRoute, const Ipv4Header &ipv4Header, Ipv4Address source, Ipv4Address destination, Ipv4Address targetAddress, uint8_t protocol, Ptr< Ipv4Route > route)
Forward the packet using the route saved in the source route option header.
static TypeId GetTypeId()
Get the type identificator.
Definition: dsr-routing.cc:116
void SendErrorRequest(DsrOptionRerrUnreachHeader &rerr, uint8_t protocol)
Send the error request packet.
void DoDispose() override
Drop trace callback.
Definition: dsr-routing.cc:565
int GetProtocolNumber() const override
Get the dsr protocol number.
Definition: dsr-routing.cc:803
void PacketNewRoute(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol)
When route vector corrupted, originate a new packet, normally not happening.
Ptr< dsr::DsrRreqTable > m_rreqTable
A "drop-front" queue used by the routing layer to cache route request sent.
Definition: dsr-routing.h:927
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void IncreaseRetransTimer()
This function is called to increase the retransmission timer for data packet in the network queue.
void CancelPassivePacketTimer(DsrMaintainBuffEntry &mb)
Cancel the passive packet retransmission timer for a specific maintenance entry.
void CancelNetworkPacketTimer(DsrMaintainBuffEntry &mb)
Cancel the network packet retransmission timer for a specific maintenance entry.
void PriorityScheduler(uint32_t priority, bool continueWithFirst)
This function is called to schedule sending packets from the network queue by priority.
void ScheduleCachedReply(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, Ptr< Ipv4Route > route, double hops)
Schedule the cached reply to a random start time to avoid possible route reply storm.
void SendAck(uint16_t ackId, Ipv4Address destination, Ipv4Address realSrc, Ipv4Address realDst, uint8_t protocol, Ptr< Ipv4Route > route)
Send network layer acknowledgment back to the earlier hop to notify the receipt of data packet.
void SetRouteCache(Ptr< dsr::DsrRouteCache > r)
Set the route cache.
Definition: dsr-routing.cc:604
void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)
This function is called by higher layer protocol when sending packets.
void Insert(Ptr< dsr::DsrOptions > option)
Insert a new Dsr Option.
std::vector< Ipv4Address > m_finalRoute
The route cache.
Definition: dsr-routing.h:906
void CancelPacketAllTimer(DsrMaintainBuffEntry &mb)
Cancel all the packet timers.
uint32_t m_broadcastJitter
The max time to delay route request broadcast.
Definition: dsr-routing.h:867
uint32_t m_maxCacheLen
Max # of cache entries for route cache.
Definition: dsr-routing.h:843
DSR Send Buffer Entry.
Definition: dsr-rsendbuff.h:48
Ptr< const Packet > GetPacket() const
Get pointer to entry's packet.
Definition: dsr-rsendbuff.h:84
void SetMaxQueueLen(uint32_t len)
Set the maximum queue length.
uint32_t GetSize()
Number of entries.
bool Dequeue(Ipv4Address dst, DsrSendBuffEntry &entry)
Return first found (the earliest) entry for the given destination.
void SetSendBufferTimeout(Time t)
Set the entry lifetime in the queue.
std::vector< DsrSendBuffEntry > & GetBuffer()
Return a pointer to the internal queue.
bool Enqueue(DsrSendBuffEntry &entry)
Push entry in queue, if there is no entry with the same packet and destination address in queue.
bool Find(Ipv4Address dst)
Check if a packet with destination dst exists in the queue.
void DropPacketWithDst(Ipv4Address dst)
Remove all packets with destination IP address dst.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeChecker > MakeStringChecker()
Definition: string.cc:30
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Definition: string.h:57
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1444
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:702
uint8_t data[writeSize]
BlackList description.
The gratuitous table entries, it maintains the already sent gratuitous route reply entries.
NetworkKey structure.
Ipv4Address m_ourAdd
local address
Ipv4Address m_destination
destination address
uint16_t m_ackId
acknowledge ID
Ipv4Address m_source
source address
Ipv4Address m_nextHop
next hop
PassiveKey structure.
Ipv4Address m_destination
destination address
Ipv4Address m_source
source address
uint8_t m_segsLeft
segments left
uint16_t m_ackId
acknowledge ID