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