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 auto result_i = m_priorityQueue.insert(std::make_pair(i, queue_i));
447 NS_ASSERT_MSG(result_i.second, "Error in creating queues");
448 }
449 Ptr<dsr::DsrRreqTable> rreqTable = CreateObject<dsr::DsrRreqTable>();
450 // Set the initial hop limit
451 rreqTable->SetInitHopLimit(m_discoveryHopLimit);
452 // Configure the request table parameters
453 rreqTable->SetRreqTableSize(m_requestTableSize);
454 rreqTable->SetRreqIdSize(m_requestTableIds);
455 rreqTable->SetUniqueRreqIdSize(m_maxRreqId);
456 SetRequestTable(rreqTable);
457 // Set the passive buffer parameters using just the send buffer parameters
458 Ptr<dsr::DsrPassiveBuffer> passiveBuffer = CreateObject<dsr::DsrPassiveBuffer>();
459 passiveBuffer->SetMaxQueueLen(m_maxSendBuffLen);
460 passiveBuffer->SetPassiveBufferTimeout(m_sendBufferTimeout);
461 SetPassiveBuffer(passiveBuffer);
462
463 // Set the send buffer parameters
466 // Set the error buffer parameters using just the send buffer parameters
469 // Set the maintenance buffer parameters
472 // Set the gratuitous reply table size
474
475 if (m_mainAddress == Ipv4Address())
476 {
477 Ipv4Address loopback("127.0.0.1");
478 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
479 {
480 // Use primary address, if multiple
481 Ipv4Address addr = m_ipv4->GetAddress(i, 0).GetLocal();
482 m_broadcast = m_ipv4->GetAddress(i, 0).GetBroadcast();
483 if (addr != loopback)
484 {
485 /*
486 * Set dsr route cache
487 */
488 Ptr<dsr::DsrRouteCache> routeCache = CreateObject<dsr::DsrRouteCache>();
489 // Configure the path cache parameters
490 routeCache->SetCacheType(m_cacheType);
491 routeCache->SetSubRoute(m_subRoute);
492 routeCache->SetMaxCacheLen(m_maxCacheLen);
493 routeCache->SetCacheTimeout(m_maxCacheTime);
494 routeCache->SetMaxEntriesEachDst(m_maxEntriesEachDst);
495 // Parameters for link cache
496 routeCache->SetStabilityDecrFactor(m_stabilityDecrFactor);
497 routeCache->SetStabilityIncrFactor(m_stabilityIncrFactor);
498 routeCache->SetInitStability(m_initStability);
499 routeCache->SetMinLifeTime(m_minLifeTime);
500 routeCache->SetUseExtends(m_useExtends);
501 routeCache->ScheduleTimer();
502 // The call back to handle link error and send error message to appropriate nodes
503 /// TODO whether this SendRerrWhenBreaksLinkToNextHop is used or not
504 // routeCache->SetCallback (MakeCallback
505 // (&DsrRouting::SendRerrWhenBreaksLinkToNextHop, this));
506 SetRouteCache(routeCache);
507 // Set the main address as the current ip address
508 m_mainAddress = addr;
509
510 m_ipv4->GetNetDevice(1)->SetPromiscReceiveCallback(
512
513 // Allow neighbor manager use this interface for layer 2 feedback if possible
514 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(addr));
515 Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice>();
516 if (!wifi)
517 {
518 break;
519 }
520 Ptr<WifiMac> mac = wifi->GetMac();
521 if (!mac)
522 {
523 break;
524 }
525
526 routeCache->AddArpCache(m_ipv4->GetInterface(i)->GetArpCache());
527 NS_LOG_LOGIC("Starting DSR on node " << m_mainAddress);
528 break;
529 }
530 }
532 }
533}
534
537{
538 // Use "NodeList/*/DeviceList/*/ as reference
539 // where element [1] is the Node Id
540 // element [2] is the NetDevice Id
541 std::vector<std::string> elements = GetElementsFromContext(context);
542 Ptr<Node> n = NodeList::GetNode(std::stoi(elements[1]));
543 NS_ASSERT(n);
544 return n->GetDevice(std::stoi(elements[3]));
545}
546
547std::vector<std::string>
549{
550 std::vector<std::string> elements;
551 size_t pos1 = 0;
552 size_t pos2;
553 while (pos1 != std::string::npos)
554 {
555 pos1 = context.find('/', pos1);
556 pos2 = context.find('/', pos1 + 1);
557 elements.push_back(context.substr(pos1 + 1, pos2 - (pos1 + 1)));
558 pos1 = pos2;
559 }
560 return elements;
561}
562
563void
565{
567 m_node = nullptr;
568 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
569 {
570 // Disable layer 2 link state monitoring (if possible)
571 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(i);
572 Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice>();
573 if (wifi)
574 {
575 Ptr<WifiMac> mac = wifi->GetMac();
576 if (mac)
577 {
578 Ptr<AdhocWifiMac> adhoc = mac->GetObject<AdhocWifiMac>();
579 if (adhoc)
580 {
581 m_routeCache->DelArpCache(m_ipv4->GetInterface(i)->GetArpCache());
582 }
583 }
584 }
585 }
587}
588
589void
591{
592 m_node = node;
593}
594
597{
599 return m_node;
600}
601
602void
604{
605 // / Set the route cache to use
606 m_routeCache = r;
607}
608
611{
612 // / Get the route cache to use
613 return m_routeCache;
614}
615
616void
618{
619 // / Set the request table to use
620 m_rreqTable = q;
621}
622
625{
626 // / Get the request table to use
627 return m_rreqTable;
628}
629
630void
632{
633 // / Set the request table to use
634 m_passiveBuffer = p;
635}
636
639{
640 // / Get the request table to use
641 return m_passiveBuffer;
642}
643
646{
647 NS_LOG_FUNCTION(this << ipv4Address);
648 int32_t nNodes = NodeList::GetNNodes();
649 for (int32_t i = 0; i < nNodes; ++i)
650 {
652 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
653 int32_t ifIndex = ipv4->GetInterfaceForAddress(ipv4Address);
654 if (ifIndex != -1)
655 {
656 return node;
657 }
658 }
659 return nullptr;
660}
661
662bool
664{
665 return m_routeCache->IsLinkCache();
666}
667
668void
670{
671 m_routeCache->UseExtends(rt);
672}
673
674bool
676{
677 return m_routeCache->LookupRoute(id, rt);
678}
679
680bool
682{
683 Ipv4Address nextHop = SearchNextHop(source, nodelist);
684 m_errorBuffer.DropPacketForErrLink(source, nextHop);
685 return m_routeCache->AddRoute_Link(nodelist, source);
686}
687
688bool
690{
691 std::vector<Ipv4Address> nodelist = rt.GetVector();
692 Ipv4Address nextHop = SearchNextHop(m_mainAddress, nodelist);
694 return m_routeCache->AddRoute(rt);
695}
696
697void
699 Ipv4Address unreachNode,
700 Ipv4Address node)
701{
702 m_routeCache->DeleteAllRoutesIncludeLink(errorSrc, unreachNode, node);
703}
704
705bool
707{
708 return m_routeCache->UpdateRouteEntry(dst);
709}
710
711bool
713{
714 return m_rreqTable->FindSourceEntry(src, dst, id);
715}
716
719{
720 NS_LOG_FUNCTION(this << address);
721 int32_t nNodes = NodeList::GetNNodes();
722 for (int32_t i = 0; i < nNodes; ++i)
723 {
725 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
726 Ptr<NetDevice> netDevice = ipv4->GetNetDevice(1);
727
728 if (netDevice->GetAddress() == address)
729 {
730 return ipv4->GetAddress(1, 0).GetLocal();
731 }
732 }
733 return nullptr;
734}
735
736void
737DsrRouting::PrintVector(std::vector<Ipv4Address>& vec)
738{
739 NS_LOG_FUNCTION(this);
740 /*
741 * Check elements in a route vector
742 */
743 if (vec.empty())
744 {
745 NS_LOG_DEBUG("The vector is empty");
746 }
747 else
748 {
749 NS_LOG_DEBUG("Print all the elements in a vector");
750 for (auto i = vec.begin(); i != vec.end(); ++i)
751 {
752 NS_LOG_DEBUG("The ip address " << *i);
753 }
754 }
755}
756
758DsrRouting::SearchNextHop(Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
759{
760 NS_LOG_FUNCTION(this << ipv4Address);
761 Ipv4Address nextHop;
762 NS_LOG_DEBUG("the vector size " << vec.size());
763 if (vec.size() == 2)
764 {
765 NS_LOG_DEBUG("The two nodes are neighbors");
766 nextHop = vec[1];
767 return nextHop;
768 }
769
770 if (ipv4Address == vec.back())
771 {
772 NS_LOG_DEBUG("We have reached to the final destination " << ipv4Address << " "
773 << vec.back());
774 return ipv4Address;
775 }
776 for (auto i = vec.begin(); i != vec.end(); ++i)
777 {
778 if (ipv4Address == (*i))
779 {
780 nextHop = *(++i);
781 return nextHop;
782 }
783 }
784
785 NS_LOG_DEBUG("Next hop address not found");
786 Ipv4Address none = "0.0.0.0";
787 return none;
788}
789
792{
793 NS_LOG_FUNCTION(this << nextHop << srcAddress);
794 m_ipv4Route = Create<Ipv4Route>();
795 m_ipv4Route->SetDestination(nextHop);
796 m_ipv4Route->SetGateway(nextHop);
797 m_ipv4Route->SetSource(srcAddress);
798 return m_ipv4Route;
799}
800
801int
803{
804 // / This is the protocol number for DSR which is 48
805 return PROT_NUMBER;
806}
807
808uint16_t
810{
811 int32_t nNodes = NodeList::GetNNodes();
812 for (int32_t i = 0; i < nNodes; ++i)
813 {
815 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
816 if (ipv4->GetAddress(1, 0).GetLocal() == address)
817 {
818 return uint16_t(i);
819 }
820 }
821 return 256;
822}
823
826{
827 if (id >= 256)
828 {
829 NS_LOG_DEBUG("Exceed the node range");
830 return "0.0.0.0";
831 }
832
834 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
835 return ipv4->GetAddress(1, 0).GetLocal();
836}
837
840{
841 if (messageType == DSR_CONTROL_PACKET)
842 {
843 return 0;
844 }
845 else
846 {
847 return 1;
848 }
849}
850
851void
853{
855 {
857 }
860}
861
862void
864{
865 NS_LOG_INFO(Simulator::Now().As(Time::S) << " Checking send buffer at " << m_mainAddress
866 << " with size " << m_sendBuffer.GetSize());
867
868 for (auto i = m_sendBuffer.GetBuffer().begin(); i != m_sendBuffer.GetBuffer().end();)
869 {
870 NS_LOG_DEBUG("Here we try to find the data packet in the send buffer");
871 Ipv4Address destination = i->GetDestination();
872 DsrRouteCacheEntry toDst;
873 bool findRoute = m_routeCache->LookupRoute(destination, toDst);
874 if (findRoute)
875 {
876 NS_LOG_INFO("We have found a route for the packet");
877 Ptr<const Packet> packet = i->GetPacket();
878 Ptr<Packet> cleanP = packet->Copy();
879 uint8_t protocol = i->GetProtocol();
880
881 i = m_sendBuffer.GetBuffer().erase(i);
882
883 DsrRoutingHeader dsrRoutingHeader;
884 Ptr<Packet> copyP = packet->Copy();
885 Ptr<Packet> dsrPacket = packet->Copy();
886 dsrPacket->RemoveHeader(dsrRoutingHeader);
887 uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
888 copyP->RemoveAtStart(offset); // Here the processed size is 8 bytes, which is the fixed
889 // sized extension header
890 // The packet to get ipv4 header
891 Ptr<Packet> ipv4P = copyP->Copy();
892 /*
893 * Peek data to get the option type as well as length and segmentsLeft field
894 */
895 uint32_t size = copyP->GetSize();
896 auto data = new uint8_t[size];
897 copyP->CopyData(data, size);
898
899 uint8_t optionType = 0;
900 optionType = *(data);
901
902 if (optionType == 3)
903 {
904 Ptr<dsr::DsrOptions> dsrOption;
905 DsrOptionHeader dsrOptionHeader;
906 uint8_t errorType = *(data + 2);
907
908 if (errorType == 1) // This is the Route Error Option
909 {
911 copyP->RemoveHeader(rerr);
912 NS_ASSERT(copyP->GetSize() == 0);
913
915 newUnreach.SetErrorType(1);
916 newUnreach.SetErrorSrc(rerr.GetErrorSrc());
917 newUnreach.SetUnreachNode(rerr.GetUnreachNode());
918 newUnreach.SetErrorDst(rerr.GetErrorDst());
919 newUnreach.SetSalvage(rerr.GetSalvage()); // Set the value about whether to
920 // salvage a packet or not
921
922 DsrOptionSRHeader sourceRoute;
923 std::vector<Ipv4Address> errorRoute = toDst.GetVector();
924 sourceRoute.SetNodesAddress(errorRoute);
925 /// When found a route and use it, UseExtends to the link cache
926 if (m_routeCache->IsLinkCache())
927 {
928 m_routeCache->UseExtends(errorRoute);
929 }
930 sourceRoute.SetSegmentsLeft(errorRoute.size() - 2);
931 uint8_t salvage = 0;
932 sourceRoute.SetSalvage(salvage);
933 Ipv4Address nextHop =
934 SearchNextHop(m_mainAddress, errorRoute); // Get the next hop address
935
936 if (nextHop == "0.0.0.0")
937 {
938 PacketNewRoute(dsrPacket, m_mainAddress, destination, protocol);
939 return;
940 }
941
942 SetRoute(nextHop, m_mainAddress);
943 uint8_t length = (sourceRoute.GetLength() + newUnreach.GetLength());
944 dsrRoutingHeader.SetNextHeader(protocol);
945 dsrRoutingHeader.SetMessageType(1);
946 dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
947 dsrRoutingHeader.SetDestId(255);
948 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
949 dsrRoutingHeader.AddDsrOption(newUnreach);
950 dsrRoutingHeader.AddDsrOption(sourceRoute);
951
952 Ptr<Packet> newPacket = Create<Packet>();
953 newPacket->AddHeader(dsrRoutingHeader); // Add the routing header with rerr and
954 // sourceRoute attached to it
955 Ptr<NetDevice> dev =
956 m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
957 m_ipv4Route->SetOutputDevice(dev);
958
959 uint32_t priority = GetPriority(DSR_CONTROL_PACKET); /// This will be priority 0
960 auto i = m_priorityQueue.find(priority);
961 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
962 NS_LOG_LOGIC("Will be inserting into priority queue number: " << priority);
963
964 // m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (),
965 // m_ipv4Route);
966
967 /// \todo New DsrNetworkQueueEntry
968 DsrNetworkQueueEntry newEntry(newPacket,
970 nextHop,
973
974 if (dsrNetworkQueue->Enqueue(newEntry))
975 {
976 Scheduler(priority);
977 }
978 else
979 {
980 NS_LOG_INFO("Packet dropped as dsr network queue is full");
981 }
982 }
983 }
984 else
985 {
986 dsrRoutingHeader.SetNextHeader(protocol);
987 dsrRoutingHeader.SetMessageType(2);
988 dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
989 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
990
991 DsrOptionSRHeader sourceRoute;
992 std::vector<Ipv4Address> nodeList =
993 toDst.GetVector(); // Get the route from the route entry we found
994 Ipv4Address nextHop =
996 nodeList); // Get the next hop address for the route
997 if (nextHop == "0.0.0.0")
998 {
999 PacketNewRoute(dsrPacket, m_mainAddress, destination, protocol);
1000 return;
1001 }
1002 uint8_t salvage = 0;
1003 // Save the whole route in the source route header of the packet
1004 sourceRoute.SetNodesAddress(nodeList);
1005 // The segmentsLeft field will indicate the hops to go
1006 sourceRoute.SetSegmentsLeft(nodeList.size() - 2);
1007 sourceRoute.SetSalvage(salvage);
1008 // When found a route and use it, UseExtends to the link cache
1009 if (m_routeCache->IsLinkCache())
1010 {
1011 m_routeCache->UseExtends(nodeList);
1012 }
1013 uint8_t length = sourceRoute.GetLength();
1014 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1015 dsrRoutingHeader.AddDsrOption(sourceRoute);
1016 cleanP->AddHeader(dsrRoutingHeader);
1017 Ptr<const Packet> mtP = cleanP->Copy();
1018 // Put the data packet in the maintenance queue for data packet retransmission
1019 DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1020 /*ourAddress=*/m_mainAddress,
1021 /*nextHop=*/nextHop,
1022 /*src=*/m_mainAddress,
1023 /*dst=*/destination,
1024 /*ackId=*/0,
1025 /*segsLeft=*/nodeList.size() - 2,
1026 /*expire=*/m_maxMaintainTime);
1027 bool result = m_maintainBuffer.Enqueue(
1028 newEntry); // Enqueue the packet the the maintenance buffer
1029 if (result)
1030 {
1031 NetworkKey networkKey;
1032 networkKey.m_ackId = newEntry.GetAckId();
1033 networkKey.m_ourAdd = newEntry.GetOurAdd();
1034 networkKey.m_nextHop = newEntry.GetNextHop();
1035 networkKey.m_source = newEntry.GetSrc();
1036 networkKey.m_destination = newEntry.GetDst();
1037
1038 PassiveKey passiveKey;
1039 passiveKey.m_ackId = 0;
1040 passiveKey.m_source = newEntry.GetSrc();
1041 passiveKey.m_destination = newEntry.GetDst();
1042 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1043
1044 LinkKey linkKey;
1045 linkKey.m_source = newEntry.GetSrc();
1046 linkKey.m_destination = newEntry.GetDst();
1047 linkKey.m_ourAdd = newEntry.GetOurAdd();
1048 linkKey.m_nextHop = newEntry.GetNextHop();
1049
1050 m_addressForwardCnt[networkKey] = 0;
1051 m_passiveCnt[passiveKey] = 0;
1052 m_linkCnt[linkKey] = 0;
1053
1054 if (m_linkAck)
1055 {
1056 ScheduleLinkPacketRetry(newEntry, protocol);
1057 }
1058 else
1059 {
1060 NS_LOG_LOGIC("Not using link acknowledgment");
1061 if (nextHop != destination)
1062 {
1063 SchedulePassivePacketRetry(newEntry, protocol);
1064 }
1065 else
1066 {
1067 // This is the first network retry
1068 ScheduleNetworkPacketRetry(newEntry, true, protocol);
1069 }
1070 }
1071 }
1072 // we need to suspend the normal timer that checks the send buffer
1073 // until we are done sending packets
1075 {
1077 }
1079 return;
1080 }
1081 }
1082 else
1083 {
1084 ++i;
1085 }
1086 }
1087 // after going through the entire send buffer and send all packets found route,
1088 // we need to resume the timer if it has been suspended
1090 {
1091 NS_LOG_DEBUG("Resume the send buffer timer");
1093 }
1094}
1095
1096bool
1098 Ptr<const Packet> packet,
1099 uint16_t protocol,
1100 const Address& from,
1101 const Address& to,
1102 NetDevice::PacketType packetType)
1103{
1104 if (protocol != Ipv4L3Protocol::PROT_NUMBER)
1105 {
1106 return false;
1107 }
1108 // Remove the ipv4 header here
1109 Ptr<Packet> pktMinusIpHdr = packet->Copy();
1110 Ipv4Header ipv4Header;
1111 pktMinusIpHdr->RemoveHeader(ipv4Header);
1112
1113 if (ipv4Header.GetProtocol() != DsrRouting::PROT_NUMBER)
1114 {
1115 return false;
1116 }
1117 // Remove the dsr routing header here
1118 Ptr<Packet> pktMinusDsrHdr = pktMinusIpHdr->Copy();
1119 DsrRoutingHeader dsrRouting;
1120 pktMinusDsrHdr->RemoveHeader(dsrRouting);
1121
1122 /*
1123 * Message type 2 means the data packet, we will further process the data
1124 * packet for delivery notification, safely ignore control packet
1125 * Another check here is our own address, if this is the data destinated for us,
1126 * process it further, otherwise, just ignore it
1127 */
1128 Ipv4Address ourAddress = m_ipv4->GetAddress(1, 0).GetLocal();
1129 // check if the message type is 2 and if the ipv4 address matches
1130 if (dsrRouting.GetMessageType() == 2 && ourAddress == m_mainAddress)
1131 {
1132 NS_LOG_DEBUG("data packet receives " << packet->GetUid());
1133 Ipv4Address sourceIp = GetIPfromID(dsrRouting.GetSourceId());
1134 Ipv4Address destinationIp = GetIPfromID(dsrRouting.GetDestId());
1135 /// This is the ip address we just received data packet from
1137
1138 Ptr<Packet> p = Create<Packet>();
1139 // Here the segments left value need to plus one to check the earlier hop maintain buffer
1140 // entry
1141 DsrMaintainBuffEntry newEntry;
1142 newEntry.SetPacket(p);
1143 newEntry.SetSrc(sourceIp);
1144 newEntry.SetDst(destinationIp);
1145 /// Remember this is the entry for previous node
1146 newEntry.SetOurAdd(previousHop);
1147 newEntry.SetNextHop(ourAddress);
1148 /// Get the previous node's maintenance buffer and passive ack
1149 Ptr<Node> node = GetNodeWithAddress(previousHop);
1150 NS_LOG_DEBUG("The previous node " << previousHop);
1151
1152 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1153 dsr->CancelLinkPacketTimer(newEntry);
1154 }
1155
1156 // Receive only IP packets and packets destined for other hosts
1157 if (packetType == NetDevice::PACKET_OTHERHOST)
1158 {
1159 // just to minimize debug output
1160 NS_LOG_INFO(this << from << to << packetType << *pktMinusIpHdr);
1161
1162 uint8_t offset =
1163 dsrRouting
1164 .GetDsrOptionsOffset(); // Get the offset for option header, 4 bytes in this case
1165 uint8_t nextHeader = dsrRouting.GetNextHeader();
1166 uint32_t sourceId = dsrRouting.GetSourceId();
1167 Ipv4Address source = GetIPfromID(sourceId);
1168
1169 // This packet is used to peek option type
1170 pktMinusIpHdr->RemoveAtStart(offset);
1171 /*
1172 * Peek data to get the option type as well as length and segmentsLeft field
1173 */
1174 uint32_t size = pktMinusIpHdr->GetSize();
1175 auto data = new uint8_t[size];
1176 pktMinusIpHdr->CopyData(data, size);
1177 uint8_t optionType = 0;
1178 optionType = *(data);
1179
1180 Ptr<dsr::DsrOptions> dsrOption;
1181
1182 if (optionType == 96) // This is the source route option
1183 {
1184 Ipv4Address promiscSource = GetIPfromMAC(Mac48Address::ConvertFrom(from));
1185 dsrOption = GetOption(
1186 optionType); // Get the relative DSR option and demux to the process function
1188 << " DSR node " << m_mainAddress
1189 << " overhearing packet PID: " << pktMinusIpHdr->GetUid() << " from "
1190 << promiscSource << " to " << GetIPfromMAC(Mac48Address::ConvertFrom(to))
1191 << " with source IP " << ipv4Header.GetSource() << " and destination IP "
1192 << ipv4Header.GetDestination() << " and packet : " << *pktMinusDsrHdr);
1193
1194 bool isPromisc = true; // Set the boolean value isPromisc as true
1195 dsrOption->Process(pktMinusIpHdr,
1196 pktMinusDsrHdr,
1198 source,
1199 ipv4Header,
1200 nextHeader,
1201 isPromisc,
1202 promiscSource);
1203 return true;
1204 }
1205 }
1206 return false;
1207}
1208
1209void
1211 Ipv4Address source,
1212 Ipv4Address destination,
1213 uint8_t protocol)
1214{
1215 NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)protocol);
1216 // Look up routes for the specific destination
1217 DsrRouteCacheEntry toDst;
1218 bool findRoute = m_routeCache->LookupRoute(destination, toDst);
1219 // Queue the packet if there is no route pre-existing
1220 if (!findRoute)
1221 {
1223 << " " << m_mainAddress
1224 << " there is no route for this packet, queue the packet");
1225
1226 Ptr<Packet> p = packet->Copy();
1227 DsrSendBuffEntry newEntry(p,
1228 destination,
1230 protocol); // Create a new entry for send buffer
1231 bool result = m_sendBuffer.Enqueue(newEntry); // Enqueue the packet in send buffer
1232 if (result)
1233 {
1234 NS_LOG_INFO(Simulator::Now().As(Time::S) << " Add packet PID: " << packet->GetUid()
1235 << " to queue. Packet: " << *packet);
1236
1237 NS_LOG_LOGIC("Send RREQ to" << destination);
1238 if ((m_addressReqTimer.find(destination) == m_addressReqTimer.end()) &&
1239 (m_nonPropReqTimer.find(destination) == m_nonPropReqTimer.end()))
1240 {
1241 /*
1242 * Call the send request function, it will update the request table entry and ttl
1243 * there
1244 */
1245 SendInitialRequest(source, destination, protocol);
1246 }
1247 }
1248 }
1249 else
1250 {
1251 Ptr<Packet> cleanP = packet->Copy();
1252 DsrRoutingHeader dsrRoutingHeader;
1253 dsrRoutingHeader.SetNextHeader(protocol);
1254 dsrRoutingHeader.SetMessageType(2);
1255 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1256 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1257
1258 DsrOptionSRHeader sourceRoute;
1259 std::vector<Ipv4Address> nodeList =
1260 toDst.GetVector(); // Get the route from the route entry we found
1261 Ipv4Address nextHop =
1262 SearchNextHop(m_mainAddress, nodeList); // Get the next hop address for the route
1263 if (nextHop == "0.0.0.0")
1264 {
1265 PacketNewRoute(cleanP, source, destination, protocol);
1266 return;
1267 }
1268 uint8_t salvage = 0;
1269 sourceRoute.SetNodesAddress(
1270 nodeList); // Save the whole route in the source route header of the packet
1271 /// When found a route and use it, UseExtends to the link cache
1272 if (m_routeCache->IsLinkCache())
1273 {
1274 m_routeCache->UseExtends(nodeList);
1275 }
1276 // The segmentsLeft field will indicate the hops to go
1277 sourceRoute.SetSegmentsLeft(nodeList.size() - 2);
1278 sourceRoute.SetSalvage(salvage);
1279
1280 uint8_t length = sourceRoute.GetLength();
1281 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1282 dsrRoutingHeader.AddDsrOption(sourceRoute);
1283 cleanP->AddHeader(dsrRoutingHeader);
1284 Ptr<const Packet> mtP = cleanP->Copy();
1285 SetRoute(nextHop, m_mainAddress);
1286 // Put the data packet in the maintenance queue for data packet retransmission
1287 DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1288 /*ourAddress=*/m_mainAddress,
1289 /*nextHop=*/nextHop,
1290 /*src=*/source,
1291 /*dst=*/destination,
1292 /*ackId=*/0,
1293 /*segsLeft=*/nodeList.size() - 2,
1294 /*expire=*/m_maxMaintainTime);
1295 bool result =
1296 m_maintainBuffer.Enqueue(newEntry); // Enqueue the packet the the maintenance buffer
1297
1298 if (result)
1299 {
1300 NetworkKey networkKey;
1301 networkKey.m_ackId = newEntry.GetAckId();
1302 networkKey.m_ourAdd = newEntry.GetOurAdd();
1303 networkKey.m_nextHop = newEntry.GetNextHop();
1304 networkKey.m_source = newEntry.GetSrc();
1305 networkKey.m_destination = newEntry.GetDst();
1306
1307 PassiveKey passiveKey;
1308 passiveKey.m_ackId = 0;
1309 passiveKey.m_source = newEntry.GetSrc();
1310 passiveKey.m_destination = newEntry.GetDst();
1311 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1312
1313 LinkKey linkKey;
1314 linkKey.m_source = newEntry.GetSrc();
1315 linkKey.m_destination = newEntry.GetDst();
1316 linkKey.m_ourAdd = newEntry.GetOurAdd();
1317 linkKey.m_nextHop = newEntry.GetNextHop();
1318
1319 m_addressForwardCnt[networkKey] = 0;
1320 m_passiveCnt[passiveKey] = 0;
1321 m_linkCnt[linkKey] = 0;
1322
1323 if (m_linkAck)
1324 {
1325 ScheduleLinkPacketRetry(newEntry, protocol);
1326 }
1327 else
1328 {
1329 NS_LOG_LOGIC("Not using link acknowledgment");
1330 if (nextHop != destination)
1331 {
1332 SchedulePassivePacketRetry(newEntry, protocol);
1333 }
1334 else
1335 {
1336 // This is the first network retry
1337 ScheduleNetworkPacketRetry(newEntry, true, protocol);
1338 }
1339 }
1340 }
1341 }
1342}
1343
1344void
1346 Ipv4Address destination,
1347 Ipv4Address originalDst,
1348 uint8_t salvage,
1349 uint8_t protocol)
1350{
1351 NS_LOG_FUNCTION(this << unreachNode << destination << originalDst << (uint32_t)salvage
1352 << (uint32_t)protocol);
1353 DsrRoutingHeader dsrRoutingHeader;
1354 dsrRoutingHeader.SetNextHeader(protocol);
1355 dsrRoutingHeader.SetMessageType(1);
1356 dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
1357 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1358
1359 DsrOptionRerrUnreachHeader rerrUnreachHeader;
1360 rerrUnreachHeader.SetErrorType(1);
1361 rerrUnreachHeader.SetErrorSrc(m_mainAddress);
1362 rerrUnreachHeader.SetUnreachNode(unreachNode);
1363 rerrUnreachHeader.SetErrorDst(destination);
1364 rerrUnreachHeader.SetOriginalDst(originalDst);
1365 rerrUnreachHeader.SetSalvage(salvage); // Set the value about whether to salvage a packet or not
1366 uint8_t rerrLength = rerrUnreachHeader.GetLength();
1367
1368 DsrRouteCacheEntry toDst;
1369 bool findRoute = m_routeCache->LookupRoute(destination, toDst);
1370 // Queue the packet if there is no route pre-existing
1371 Ptr<Packet> newPacket = Create<Packet>();
1372 if (!findRoute)
1373 {
1374 if (destination == m_mainAddress)
1375 {
1376 NS_LOG_INFO("We are the error source, send request to original dst " << originalDst);
1377 // Send error request message if we are the source node
1378 SendErrorRequest(rerrUnreachHeader, protocol);
1379 }
1380 else
1381 {
1383 << " " << m_mainAddress
1384 << " there is no route for this packet, queue the packet");
1385
1386 dsrRoutingHeader.SetPayloadLength(rerrLength + 2);
1387 dsrRoutingHeader.AddDsrOption(rerrUnreachHeader);
1388 newPacket->AddHeader(dsrRoutingHeader);
1389 Ptr<Packet> p = newPacket->Copy();
1390 // Save the error packet in the error buffer
1391 DsrErrorBuffEntry newEntry(p,
1392 destination,
1394 unreachNode,
1396 protocol);
1397 bool result = m_errorBuffer.Enqueue(newEntry); // Enqueue the packet in send buffer
1398 if (result)
1399 {
1401 << " Add packet PID: " << p->GetUid() << " to queue. Packet: " << *p);
1402 NS_LOG_LOGIC("Send RREQ to" << destination);
1403 if ((m_addressReqTimer.find(destination) == m_addressReqTimer.end()) &&
1404 (m_nonPropReqTimer.find(destination) == m_nonPropReqTimer.end()))
1405 {
1406 NS_LOG_DEBUG("When there is no existing route request for "
1407 << destination << ", initialize one");
1408 /*
1409 * Call the send request function, it will update the request table entry and
1410 * ttl there
1411 */
1412 SendInitialRequest(m_mainAddress, destination, protocol);
1413 }
1414 }
1415 }
1416 }
1417 else
1418 {
1419 std::vector<Ipv4Address> nodeList = toDst.GetVector();
1420 Ipv4Address nextHop = SearchNextHop(m_mainAddress, nodeList);
1421 if (nextHop == "0.0.0.0")
1422 {
1423 NS_LOG_DEBUG("The route is not right");
1424 PacketNewRoute(newPacket, m_mainAddress, destination, protocol);
1425 return;
1426 }
1427 DsrOptionSRHeader sourceRoute;
1428 sourceRoute.SetNodesAddress(nodeList);
1429 /// When found a route and use it, UseExtends to the link cache
1430 if (m_routeCache->IsLinkCache())
1431 {
1432 m_routeCache->UseExtends(nodeList);
1433 }
1434 sourceRoute.SetSegmentsLeft(nodeList.size() - 2);
1435 uint8_t srLength = sourceRoute.GetLength();
1436 uint8_t length = (srLength + rerrLength);
1437
1438 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
1439 dsrRoutingHeader.AddDsrOption(rerrUnreachHeader);
1440 dsrRoutingHeader.AddDsrOption(sourceRoute);
1441 newPacket->AddHeader(dsrRoutingHeader);
1442
1443 SetRoute(nextHop, m_mainAddress);
1444 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
1445 m_ipv4Route->SetOutputDevice(dev);
1446 NS_LOG_INFO("Send the packet to the next hop address " << nextHop << " from "
1447 << m_mainAddress << " with the size "
1448 << newPacket->GetSize());
1449
1451 auto i = m_priorityQueue.find(priority);
1452 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1453 NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue
1454 << " number: " << priority);
1455
1456 // m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
1457
1458 /// \todo New DsrNetworkQueueEntry
1459 DsrNetworkQueueEntry newEntry(newPacket,
1461 nextHop,
1463 m_ipv4Route);
1464
1465 if (dsrNetworkQueue->Enqueue(newEntry))
1466 {
1467 Scheduler(priority);
1468 }
1469 else
1470 {
1471 NS_LOG_INFO("Packet dropped as dsr network queue is full");
1472 }
1473 }
1474}
1475
1476void
1478 DsrOptionSRHeader& sourceRoute,
1479 Ipv4Address nextHop,
1480 uint8_t protocol,
1481 Ptr<Ipv4Route> route)
1482{
1483 NS_LOG_FUNCTION(this << rerr << sourceRoute << nextHop << (uint32_t)protocol << route);
1484 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
1485 DsrRoutingHeader dsrRoutingHeader;
1486 dsrRoutingHeader.SetNextHeader(protocol);
1487 dsrRoutingHeader.SetMessageType(1);
1488 dsrRoutingHeader.SetSourceId(GetIDfromIP(rerr.GetErrorSrc()));
1489 dsrRoutingHeader.SetDestId(GetIDfromIP(rerr.GetErrorDst()));
1490
1491 uint8_t length = (sourceRoute.GetLength() + rerr.GetLength());
1492 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
1493 dsrRoutingHeader.AddDsrOption(rerr);
1494 dsrRoutingHeader.AddDsrOption(sourceRoute);
1495 Ptr<Packet> packet = Create<Packet>();
1496 packet->AddHeader(dsrRoutingHeader);
1497 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
1498 route->SetOutputDevice(dev);
1499
1501 auto i = m_priorityQueue.find(priority);
1502 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1503 NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue
1504 << " number: " << priority);
1505
1506 // m_downTarget (packet, m_mainAddress, nextHop, GetProtocolNumber (), route);
1507
1508 /// \todo New DsrNetworkQueueEntry
1509 DsrNetworkQueueEntry newEntry(packet, m_mainAddress, nextHop, Simulator::Now(), route);
1510
1511 if (dsrNetworkQueue->Enqueue(newEntry))
1512 {
1513 Scheduler(priority);
1514 }
1515 else
1516 {
1517 NS_LOG_INFO("Packet dropped as dsr network queue is full");
1518 }
1519}
1520
1521void
1523 Ipv4Address source,
1524 Ipv4Address destination,
1525 uint8_t protocol,
1526 Ptr<Ipv4Route> route)
1527{
1528 NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)protocol << route);
1529 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
1530
1531 if (protocol == 1)
1532 {
1533 NS_LOG_INFO("Drop packet. Not handling ICMP packet for now");
1534 }
1535 else
1536 {
1537 // Look up routes for the specific destination
1538 DsrRouteCacheEntry toDst;
1539 bool findRoute = m_routeCache->LookupRoute(destination, toDst);
1540 // Queue the packet if there is no route pre-existing
1541 if (!findRoute)
1542 {
1544 << " " << m_mainAddress
1545 << " there is no route for this packet, queue the packet");
1546
1547 Ptr<Packet> p = packet->Copy();
1548 DsrSendBuffEntry newEntry(p,
1549 destination,
1551 protocol); // Create a new entry for send buffer
1552 bool result = m_sendBuffer.Enqueue(newEntry); // Enqueue the packet in send buffer
1553 if (result)
1554 {
1555 NS_LOG_INFO(Simulator::Now().As(Time::S) << " Add packet PID: " << packet->GetUid()
1556 << " to send buffer. Packet: " << *packet);
1557 // Only when there is no existing route request timer when new route request is
1558 // scheduled
1559 if ((m_addressReqTimer.find(destination) == m_addressReqTimer.end()) &&
1560 (m_nonPropReqTimer.find(destination) == m_nonPropReqTimer.end()))
1561 {
1562 /*
1563 * Call the send request function, it will update the request table entry and
1564 * ttl value
1565 */
1566 NS_LOG_LOGIC("Send initial RREQ to " << destination);
1567 SendInitialRequest(source, destination, protocol);
1568 }
1569 else
1570 {
1571 NS_LOG_LOGIC("There is existing route request timer with request count "
1572 << m_rreqTable->GetRreqCnt(destination));
1573 }
1574 }
1575 }
1576 else
1577 {
1578 Ptr<Packet> cleanP = packet->Copy();
1579 DsrRoutingHeader dsrRoutingHeader;
1580 dsrRoutingHeader.SetNextHeader(protocol);
1581 dsrRoutingHeader.SetMessageType(2);
1582 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1583 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1584
1585 DsrOptionSRHeader sourceRoute;
1586 std::vector<Ipv4Address> nodeList =
1587 toDst.GetVector(); // Get the route from the route entry we found
1588 Ipv4Address nextHop =
1589 SearchNextHop(m_mainAddress, nodeList); // Get the next hop address for the route
1590 if (nextHop == "0.0.0.0")
1591 {
1592 PacketNewRoute(cleanP, source, destination, protocol);
1593 return;
1594 }
1595 uint8_t salvage = 0;
1596 sourceRoute.SetNodesAddress(
1597 nodeList); // Save the whole route in the source route header of the packet
1598 /// When found a route and use it, UseExtends to the link cache
1599 if (m_routeCache->IsLinkCache())
1600 {
1601 m_routeCache->UseExtends(nodeList);
1602 }
1603 // The segmentsLeft field will indicate the hops to go
1604 sourceRoute.SetSegmentsLeft(nodeList.size() - 2);
1605 sourceRoute.SetSalvage(salvage);
1606
1607 uint8_t length = sourceRoute.GetLength();
1608
1609 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1610 dsrRoutingHeader.AddDsrOption(sourceRoute);
1611 cleanP->AddHeader(dsrRoutingHeader);
1612
1613 Ptr<const Packet> mtP = cleanP->Copy();
1614 NS_LOG_DEBUG("maintain packet size " << cleanP->GetSize());
1615 // Put the data packet in the maintenance queue for data packet retransmission
1616 DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1617 /*ourAddress=*/m_mainAddress,
1618 /*nextHop=*/nextHop,
1619 /*src=*/source,
1620 /*dst=*/destination,
1621 /*ackId=*/0,
1622 /*segsLeft=*/nodeList.size() - 2,
1623 /*expire=*/m_maxMaintainTime);
1624 bool result =
1625 m_maintainBuffer.Enqueue(newEntry); // Enqueue the packet the the maintenance buffer
1626 if (result)
1627 {
1628 NetworkKey networkKey;
1629 networkKey.m_ackId = newEntry.GetAckId();
1630 networkKey.m_ourAdd = newEntry.GetOurAdd();
1631 networkKey.m_nextHop = newEntry.GetNextHop();
1632 networkKey.m_source = newEntry.GetSrc();
1633 networkKey.m_destination = newEntry.GetDst();
1634
1635 PassiveKey passiveKey;
1636 passiveKey.m_ackId = 0;
1637 passiveKey.m_source = newEntry.GetSrc();
1638 passiveKey.m_destination = newEntry.GetDst();
1639 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1640
1641 LinkKey linkKey;
1642 linkKey.m_source = newEntry.GetSrc();
1643 linkKey.m_destination = newEntry.GetDst();
1644 linkKey.m_ourAdd = newEntry.GetOurAdd();
1645 linkKey.m_nextHop = newEntry.GetNextHop();
1646
1647 m_addressForwardCnt[networkKey] = 0;
1648 m_passiveCnt[passiveKey] = 0;
1649 m_linkCnt[linkKey] = 0;
1650
1651 if (m_linkAck)
1652 {
1653 ScheduleLinkPacketRetry(newEntry, protocol);
1654 }
1655 else
1656 {
1657 NS_LOG_LOGIC("Not using link acknowledgment");
1658 if (nextHop != destination)
1659 {
1660 SchedulePassivePacketRetry(newEntry, protocol);
1661 }
1662 else
1663 {
1664 // This is the first network retry
1665 ScheduleNetworkPacketRetry(newEntry, true, protocol);
1666 }
1667 }
1668 }
1669
1670 if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(destination))
1671 {
1672 // Try to send packet from *previously* queued entries from send buffer if any
1675 this,
1676 sourceRoute,
1677 nextHop,
1678 protocol);
1679 }
1680 }
1681 }
1682}
1683
1684uint16_t
1686{
1687 NS_LOG_FUNCTION(this << packet << nextHop);
1688 // This packet is used to peek option type
1689 Ptr<Packet> dsrP = packet->Copy();
1690 Ptr<Packet> tmpP = packet->Copy();
1691
1692 DsrRoutingHeader dsrRoutingHeader;
1693 dsrP->RemoveHeader(dsrRoutingHeader); // Remove the DSR header in whole
1694 uint8_t protocol = dsrRoutingHeader.GetNextHeader();
1695 uint32_t sourceId = dsrRoutingHeader.GetSourceId();
1696 uint32_t destinationId = dsrRoutingHeader.GetDestId();
1697 uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
1698 tmpP->RemoveAtStart(
1699 offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
1700
1701 // Get the number of routers' address field
1702 uint8_t buf[2];
1703 tmpP->CopyData(buf, sizeof(buf));
1704 uint8_t numberAddress = (buf[1] - 2) / 4;
1705 DsrOptionSRHeader sourceRoute;
1706 sourceRoute.SetNumberAddress(numberAddress);
1707 tmpP->RemoveHeader(sourceRoute); // this is a clean packet without any dsr involved headers
1708
1709 DsrOptionAckReqHeader ackReq;
1710 m_ackId = m_routeCache->CheckUniqueAckId(nextHop);
1711 ackReq.SetAckId(m_ackId);
1712 uint8_t length = (sourceRoute.GetLength() + ackReq.GetLength());
1713 DsrRoutingHeader newDsrRoutingHeader;
1714 newDsrRoutingHeader.SetNextHeader(protocol);
1715 newDsrRoutingHeader.SetMessageType(2);
1716 newDsrRoutingHeader.SetSourceId(sourceId);
1717 newDsrRoutingHeader.SetDestId(destinationId);
1718 newDsrRoutingHeader.SetPayloadLength(length + 4);
1719 newDsrRoutingHeader.AddDsrOption(sourceRoute);
1720 newDsrRoutingHeader.AddDsrOption(ackReq);
1721 dsrP->AddHeader(newDsrRoutingHeader);
1722 // give the dsrP value to packet and then return
1723 packet = dsrP;
1724 return m_ackId;
1725}
1726
1727void
1729 Ipv4Address source,
1730 Ipv4Address nextHop,
1731 uint8_t protocol)
1732{
1733 NS_LOG_FUNCTION(this << packet << source << nextHop << (uint32_t)protocol);
1734 // Send out the data packet
1736 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
1737 m_ipv4Route->SetOutputDevice(dev);
1738
1740 auto i = m_priorityQueue.find(priority);
1741 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1742 NS_LOG_INFO("Will be inserting into priority queue number: " << priority);
1743
1744 // m_downTarget (packet, source, nextHop, GetProtocolNumber (), m_ipv4Route);
1745
1746 /// \todo New DsrNetworkQueueEntry
1747 DsrNetworkQueueEntry newEntry(packet, source, nextHop, Simulator::Now(), m_ipv4Route);
1748
1749 if (dsrNetworkQueue->Enqueue(newEntry))
1750 {
1751 Scheduler(priority);
1752 }
1753 else
1754 {
1755 NS_LOG_INFO("Packet dropped as dsr network queue is full");
1756 }
1757}
1758
1759void
1761{
1762 NS_LOG_FUNCTION(this);
1763 PriorityScheduler(priority, true);
1764}
1765
1766void
1767DsrRouting::PriorityScheduler(uint32_t priority, bool continueWithFirst)
1768{
1769 NS_LOG_FUNCTION(this << priority << continueWithFirst);
1770 uint32_t numPriorities;
1771 if (continueWithFirst)
1772 {
1773 numPriorities = 0;
1774 }
1775 else
1776 {
1777 numPriorities = priority;
1778 }
1779 // priorities ranging from 0 to m_numPriorityQueues, with 0 as the highest priority
1780 for (uint32_t i = priority; numPriorities < m_numPriorityQueues; numPriorities++)
1781 {
1782 auto q = m_priorityQueue.find(i);
1783 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = q->second;
1784 uint32_t queueSize = dsrNetworkQueue->GetSize();
1785 if (queueSize == 0)
1786 {
1787 if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1788 {
1789 i = 0;
1790 }
1791 else
1792 {
1793 i++;
1794 }
1795 }
1796 else
1797 {
1798 uint32_t totalQueueSize = 0;
1799 for (auto j = m_priorityQueue.begin(); j != m_priorityQueue.end(); j++)
1800 {
1801 NS_LOG_INFO("The size of the network queue for " << j->first << " is "
1802 << j->second->GetSize());
1803 totalQueueSize += j->second->GetSize();
1804 NS_LOG_INFO("The total network queue size is " << totalQueueSize);
1805 }
1806 if (totalQueueSize > 5)
1807 {
1808 // Here the queue size is larger than 5, we need to increase the retransmission
1809 // timer for each packet in the network queue
1811 }
1812 DsrNetworkQueueEntry newEntry;
1813 dsrNetworkQueue->Dequeue(newEntry);
1814 if (SendRealDown(newEntry))
1815 {
1816 NS_LOG_LOGIC("Packet sent by Dsr. Calling PriorityScheduler after some time");
1817 // packet was successfully sent down. call scheduler after some time
1820 this,
1821 i,
1822 false);
1823 }
1824 else
1825 {
1826 // packet was dropped by Dsr. Call scheduler immediately so that we can
1827 // send another packet immediately.
1828 NS_LOG_LOGIC("Packet dropped by Dsr. Calling PriorityScheduler immediately");
1830 }
1831
1832 if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1833 {
1834 i = 0;
1835 }
1836 else
1837 {
1838 i++;
1839 }
1840 }
1841 }
1842}
1843
1844void
1846{
1847 NS_LOG_FUNCTION(this);
1848 // We may want to get the queue first and then we need to save a vector of the entries here and
1849 // then find
1851 auto i = m_priorityQueue.find(priority);
1852 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1853
1854 std::vector<DsrNetworkQueueEntry> newNetworkQueue = dsrNetworkQueue->GetQueue();
1855 for (auto i = newNetworkQueue.begin(); i != newNetworkQueue.end(); i++)
1856 {
1857 Ipv4Address nextHop = i->GetNextHopAddress();
1858 for (auto j = m_addressForwardTimer.begin(); j != m_addressForwardTimer.end(); j++)
1859 {
1860 if (nextHop == j->first.m_nextHop)
1861 {
1862 NS_LOG_DEBUG("The network delay left is " << j->second.GetDelayLeft());
1863 j->second.SetDelay(j->second.GetDelayLeft() + m_retransIncr);
1864 }
1865 }
1866 }
1867}
1868
1869bool
1871{
1872 NS_LOG_FUNCTION(this);
1873 Ipv4Address source = newEntry.GetSourceAddress();
1874 Ipv4Address nextHop = newEntry.GetNextHopAddress();
1875 Ptr<Packet> packet = newEntry.GetPacket()->Copy();
1876 Ptr<Ipv4Route> route = newEntry.GetIpv4Route();
1877 m_downTarget(packet, source, nextHop, GetProtocolNumber(), route);
1878 return true;
1879}
1880
1881void
1883 Ipv4Address nextHop,
1884 uint8_t protocol)
1885{
1886 NS_LOG_FUNCTION(this << nextHop << (uint32_t)protocol);
1887 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
1888
1889 // Reconstruct the route and Retransmit the data packet
1890 std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
1891 Ipv4Address destination = nodeList.back();
1892 Ipv4Address source = nodeList.front(); // Get the source address
1893 NS_LOG_INFO("The nexthop address " << nextHop << " the source " << source << " the destination "
1894 << destination);
1895 /*
1896 * Here we try to find data packet from send buffer, if packet with this destination found, send
1897 * it out
1898 */
1899 if (m_sendBuffer.Find(destination))
1900 {
1901 NS_LOG_DEBUG("destination over here " << destination);
1902
1903 /// When found a route and use it, UseExtends to the link cache
1904 if (m_routeCache->IsLinkCache())
1905 {
1906 m_routeCache->UseExtends(nodeList);
1907 }
1908 DsrSendBuffEntry entry;
1909 if (m_sendBuffer.Dequeue(destination, entry))
1910 {
1911 Ptr<Packet> packet = entry.GetPacket()->Copy();
1912 Ptr<Packet> p = packet->Copy(); // get a copy of the packet
1913 // Set the source route option
1914 DsrRoutingHeader dsrRoutingHeader;
1915 dsrRoutingHeader.SetNextHeader(protocol);
1916 dsrRoutingHeader.SetMessageType(2);
1917 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1918 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1919
1920 uint8_t length = sourceRoute.GetLength();
1921 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1922 dsrRoutingHeader.AddDsrOption(sourceRoute);
1923
1924 p->AddHeader(dsrRoutingHeader);
1925
1926 Ptr<const Packet> mtP = p->Copy();
1927 // Put the data packet in the maintenance queue for data packet retransmission
1928 DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1929 /*ourAddress=*/m_mainAddress,
1930 /*nextHop=*/nextHop,
1931 /*src=*/source,
1932 /*dst=*/destination,
1933 /*ackId=*/0,
1934 /*segsLeft=*/nodeList.size() - 2,
1935 /*expire=*/m_maxMaintainTime);
1936 bool result =
1937 m_maintainBuffer.Enqueue(newEntry); // Enqueue the packet the the maintenance buffer
1938
1939 if (result)
1940 {
1941 NetworkKey networkKey;
1942 networkKey.m_ackId = newEntry.GetAckId();
1943 networkKey.m_ourAdd = newEntry.GetOurAdd();
1944 networkKey.m_nextHop = newEntry.GetNextHop();
1945 networkKey.m_source = newEntry.GetSrc();
1946 networkKey.m_destination = newEntry.GetDst();
1947
1948 PassiveKey passiveKey;
1949 passiveKey.m_ackId = 0;
1950 passiveKey.m_source = newEntry.GetSrc();
1951 passiveKey.m_destination = newEntry.GetDst();
1952 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1953
1954 LinkKey linkKey;
1955 linkKey.m_source = newEntry.GetSrc();
1956 linkKey.m_destination = newEntry.GetDst();
1957 linkKey.m_ourAdd = newEntry.GetOurAdd();
1958 linkKey.m_nextHop = newEntry.GetNextHop();
1959
1960 m_addressForwardCnt[networkKey] = 0;
1961 m_passiveCnt[passiveKey] = 0;
1962 m_linkCnt[linkKey] = 0;
1963
1964 if (m_linkAck)
1965 {
1966 ScheduleLinkPacketRetry(newEntry, protocol);
1967 }
1968 else
1969 {
1970 NS_LOG_LOGIC("Not using link acknowledgment");
1971 if (nextHop != destination)
1972 {
1973 SchedulePassivePacketRetry(newEntry, protocol);
1974 }
1975 else
1976 {
1977 // This is the first network retry
1978 ScheduleNetworkPacketRetry(newEntry, true, protocol);
1979 }
1980 }
1981 }
1982
1983 NS_LOG_DEBUG("send buffer size here and the destination " << m_sendBuffer.GetSize()
1984 << " " << destination);
1985 if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(destination))
1986 {
1987 NS_LOG_LOGIC("Schedule sending the next packet in send buffer");
1990 this,
1991 sourceRoute,
1992 nextHop,
1993 protocol);
1994 }
1995 }
1996 else
1997 {
1998 NS_LOG_LOGIC("All queued packets are out-dated for the destination in send buffer");
1999 }
2000 }
2001 /*
2002 * Here we try to find data packet from send buffer, if packet with this destination found, send
2003 * it out
2004 */
2005 else if (m_errorBuffer.Find(destination))
2006 {
2007 DsrErrorBuffEntry entry;
2008 if (m_errorBuffer.Dequeue(destination, entry))
2009 {
2010 Ptr<Packet> packet = entry.GetPacket()->Copy();
2011 NS_LOG_DEBUG("The queued packet size " << packet->GetSize());
2012
2013 DsrRoutingHeader dsrRoutingHeader;
2014 Ptr<Packet> copyP = packet->Copy();
2015 Ptr<Packet> dsrPacket = packet->Copy();
2016 dsrPacket->RemoveHeader(dsrRoutingHeader);
2017 uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
2018 copyP->RemoveAtStart(offset); // Here the processed size is 8 bytes, which is the fixed
2019 // sized extension header
2020 /*
2021 * Peek data to get the option type as well as length and segmentsLeft field
2022 */
2023 uint32_t size = copyP->GetSize();
2024 auto data = new uint8_t[size];
2025 copyP->CopyData(data, size);
2026
2027 uint8_t optionType = 0;
2028 optionType = *(data);
2029 NS_LOG_DEBUG("The option type value in send packet " << (uint32_t)optionType);
2030 if (optionType == 3)
2031 {
2032 NS_LOG_DEBUG("The packet is error packet");
2033 Ptr<dsr::DsrOptions> dsrOption;
2034 DsrOptionHeader dsrOptionHeader;
2035
2036 uint8_t errorType = *(data + 2);
2037 NS_LOG_DEBUG("The error type");
2038 if (errorType == 1)
2039 {
2040 NS_LOG_DEBUG("The packet is route error unreach packet");
2042 copyP->RemoveHeader(rerr);
2043 NS_ASSERT(copyP->GetSize() == 0);
2044 uint8_t length = (sourceRoute.GetLength() + rerr.GetLength());
2045
2046 DsrOptionRerrUnreachHeader newUnreach;
2047 newUnreach.SetErrorType(1);
2048 newUnreach.SetErrorSrc(rerr.GetErrorSrc());
2049 newUnreach.SetUnreachNode(rerr.GetUnreachNode());
2050 newUnreach.SetErrorDst(rerr.GetErrorDst());
2051 newUnreach.SetOriginalDst(rerr.GetOriginalDst());
2052 newUnreach.SetSalvage(rerr.GetSalvage()); // Set the value about whether to
2053 // salvage a packet or not
2054
2055 std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
2056 DsrRoutingHeader newRoutingHeader;
2057 newRoutingHeader.SetNextHeader(protocol);
2058 newRoutingHeader.SetMessageType(1);
2059 newRoutingHeader.SetSourceId(GetIDfromIP(rerr.GetErrorSrc()));
2060 newRoutingHeader.SetDestId(GetIDfromIP(rerr.GetErrorDst()));
2061 newRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
2062 newRoutingHeader.AddDsrOption(newUnreach);
2063 newRoutingHeader.AddDsrOption(sourceRoute);
2064 /// When found a route and use it, UseExtends to the link cache
2065 if (m_routeCache->IsLinkCache())
2066 {
2067 m_routeCache->UseExtends(nodeList);
2068 }
2069 SetRoute(nextHop, m_mainAddress);
2070 Ptr<Packet> newPacket = Create<Packet>();
2071 newPacket->AddHeader(newRoutingHeader); // Add the extension header with rerr
2072 // and sourceRoute attached to it
2073 Ptr<NetDevice> dev =
2074 m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
2075 m_ipv4Route->SetOutputDevice(dev);
2076
2078 auto i = m_priorityQueue.find(priority);
2079 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2080 NS_LOG_DEBUG("Will be inserting into priority queue "
2081 << dsrNetworkQueue << " number: " << priority);
2082
2083 // m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (),
2084 // m_ipv4Route);
2085
2086 /// \todo New DsrNetworkQueueEntry
2087 DsrNetworkQueueEntry newEntry(newPacket,
2089 nextHop,
2091 m_ipv4Route);
2092
2093 if (dsrNetworkQueue->Enqueue(newEntry))
2094 {
2095 Scheduler(priority);
2096 }
2097 else
2098 {
2099 NS_LOG_INFO("Packet dropped as dsr network queue is full");
2100 }
2101 }
2102 }
2103
2104 if (m_errorBuffer.GetSize() != 0 && m_errorBuffer.Find(destination))
2105 {
2106 NS_LOG_LOGIC("Schedule sending the next packet in error buffer");
2109 this,
2110 sourceRoute,
2111 nextHop,
2112 protocol);
2113 }
2114 }
2115 }
2116 else
2117 {
2118 NS_LOG_DEBUG("Packet not found in either the send or error buffer");
2119 }
2120}
2121
2122bool
2124 Ipv4Address source,
2125 Ipv4Address destination,
2126 uint8_t segsLeft,
2127 uint16_t fragmentOffset,
2128 uint16_t identification,
2129 bool saveEntry)
2130{
2131 NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)segsLeft);
2132
2133 Ptr<Packet> p = packet->Copy();
2134 // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
2135 DsrPassiveBuffEntry newEntry;
2136 newEntry.SetPacket(p);
2137 newEntry.SetSource(source);
2138 newEntry.SetDestination(destination);
2139 newEntry.SetIdentification(identification);
2140 newEntry.SetFragmentOffset(fragmentOffset);
2141 newEntry.SetSegsLeft(segsLeft); // We try to make sure the segments left is larger for 1
2142
2143 NS_LOG_DEBUG("The passive buffer size " << m_passiveBuffer->GetSize());
2144
2145 if (m_passiveBuffer->AllEqual(newEntry) && (!saveEntry))
2146 {
2147 // The PromiscEqual function will remove the maintain buffer entry if equal value found
2148 // It only compares the source and destination address, ackId, and the segments left value
2149 NS_LOG_DEBUG("We get the all equal for passive buffer here");
2150
2151 DsrMaintainBuffEntry mbEntry;
2152 mbEntry.SetPacket(p);
2153 mbEntry.SetSrc(source);
2154 mbEntry.SetDst(destination);
2155 mbEntry.SetAckId(0);
2156 mbEntry.SetSegsLeft(segsLeft + 1);
2157
2158 CancelPassivePacketTimer(mbEntry);
2159 return true;
2160 }
2161 if (saveEntry)
2162 {
2163 /// Save this passive buffer entry for later check
2164 m_passiveBuffer->Enqueue(newEntry);
2165 }
2166 return false;
2167}
2168
2169bool
2171 Ipv4Address source,
2172 Ipv4Address destination,
2173 uint8_t segsLeft)
2174{
2175 NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)segsLeft);
2176
2177 NS_LOG_DEBUG("Cancel the passive timer");
2178
2179 Ptr<Packet> p = packet->Copy();
2180 // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
2181 DsrMaintainBuffEntry newEntry;
2182 newEntry.SetPacket(p);
2183 newEntry.SetSrc(source);
2184 newEntry.SetDst(destination);
2185 newEntry.SetAckId(0);
2186 newEntry.SetSegsLeft(segsLeft + 1);
2187
2188 if (m_maintainBuffer.PromiscEqual(newEntry))
2189 {
2190 // The PromiscEqual function will remove the maintain buffer entry if equal value found
2191 // It only compares the source and destination address, ackId, and the segments left value
2192 CancelPassivePacketTimer(newEntry);
2193 return true;
2194 }
2195 return false;
2196}
2197
2198void
2200 const Ipv4Header& ipv4Header,
2201 Ipv4Address realSrc,
2202 Ipv4Address realDst)
2203{
2204 NS_LOG_FUNCTION(this << (uint32_t)ackId << ipv4Header << realSrc << realDst);
2205 Ipv4Address sender = ipv4Header.GetDestination();
2206 Ipv4Address receiver = ipv4Header.GetSource();
2207 /*
2208 * Create a packet to fill maintenance buffer, not used to compare with maintenance entry
2209 * The reason is ack header doesn't have the original packet copy
2210 */
2211 Ptr<Packet> mainP = Create<Packet>();
2212 DsrMaintainBuffEntry newEntry(/*packet=*/mainP,
2213 /*ourAddress=*/sender,
2214 /*nextHop=*/receiver,
2215 /*src=*/realSrc,
2216 /*dst=*/realDst,
2217 /*ackId=*/ackId,
2218 /*segsLeft=*/0,
2219 /*expire=*/Simulator::Now());
2220 CancelNetworkPacketTimer(newEntry); // Only need to cancel network packet timer
2221}
2222
2223void
2225{
2226 NS_LOG_FUNCTION(this);
2230}
2231
2232void
2234{
2235 NS_LOG_FUNCTION(this);
2236 LinkKey linkKey;
2237 linkKey.m_ourAdd = mb.GetOurAdd();
2238 linkKey.m_nextHop = mb.GetNextHop();
2239 linkKey.m_source = mb.GetSrc();
2240 linkKey.m_destination = mb.GetDst();
2241 /*
2242 * Here we have found the entry for send retries, so we get the value and increase it by one
2243 */
2244 /// TODO need to think about this part
2245 m_linkCnt[linkKey] = 0;
2246 m_linkCnt.erase(linkKey);
2247
2248 // TODO if find the linkkey, we need to remove it
2249
2250 // Find the network acknowledgment timer
2251 auto i = m_linkAckTimer.find(linkKey);
2252 if (i == m_linkAckTimer.end())
2253 {
2254 NS_LOG_INFO("did not find the link timer");
2255 }
2256 else
2257 {
2258 NS_LOG_INFO("did find the link timer");
2259 /*
2260 * Schedule the packet retry
2261 * Push back the nextHop, source, destination address
2262 */
2263 m_linkAckTimer[linkKey].Cancel();
2264 if (m_linkAckTimer[linkKey].IsRunning())
2265 {
2266 NS_LOG_INFO("Timer not canceled");
2267 }
2268 m_linkAckTimer.erase(linkKey);
2269 }
2270
2271 // Erase the maintenance entry
2272 // yet this does not check the segments left value here
2273 NS_LOG_DEBUG("The link buffer size " << m_maintainBuffer.GetSize());
2275 {
2276 NS_LOG_INFO("Link acknowledgment received, remove same maintenance buffer entry");
2277 }
2278}
2279
2280void
2282{
2283 NS_LOG_FUNCTION(this);
2284 NetworkKey networkKey;
2285 networkKey.m_ackId = mb.GetAckId();
2286 networkKey.m_ourAdd = mb.GetOurAdd();
2287 networkKey.m_nextHop = mb.GetNextHop();
2288 networkKey.m_source = mb.GetSrc();
2289 networkKey.m_destination = mb.GetDst();
2290 /*
2291 * Here we have found the entry for send retries, so we get the value and increase it by one
2292 */
2293 m_addressForwardCnt[networkKey] = 0;
2294 m_addressForwardCnt.erase(networkKey);
2295
2296 NS_LOG_INFO("ackId " << mb.GetAckId() << " ourAdd " << mb.GetOurAdd() << " nextHop "
2297 << mb.GetNextHop() << " source " << mb.GetSrc() << " destination "
2298 << mb.GetDst() << " segsLeft " << (uint32_t)mb.GetSegsLeft());
2299 // Find the network acknowledgment timer
2300 auto i = m_addressForwardTimer.find(networkKey);
2301 if (i == m_addressForwardTimer.end())
2302 {
2303 NS_LOG_INFO("did not find the packet timer");
2304 }
2305 else
2306 {
2307 NS_LOG_INFO("did find the packet timer");
2308 /*
2309 * Schedule the packet retry
2310 * Push back the nextHop, source, destination address
2311 */
2312 m_addressForwardTimer[networkKey].Cancel();
2313 if (m_addressForwardTimer[networkKey].IsRunning())
2314 {
2315 NS_LOG_INFO("Timer not canceled");
2316 }
2317 m_addressForwardTimer.erase(networkKey);
2318 }
2319 // Erase the maintenance entry
2320 // yet this does not check the segments left value here
2322 {
2323 NS_LOG_INFO("Remove same maintenance buffer entry based on network acknowledgment");
2324 }
2325}
2326
2327void
2329{
2330 NS_LOG_FUNCTION(this);
2331 PassiveKey passiveKey;
2332 passiveKey.m_ackId = 0;
2333 passiveKey.m_source = mb.GetSrc();
2334 passiveKey.m_destination = mb.GetDst();
2335 passiveKey.m_segsLeft = mb.GetSegsLeft();
2336
2337 m_passiveCnt[passiveKey] = 0;
2338 m_passiveCnt.erase(passiveKey);
2339
2340 // Find the passive acknowledgment timer
2341 auto j = m_passiveAckTimer.find(passiveKey);
2342 if (j == m_passiveAckTimer.end())
2343 {
2344 NS_LOG_INFO("did not find the passive timer");
2345 }
2346 else
2347 {
2348 NS_LOG_INFO("find the passive timer");
2349 /*
2350 * Cancel passive acknowledgment timer
2351 */
2352 m_passiveAckTimer[passiveKey].Cancel();
2353 if (m_passiveAckTimer[passiveKey].IsRunning())
2354 {
2355 NS_LOG_INFO("Timer not canceled");
2356 }
2357 m_passiveAckTimer.erase(passiveKey);
2358 }
2359}
2360
2361void
2363{
2364 NS_LOG_FUNCTION(this << nextHop << (uint32_t)protocol);
2365
2367 std::vector<Ipv4Address> previousErrorDst;
2368 if (m_maintainBuffer.Dequeue(nextHop, entry))
2369 {
2370 Ipv4Address source = entry.GetSrc();
2371 Ipv4Address destination = entry.GetDst();
2372
2373 Ptr<Packet> dsrP = entry.GetPacket()->Copy();
2374 Ptr<Packet> p = dsrP->Copy();
2375 Ptr<Packet> packet = dsrP->Copy();
2376 DsrRoutingHeader dsrRoutingHeader;
2377 dsrP->RemoveHeader(dsrRoutingHeader); // Remove the dsr header in whole
2378 uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
2379 p->RemoveAtStart(offset);
2380
2381 // Get the number of routers' address field
2382 uint8_t buf[2];
2383 p->CopyData(buf, sizeof(buf));
2384 uint8_t numberAddress = (buf[1] - 2) / 4;
2385 NS_LOG_DEBUG("The number of addresses " << (uint32_t)numberAddress);
2386 DsrOptionSRHeader sourceRoute;
2387 sourceRoute.SetNumberAddress(numberAddress);
2388 p->RemoveHeader(sourceRoute);
2389 std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
2390 uint8_t salvage = sourceRoute.GetSalvage();
2391 Ipv4Address address1 = nodeList[1];
2392 PrintVector(nodeList);
2393
2394 /*
2395 * If the salvage is not 0, use the first address in the route as the error dst in error
2396 * header otherwise use the source of packet as the error destination
2397 */
2398 Ipv4Address errorDst;
2399 if (salvage)
2400 {
2401 errorDst = address1;
2402 }
2403 else
2404 {
2405 errorDst = source;
2406 }
2407 /// TODO if the errorDst is not seen before
2408 if (std::find(previousErrorDst.begin(), previousErrorDst.end(), destination) ==
2409 previousErrorDst.end())
2410 {
2411 NS_LOG_DEBUG("have not seen this dst before " << errorDst << " in "
2412 << previousErrorDst.size());
2413 SendUnreachError(nextHop, errorDst, destination, salvage, protocol);
2414 previousErrorDst.push_back(errorDst);
2415 }
2416
2417 /*
2418 * Cancel the packet timer and then salvage the data packet
2419 */
2420
2421 CancelPacketAllTimer(entry);
2422 SalvagePacket(packet, source, destination, protocol);
2423
2425 {
2426 NS_LOG_INFO("Cancel the packet timer for next maintenance entry");
2429 this,
2430 nextHop,
2431 protocol);
2432 }
2433 }
2434 else
2435 {
2436 NS_LOG_INFO("Maintenance buffer entry not found");
2437 }
2438 /// TODO need to think about whether we need the network queue entry or not
2439}
2440
2441void
2443 Ipv4Address source,
2444 Ipv4Address dst,
2445 uint8_t protocol)
2446{
2447 NS_LOG_FUNCTION(this << packet << source << dst << (uint32_t)protocol);
2448 // Create two copies of packet
2449 Ptr<Packet> p = packet->Copy();
2450 Ptr<Packet> newPacket = packet->Copy();
2451 // Remove the routing header in a whole to get a clean packet
2452 DsrRoutingHeader dsrRoutingHeader;
2453 p->RemoveHeader(dsrRoutingHeader);
2454 // Remove offset of dsr routing header
2455 uint8_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
2456 newPacket->RemoveAtStart(offset);
2457
2458 // Get the number of routers' address field
2459 uint8_t buf[2];
2460 newPacket->CopyData(buf, sizeof(buf));
2461 uint8_t numberAddress = (buf[1] - 2) / 4;
2462
2463 DsrOptionSRHeader sourceRoute;
2464 sourceRoute.SetNumberAddress(numberAddress);
2465 newPacket->RemoveHeader(sourceRoute);
2466 uint8_t salvage = sourceRoute.GetSalvage();
2467 /*
2468 * Look in the route cache for other routes for this destination
2469 */
2470 DsrRouteCacheEntry toDst;
2471 bool findRoute = m_routeCache->LookupRoute(dst, toDst);
2472 if (findRoute && (salvage < m_maxSalvageCount))
2473 {
2474 NS_LOG_DEBUG("We have found a route for the packet");
2475 DsrRoutingHeader newDsrRoutingHeader;
2476 newDsrRoutingHeader.SetNextHeader(protocol);
2477 newDsrRoutingHeader.SetMessageType(2);
2478 newDsrRoutingHeader.SetSourceId(GetIDfromIP(source));
2479 newDsrRoutingHeader.SetDestId(GetIDfromIP(dst));
2480
2481 std::vector<Ipv4Address> nodeList =
2482 toDst.GetVector(); // Get the route from the route entry we found
2483 Ipv4Address nextHop =
2484 SearchNextHop(m_mainAddress, nodeList); // Get the next hop address for the route
2485 if (nextHop == "0.0.0.0")
2486 {
2487 PacketNewRoute(p, source, dst, protocol);
2488 return;
2489 }
2490 // Increase the salvage count by 1
2491 salvage++;
2492 DsrOptionSRHeader sourceRoute;
2493 sourceRoute.SetSalvage(salvage);
2494 // Save the whole route in the source route header of the packet
2495 sourceRoute.SetNodesAddress(nodeList);
2496 // The segmentsLeft field will indicate the hops to go
2497 sourceRoute.SetSegmentsLeft(nodeList.size() - 2);
2498 /// When found a route and use it, UseExtends to the link cache
2499 if (m_routeCache->IsLinkCache())
2500 {
2501 m_routeCache->UseExtends(nodeList);
2502 }
2503 uint8_t length = sourceRoute.GetLength();
2504 NS_LOG_INFO("length of source route header " << (uint32_t)(sourceRoute.GetLength()));
2505 newDsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
2506 newDsrRoutingHeader.AddDsrOption(sourceRoute);
2507 p->AddHeader(newDsrRoutingHeader);
2508
2509 SetRoute(nextHop, m_mainAddress);
2510 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
2511 m_ipv4Route->SetOutputDevice(dev);
2512
2513 // Send out the data packet
2515 auto i = m_priorityQueue.find(priority);
2516 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2517 NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue
2518 << " number: " << priority);
2519
2520 // m_downTarget (p, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
2521
2522 /// \todo New DsrNetworkQueueEntry
2524
2525 if (dsrNetworkQueue->Enqueue(newEntry))
2526 {
2527 Scheduler(priority);
2528 }
2529 else
2530 {
2531 NS_LOG_INFO("Packet dropped as dsr network queue is full");
2532 }
2533
2534 /*
2535 * Mark the next hop address in blacklist
2536 */
2537 // NS_LOG_DEBUG ("Save the next hop node in blacklist");
2538 // m_rreqTable->MarkLinkAsUnidirectional (nextHop, m_blacklistTimeout);
2539 }
2540 else
2541 {
2542 NS_LOG_DEBUG("Will not salvage this packet, silently drop");
2543 }
2544}
2545
2546void
2548{
2549 NS_LOG_FUNCTION(this << (uint32_t)protocol);
2550
2551 Ptr<Packet> p = mb.GetPacket()->Copy();
2552 Ipv4Address source = mb.GetSrc();
2553 Ipv4Address nextHop = mb.GetNextHop();
2554
2555 // Send the data packet out before schedule the next packet transmission
2556 SendPacket(p, source, nextHop, protocol);
2557
2558 LinkKey linkKey;
2559 linkKey.m_source = mb.GetSrc();
2560 linkKey.m_destination = mb.GetDst();
2561 linkKey.m_ourAdd = mb.GetOurAdd();
2562 linkKey.m_nextHop = mb.GetNextHop();
2563
2564 if (m_linkAckTimer.find(linkKey) == m_linkAckTimer.end())
2565 {
2567 m_linkAckTimer[linkKey] = timer;
2568 }
2569 m_linkAckTimer[linkKey].SetFunction(&DsrRouting::LinkScheduleTimerExpire, this);
2570 m_linkAckTimer[linkKey].Cancel();
2571 m_linkAckTimer[linkKey].SetArguments(mb, protocol);
2572 m_linkAckTimer[linkKey].Schedule(m_linkAckTimeout);
2573}
2574
2575void
2577{
2578 NS_LOG_FUNCTION(this << (uint32_t)protocol);
2579
2580 Ptr<Packet> p = mb.GetPacket()->Copy();
2581 Ipv4Address source = mb.GetSrc();
2582 Ipv4Address nextHop = mb.GetNextHop();
2583
2584 // Send the data packet out before schedule the next packet transmission
2585 SendPacket(p, source, nextHop, protocol);
2586
2587 PassiveKey passiveKey;
2588 passiveKey.m_ackId = 0;
2589 passiveKey.m_source = mb.GetSrc();
2590 passiveKey.m_destination = mb.GetDst();
2591 passiveKey.m_segsLeft = mb.GetSegsLeft();
2592
2593 if (m_passiveAckTimer.find(passiveKey) == m_passiveAckTimer.end())
2594 {
2596 m_passiveAckTimer[passiveKey] = timer;
2597 }
2598 NS_LOG_DEBUG("The passive acknowledgment option for data packet");
2599 m_passiveAckTimer[passiveKey].SetFunction(&DsrRouting::PassiveScheduleTimerExpire, this);
2600 m_passiveAckTimer[passiveKey].Cancel();
2601 m_passiveAckTimer[passiveKey].SetArguments(mb, protocol);
2602 m_passiveAckTimer[passiveKey].Schedule(m_passiveAckTimeout);
2603}
2604
2605void
2607{
2608 Ptr<Packet> p = Create<Packet>();
2609 Ptr<Packet> dsrP = Create<Packet>();
2610 // The new entry will be used for retransmission
2611 NetworkKey networkKey;
2612 Ipv4Address nextHop = mb.GetNextHop();
2613 NS_LOG_DEBUG("is the first retry or not " << isFirst);
2614 if (isFirst)
2615 {
2616 // This is the very first network packet retry
2617 p = mb.GetPacket()->Copy();
2618 // Here we add the ack request header to the data packet for network acknowledgement
2619 uint16_t ackId = AddAckReqHeader(p, nextHop);
2620
2621 Ipv4Address source = mb.GetSrc();
2622 Ipv4Address nextHop = mb.GetNextHop();
2623 // Send the data packet out before schedule the next packet transmission
2624 SendPacket(p, source, nextHop, protocol);
2625
2626 dsrP = p->Copy();
2627 DsrMaintainBuffEntry newEntry = mb;
2628 // The function AllEqual will find the exact entry and delete it if found
2630 newEntry.SetPacket(dsrP);
2631 newEntry.SetAckId(ackId);
2633
2634 networkKey.m_ackId = newEntry.GetAckId();
2635 networkKey.m_ourAdd = newEntry.GetOurAdd();
2636 networkKey.m_nextHop = newEntry.GetNextHop();
2637 networkKey.m_source = newEntry.GetSrc();
2638 networkKey.m_destination = newEntry.GetDst();
2639
2640 m_addressForwardCnt[networkKey] = 0;
2641 if (!m_maintainBuffer.Enqueue(newEntry))
2642 {
2643 NS_LOG_ERROR("Failed to enqueue packet retry");
2644 }
2645
2646 if (m_addressForwardTimer.find(networkKey) == m_addressForwardTimer.end())
2647 {
2649 m_addressForwardTimer[networkKey] = timer;
2650 }
2651
2652 // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment
2653 // option
2655 this);
2656 m_addressForwardTimer[networkKey].Cancel();
2657 m_addressForwardTimer[networkKey].SetArguments(newEntry, protocol);
2658 NS_LOG_DEBUG("The packet retries time for " << newEntry.GetAckId() << " is "
2659 << m_sendRetries << " and the delay time is "
2660 << Time(2 * m_nodeTraversalTime).As(Time::S));
2661 // Back-off mechanism
2662 m_addressForwardTimer[networkKey].Schedule(Time(2 * m_nodeTraversalTime));
2663 }
2664 else
2665 {
2666 networkKey.m_ackId = mb.GetAckId();
2667 networkKey.m_ourAdd = mb.GetOurAdd();
2668 networkKey.m_nextHop = mb.GetNextHop();
2669 networkKey.m_source = mb.GetSrc();
2670 networkKey.m_destination = mb.GetDst();
2671 /*
2672 * Here we have found the entry for send retries, so we get the value and increase it by one
2673 */
2674 m_sendRetries = m_addressForwardCnt[networkKey];
2675 NS_LOG_DEBUG("The packet retry we have done " << m_sendRetries);
2676
2677 p = mb.GetPacket()->Copy();
2678 dsrP = mb.GetPacket()->Copy();
2679
2680 Ipv4Address source = mb.GetSrc();
2681 Ipv4Address nextHop = mb.GetNextHop();
2682 // Send the data packet out before schedule the next packet transmission
2683 SendPacket(p, source, nextHop, protocol);
2684
2685 NS_LOG_DEBUG("The packet with dsr header " << dsrP->GetSize());
2686 networkKey.m_ackId = mb.GetAckId();
2687 networkKey.m_ourAdd = mb.GetOurAdd();
2688 networkKey.m_nextHop = mb.GetNextHop();
2689 networkKey.m_source = mb.GetSrc();
2690 networkKey.m_destination = mb.GetDst();
2691 /*
2692 * If a data packet has been attempted SendRetries times at the maximum TTL without
2693 * receiving any ACK, all data packets destined for the corresponding destination SHOULD be
2694 * dropped from the send buffer
2695 *
2696 * The maxMaintRexmt also needs to decrease one for the passive ack packet
2697 */
2698 /*
2699 * Check if the send retry time for a certain packet has already passed max maintenance
2700 * retransmission time or not
2701 */
2702
2703 // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment
2704 // option
2706 this);
2707 m_addressForwardTimer[networkKey].Cancel();
2708 m_addressForwardTimer[networkKey].SetArguments(mb, protocol);
2709 NS_LOG_DEBUG("The packet retries time for "
2710 << mb.GetAckId() << " is " << m_sendRetries << " and the delay time is "
2712 // Back-off mechanism
2713 m_addressForwardTimer[networkKey].Schedule(Time(2 * m_sendRetries * m_nodeTraversalTime));
2714 }
2715}
2716
2717void
2719{
2720 NS_LOG_FUNCTION(this << (uint32_t)protocol);
2721 Ipv4Address nextHop = mb.GetNextHop();
2722 Ptr<const Packet> packet = mb.GetPacket();
2723 SetRoute(nextHop, m_mainAddress);
2724 Ptr<Packet> p = packet->Copy();
2725
2726 LinkKey lk;
2727 lk.m_source = mb.GetSrc();
2728 lk.m_destination = mb.GetDst();
2729 lk.m_ourAdd = mb.GetOurAdd();
2730 lk.m_nextHop = mb.GetNextHop();
2731
2732 // Cancel passive ack timer
2733 m_linkAckTimer[lk].Cancel();
2734 if (m_linkAckTimer[lk].IsRunning())
2735 {
2736 NS_LOG_DEBUG("Timer not canceled");
2737 }
2738 m_linkAckTimer.erase(lk);
2739
2740 // Increase the send retry times
2743 {
2744 m_linkCnt[lk] = ++m_linkRetries;
2745 ScheduleLinkPacketRetry(mb, protocol);
2746 }
2747 else
2748 {
2749 NS_LOG_INFO("We need to send error messages now");
2750
2751 // Delete all the routes including the links
2752 m_routeCache->DeleteAllRoutesIncludeLink(m_mainAddress, nextHop, m_mainAddress);
2753 /*
2754 * here we cancel the packet retransmission time for all the packets have next hop address
2755 * as nextHop Also salvage the packet for the all the packet destined for the nextHop
2756 * address this is also responsible for send unreachable error back to source
2757 */
2758 CancelPacketTimerNextHop(nextHop, protocol);
2759 }
2760}
2761
2762void
2764{
2765 NS_LOG_FUNCTION(this << (uint32_t)protocol);
2766 Ipv4Address nextHop = mb.GetNextHop();
2767 Ptr<const Packet> packet = mb.GetPacket();
2768 SetRoute(nextHop, m_mainAddress);
2769 Ptr<Packet> p = packet->Copy();
2770
2771 PassiveKey pk;
2772 pk.m_ackId = 0;
2773 pk.m_source = mb.GetSrc();
2774 pk.m_destination = mb.GetDst();
2775 pk.m_segsLeft = mb.GetSegsLeft();
2776
2777 // Cancel passive ack timer
2778 m_passiveAckTimer[pk].Cancel();
2779 if (m_passiveAckTimer[pk].IsRunning())
2780 {
2781 NS_LOG_DEBUG("Timer not canceled");
2782 }
2783 m_passiveAckTimer.erase(pk);
2784
2785 // Increase the send retry times
2788 {
2790 SchedulePassivePacketRetry(mb, protocol);
2791 }
2792 else
2793 {
2794 // This is the first network acknowledgement retry
2795 // Cancel the passive packet timer now and remove maintenance buffer entry for it
2797 ScheduleNetworkPacketRetry(mb, true, protocol);
2798 }
2799}
2800
2801int64_t
2803{
2804 NS_LOG_FUNCTION(this << stream);
2806 return 1;
2807}
2808
2809void
2811{
2812 Ptr<Packet> p = mb.GetPacket()->Copy();
2813 Ipv4Address source = mb.GetSrc();
2814 Ipv4Address nextHop = mb.GetNextHop();
2815 Ipv4Address dst = mb.GetDst();
2816
2817 NetworkKey networkKey;
2818 networkKey.m_ackId = mb.GetAckId();
2819 networkKey.m_ourAdd = mb.GetOurAdd();
2820 networkKey.m_nextHop = nextHop;
2821 networkKey.m_source = source;
2822 networkKey.m_destination = dst;
2823
2824 // Increase the send retry times
2825 m_sendRetries = m_addressForwardCnt[networkKey];
2826
2828 {
2829 // Delete all the routes including the links
2830 m_routeCache->DeleteAllRoutesIncludeLink(m_mainAddress, nextHop, m_mainAddress);
2831 /*
2832 * here we cancel the packet retransmission time for all the packets have next hop address
2833 * as nextHop Also salvage the packet for the all the packet destined for the nextHop
2834 * address
2835 */
2836 CancelPacketTimerNextHop(nextHop, protocol);
2837 }
2838 else
2839 {
2840 m_addressForwardCnt[networkKey] = ++m_sendRetries;
2841 ScheduleNetworkPacketRetry(mb, false, protocol);
2842 }
2843}
2844
2845void
2847 DsrOptionSRHeader& sourceRoute,
2848 const Ipv4Header& ipv4Header,
2849 Ipv4Address source,
2850 Ipv4Address nextHop,
2851 Ipv4Address targetAddress,
2852 uint8_t protocol,
2853 Ptr<Ipv4Route> route)
2854{
2855 NS_LOG_FUNCTION(this << packet << sourceRoute << source << nextHop << targetAddress
2856 << (uint32_t)protocol << route);
2857 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
2858
2859 DsrRoutingHeader dsrRoutingHeader;
2860 dsrRoutingHeader.SetNextHeader(protocol);
2861 dsrRoutingHeader.SetMessageType(2);
2862 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
2863 dsrRoutingHeader.SetDestId(GetIDfromIP(targetAddress));
2864
2865 // We get the salvage value in sourceRoute header and set it to route error header if triggered
2866 // error
2867 Ptr<Packet> p = packet->Copy();
2868 uint8_t length = sourceRoute.GetLength();
2869 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
2870 dsrRoutingHeader.AddDsrOption(sourceRoute);
2871 p->AddHeader(dsrRoutingHeader);
2872
2873 Ptr<const Packet> mtP = p->Copy();
2874
2875 DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
2876 /*ourAddress=*/m_mainAddress,
2877 /*nextHop=*/nextHop,
2878 /*src=*/source,
2879 /*dst=*/targetAddress,
2880 /*ackId=*/m_ackId,
2881 /*segsLeft=*/sourceRoute.GetSegmentsLeft(),
2882 /*expire=*/m_maxMaintainTime);
2883 bool result = m_maintainBuffer.Enqueue(newEntry);
2884
2885 if (result)
2886 {
2887 NetworkKey networkKey;
2888 networkKey.m_ackId = newEntry.GetAckId();
2889 networkKey.m_ourAdd = newEntry.GetOurAdd();
2890 networkKey.m_nextHop = newEntry.GetNextHop();
2891 networkKey.m_source = newEntry.GetSrc();
2892 networkKey.m_destination = newEntry.GetDst();
2893
2894 PassiveKey passiveKey;
2895 passiveKey.m_ackId = 0;
2896 passiveKey.m_source = newEntry.GetSrc();
2897 passiveKey.m_destination = newEntry.GetDst();
2898 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
2899
2900 LinkKey linkKey;
2901 linkKey.m_source = newEntry.GetSrc();
2902 linkKey.m_destination = newEntry.GetDst();
2903 linkKey.m_ourAdd = newEntry.GetOurAdd();
2904 linkKey.m_nextHop = newEntry.GetNextHop();
2905
2906 m_addressForwardCnt[networkKey] = 0;
2907 m_passiveCnt[passiveKey] = 0;
2908 m_linkCnt[linkKey] = 0;
2909
2910 if (m_linkAck)
2911 {
2912 ScheduleLinkPacketRetry(newEntry, protocol);
2913 }
2914 else
2915 {
2916 NS_LOG_LOGIC("Not using link acknowledgment");
2917 if (nextHop != targetAddress)
2918 {
2919 SchedulePassivePacketRetry(newEntry, protocol);
2920 }
2921 else
2922 {
2923 // This is the first network retry
2924 ScheduleNetworkPacketRetry(newEntry, true, protocol);
2925 }
2926 }
2927 }
2928}
2929
2930void
2931DsrRouting::SendInitialRequest(Ipv4Address source, Ipv4Address destination, uint8_t protocol)
2932{
2933 NS_LOG_FUNCTION(this << source << destination << (uint32_t)protocol);
2934 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
2935 Ptr<Packet> packet = Create<Packet>();
2936 // Create an empty Ipv4 route ptr
2937 Ptr<Ipv4Route> route;
2938 /*
2939 * Construct the route request option header
2940 */
2941 DsrRoutingHeader dsrRoutingHeader;
2942 dsrRoutingHeader.SetNextHeader(protocol);
2943 dsrRoutingHeader.SetMessageType(1);
2944 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
2945 dsrRoutingHeader.SetDestId(255);
2946
2947 DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
2948 rreqHeader.AddNodeAddress(m_mainAddress); // Add our own address in the header
2949 rreqHeader.SetTarget(destination);
2950 m_requestId =
2951 m_rreqTable->CheckUniqueRreqId(destination); // Check the Id cache for duplicate ones
2952 rreqHeader.SetId(m_requestId);
2953
2954 dsrRoutingHeader.AddDsrOption(rreqHeader); // Add the rreqHeader to the dsr extension header
2955 uint8_t length = rreqHeader.GetLength();
2956 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
2957 packet->AddHeader(dsrRoutingHeader);
2958
2959 // Schedule the route requests retry with non-propagation set true
2960 bool nonProp = true;
2961 std::vector<Ipv4Address> address;
2962 address.push_back(source);
2963 address.push_back(destination);
2964 /*
2965 * Add the socket ip ttl tag to the packet to limit the scope of route requests
2966 */
2967 SocketIpTtlTag tag;
2968 tag.SetTtl(0);
2969 Ptr<Packet> nonPropPacket = packet->Copy();
2970 nonPropPacket->AddPacketTag(tag);
2971 // Increase the request count
2972 m_rreqTable->FindAndUpdate(destination);
2973 SendRequest(nonPropPacket, source);
2974 // Schedule the next route request
2975 ScheduleRreqRetry(packet, address, nonProp, m_requestId, protocol);
2976}
2977
2978void
2980{
2981 NS_LOG_FUNCTION(this << (uint32_t)protocol);
2982 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
2983 uint8_t salvage = rerr.GetSalvage();
2984 Ipv4Address dst = rerr.GetOriginalDst();
2985 NS_LOG_DEBUG("our own address here " << m_mainAddress << " error source " << rerr.GetErrorSrc()
2986 << " error destination " << rerr.GetErrorDst()
2987 << " error next hop " << rerr.GetUnreachNode()
2988 << " original dst " << rerr.GetOriginalDst());
2989 DsrRouteCacheEntry toDst;
2990 if (m_routeCache->LookupRoute(dst, toDst))
2991 {
2992 /*
2993 * Found a route the dst, construct the source route option header
2994 */
2995 DsrOptionSRHeader sourceRoute;
2996 std::vector<Ipv4Address> ip = toDst.GetVector();
2997 sourceRoute.SetNodesAddress(ip);
2998 /// When found a route and use it, UseExtends to the link cache
2999 if (m_routeCache->IsLinkCache())
3000 {
3001 m_routeCache->UseExtends(ip);
3002 }
3003 sourceRoute.SetSegmentsLeft(ip.size() - 2);
3004 sourceRoute.SetSalvage(salvage);
3005 Ipv4Address nextHop = SearchNextHop(m_mainAddress, ip); // Get the next hop address
3006 NS_LOG_DEBUG("The nextHop address " << nextHop);
3007 Ptr<Packet> packet = Create<Packet>();
3008 if (nextHop == "0.0.0.0")
3009 {
3010 NS_LOG_DEBUG("Error next hop address");
3011 PacketNewRoute(packet, m_mainAddress, dst, protocol);
3012 return;
3013 }
3014 SetRoute(nextHop, m_mainAddress);
3015 CancelRreqTimer(dst, true);
3016 /// Try to send out the packet from the buffer once we found one route
3017 if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(dst))
3018 {
3019 SendPacketFromBuffer(sourceRoute, nextHop, protocol);
3020 }
3021 NS_LOG_LOGIC("Route to " << dst << " found");
3022 }
3023 else
3024 {
3025 NS_LOG_INFO("No route found, initiate route error request");
3026 Ptr<Packet> packet = Create<Packet>();
3027 Ipv4Address originalDst = rerr.GetOriginalDst();
3028 // Create an empty route ptr
3029 Ptr<Ipv4Route> route = nullptr;
3030 /*
3031 * Construct the route request option header
3032 */
3033 DsrRoutingHeader dsrRoutingHeader;
3034 dsrRoutingHeader.SetNextHeader(protocol);
3035 dsrRoutingHeader.SetMessageType(1);
3036 dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
3037 dsrRoutingHeader.SetDestId(255);
3038
3039 Ptr<Packet> dstP = Create<Packet>();
3040 DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
3041 rreqHeader.AddNodeAddress(m_mainAddress); // Add our own address in the header
3042 rreqHeader.SetTarget(originalDst);
3043 m_requestId =
3044 m_rreqTable->CheckUniqueRreqId(originalDst); // Check the Id cache for duplicate ones
3045 rreqHeader.SetId(m_requestId);
3046
3047 dsrRoutingHeader.AddDsrOption(rreqHeader); // Add the rreqHeader to the dsr extension header
3048 dsrRoutingHeader.AddDsrOption(rerr);
3049 uint8_t length = rreqHeader.GetLength() + rerr.GetLength();
3050 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
3051 dstP->AddHeader(dsrRoutingHeader);
3052 // Schedule the route requests retry, propagate the route request message as it contains
3053 // error
3054 bool nonProp = false;
3055 std::vector<Ipv4Address> address;
3056 address.push_back(m_mainAddress);
3057 address.push_back(originalDst);
3058 /*
3059 * Add the socket ip ttl tag to the packet to limit the scope of route requests
3060 */
3061 SocketIpTtlTag tag;
3062 tag.SetTtl((uint8_t)m_discoveryHopLimit);
3063 Ptr<Packet> propPacket = dstP->Copy();
3064 propPacket->AddPacketTag(tag);
3065
3066 if ((m_addressReqTimer.find(originalDst) == m_addressReqTimer.end()) &&
3067 (m_nonPropReqTimer.find(originalDst) == m_nonPropReqTimer.end()))
3068 {
3069 NS_LOG_INFO("Only when there is no existing route request time when the initial route "
3070 "request is scheduled");
3071 SendRequest(propPacket, m_mainAddress);
3072 ScheduleRreqRetry(dstP, address, nonProp, m_requestId, protocol);
3073 }
3074 else
3075 {
3076 NS_LOG_INFO("There is existing route request, find the existing route request entry");
3077 /*
3078 * Cancel the route request timer first before scheduling the route request
3079 * in this case, we do not want to remove the route request entry, so the isRemove value
3080 * is false
3081 */
3082 CancelRreqTimer(originalDst, false);
3083 ScheduleRreqRetry(dstP, address, nonProp, m_requestId, protocol);
3084 }
3085 }
3086}
3087
3088void
3090{
3091 NS_LOG_FUNCTION(this << dst << isRemove);
3092 // Cancel the non propagation request timer if found
3093 if (m_nonPropReqTimer.find(dst) == m_nonPropReqTimer.end())
3094 {
3095 NS_LOG_DEBUG("Did not find the non-propagation timer");
3096 }
3097 else
3098 {
3099 NS_LOG_DEBUG("did find the non-propagation timer");
3100 }
3101 m_nonPropReqTimer[dst].Cancel();
3102
3103 if (m_nonPropReqTimer[dst].IsRunning())
3104 {
3105 NS_LOG_DEBUG("Timer not canceled");
3106 }
3107 m_nonPropReqTimer.erase(dst);
3108
3109 // Cancel the address request timer if found
3110 if (m_addressReqTimer.find(dst) == m_addressReqTimer.end())
3111 {
3112 NS_LOG_DEBUG("Did not find the propagation timer");
3113 }
3114 else
3115 {
3116 NS_LOG_DEBUG("did find the propagation timer");
3117 }
3118 m_addressReqTimer[dst].Cancel();
3119 if (m_addressReqTimer[dst].IsRunning())
3120 {
3121 NS_LOG_DEBUG("Timer not canceled");
3122 }
3123 m_addressReqTimer.erase(dst);
3124 /*
3125 * If the route request is scheduled to remove the route request entry
3126 * Remove the route request entry with the route retry times done for certain destination
3127 */
3128 if (isRemove)
3129 {
3130 // remove the route request entry from route request table
3131 m_rreqTable->RemoveRreqEntry(dst);
3132 }
3133}
3134
3135void
3137 std::vector<Ipv4Address> address,
3138 bool nonProp,
3139 uint32_t requestId,
3140 uint8_t protocol)
3141{
3142 NS_LOG_FUNCTION(this << packet << nonProp << requestId << (uint32_t)protocol);
3143 Ipv4Address source = address[0];
3144 Ipv4Address dst = address[1];
3145 if (nonProp)
3146 {
3147 // The nonProp route request is only sent out only and is already used
3148 if (m_nonPropReqTimer.find(dst) == m_nonPropReqTimer.end())
3149 {
3151 m_nonPropReqTimer[dst] = timer;
3152 }
3153 std::vector<Ipv4Address> address;
3154 address.push_back(source);
3155 address.push_back(dst);
3157 m_nonPropReqTimer[dst].Cancel();
3158 m_nonPropReqTimer[dst].SetArguments(packet, address, requestId, protocol);
3160 }
3161 else
3162 {
3163 // Cancel the non propagation request timer if found
3164 m_nonPropReqTimer[dst].Cancel();
3165 if (m_nonPropReqTimer[dst].IsRunning())
3166 {
3167 NS_LOG_DEBUG("Timer not canceled");
3168 }
3169 m_nonPropReqTimer.erase(dst);
3170
3171 if (m_addressReqTimer.find(dst) == m_addressReqTimer.end())
3172 {
3174 m_addressReqTimer[dst] = timer;
3175 }
3176 std::vector<Ipv4Address> address;
3177 address.push_back(source);
3178 address.push_back(dst);
3180 m_addressReqTimer[dst].Cancel();
3181 m_addressReqTimer[dst].SetArguments(packet, address, requestId, protocol);
3182 Time rreqDelay;
3183 // back off mechanism for sending route requests
3184 if (m_rreqTable->GetRreqCnt(dst))
3185 {
3186 // When the route request count is larger than 0
3187 // This is the exponential back-off mechanism for route request
3188 rreqDelay = Time(std::pow(static_cast<double>(m_rreqTable->GetRreqCnt(dst)), 2.0) *
3190 }
3191 else
3192 {
3193 // This is the first route request retry
3194 rreqDelay = m_requestPeriod;
3195 }
3196 NS_LOG_LOGIC("Request count for " << dst << " " << m_rreqTable->GetRreqCnt(dst)
3197 << " with delay time " << rreqDelay.As(Time::S));
3198 if (rreqDelay > m_maxRequestPeriod)
3199 {
3200 // use the max request period
3201 NS_LOG_LOGIC("The max request delay time " << m_maxRequestPeriod.As(Time::S));
3203 }
3204 else
3205 {
3206 NS_LOG_LOGIC("The request delay time " << rreqDelay.As(Time::S));
3207 m_addressReqTimer[dst].Schedule(rreqDelay);
3208 }
3209 }
3210}
3211
3212void
3214 std::vector<Ipv4Address> address,
3215 uint32_t requestId,
3216 uint8_t protocol)
3217{
3218 NS_LOG_FUNCTION(this << packet << requestId << (uint32_t)protocol);
3219 // Get a clean packet without dsr header
3220 Ptr<Packet> dsrP = packet->Copy();
3221 DsrRoutingHeader dsrRoutingHeader;
3222 dsrP->RemoveHeader(dsrRoutingHeader); // Remove the dsr header in whole
3223
3224 Ipv4Address source = address[0];
3225 Ipv4Address dst = address[1];
3226 DsrRouteCacheEntry toDst;
3227 if (m_routeCache->LookupRoute(dst, toDst))
3228 {
3229 /*
3230 * Found a route the dst, construct the source route option header
3231 */
3232 DsrOptionSRHeader sourceRoute;
3233 std::vector<Ipv4Address> ip = toDst.GetVector();
3234 sourceRoute.SetNodesAddress(ip);
3235 // When we found the route and use it, UseExtends for the link cache
3236 if (m_routeCache->IsLinkCache())
3237 {
3238 m_routeCache->UseExtends(ip);
3239 }
3240 sourceRoute.SetSegmentsLeft(ip.size() - 2);
3241 /// Set the salvage value to 0
3242 sourceRoute.SetSalvage(0);
3243 Ipv4Address nextHop = SearchNextHop(m_mainAddress, ip); // Get the next hop address
3244 NS_LOG_INFO("The nextHop address is " << nextHop);
3245 if (nextHop == "0.0.0.0")
3246 {
3247 NS_LOG_DEBUG("Error next hop address");
3248 PacketNewRoute(dsrP, source, dst, protocol);
3249 return;
3250 }
3251 SetRoute(nextHop, m_mainAddress);
3252 CancelRreqTimer(dst, true);
3253 /// Try to send out data packet from the send buffer if found
3254 if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(dst))
3255 {
3256 SendPacketFromBuffer(sourceRoute, nextHop, protocol);
3257 }
3258 NS_LOG_LOGIC("Route to " << dst << " found");
3259 return;
3260 }
3261 /*
3262 * If a route discovery has been attempted m_rreqRetries times at the maximum TTL without
3263 * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
3264 * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the
3265 * application.
3266 */
3267 NS_LOG_LOGIC("The new request count for " << dst << " is " << m_rreqTable->GetRreqCnt(dst)
3268 << " the max " << m_rreqRetries);
3269 if (m_rreqTable->GetRreqCnt(dst) >= m_rreqRetries)
3270 {
3271 NS_LOG_LOGIC("Route discovery to " << dst << " has been attempted " << m_rreqRetries
3272 << " times");
3273 CancelRreqTimer(dst, true);
3274 NS_LOG_DEBUG("Route not found. Drop packet with dst " << dst);
3276 }
3277 else
3278 {
3279 SocketIpTtlTag tag;
3280 tag.SetTtl((uint8_t)m_discoveryHopLimit);
3281 Ptr<Packet> propPacket = packet->Copy();
3282 propPacket->AddPacketTag(tag);
3283 // Increase the request count
3284 m_rreqTable->FindAndUpdate(dst);
3285 SendRequest(propPacket, source);
3286 NS_LOG_DEBUG("Check the route request entry " << source << " " << dst);
3287 ScheduleRreqRetry(packet, address, false, requestId, protocol);
3288 }
3289}
3290
3291void
3293{
3294 NS_LOG_FUNCTION(this << packet << source);
3295
3296 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
3297 /*
3298 * The destination address here is directed broadcast address
3299 */
3301 auto i = m_priorityQueue.find(priority);
3302 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3303 NS_LOG_LOGIC("Inserting into priority queue number: " << priority);
3304
3305 // m_downTarget (packet, source, m_broadcast, GetProtocolNumber (), 0);
3306
3307 /// \todo New DsrNetworkQueueEntry
3308 DsrNetworkQueueEntry newEntry(packet, source, m_broadcast, Simulator::Now(), nullptr);
3309 if (dsrNetworkQueue->Enqueue(newEntry))
3310 {
3311 Scheduler(priority);
3312 }
3313 else
3314 {
3315 NS_LOG_INFO("Packet dropped as dsr network queue is full");
3316 }
3317}
3318
3319void
3321{
3322 NS_LOG_FUNCTION(this << packet);
3323 /*
3324 * This is a forwarding case when sending route requests, a random delay time [0,
3325 * m_broadcastJitter] used before forwarding as link-layer broadcast
3326 */
3329 this,
3330 packet,
3332}
3333
3334void
3336 Ipv4Address srcAddress,
3337 std::vector<Ipv4Address>& nodeList,
3338 uint8_t protocol)
3339{
3340 NS_LOG_FUNCTION(this << source << srcAddress << (uint32_t)protocol);
3341 if (!(m_graReply.FindAndUpdate(source,
3342 srcAddress,
3343 m_gratReplyHoldoff))) // Find the gratuitous reply entry
3344 {
3345 NS_LOG_LOGIC("Update gratuitous reply " << source);
3346 GraReplyEntry graReplyEntry(source, srcAddress, m_gratReplyHoldoff + Simulator::Now());
3347 m_graReply.AddEntry(graReplyEntry);
3348 /*
3349 * Automatic route shortening
3350 */
3351 m_finalRoute.clear(); // Clear the final route vector
3352 /**
3353 * Push back the node addresses other than those between srcAddress and our own ip address
3354 */
3355 auto before = find(nodeList.begin(), nodeList.end(), srcAddress);
3356 for (auto i = nodeList.begin(); i != before; ++i)
3357 {
3358 m_finalRoute.push_back(*i);
3359 }
3360 m_finalRoute.push_back(srcAddress);
3361 auto after = find(nodeList.begin(), nodeList.end(), m_mainAddress);
3362 for (auto j = after; j != nodeList.end(); ++j)
3363 {
3364 m_finalRoute.push_back(*j);
3365 }
3367 rrep.SetNodesAddress(m_finalRoute); // Set the node addresses in the route reply header
3368 // Get the real reply source and destination
3369 Ipv4Address replySrc = m_finalRoute.back();
3370 Ipv4Address replyDst = m_finalRoute.front();
3371 /*
3372 * Set the route and use it in send back route reply
3373 */
3374 m_ipv4Route = SetRoute(srcAddress, m_mainAddress);
3375 /*
3376 * This part adds DSR header to the packet and send reply
3377 */
3378 DsrRoutingHeader dsrRoutingHeader;
3379 dsrRoutingHeader.SetNextHeader(protocol);
3380 dsrRoutingHeader.SetMessageType(1);
3381 dsrRoutingHeader.SetSourceId(GetIDfromIP(replySrc));
3382 dsrRoutingHeader.SetDestId(GetIDfromIP(replyDst));
3383
3384 uint8_t length =
3385 rrep.GetLength(); // Get the length of the rrep header excluding the type header
3386 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
3387 dsrRoutingHeader.AddDsrOption(rrep);
3388 Ptr<Packet> newPacket = Create<Packet>();
3389 newPacket->AddHeader(dsrRoutingHeader);
3390 /*
3391 * Send gratuitous reply
3392 */
3393 NS_LOG_INFO("Send back gratuitous route reply");
3394 SendReply(newPacket, m_mainAddress, srcAddress, m_ipv4Route);
3395 }
3396 else
3397 {
3398 NS_LOG_INFO("The same gratuitous route reply has already sent");
3399 }
3400}
3401
3402void
3404 Ipv4Address source,
3405 Ipv4Address nextHop,
3406 Ptr<Ipv4Route> route)
3407{
3408 NS_LOG_FUNCTION(this << packet << source << nextHop);
3409 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
3410
3411 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(m_mainAddress));
3412 route->SetOutputDevice(dev);
3413 NS_LOG_INFO("The output device " << dev << " packet is: " << *packet);
3414
3416 auto i = m_priorityQueue.find(priority);
3417 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3418 NS_LOG_INFO("Inserting into priority queue number: " << priority);
3419
3420 // m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
3421
3422 /// \todo New DsrNetworkQueueEntry
3423 DsrNetworkQueueEntry newEntry(packet, source, nextHop, Simulator::Now(), route);
3424 if (dsrNetworkQueue->Enqueue(newEntry))
3425 {
3426 Scheduler(priority);
3427 }
3428 else
3429 {
3430 NS_LOG_INFO("Packet dropped as dsr network queue is full");
3431 }
3432}
3433
3434void
3436 Ipv4Address source,
3437 Ipv4Address nextHop,
3438 Ptr<Ipv4Route> route)
3439{
3440 NS_LOG_FUNCTION(this << packet << source << nextHop);
3441 Simulator::ScheduleNow(&DsrRouting::SendReply, this, packet, source, nextHop, route);
3442}
3443
3444void
3446 Ipv4Address source,
3447 Ipv4Address destination,
3448 Ptr<Ipv4Route> route,
3449 double hops)
3450{
3451 NS_LOG_FUNCTION(this << packet << source << destination);
3453 Time(2 * m_nodeTraversalTime * (hops - 1 + m_uniformRandomVariable->GetValue(0, 1))),
3455 this,
3456 packet,
3457 source,
3458 destination,
3459 route);
3460}
3461
3462void
3463DsrRouting::SendAck(uint16_t ackId,
3464 Ipv4Address destination,
3465 Ipv4Address realSrc,
3466 Ipv4Address realDst,
3467 uint8_t protocol,
3468 Ptr<Ipv4Route> route)
3469{
3470 NS_LOG_FUNCTION(this << ackId << destination << realSrc << realDst << (uint32_t)protocol
3471 << route);
3472 NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
3473
3474 // This is a route reply option header
3475 DsrRoutingHeader dsrRoutingHeader;
3476 dsrRoutingHeader.SetNextHeader(protocol);
3477 dsrRoutingHeader.SetMessageType(1);
3478 dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
3479 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
3480
3482 /*
3483 * Set the ack Id and set the ack source address and destination address
3484 */
3485 ack.SetAckId(ackId);
3486 ack.SetRealSrc(realSrc);
3487 ack.SetRealDst(realDst);
3488
3489 uint8_t length = ack.GetLength();
3490 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
3491 dsrRoutingHeader.AddDsrOption(ack);
3492
3493 Ptr<Packet> packet = Create<Packet>();
3494 packet->AddHeader(dsrRoutingHeader);
3495 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
3496 route->SetOutputDevice(dev);
3497
3499 auto i = m_priorityQueue.find(priority);
3500 Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3501
3502 NS_LOG_LOGIC("Will be inserting into priority queue " << dsrNetworkQueue
3503 << " number: " << priority);
3504
3505 // m_downTarget (packet, m_mainAddress, destination, GetProtocolNumber (), route);
3506
3507 /// \todo New DsrNetworkQueueEntry
3508 DsrNetworkQueueEntry newEntry(packet, m_mainAddress, destination, Simulator::Now(), route);
3509 if (dsrNetworkQueue->Enqueue(newEntry))
3510 {
3511 Scheduler(priority);
3512 }
3513 else
3514 {
3515 NS_LOG_INFO("Packet dropped as dsr network queue is full");
3516 }
3517}
3518
3521{
3522 NS_LOG_FUNCTION(this << p << ip << incomingInterface);
3523
3524 NS_LOG_INFO("Our own IP address " << m_mainAddress << " The incoming interface address "
3525 << incomingInterface);
3526 m_node = GetNode(); // Get the node
3527 Ptr<Packet> packet = p->Copy(); // Save a copy of the received packet
3528 /*
3529 * When forwarding or local deliver packets, this one should be used always!!
3530 */
3531 DsrRoutingHeader dsrRoutingHeader;
3532 packet->RemoveHeader(dsrRoutingHeader); // Remove the DSR header in whole
3533 Ptr<Packet> copy = packet->Copy();
3534
3535 uint8_t protocol = dsrRoutingHeader.GetNextHeader();
3536 uint32_t sourceId = dsrRoutingHeader.GetSourceId();
3537 Ipv4Address source = GetIPfromID(sourceId);
3538 NS_LOG_INFO("The source address " << source << " with source id " << sourceId);
3539 /*
3540 * Get the IP source and destination address
3541 */
3542 Ipv4Address src = ip.GetSource();
3543
3544 bool isPromisc = false;
3545 uint32_t offset =
3546 dsrRoutingHeader
3547 .GetDsrOptionsOffset(); // Get the offset for option header, 8 bytes in this case
3548
3549 // This packet is used to peek option type
3550 p->RemoveAtStart(offset);
3551
3552 Ptr<dsr::DsrOptions> dsrOption;
3553 DsrOptionHeader dsrOptionHeader;
3554 /*
3555 * Peek data to get the option type as well as length and segmentsLeft field
3556 */
3557 uint32_t size = p->GetSize();
3558 auto data = new uint8_t[size];
3559 p->CopyData(data, size);
3560
3561 uint8_t optionType = 0;
3562 uint8_t optionLength = 0;
3563 uint8_t segmentsLeft = 0;
3564
3565 optionType = *(data);
3566 NS_LOG_LOGIC("The option type value " << (uint32_t)optionType << " with packet id "
3567 << p->GetUid());
3568 dsrOption =
3569 GetOption(optionType); // Get the relative dsr option and demux to the process function
3570 Ipv4Address promiscSource; /// this is just here for the sake of passing in the promisc source
3571 if (optionType == 1) // This is the request option
3572 {
3573 BlackList* blackList = m_rreqTable->FindUnidirectional(src);
3574 if (blackList)
3575 {
3576 NS_LOG_INFO("Discard this packet due to unidirectional link");
3577 m_dropTrace(p);
3578 }
3579
3580 dsrOption = GetOption(optionType);
3581 optionLength =
3582 dsrOption
3583 ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3584
3585 if (optionLength == 0)
3586 {
3587 NS_LOG_INFO("Discard this packet");
3588 m_dropTrace(p);
3589 }
3590 }
3591 else if (optionType == 2)
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
3605 else if (optionType == 32) // This is the ACK option
3606 {
3607 NS_LOG_INFO("This is the ack option");
3608 dsrOption = GetOption(optionType);
3609 optionLength =
3610 dsrOption
3611 ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3612
3613 if (optionLength == 0)
3614 {
3615 NS_LOG_INFO("Discard this packet");
3616 m_dropTrace(p);
3617 }
3618 }
3619
3620 else if (optionType == 3) // This is a route error header
3621 {
3622 // populate this route error
3623 NS_LOG_INFO("The option type value " << (uint32_t)optionType);
3624
3625 dsrOption = GetOption(optionType);
3626 optionLength =
3627 dsrOption
3628 ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3629
3630 if (optionLength == 0)
3631 {
3632 NS_LOG_INFO("Discard this packet");
3633 m_dropTrace(p);
3634 }
3635 NS_LOG_INFO("The option Length " << (uint32_t)optionLength);
3636 }
3637
3638 else if (optionType == 96) // This is the source route option
3639 {
3640 dsrOption = GetOption(optionType);
3641 optionLength =
3642 dsrOption
3643 ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3644 segmentsLeft = data[3];
3645 if (optionLength == 0)
3646 {
3647 NS_LOG_INFO("Discard this packet");
3648 m_dropTrace(p);
3649 }
3650 else
3651 {
3652 if (segmentsLeft == 0)
3653 {
3654 // / Get the next header
3655 uint8_t nextHeader = dsrRoutingHeader.GetNextHeader();
3657 Ptr<IpL4Protocol> nextProto = l3proto->GetProtocol(nextHeader);
3658 if (!nextProto)
3659 {
3660 NS_FATAL_ERROR("Should not have 0 next protocol value");
3661 }
3662
3663 // we need to make a copy in the unlikely event we hit the
3664 // RX_ENDPOINT_UNREACH code path
3665 // Here we can use the packet that has been get off whole DSR header
3666 IpL4Protocol::RxStatus status = nextProto->Receive(copy, ip, incomingInterface);
3667 NS_LOG_DEBUG("The receive status " << status);
3668 switch (status)
3669 {
3671 // fall through
3673 // fall through
3675 break;
3678 {
3679 break; // Do not reply to broadcast or multicast
3680 }
3681 // Another case to suppress ICMP is a subnet-directed broadcast
3682 }
3683 return status;
3684 }
3685 else
3686 {
3687 NS_LOG_INFO("This is not the final destination, the packet has already been "
3688 "forward to next hop");
3689 }
3690 }
3691 }
3692 else
3693 {
3694 NS_LOG_LOGIC("Unknown Option. Drop!");
3695 /*
3696 * Initialize the salvage value to 0
3697 */
3698 uint8_t salvage = 0;
3699
3700 DsrOptionRerrUnsupportedHeader rerrUnsupportedHeader;
3701 rerrUnsupportedHeader.SetErrorType(3); // The error type 3 means Option not supported
3702 rerrUnsupportedHeader.SetErrorSrc(
3703 m_mainAddress); // The error source address is our own address
3704 rerrUnsupportedHeader.SetUnsupported(optionType); // The unsupported option type number
3705 rerrUnsupportedHeader.SetErrorDst(
3706 src); // Error destination address is the destination of the data packet
3707 rerrUnsupportedHeader.SetSalvage(
3708 salvage); // Set the value about whether to salvage a packet or not
3709
3710 /*
3711 * The unknown option error is not supported currently in this implementation, and it's also
3712 * not likely to happen in simulations
3713 */
3714 // SendError (rerrUnsupportedHeader, 0, protocol); // Send the error packet
3715 }
3716 return IpL4Protocol::RX_OK;
3717}
3718
3721{
3722 NS_LOG_FUNCTION(this << p << ip.GetSource() << ip.GetDestination() << incomingInterface);
3724}
3725
3726void
3728{
3729 m_downTarget = callback;
3730}
3731
3732void
3734{
3735 NS_FATAL_ERROR("Unimplemented");
3736}
3737
3740{
3741 return m_downTarget;
3742}
3743
3746{
3747 NS_FATAL_ERROR("Unimplemented");
3748 return MakeNullCallback<void, Ptr<Packet>, Ipv6Address, Ipv6Address, uint8_t, Ptr<Ipv6Route>>();
3749}
3750
3751void
3753{
3754 m_options.push_back(option);
3755}
3756
3758DsrRouting::GetOption(int optionNumber)
3759{
3760 for (auto i = m_options.begin(); i != m_options.end(); ++i)
3761 {
3762 if ((*i)->GetOptionNumber() == optionNumber)
3763 {
3764 return *i;
3765 }
3766 }
3767 return nullptr;
3768}
3769} /* namespace dsr */
3770} /* namespace ns3 */
a polymophic address class
Definition: address.h:101
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:569
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:80
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:423
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:522
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition: socket.h:1124
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:604
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:415
@ S
second
Definition: nstime.h:116
AttributeValue implementation for Time.
Definition: nstime.h:1413
A simple virtual Timer class.
Definition: timer.h:78
void SetFunction(FN fn)
Definition: timer.h:279
@ CANCEL_ON_DESTROY
This policy cancels the event from the destructor of the Timer or from Suspend().
Definition: timer.h:97
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:932
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:624
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:863
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:590
void SendBuffTimerExpire()
The send buffer timer expire.
Definition: dsr-routing.cc:852
void SetPassiveBuffer(Ptr< dsr::DsrPassiveBuffer > r)
Set the node.
Definition: dsr-routing.cc:631
std::vector< std::string > GetElementsFromContext(std::string context)
Get the elements from the tracing context.
Definition: dsr-routing.cc:548
void UseExtends(DsrRouteCacheEntry::IP_VECTOR rt)
Extends the lifetime of a route cache entry.
Definition: dsr-routing.cc:669
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:737
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:681
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:809
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:536
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:712
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:638
Ipv4Address GetIPfromMAC(Mac48Address address)
Get the Ip address from mac address.
Definition: dsr-routing.cc:718
Ptr< dsr::DsrRouteCache > GetRouteCache() const
Get the route cache.
Definition: dsr-routing.cc:610
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:617
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:839
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:698
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:663
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:791
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:675
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:758
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:645
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:706
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:596
Ipv4Address GetIPfromID(uint16_t id)
Get the ip address from id.
Definition: dsr-routing.cc:825
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:689
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:564
int GetProtocolNumber() const override
Get the dsr protocol number.
Definition: dsr-routing.cc:802
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:603
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:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
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:1434
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
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:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
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:704
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
std::ofstream queueSize