详尽分析aodv-routing-protocol.cc
代码
- 预处理命令
包括宏定义#define 和 引入头文件#include
#define NS_LOG_APPEND_CONTEXT \
if (m_ipv4) {
std::clog << "[node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
#include "aodv-routing-protocol.h"
#include "ns3/log.h"
#include "ns3/boolean.h"
#include "ns3/random-variable-stream.h"
#include "ns3/inet-socket-address.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/packet.h" // trace
#include "ns3/udp-socket-factory.h"
#include "ns3/udp-l4-protocol.h"
#include "ns3/udp-header.h"
#include "ns3/wifi-net-device.h"
#include "ns3/adhoc-wifi-mac.h"
#include "ns3/string.h"
#include "ns3/pointer.h"
#include <algorithm>
#include <limits>
- 进入ns3命名空间后为日志组建命名
namespace ns3
NS_LOG_COMPONENT_DEFINE ("AodvRoutingProtocol");
- 进入aodv命名空间
注册一个新的RoutingProtocol类
设置AODV控制流使用的UDP端口号为654
namespace aodv
NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
const uint32_t RoutingProtocol::AODV_PORT = 654;
-设置AODV实现使用的标记
标记数据包中的一组字节。可以通过这个抽象基类的子类创建新类型的标记文章来源:https://www.toymoban.com/news/detail-411104.html
class DeferredRouteOutputTag : public Tag
{
public:
DeferredRouteOutputTag (int32_t o = -1) : Tag (), m_oif (o) {
}
static TypeId GetTypeId ()
{
//class ns3::TypeId 接口的唯一标识符。这个类记录了关于Object基类的一个子类的大量元信息,包括子类的基类,子类中可访问的构造函数集,子类内可访问的“属性”集
static TypeId tid = TypeId ("ns3::aodv::DeferredRouteOutputTag") //括号内为:要构造的接口的名称
.SetParent<Tag> ()
.SetGroupName("Aodv")
.AddConstructor<DeferredRouteOutputTag> ()
;
return tid;
}
TypeId GetInstanceTypeId () const
{
return GetTypeId ();
}
int32_t GetInterface() const
{
return m_oif;
}
void SetInterface(int32_t oif)
{
m_oif = oif;
}
uint32_t GetSerializedSize () const
{
return sizeof(int32_t);
}
void Serialize (TagBuffer i) const
{
i.WriteU32 (m_oif);
}
void Deserialize (TagBuffer i)
{
m_oif = i.ReadU32 ();
}
void Print (std::ostream &os) const
{
os << "DeferredRouteOutputTag: output interface = " << m_oif;
}
private:
/// Positive if output device is fixed in RouteOutput 如果输出设备在RouteOutput固定,则为正
int32_t m_oif;
};
- 注册一个新的DeferredRouteOutputTag类
NS_OBJECT_ENSURE_REGISTERED (DeferredRouteOutputTag);
- 设置RoutingProtocol的属性
RoutingProtocol::RoutingProtocol () :
m_rreqRetries (2), //重传RREQ的最大数目
m_ttlStart (1), //RREQ的TTL初始值
m_ttlIncrement (2), //在RREQ传播中每次尝试使用扩展环搜索的TTL增加值
m_ttlThreshold (7), //扩展环搜索中最大的TTL值
m_timeoutBuffer (2), //为超时提供缓冲区
m_rreqRateLimit (10), //每秒RREQ的最大数目
m_rerrRateLimit (10), //每秒RERR的最大数目
m_activeRouteTimeout (Seconds (3)), //路由有效的时间长度
m_netDiameter (35), //测量网络中两节点最大可能的跳数
m_nodeTraversalTime (MilliSeconds (40)), //保守估计数据包的每一跳传输时间,包括队列等待时间、中断处理时间、传输时间
m_netTraversalTime (Time ((2 * m_netDiameter) * m_nodeTraversalTime)), //估计网络传播平均时间
m_pathDiscoveryTime ( Time (2 * m_netTraversalTime)), //估计网络中发现路由所需的的最大时间
m_myRouteTimeout (Time (2 * std::max (m_pathDiscoveryTime, m_activeRouteTimeout))), //该节点产生的RREP中生存时间域的值
m_helloInterval (Seconds (1)), //每个hello消息间隔,节点检查自己是否在上一个hello间隔中发送了一个广播消息。若无,该节点可能发送一个hello消息
m_allowedHelloLoss (2), //有效链接可能丢失的hello消息数
m_deletePeriod (Time (5 * std::max (m_activeRouteTimeout, m_helloInterval))), //提供节点A能将邻居节点B作为下一跳节点的(目的地为D)的时间上限,此时节点B到节点D的路由无效
m_nextHopWait (m_nodeTraversalTime + MilliSeconds (10)), //等待邻居节点回复RREP_ACK的时间
m_blackListTimeout (Time (m_rreqRetries * m_netTraversalTime)), //将那个节点加入黑名单的时间
m_maxQueueLen (64), //路由协议允许缓冲的最大数据包数目
m_maxQueueTime (Seconds (30)), //路由协议允许的缓冲一个数据包的最大时间
m_destinationOnly (true), //指示只有目的节点才能回复RREQ
m_gratuitousReply (true), //指示一个RREP是否应该单播到发起路由发现的节点
m_enableHello (false), //指示一个hello消息是否可行
m_routingTable (m_deletePeriod), //路由表
m_queue (m_maxQueueLen, m_maxQueueTime), //路由层缓存未找到路由的数据包时,采用drop-front队列
m_requestId (0), //广播ID
m_seqNo (0), //request序列号
m_rreqIdCache (m_pathDiscoveryTime), //处理重复的RREQ
m_dpd (m_pathDiscoveryTime), //处理广播/多播的数据包
m_nb (m_helloInterval), //处理邻居
m_rreqCount (0), //RREQ速率控制使用的RREQ数量
m_rerrCount (0), //RERR速率控制使用的RERR数量
m_enableEtx (true), //启用ETX度量的链路探测数据包
m_lppInterval (Seconds (1)), //LPP间隔
m_lppTimer (Timer::CANCEL_ON_DESTROY), //链路探测包计时器
m_htimer (Timer::CANCEL_ON_DESTROY), //hello计时器
m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY), //RREQ速率限制计时器
m_rerrRateLimitTimer (Timer::CANCEL_ON_DESTROY), //RERR速率限制计时器
m_lastBcastTime (Seconds (0)) //跟踪上次广播时间
- 设置链路失败回调
m_nb.SetCallback (MakeCallback (&RoutingProtocol::SendRerrWhenBreaksLinkToNextHop, this));
- 声明TypeID中新的属性
TypeId
RoutingProtocol::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::aodv::RoutingProtocol")
.SetParent<Ipv4RoutingProtocol> ()
.SetGroupName("Aodv")
.AddConstructor<RoutingProtocol> ()
.AddAttribute ("HelloInterval", "HELLO messages emission interval.",
TimeValue (Seconds (1)),
MakeTimeAccessor (&RoutingProtocol::m_helloInterval),
MakeTimeChecker ())
.AddAttribute ("TtlStart", "Initial TTL value for RREQ.",
UintegerValue (1),
MakeUintegerAccessor (&RoutingProtocol::m_ttlStart),
MakeUintegerChecker<uint16_t> ())
.AddAttribute ("TtlIncrement", "TTL increment for each attempt using the expanding ring search for RREQ dissemination.",
UintegerValue (2),
MakeUintegerAccessor (&RoutingProtocol::m_ttlIncrement),
MakeUintegerChecker<uint16_t> ())
.AddAttribute ("TtlThreshold", "Maximum TTL value for expanding ring search, TTL = NetDiameter is used beyond this value.",
UintegerValue (7),
MakeUintegerAccessor (&RoutingProtocol::m_ttlThreshold),
MakeUintegerChecker<uint16_t> ())
.AddAttribute ("TimeoutBuffer", "Provide a buffer for the timeout.",
UintegerValue (2),
MakeUintegerAccessor (&RoutingProtocol::m_timeoutBuffer),
MakeUintegerChecker<uint16_t> ())
.AddAttribute ("RreqRetries", "Maximum number of retransmissions of RREQ to discover a route",
UintegerValue (2),
MakeUintegerAccessor (&RoutingProtocol::m_rreqRetries),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("RreqRateLimit", "Maximum number of RREQ per second.",
UintegerValue (10),
MakeUintegerAccessor (&RoutingProtocol::m_rreqRateLimit),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("RerrRateLimit", "Maximum number of RERR per second.",
UintegerValue (10),
MakeUintegerAccessor (&RoutingProtocol::m_rerrRateLimit),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("NodeTraversalTime", "Conservative estimate of the average one hop traversal time for packets and should include "
"queuing delays, interrupt processing times and transfer times.",
TimeValue (MilliSeconds (40)),
MakeTimeAccessor (&RoutingProtocol::m_nodeTraversalTime),
MakeTimeChecker ())
.AddAttribute ("NextHopWait", "Period of our waiting for the neighbour's RREP_ACK = 10 ms + NodeTraversalTime",
TimeValue (MilliSeconds (50)),
MakeTimeAccessor (&RoutingProtocol::m_nextHopWait),
MakeTimeChecker ())
.AddAttribute ("ActiveRouteTimeout", "Period of time during which the route is considered to be valid",
TimeValue (Seconds (3)),
MakeTimeAccessor (&RoutingProtocol::m_activeRouteTimeout),
MakeTimeChecker ())
.AddAttribute ("MyRouteTimeout", "Value of lifetime field in RREP generating by this node = 2 * max(ActiveRouteTimeout, PathDiscoveryTime)",
TimeValue (Seconds (11.2)),
MakeTimeAccessor (&RoutingProtocol::m_myRouteTimeout),
MakeTimeChecker ())
.AddAttribute ("BlackListTimeout", "Time for which the node is put into the blacklist = RreqRetries * NetTraversalTime",
TimeValue (Seconds (5.6)),
MakeTimeAccessor (&RoutingProtocol::m_blackListTimeout),
MakeTimeChecker ())
.AddAttribute ("DeletePeriod", "DeletePeriod is intended to provide an upper bound on the time for which an upstream node A "
"can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D."
" = 5 * max (HelloInterval, ActiveRouteTimeout)",
TimeValue (Seconds (15)),
MakeTimeAccessor (&RoutingProtocol::m_deletePeriod),
MakeTimeChecker ())
.AddAttribute ("NetDiameter", "Net diameter measures the maximum possible number of hops between two nodes in the network",
UintegerValue (35),
MakeUintegerAccessor (&RoutingProtocol::m_netDiameter),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("NetTraversalTime", "Estimate of the average net traversal time = 2 * NodeTraversalTime * NetDiameter",
TimeValue (Seconds (2.8)),
MakeTimeAccessor (&RoutingProtocol::m_netTraversalTime),
MakeTimeChecker ())
.AddAttribute ("PathDiscoveryTime", "Estimate of maximum time needed to find route in network = 2 * NetTraversalTime",
TimeValue (Seconds (5.6)),
MakeTimeAccessor (&RoutingProtocol::m_pathDiscoveryTime),
MakeTimeChecker ())
.AddAttribute ("MaxQueueLen", "Maximum number of packets that we allow a routing protocol to buffer.",
UintegerValue (1024), //originaly it was 64
MakeUintegerAccessor (&RoutingProtocol::SetMaxQueueLen,
&RoutingProtocol::GetMaxQueueLen),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("MaxQueueTime", "Maximum time packets can be queued (in seconds)",
TimeValue (Seconds (30)),
MakeTimeAccessor (&RoutingProtocol::SetMaxQueueTime,
&RoutingProtocol::GetMaxQueueTime),
MakeTimeChecker ())
.AddAttribute ("AllowedHelloLoss", "Number of hello messages which may be loss for valid link.",
UintegerValue (2),
MakeUintegerAccessor (&RoutingProtocol::m_allowedHelloLoss),
MakeUintegerChecker<uint16_t> ())
.AddAttribute ("GratuitousReply", "Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.",
BooleanValue (true),
MakeBooleanAccessor (&RoutingProtocol::SetGratuitousReplyFlag,
&RoutingProtocol::GetGratuitousReplyFlag),
MakeBooleanChecker ())
.AddAttribute ("DestinationOnly", "Indicates only the destination may respond to this RREQ.",
BooleanValue (true),
MakeBooleanAccessor (&RoutingProtocol::SetDestinationOnlyFlag,
&RoutingProtocol::GetDestinationOnlyFlag),
MakeBooleanChecker ())
.AddAttribute ("EnableHello", "Indicates whether a hello messages enable.",
BooleanValue (false),
MakeBooleanAccessor (&RoutingProtocol::SetHelloEnable,
&RoutingProtocol::GetHelloEnable),
MakeBooleanChecker ())
.AddAttribute ("EnableBroadcast", "Indicates whether a broadcast data packets forwarding enable.",
BooleanValue (true),
MakeBooleanAccessor (&RoutingProtocol::SetBroadcastEnable,
&RoutingProtocol::GetBroadcastEnable),
MakeBooleanChecker ())
.AddAttribute ("UniformRv",
"Access to the underlying UniformRandomVariable",
StringValue ("ns3::UniformRandomVariable"),
MakePointerAccessor (&RoutingProtocol::m_uniformRandomVariable),
MakePointerChecker<UniformRandomVariable> ())
.AddAttribute ("EnableEtx", "Enable ETX metrix.",
BooleanValue (true),
MakeBooleanAccessor (&RoutingProtocol::SetEtxEnable,
&RoutingProtocol::GetEtxEnable),
MakeBooleanChecker ())
.AddAttribute ("LppInterval", "Link probe packet emission interval.", //链路探测包发送间隔
TimeValue (Seconds (1)),
MakeTimeAccessor (&RoutingProtocol::m_lppInterval),
MakeTimeChecker ())
.AddTraceSource ("Tx", "A new routing protocol packet is created and is sent", // trace
MakeTraceSourceAccessor (&RoutingProtocol::m_txTrace),
"ns3::Packet::TracedCallback")
;
return tid;
}
这里的AddTraceSource函数增加了一个名为“Tx”的traceSource,用于描述一个路由协议数据包生成并且被传输,此时会调用m_txTrace函数。文章来源地址https://www.toymoban.com/news/detail-411104.html
- 设置路由协议允许的缓冲队列长度
void
RoutingProtocol::SetMaxQueueLen (uint32_t len) //设置最大队列长度为64
{
m_maxQueueLen = len;
m_queue.SetMaxQueueLen (len);
}
- 设置路由协议允许的缓冲一个数据包的最长时间
void
RoutingProtocol::SetMaxQueueTime (Time t) //设置最大队列时间30s
{
m_maxQueueTime = t;
m_queue.SetQueueTimeout (t);
}
- 构造析构函数
RoutingProtocol::~RoutingProtocol ()
{
}
- 声明dispose函数
void
RoutingProtocol::DoDispose ()
{
m_ipv4 = 0;
for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++)
{
iter->first->Close ();
}
m_socketAddresses.clear (); //每个IP接口的原始单播套接字
for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
m_socketSubnetBroadcastAddresses.begin (); iter != m_socketSubnetBroadcastAddresses.end (); iter++)
{
iter->first->Close ();
}
m_socketSubnetBroadcastAddresses.clear (); //每个IP接口的原始子网定向广播套接字
Ipv4RoutingProtocol::DoDispose ();
}
- 声明用于打印路由表的函数
void //打印路由表
RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream,Time::Unit unit) const
{
*stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId ()
<< "; Time: " << Now().As (unit)
<< ", Local time: " << GetObject<Node> ()->GetLocalTime ().As (unit)
<< ", AODV Routing table" << std::endl;
m_routingTable.Print (stream);
*stream->GetStream () << std::endl;
}
- 设置随机数序列
int64_t
RoutingProtocol::AssignStreams (int64_t stream) //为随机变量分配一个固定的随机数序列。并返回被分配的序列
{
NS_LOG_FUNCTION (this << stream);
m_uniformRandomVariable->SetStream (stream);
return 1;
}
- 设置start函数,开始路由操作
void
RoutingProtocol::Start () //开始路由操作
{
NS_LOG_FUNCTION (this);
if (m_enableHello)
{
m_nb.ScheduleTimer ();
}
m_rreqRateLimitTimer.SetFunction (&RoutingProtocol::RreqRateLimitTimerExpire, //重制RREQ计数并调度延迟1秒的RREQ限制计时器
this);
m_rreqRateLimitTimer.Schedule (Seconds (1));
m_rerrRateLimitTimer.SetFunction (&RoutingProtocol::RerrRateLimitTimerExpire,//重制RERR计数并调度延迟1秒的RERR限制计时器
this);
m_rerrRateLimitTimer.Schedule (Seconds (1));
}
- 设置路由输出函数
Ptr<Ipv4Route>
RoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, //RouteOutput()在主动发包时调用,当找到路由时返回路由地址
Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
{
NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
if (!p)
{
NS_LOG_DEBUG("Packet is == 0");
return LoopbackRoute (header, oif); // later
}
if (m_socketAddresses.empty ())
{
sockerr = Socket::ERROR_NOROUTETOHOST;
NS_LOG_LOGIC ("No aodv interfaces");
Ptr<Ipv4Route> route;
return route;
}
sockerr = Socket::ERROR_NOTERROR;
Ptr<Ipv4Route> route;
Ipv4Address dst = header.GetDestination ();
RoutingTableEntry rt;
if (m_routingTable.LookupValidRoute (dst, rt))
{
route
到了这里,关于NS3中路由协议分析【AODV代码分析】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!