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)),
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
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);
446 // Set the passive buffer parameters using just the send buffer parameters
448 passiveBuffer->SetMaxQueueLen(m_maxSendBuffLen);
449 passiveBuffer->SetPassiveBufferTimeout(m_sendBufferTimeout);
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));
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{
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
676
677bool
679{
680 std::vector<Ipv4Address> nodelist = rt.GetVector();
683 return m_routeCache->AddRoute(rt);
684}
685
686void
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);
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
748{
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{
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{
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();
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
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 {
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
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
912 std::vector<Ipv4Address> errorRoute = toDst.GetVector();
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);
936 dsrRoutingHeader.SetDestId(255);
937 dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
938 dsrRoutingHeader.AddDsrOption(newUnreach);
939 dsrRoutingHeader.AddDsrOption(sourceRoute);
940
942 newPacket->AddHeader(dsrRoutingHeader); // Add the routing header with rerr and
943 // sourceRoute attached to it
944 Ptr<NetDevice> dev =
945 m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
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);
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
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);
978 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
979
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
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 {
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
1028 passiveKey.m_ackId = 0;
1029 passiveKey.m_source = newEntry.GetSrc();
1030 passiveKey.m_destination = newEntry.GetDst();
1031 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1032
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
1041 m_linkCnt[linkKey] = 0;
1042
1043 if (m_linkAck)
1044 {
1046 }
1047 else
1048 {
1049 NS_LOG_LOGIC("Not using link acknowledgment");
1050 if (nextHop != destination)
1051 {
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,
1092{
1093 if (protocol != Ipv4L3Protocol::PROT_NUMBER)
1094 {
1095 return false;
1096 }
1097 // Remove the ipv4 header here
1098 Ptr<Packet> pktMinusIpHdr = packet->Copy();
1100 pktMinusIpHdr->RemoveHeader(ipv4Header);
1101
1102 if (ipv4Header.GetProtocol() != DsrRouting::PROT_NUMBER)
1103 {
1104 return false;
1105 }
1106 // Remove the dsr routing header here
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());
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
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
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
1147 {
1148 // just to minimize debug output
1149 NS_LOG_INFO(this << from << to << packetType << *pktMinusIpHdr);
1150
1151 uint8_t offset =
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();
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
1170
1171 if (optionType == 96) // This is the source route option
1172 {
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 "
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,
1187 source,
1188 ipv4Header,
1189 nextHeader,
1190 isPromisc,
1192 return true;
1193 }
1194 }
1195 return false;
1196}
1197
1198void
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
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();
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();
1243 dsrRoutingHeader.SetMessageType(2);
1244 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1245 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1246
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
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 {
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
1297 passiveKey.m_ackId = 0;
1298 passiveKey.m_source = newEntry.GetSrc();
1299 passiveKey.m_destination = newEntry.GetDst();
1300 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1301
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
1310 m_linkCnt[linkKey] = 0;
1311
1312 if (m_linkAck)
1313 {
1315 }
1316 else
1317 {
1318 NS_LOG_LOGIC("Not using link acknowledgment");
1319 if (nextHop != destination)
1320 {
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,
1337 uint8_t salvage,
1338 uint8_t protocol)
1339{
1340 NS_LOG_FUNCTION(this << unreachNode << destination << originalDst << (uint32_t)salvage
1341 << (uint32_t)protocol);
1344 dsrRoutingHeader.SetMessageType(1);
1346 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1347
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
1358 bool findRoute = m_routeCache->LookupRoute(destination, toDst);
1359 // Queue the packet if there is no route pre-existing
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
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
1381 destination,
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();
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 }
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);
1433 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(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);
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
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
1468 Ipv4Address nextHop,
1469 uint8_t protocol,
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");
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);
1486 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
1487 route->SetOutputDevice(dev);
1488
1490 auto i = m_priorityQueue.find(priority);
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
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
1513 Ipv4Address destination,
1514 uint8_t protocol,
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
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();
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();
1570 dsrRoutingHeader.SetMessageType(2);
1571 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1572 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1573
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
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 {
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
1625 passiveKey.m_ackId = 0;
1626 passiveKey.m_source = newEntry.GetSrc();
1627 passiveKey.m_destination = newEntry.GetDst();
1628 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1629
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
1638 m_linkCnt[linkKey] = 0;
1639
1640 if (m_linkAck)
1641 {
1643 }
1644 else
1645 {
1646 NS_LOG_LOGIC("Not using link acknowledgment");
1647 if (nextHop != destination)
1648 {
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,
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
1682 dsrP->RemoveHeader(dsrRoutingHeader); // Remove the DSR header in whole
1683 uint8_t protocol = dsrRoutingHeader.GetNextHeader();
1684 uint32_t sourceId = dsrRoutingHeader.GetSourceId();
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;
1696 tmpP->RemoveHeader(sourceRoute); // this is a clean packet without any dsr involved headers
1697
1699 m_ackId = m_routeCache->CheckUniqueAckId(nextHop);
1701 uint8_t length = (sourceRoute.GetLength() + ackReq.GetLength());
1704 newDsrRoutingHeader.SetMessageType(2);
1705 newDsrRoutingHeader.SetSourceId(sourceId);
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
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
1725 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
1726 m_ipv4Route->SetOutputDevice(dev);
1727
1729 auto i = m_priorityQueue.find(priority);
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
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
1757{
1758 NS_LOG_FUNCTION(this << priority << 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
1770 {
1771 auto q = m_priorityQueue.find(i);
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 {
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 }
1802 dsrNetworkQueue->Dequeue(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);
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 }
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
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
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 {
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
1938 passiveKey.m_ackId = 0;
1939 passiveKey.m_source = newEntry.GetSrc();
1940 passiveKey.m_destination = newEntry.GetDst();
1941 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1942
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
1951 m_linkCnt[linkKey] = 0;
1952
1953 if (m_linkAck)
1954 {
1956 }
1957 else
1958 {
1959 NS_LOG_LOGIC("Not using link acknowledgment");
1960 if (nextHop != destination)
1961 {
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,
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 {
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
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");
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
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();
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);
2060 newPacket->AddHeader(newRoutingHeader); // Add the extension header with rerr
2061 // and sourceRoute attached to it
2062 Ptr<NetDevice> dev =
2063 m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
2064 m_ipv4Route->SetOutputDevice(dev);
2065
2067 auto i = m_priorityQueue.find(priority);
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
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,
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
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
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
2141 mbEntry.SetPacket(p);
2142 mbEntry.SetSrc(source);
2143 mbEntry.SetDst(destination);
2144 mbEntry.SetAckId(0);
2145 mbEntry.SetSegsLeft(segsLeft + 1);
2146
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
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
2172 newEntry.SetSrc(source);
2173 newEntry.SetDst(destination);
2174 newEntry.SetAckId(0);
2175 newEntry.SetSegsLeft(segsLeft + 1);
2176
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
2182 return true;
2183 }
2184 return false;
2185}
2186
2187void
2189 const Ipv4Header& ipv4Header,
2192{
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 */
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);
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);
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 */
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 */
2302 if (m_addressForwardTimer[networkKey].IsRunning())
2303 {
2304 NS_LOG_INFO("Timer not canceled");
2305 }
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);
2321 passiveKey.m_ackId = 0;
2322 passiveKey.m_source = mb.GetSrc();
2323 passiveKey.m_destination = mb.GetDst();
2324 passiveKey.m_segsLeft = mb.GetSegsLeft();
2325
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 }
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();
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);
2377 p->RemoveHeader(sourceRoute);
2378 std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
2379 uint8_t salvage = sourceRoute.GetSalvage();
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 */
2388 if (salvage)
2389 {
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
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
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
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
2454 newPacket->RemoveHeader(sourceRoute);
2455 uint8_t salvage = sourceRoute.GetSalvage();
2456 /*
2457 * Look in the route cache for other routes for this destination
2458 */
2460 bool findRoute = m_routeCache->LookupRoute(dst, toDst);
2462 {
2463 NS_LOG_DEBUG("We have found a route for the packet");
2466 newDsrRoutingHeader.SetMessageType(2);
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++;
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);
2499 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
2500 m_ipv4Route->SetOutputDevice(dev);
2501
2502 // Send out the data packet
2504 auto i = m_priorityQueue.find(priority);
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
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);
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
2577 passiveKey.m_ackId = 0;
2578 passiveKey.m_source = mb.GetSrc();
2579 passiveKey.m_destination = mb.GetDst();
2580 passiveKey.m_segsLeft = mb.GetSegsLeft();
2581
2583 {
2586 }
2587 NS_LOG_DEBUG("The passive acknowledgment option for data packet");
2589 m_passiveAckTimer[passiveKey].Cancel();
2590 m_passiveAckTimer[passiveKey].SetArguments(mb, protocol);
2592}
2593
2594void
2596{
2599 // The new entry will be used for retransmission
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();
2617 // The function AllEqual will find the exact entry and delete it if found
2619 newEntry.SetPacket(dsrP);
2620 newEntry.SetAckId(ackId);
2621 newEntry.SetExpireTime(m_maxMaintainTime);
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
2631 {
2632 NS_LOG_ERROR("Failed to enqueue packet retry");
2633 }
2634
2636 {
2639 }
2640
2641 // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment
2642 // option
2644 this);
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
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 */
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);
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
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 {
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
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
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 {
2830 ScheduleNetworkPacketRetry(mb, false, protocol);
2831 }
2832}
2833
2834void
2837 const Ipv4Header& ipv4Header,
2839 Ipv4Address nextHop,
2841 uint8_t protocol,
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
2850 dsrRoutingHeader.SetMessageType(2);
2851 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
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
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 {
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
2884 passiveKey.m_ackId = 0;
2885 passiveKey.m_source = newEntry.GetSrc();
2886 passiveKey.m_destination = newEntry.GetDst();
2887 passiveKey.m_segsLeft = newEntry.GetSegsLeft();
2888
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
2897 m_linkCnt[linkKey] = 0;
2898
2899 if (m_linkAck)
2900 {
2902 }
2903 else
2904 {
2905 NS_LOG_LOGIC("Not using link acknowledgment");
2906 if (nextHop != targetAddress)
2907 {
2909 }
2910 else
2911 {
2912 // This is the first network retry
2913 ScheduleNetworkPacketRetry(newEntry, true, protocol);
2914 }
2915 }
2916 }
2917}
2918
2919void
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
2927 /*
2928 * Construct the route request option header
2929 */
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 */
2957 tag.SetTtl(0);
2958 Ptr<Packet> nonPropPacket = packet->Copy();
2959 nonPropPacket->AddPacketTag(tag);
2960 // Increase the request count
2961 m_rreqTable->FindAndUpdate(destination);
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());
2979 if (m_routeCache->LookupRoute(dst, toDst))
2980 {
2981 /*
2982 * Found a route the dst, construct the source route option header
2983 */
2985 std::vector<Ipv4Address> ip = toDst.GetVector();
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 */
3024 dsrRoutingHeader.SetMessageType(1);
3026 dsrRoutingHeader.SetDestId(255);
3027
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 */
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()) &&
3057 {
3058 NS_LOG_INFO("Only when there is no existing route request time when the initial route "
3059 "request is scheduled");
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 */
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,
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);
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
3184 }
3185 NS_LOG_LOGIC("Request count for " << dst << " " << m_rreqTable->GetRreqCnt(dst)
3186 << " with delay time " << rreqDelay.As(Time::S));
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,
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();
3211 dsrP->RemoveHeader(dsrRoutingHeader); // Remove the dsr header in whole
3212
3213 Ipv4Address source = address[0];
3214 Ipv4Address dst = address[1];
3216 if (m_routeCache->LookupRoute(dst, toDst))
3217 {
3218 /*
3219 * Found a route the dst, construct the source route option header
3220 */
3222 std::vector<Ipv4Address> ip = toDst.GetVector();
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 {
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);
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);
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
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
3326 std::vector<Ipv4Address>& nodeList,
3327 uint8_t protocol)
3328{
3329 NS_LOG_FUNCTION(this << source << srcAddress << (uint32_t)protocol);
3331 srcAddress,
3332 m_gratReplyHoldoff))) // Find the gratuitous reply entry
3333 {
3334 NS_LOG_LOGIC("Update gratuitous reply " << source);
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
3360 /*
3361 * Set the route and use it in send back route reply
3362 */
3364 /*
3365 * This part adds DSR header to the packet and send reply
3366 */
3369 dsrRoutingHeader.SetMessageType(1);
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);
3378 newPacket->AddHeader(dsrRoutingHeader);
3379 /*
3380 * Send gratuitous reply
3381 */
3382 NS_LOG_INFO("Send back gratuitous route reply");
3384 }
3385 else
3386 {
3387 NS_LOG_INFO("The same gratuitous route reply has already sent");
3388 }
3389}
3390
3391void
3394 Ipv4Address nextHop,
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);
3407 NS_LOG_INFO("Inserting into priority queue number: " << priority);
3408
3409 // m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
3410
3411 /// @todo New DsrNetworkQueueEntry
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
3426 Ipv4Address nextHop,
3428{
3429 NS_LOG_FUNCTION(this << packet << source << nextHop);
3430 Simulator::ScheduleNow(&DsrRouting::SendReply, this, packet, source, nextHop, route);
3431}
3432
3433void
3436 Ipv4Address destination,
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
3453 Ipv4Address destination,
3456 uint8_t protocol,
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
3466 dsrRoutingHeader.SetMessageType(1);
3468 dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
3469
3471 /*
3472 * Set the ack Id and set the ack source address and destination address
3473 */
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);
3484 Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
3485 route->SetOutputDevice(dev);
3486
3488 auto i = m_priorityQueue.find(priority);
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
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 "
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 */
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();
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 =
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
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
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 {
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");
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
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 {
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();
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
3656 NS_LOG_DEBUG("The receive status " << status);
3657 switch (status)
3658 {
3660 // fall through
3662 // fall through
3664 break;
3666 if (ip.GetDestination().IsBroadcast() || ip.GetDestination().IsMulticast())
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
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
3745
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.
AttributeValue implementation for Boolean.
Definition boolean.h:26
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.
static Ipv4Address GetBroadcast()
Packet header for IPv4.
Definition ipv4-header.h:23
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition ipv4.h:69
Implement the IPv4 layer.
static constexpr uint16_t PROT_NUMBER
Protocol number.
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
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
AttributeValue implementation for Pointer.
Definition pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
Maintain the event list.
Definition scheduler.h:146
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
AttributeValue implementation for Time.
Definition nstime.h:1431
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:49
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.
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 SetNextHeader(uint8_t protocol)
Set the "Next header" field.
uint8_t GetNextHeader() const
Get the next 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.
void SetPacket(Ptr< const Packet > p)
Set packet.
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.
Header of Dsr Option ack.
void SetAckId(uint16_t identification)
Set the Ack id number.
Header of Dsr Option ack request.
void SetAckId(uint16_t identification)
Set the Ack request id number.
header for Dsr Options.
void SetErrorType(uint8_t errorType)
Set the route error type.
Route Error (RERR) Unreachable node address option Message Format.
Route Error (RERR) Unsupported option Message Format.
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 AddNodeAddress(Ipv4Address ipv4)
Add one node address.
Header of Dsr Option Source Route.
void SetNumberAddress(uint8_t n)
Set the number of ipv4 address.
void SetSalvage(uint8_t salvage)
Set the salvage value for a packet.
void SetNodesAddress(std::vector< Ipv4Address > ipv4Address)
Set the vector of ipv4 address.
DSR Passive Buffer Entry.
void SetPacket(Ptr< const Packet > p)
Set packet function.
DsrRouteCacheEntry class for entries in the route cache.
Definition dsr-rcache.h:218
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.
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 AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1452
#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
#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:1368
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1356
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 AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition nstime.h:1432
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 AttributeAccessor > MakePointerAccessor(T1 a1)
Definition pointer.h:248
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
uint8_t data[writeSize]
BlackList description.
The gratuitous table entries, it maintains the already sent gratuitous route reply entries.
NetworkKey structure.
uint16_t m_ackId
acknowledge ID
PassiveKey structure.
uint16_t m_ackId
acknowledge ID
std::ofstream queueSize