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