AODV路由协议中文说明
AODV路由协议中文说明

内容目录1导言 (3)2概述 (4)3AODV术语 (5)4适用性综述 (7)5消息格式 (8)6AODV操作 (13)管理序列号 (13)路由表项和先驱列表 (15)生成路由请求 (16)控制路由请求消息的传播 (17)处理和转发路由请求 (18)生成路由回复 (20)接受和转发路由回复 (22)对单向连接的操作 (23)Hello消息 (24)维护本地连接 (25)路由错误,路由超时和路由删除 (26)本地修复 (28)重启后的操作 (30)接口 (31)7AODV和集群网络 (31)8AODV在其他网络中的应用 (32)9扩展 (34)10参数配置 (35)网络组诺基亚研发中心 C. Perkins RFC:3561加州大学圣芭芭拉分校 E. Belding-Royer类别:试验版辛辛那提大学 S. Das2003年7月Ad hoc网络中基于距离数组的按需(AODV)路由协议本备忘状态本备忘定义的只是一个试验性质的网络社区协议而已,它不是任何一种类型的网络标准。
我们非常需要各种讨论和建议用于改进这个协议。
本备忘录的分发不受任何限制。
版权声明复制权属于整个因特网社区,保留所有权利。
摘要本协议用于特定网络中的可移动节点。
它能在动态变化的点对点网络中确定一条到目的地的路由,并且具有接入速度快,计算量小,内存占用低,网络负荷轻等特点。
它采用目的序列号来确保在任何时候都不会出现回环(甚至在路由控制信息出现异常的时候也是如此),避免了传统的距离数组协议中会出现的很多问题(比如无穷计数问题)。
目录1导言AODV算法旨在多个移动节点中建立和维护一个动态的,自启动的,多跳路由的专属网络。
AODV使得移动节点能快速获得通向新的目的节点的路由,并且节点仅需要维护通向它信号所及范围内的节点的路由,更远的节点的路由信息则不需要维护。
网络中连接的断开和异动会使得网络拓扑结构发生变化,AODV使得移动节点能适时对这种变化做出响应。
AODV简介

2 AODV路由发现
正向路由的建立:RREQ分组最终将到达一个节点,该节点 可能是目的节点,或者这个节点由到达目的节点的路由。 如果这个中间节点有到达目的的路由项,它就会比较路由 项里的目的序列号和RREQ分组里的目的序列号的大小来判 断自己已有的路由是否是比较新的。如果是就对收到的 RREQ分组做出响应,否,则更改RREQ中的目的节点序列号 至当前最大,跳数字段加1,然后继续广播。 在RREP转发回源节点的过程中,沿着这条路径上的每一个 节点都将建立到目的节点的正向路由,也就是记录下RREP 是从哪一个邻居节点来的地址以及记录下RREP中目的节点 的最新序列号。
链路断广播RRER:
4 AODV优点
使用序列号机制,避免路由环路 支持中间结点应答,减少了广播数 节点只存储需要的路由,减少了内存的要求和不必要的复 制。 时延较大,不支持单向信道。
2 AODV路由发现
AODV借鉴了DSDV中的列号的思想,每一个节点都维持了独立序列 号计数器,利用这种机制就能有效地防止路由环的形成。当源节点想 与另外一个节点通信,而它的路由表中又没有相应的路由信息时,源 节点通过向自己的邻居广播RREQ(Route Requests)分组来发起一 次路由发现过程。 反向路由的建立:当RREQ分组从源节点转发,沿途所经过的节点都 要自动建立到源节点的反向路由。节点通过记录收到的第一个RREQ 分组的邻居地址来建立反向路由。
AODV路由发现:
3 AODV路由维护
(1)与活动路由无关的节点移动,并不影响信源到信宿 的寻径。 (2)如果信源节点移动导致路由不可用,则由信源重新 发起路由发现过程。 (3)当信宿节点或活动路由的中间结点移动,导致链路 中断,则链路的"上游节点“主动发送一个RERR,该 RERR的信宿大于其所获取的信宿序列号,跳计数设为无 穷大,并广播到所有活动邻居。
基于能耗优化的AODV路由协议

传感 器与微系统( rnd cr n coyt ehooi ) Ta su e a dMi ss m T cnlg s r e e
21 0 2年 第 3 卷 第 7期 1
基 于 能 耗 优 化 的 A V 路 由协 议 OD
李 智 明 ,陈佳 品 ,李振 波
( 海 交 通 大 学 微 纳 科 学 技 术研 究 院纳 米/ 米 制造 技术 国 家重 点 实验 室 , 海 2 04 ) 上 微 上 0 20
Ab ta t I r e oo t z n aa c ee eg o s mp in o a h n d sS st r ln h e vc i s r c : n od rt p i ea d b l n e t n r y c n u t f c o e O a o p oo gt e s r ie l e mi h o能量消耗从而达到延长 了网络寿命的 目的 , 出 为 提
了一种基于能耗优化的 A D E A D 路 由协议 。EA D O V( — O V) — O V优先选择 剩余 能量较高 的节点参 与路 由同 时选择能耗相对较小的路径作为路由 , 引进了被动更 新路 由和动态 调整发射功率两 种机制 。N - S2仿真结 果表 明 : 与传统 A D O V相 比, — O V降低 了网络 的整体能耗 , EA D 有效均衡使用各节点 的能量 , 长 了网络 寿 延
n t r j Jao ewok Sm1 t r l
0 引 言
传感器 网络 中, 发射 功率是恒定不变 的 , 为了减少跳 数和增 加发送的成功率 , 常常是 以较大 的功率来发射 信号 。这 种 恒定发射 功率 的方式 不仅会浪 费节点 的发射功耗 , 也造 成 不 必 的接 收 功耗 与 干扰 , 且 还 会 降低 网 络 的安 全 而
aodv中文翻译]
![aodv中文翻译]](https://img.taocdn.com/s3/m/dc37a8ee856a561252d36f12.png)
Nokia Research Center
Category: Experimental
E. Belding-Royer
University of California, Santa Barbara
S. Das
University of Cincinnati
July 2003
Ad hoc On-Demand Distance Vector (AODV) Routing
6.6.1. 目的节点产生路由回复 ......................................................... 18 6.6.2. 中间节点产生路由回复 ........................................................ 18 6.6.3. 产生 RREP 副本..................................................................... 18 6.7. 路由回复的处理与转发 .................................................................... 19 6.8. 单向链路的处理 ............................................................................ 20 6.9. Hello 消息 ................................................................................. 20 6.10 保持本地连接 .............................................................................. 21 6.11 路由错误消息、路由过期与路由删除 ............................................. 21 6.12 本地修复.........................................................................................22 6.13 重新启动问题 .............................................................................. 23 7. AODV 与合并网络 ............................................................................... 24 8. AODV 在其它网络的应用 ...................................................................... 25 9. 网络扩展 ................................................................................................ 25 9.1. Hello Interval Extension 信息格式 ................................................ 26
AODV协议详解

AODV协议详解1 AODV 报文格式AODV 有三种基本的协议报文类型:RREQ 报文、RREP 报文和RRER 报文。
1.1 RREQ 报文a. 对RREQ 的处理接收到RREQ 的结点做如下处理:(1)创建一个表项,先不分配有效序列号,用于记录反向路径。
(2)如果在“路由发现定时”内已收到一个具有相同标识的RREQ 报文,则抛弃该报文,不做任何处理;否则,对该表项进行更新如下:I.下一跳结点=广播RREQ 的邻居。
II.跳数=RREQ 报文的“跳计数”字段值。
III.设置表项的“过时计时器”。
(3)如果满足以下条件,则结点产生“路由回答报文”RREP,并发送到信源;否则更新RREQ 报文并广播更新后的RREQ 报文。
I.该结点是信宿。
II.结点的路由表中有到信宿的活动表项,且表项的信宿序列号大于RREQ中的信宿序列号。
(4)更新RREQ 报文并广播更新后的RREQ 报文I.信宿序列号=本结点收到的信宿相关的最大序列号。
II.跳计数加1。
1.2 RREP 报文(1)信宿结点产生RREP执行如下操作:I.如果收到相应的RREQ 的信宿序列号与信宿维护的当前序列号相等,则信宿将自己维护的序列号加1,否则不变。
II.跳计数=0。
III.定时器值。
(2)中间结点产生的RREP执行如下操作:I.本结点获取的该信宿的最大序列号。
II.跳计数=本结点到信宿的跳数(查相应表项即可得到)。
III.更新本结点维护的“前向路由表项”的下一跳和“反向路由表项”的前一跳b. 对RREP 的处理结点对接收到的RREP 作如下处理。
(1)如果没有与RREP 报文中的信宿相匹配的表项,则先创建一个“前向路表”空表项。
(2)否则,满足如下条件对已有表项进行更新。
条件:I.现有表项的信宿序列号小于RREP 报文中的序列号。
II.现有的表项没有激活。
III.信宿序列号相同,但RREP 报文的“跳计数”值小于表项相对应的值;通过更新或创建,产生一个新的前向路由。
无线传感器网络路由协议

无线传感器网络路由协议无线传感器网络(Wireless Sensor Network,WSN)是由大量低成本、低功耗的传感器节点组成的网络系统,用于感知和收集环境信息。
无线传感器网络的路由协议起着关键作用,它决定了数据在网络中的传输路径和方式,影响着整个网络的性能、能耗以及生存时间。
1. LEACH(Low-Energy Adaptive Clustering Hierarchy)是一种经典的层次化路由协议。
它将网络中的节点划分为若干个簇(Cluster),每个簇有一个簇首节点(Cluster Head)。
簇首节点负责收集和聚合簇内节点的数据,并将聚合后的数据传输给基站节点,从而减少了网络中节点之间的通信量,节省了能耗。
2. AODV(Ad Hoc On-Demand Distance Vector)是一种平面路由协议,适用于无线传感器网络中节点数量较少且网络拓扑较稳定的情况。
AODV协议通过维护路由表来选择最短路径,当节点需要发送数据时,它会向周围节点发起路由请求,并根据收到的响应建立起路由路径。
3. GPSR(Greedy Perimeter Stateless Routing)是一种基于地理位置的路由协议。
它通过利用节点的地理位置信息来进行路由选择,具有低能耗和高效的特点。
GPSR协议将整个网络划分为若干个区域,每个节点知道自己的位置以及周围节点的位置,当需要发送数据时,节点会选择最近的邻居节点来进行转发,直到达到目的节点。
除了以上几种常见的路由协议,还有很多其他的无线传感器网络路由协议,如HEED(Hybrid Energy-Efficient Distributed clustering)、PEGASIS(Power-Efficient Gathering in Sensor Information Systems)等,它们各自具备不同的优势和适用场景。
总之,无线传感器网络的路由协议在保证数据传输可靠性和网络能耗方面起着重要的作用。
aodv翻译修正 (2)

AODV协议的简单描述Ad hoc网络的Ad hoc 按需矢量距离(AODV)算法能够支持在参与移动结点间建立和维护动态,自启动和多跳的路由。
AODV 允许移动结点快速地得到新目的结点的路由,并且不需要结点修复不再活跃通信中的路由。
AODV以实时方式支持移动结点响应断开链接和网络拓扑结构的变化。
AODV的运行是无环路的,并且由于它避免了beelman-ford“无限制计数”问题,使得它能够在Ad Hoc网络拓扑结构变化时很快收敛。
(典型情况,网络中一个结点移动时)。
当链接断开时,AODV能够通知受影响的结点结合使得它们能够取消使用次链接路由。
AODV的一个特性是它为每个路由项使用一个目的结点序列号。
这个目的结点序列号是由目的结点创建的,这个序列号被包含在它发送给请求结点的任何一个路由信息中。
使用目的结点序列号确保了无环路由并且使得程序简单化。
在到达同一个目的地址的两个路由中,请求结点会被要求选择序列号较大的那个路由。
[14]3.2.2AODV是一个路由协议,它通过路由表的管理来运作。
路由表甚至必须为短期的路由保持信息,比如创建起来临时存储通向发起RREQs结点的反向路径的路由。
AODV的原路由表有如下的域:1.目的结点IP地址2.目的序列号3.有效目的序列号标志4.其它状态和路由标志(例如,有效,无效,可修复,修复中)5.网络接口6.跳数(到达目的结点需要的跳数)7.下一跳8.前驱表9.生存周期(路由的终止或者删除时间)3.2.3协议使用的一些术语在这个加入信任度的协议中,所使用的术语基本参照原AODV协议首先定义了一些使用字面意思的大写字母,例如MUST,SHOULD,MAY,等等来为不同的协议特征指出需求级别。
以下是AODV中使用的其它术语。
活跃路由:一个通向一个目的结点的路由表项标记为有效的路由。
在网络中,只有活跃的路由才能够用来传输数据包广播:广播意味着向限定的广播IP地址255.255.255.255传播。
NS2中AODV协议解释

分类:ns仿真2012-05-28 20:23 1285人阅读评论(5) 收藏举报dststructrtfdelaytclfunction[cpp]view plaincopy1.//#include <ip.h>2.3.#include <aodv/aodv.h>4.#include <aodv/aodv_packet.h>5.#include <random.h>6.#include <cmu-trace.h>7.//#include <energy-model.h>8.9.#define max(a,b) ( (a) > (b) ? (a) : (b) )10.#define CURRENT_TIME Scheduler::instance().clock()11.12.//#define DEBUG13.//#define ERROR14.15.#ifdef DEBUG16.static int extra_route_reply = 0;17.static int limit_route_request = 0;18.static int route_request = 0;19.#endif20.21.22./*23. TCL Hooks24.*/25.26.27.int hdr_aodv::offset_;28.static class AODVHeaderClass : public PacketHeaderClass {29.public:30. AODVHeaderClass() : PacketHeaderClass("PacketHeader/AODV",31.sizeof(hdr_all_aodv)) {32. bind_offset(&hdr_aodv::offset_);33. }34.} class_rtProtoAODV_hdr;35./*AODVclass 只有两个函数,构造函数和creat函数*/36.static class AODVclass : public TclClass {37.public:38. AODVclass() : TclClass("Agent/AODV") {}39. TclObject* create(int argc, const char*const* argv) {40. assert(argc == 5);41.//return (new AODV((nsaddr_t) atoi(argv[4])));42.return (new AODV((nsaddr_t) Address::instance().str2addr(argv[4])));43. }44.} class_rtProtoAODV;45.46./*command函数实现了命令的分发*/47.int48.AODV::command(int argc, const char*const* argv) {49.if(argc == 2) {//命令的参数个数是250. Tcl& tcl = Tcl::instance();51.52.if(strncasecmp(argv[1], "id", 2) == 0) {//命令所要求的操作为id53. tcl.resultf("%d", index);54.return TCL_OK;55. }56.57.if(strncasecmp(argv[1], "start", 2) == 0) {//命令所要求的操作为start58. btimer.handle((Event*) 0);59.60.#ifndef AODV_LINK_LAYER_DETECTION61. htimer.handle((Event*) 0);62. ntimer.handle((Event*) 0);63.#endif // LINK LAYER DETECTION64.65. rtimer.handle((Event*) 0);66.return TCL_OK;67. }68. }69.else if(argc == 3) {//命令参数个数等于370.if(strcmp(argv[1], "index") == 0) {//命令所要求的操作为index71. index = atoi(argv[2]);72.return TCL_OK;73. }74.//命令所要求的操作为log-target或者tracetarget75.else if(strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0) {76. logtarget = (Trace*) TclObject::lookup(argv[2]);77.if(logtarget == 0)78.return TCL_ERROR;79.return TCL_OK;80. }81.else if(strcmp(argv[1], "drop-target") == 0)82. {83.//命令所要求的操作为drop-target84.int stat = mand(argc,argv);85.if (stat != TCL_OK) return stat;86.return Agent::command(argc, argv);87. }88.89.//命令所要求的操作if-queue90.else if(strcmp(argv[1], "if-queue") == 0) {91. ifqueue = (PriQueue*) TclObject::lookup(argv[2]);92.93.if(ifqueue == 0)94.return TCL_ERROR;95.return TCL_OK;96. }97.//命令所要求的操作为port-dmux98.else if (strcmp(argv[1], "port-dmux") == 0) {99. dmux_ = (PortClassifier *)TclObject::lookup(argv[2]);100.if (dmux_ == 0) {101. fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__,102. argv[1], argv[2]);103.return TCL_ERROR;104. }105.return TCL_OK;106. }107. }108.return Agent::command(argc, argv);109.}110.111./*112. Constructor113.*/114.115.AODV::AODV(nsaddr_t id) : Agent(PT_AODV),116. btimer(this), htimer(this), ntimer(this),117. rtimer(this), lrtimer(this), rqueue() {118.119.120. index = id;121. seqno = 2;122. bid = 1;123.124. LIST_INIT(&nbhead);125. LIST_INIT(&bihead);126.127. logtarget = 0;128. ifqueue = 0;129.}130.131./*132. Timers133.*/134.//广播定时器135.void136.BroadcastTimer::handle(Event*) {137. agent->id_purge();138. Scheduler::instance().schedule(this, &intr, BCAST_ID_SAVE);139.}140.//hello报文定时器141.void142.HelloTimer::handle(Event*) {143. agent->sendHello();144.double interval = MinHelloInterval +145. ((MaxHelloInterval - MinHelloInterval) * Random::uniform()); 146. assert(interval >= 0);147. Scheduler::instance().schedule(this, &intr, interval);148.}149.//邻居定时器150.void151.NeighborTimer::handle(Event*) {152. agent->nb_purge();153. Scheduler::instance().schedule(this, &intr, HELLO_INTERVAL);154.}155.路由缓存定时器156.void157.RouteCacheTimer::handle(Event*) {158. agent->rt_purge();159.#define FREQUENCY 0.5 // sec160. Scheduler::instance().schedule(this, &intr, FREQUENCY);161.}162.//路由缓存定时器163.void164.LocalRepairTimer::handle(Event* p) { // SRD: 5/4/99165.aodv_rt_entry *rt;166.struct hdr_ip *ih = HDR_IP( (Packet *)p);167.168./* you get here after the timeout in a local repair attempt */169./* fprintf(stderr, "%s\n", __FUNCTION__); */170.171.172. rt = agent->rtable.rt_lookup(ih->daddr());173.174.if (rt && rt->rt_flags != RTF_UP) {175.// route is yet to be repaired176.// I will be conservative and bring down the route177.// and send route errors upstream.178./* The following assert fails, not sure why */179./* assert (rt->rt_flags == RTF_IN_REPAIR); */180.181.//rt->rt_seqno++;182. agent->rt_down(rt);183.// send RERR184.#ifdef DEBUG185. fprintf(stderr,"Node %d: Dst - %d, failed local repair\n",index, rt->rt_dst); 186.#endif187. }188. Packet::free((Packet *)p);189.}190.191.192./*193. Broadcast ID Management Functions194.*/195.196.197.void198.AODV::id_insert(nsaddr_t id, u_int32_t bid) { 199.BroadcastID *b = new BroadcastID(id, bid); 200.201. assert(b);202. b->expire = CURRENT_TIME + BCAST_ID_SAVE; 203. LIST_INSERT_HEAD(&bihead, b, link);204.}205.206./* SRD */207.bool208.AODV::id_lookup(nsaddr_t id, u_int32_t bid) { 209.BroadcastID *b = bihead.lh_first;210.211.// Search the list for a match of source and bid 212.for( ; b; b = b->link.le_next) {213.if ((b->src == id) && (b->id == bid))214.return true;215. }216.return false;217.}218.219.void220.AODV::id_purge() {221.BroadcastID *b = bihead.lh_first;222.BroadcastID *bn;223.double now = CURRENT_TIME;224.225.for(; b; b = bn) {226. bn = b->link.le_next;227.if(b->expire <= now) {228. LIST_REMOVE(b,link);229.delete b;230. }231. }232.}233.234./*235. Helper Functions236.*/237.238.double239.AODV::PerHopTime(aodv_rt_entry *rt) {240.int num_non_zero = 0, i;241.double total_latency = 0.0;242.243.if (!rt)244.return ((double) NODE_TRAVERSAL_TIME );245.246.for (i=0; i < MAX_HISTORY; i++) {247.if (rt->rt_disc_latency[i] > 0.0) {248. num_non_zero++;249. total_latency += rt->rt_disc_latency[i]; 250. }251. }252.if (num_non_zero > 0)253.return(total_latency / (double) num_non_zero); 254.else255.return((double) NODE_TRAVERSAL_TIME);256.257.}258.259./*260. Link Failure Management Functions261.*/262.263.static void264.aodv_rt_failed_callback(Packet *p, void *arg) { 265. ((AODV*) arg)->rt_ll_failed(p);266.}267.268./*269. * This routine is invoked when the link-layer reports a route failed. 270. */271./*邻居链路down掉,处理*/272.void273.AODV::rt_ll_failed(Packet *p) {274.struct hdr_cmn *ch = HDR_CMN(p);275.struct hdr_ip *ih = HDR_IP(p);276.aodv_rt_entry *rt;277.nsaddr_t broken_nbr = ch->next_hop_;//记录下一跳邻居的地址278.279.#ifndef AODV_LINK_LAYER_DETECTION280. drop(p, DROP_RTR_MAC_CALLBACK);281.#else282.283./*284. * Non-data packets and Broadcast Packets can be dropped.285. */286.//如果是非数据或者广播报文,则可以直接丢弃287.if(! DATA_PACKET(ch->ptype()) ||288. (u_int32_t) ih->daddr() == IP_BROADCAST) {289. drop(p, DROP_RTR_MAC_CALLBACK);290.return;291. }292. log_link_broke(p);293.//如果不存在到达目的节点的路径,丢弃报文294.if((rt = rtable.rt_lookup(ih->daddr())) == 0) {295. drop(p, DROP_RTR_MAC_CALLBACK);296.return;297. }298. log_link_del(ch->next_hop_);299.300.#ifdef AODV_LOCAL_REPAIR301./* if the broken link is closer to the dest than source,302. attempt a local repair. Otherwise, bring down the route. */ 303.304.//如果转发的跳数大于到达目的节点的跳数,则进行路由修复;否则丢弃通过此邻居的305.//数据并且删除此邻居306.if (ch->num_forwards() > rt->rt_hops) {307. local_rt_repair(rt, p); // local repair308.// retrieve all the packets in the ifq using this link,309.// queue the packets for which local repair is done,310.return;311. }312.else313.#endif // LOCAL REPAIR314.315. {316. drop(p, DROP_RTR_MAC_CALLBACK);317.// Do the same thing for other packets in the interface queue using the 318.// broken link -Mahesh319.while((p = ifqueue->filter(broken_nbr))) {320. drop(p, DROP_RTR_MAC_CALLBACK);321. }322. nb_delete(broken_nbr);323. }324.325.#endif // LINK LAYER DETECTION326.}327./*当发现邻居失效的时候,就会调用此函数*/328.void329.AODV::handle_link_failure(nsaddr_t id) {330.aodv_rt_entry *rt, *rtn;331.Packet *rerr = Packet::alloc();332.struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);333.334. re->DestCount = 0;335.//查找通过此邻居节点到达目的的路由,336.for(rt = rtable.head(); rt; rt = rtn) { // for each rt entry337. rtn = rt->rt_link.le_next;338.//如果跳数不是无限大并且下一跳就是失效的邻居339.if ((rt->rt_hops != INFINITY2) && (rt->rt_nexthop == id) ) {340. assert (rt->rt_flags == RTF_UP);341. assert((rt->rt_seqno%2) == 0);342. rt->rt_seqno++;343. re->unreachable_dst[re->DestCount] = rt->rt_dst;344. re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;345.#ifdef DEBUG346. fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\n", __FUNCTION__, CURRENT_TIME,347. index, re->unreachable_dst[re->DestCount],348. re->unreachable_dst_seqno[re->DestCount], rt->rt_nexthop);349.#endif // DEBUG350. re->DestCount += 1;351. rt_down(rt);//将此路由down掉352. }353.// remove the lost neighbor from all the precursor lists354. rt->pc_delete(id);//删除此路由的前缀列表355. }356./*如果存在通过此邻居到达目的节点的路由,则发送错误报文*/357.if (re->DestCount > 0) {358.#ifdef DEBUG359. fprintf(stderr, "%s(%f): %d\tsending RERR...\n", __FUNCTION__, CURRENT_TIME, index); 360.#endif // DEBUG361. sendError(rerr, false);362. }363.else {364. Packet::free(rerr);365. }366.}367.368.void369.AODV::local_rt_repair(aodv_rt_entry *rt, Packet *p) {370.#ifdef DEBUG371. fprintf(stderr,"%s: Dst - %d\n", __FUNCTION__, rt->rt_dst);372.#endif373.// Buffer the packet374. rqueue.enque(p);375.376.// mark the route as under repair377. rt->rt_flags = RTF_IN_REPAIR;378.379. sendRequest(rt->rt_dst);380.381.// set up a timer interrupt382. Scheduler::instance().schedule(&lrtimer, p->copy(), rt->rt_req_timeout);383.}384./*更新路由条目*/385.void386.AODV::rt_update(aodv_rt_entry *rt, u_int32_t seqnum, u_int16_t metric, 387. nsaddr_t nexthop, double expire_time) {388.389. rt->rt_seqno = seqnum;390. rt->rt_hops = metric;391. rt->rt_flags = RTF_UP;392. rt->rt_nexthop = nexthop;393. rt->rt_expire = expire_time;394.}395./*将此路由条目down掉*/396.void397.AODV::rt_down(aodv_rt_entry *rt) {398./*399. * Make sure that you don't "down" a route more than once.400. */401.402.if(rt->rt_flags == RTF_DOWN) {403.return;404. }405.406.// assert (rt->rt_seqno%2); // is the seqno odd?407. rt->rt_last_hop_count = rt->rt_hops;408. rt->rt_hops = INFINITY2;409. rt->rt_flags = RTF_DOWN;410. rt->rt_nexthop = 0;411. rt->rt_expire = 0;412.413.} /* rt_down function */414.415./*416. Route Handling Functions417.*/418.419.void420.AODV::rt_resolve(Packet *p) {421.struct hdr_cmn *ch = HDR_CMN(p);422.struct hdr_ip *ih = HDR_IP(p);423.aodv_rt_entry *rt;424.425./*426. * Set the transmit failure callback. That427. * won't change.428. */429.//这是一个指针,具体请看另一篇博客430. ch->xmit_failure_ = aodv_rt_failed_callback;431. ch->xmit_failure_data_ = (void*) this;432. rt = rtable.rt_lookup(ih->daddr());433.if(rt == 0) {434. rt = rtable.rt_add(ih->daddr());435. }436.437./*438. * If the route is up, forward the packet439. */440.//如果存在路由,则转发441.if(rt->rt_flags == RTF_UP) {442. assert(rt->rt_hops != INFINITY2);443. forward(rt, p, NO_DELAY);444. }445./*446. * if I am the source of the packet, then do a Route Request. 447. */448.else if(ih->saddr() == index)449.// {450.//如果是源节点且没有到达目的节点的路由,缓存数分组451.//发送路由请求452. rqueue.enque(p);453. sendRequest(rt->rt_dst);454. }455./*456. * A local repair is in progress. Buffer the packet.457. */458.//如果此路由处于修复状态,则缓存分组459.else if (rt->rt_flags == RTF_IN_REPAIR) {460. rqueue.enque(p);461. }462.463./*464. * I am trying to forward a packet for someone else to which 465. * I don't have a route.466. */467.//否则发送错误报文468.else {469. Packet *rerr = Packet::alloc();470.struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);471./*472. * For now, drop the packet and send error upstream.473. * Now the route errors are broadcast to upstream474. * neighbors - Mahesh 09/11/99475. */476.477. assert (rt->rt_flags == RTF_DOWN);478. re->DestCount = 0;479. re->unreachable_dst[re->DestCount] = rt->rt_dst;480. re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno; 481. re->DestCount += 1;482.#ifdef DEBUG483. fprintf(stderr, "%s: sending RERR...\n", __FUNCTION__); 484.#endif485. sendError(rerr, false);486.487. drop(p, DROP_RTR_NO_ROUTE);488. }489.490.}491./*定时查看路由缓存条目*/492.void493.AODV::rt_purge() {494.aodv_rt_entry *rt, *rtn;495.double now = CURRENT_TIME;496.double delay = 0.0;497.Packet *p;498.499.for(rt = rtable.head(); rt; rt = rtn) { // for each rt entry 500. rtn = rt->rt_link.le_next;501.//如果此路由条目标注为有效,但是生存时间为0502.//丢弃前往目的分组,并且将此路由条目down掉503.if ((rt->rt_flags == RTF_UP) && (rt->rt_expire < now)) { 504.// if a valid route has expired, purge all packets from 505.// send buffer and invalidate the route. 506. assert(rt->rt_hops != INFINITY2);507.while((p = rqueue.deque(rt->rt_dst))) {508.#ifdef DEBUG509. fprintf(stderr, "%s: calling drop()\n",510. __FUNCTION__);511.#endif // DEBUG512. drop(p, DROP_RTR_NO_ROUTE);513. }514. rt->rt_seqno++;515. assert (rt->rt_seqno%2);516. rt_down(rt);517. }518.//如果此路由条目并没有过期,则可以发送分组519.else if (rt->rt_flags == RTF_UP) {520.// If the route is not expired,521.// and there are packets in the sendbuffer waiting,522.// forward them. This should not be needed, but this extra 523.// check does no harm.524. assert(rt->rt_hops != INFINITY2);525.while((p = rqueue.deque(rt->rt_dst))) {526. forward (rt, p, delay);527. delay += ARP_DELAY;528. }529. }530.//如果此路由条目已经down掉,但是有前往目的的分组,则发送路由请求531.else if (rqueue.find(rt->rt_dst))532.// If the route is down and533.// if there is a packet for this destination waiting in 534.// the sendbuffer, then send out route request. sendRequest 535.// will check whether it is time to really send out request 536.// or not.537.// This may not be crucial to do it here, as each generated 538.// packet will do a sendRequest anyway.539.540. sendRequest(rt->rt_dst);541. }542.543.}544.545./*546. Packet Reception Routines547.*/548.549.void550.AODV::recv(Packet *p, Handler*) {551.struct hdr_cmn *ch = HDR_CMN(p);552.struct hdr_ip *ih = HDR_IP(p);553.554. assert(initialized());555.//assert(p->incoming == 0);556.// XXXXX NOTE: use of incoming flag has been depracated; In order to track direction of pkt flow, direction_ i n hdr_cmn is used instead. see packet.h for details.557.//如果分组类型是AODV类型,则交给recvAodv函数558.if(ch->ptype() == PT_AODV) {559. ih->ttl_ -= 1;560. recvAODV(p);561.return;562. }563.564.565./*566. * Must be a packet I'm originating...567. */568.//如果是我发送的报文,加上包头,ch->num_forward()是转发的跳数569.if((ih->saddr() == index) && (ch->num_forwards() == 0)) {570./*571. * Add the IP Header572. */573. ch->size() += IP_HDR_LEN;574.// Added by Parag Dadhania && John Novatnack to handle broadcasting575.if ( (u_int32_t)ih->daddr() != IP_BROADCAST)576. ih->ttl_ = NETWORK_DIAMETER;577.}578./*579. * I received a packet that I sent. Probably580. * a routing loop.581. */582.//出现路由环路,丢弃583.else if(ih->saddr() == index) {584. drop(p, DROP_RTR_ROUTE_LOOP);585.return;586. }587./*588. * Packet I'm forwarding...589. */590.else {591./*592. * Check the TTL. If it is zero, then discard.593. */594.//如果ttl值为零,丢弃595.if(--ih->ttl_ == 0) {596. drop(p, DROP_RTR_TTL);597.return;598. }599. }600.// Added by Parag Dadhania && John Novatnack to handle broadcasting 601.//如果不是广播报文,交给re_resolve函数处理;如果是广播报文,则转发602.if ( (u_int32_t)ih->daddr() != IP_BROADCAST)603. rt_resolve(p);604.else605. forward((aodv_rt_entry*) 0, p, NO_DELAY);606.}607.608.609.void610.AODV::recvAODV(Packet *p) {611.struct hdr_aodv *ah = HDR_AODV(p);612.struct hdr_ip *ih = HDR_IP(p);613.614. assert(ih->sport() == RT_PORT);615. assert(ih->dport() == RT_PORT);616.617./*618. * Incoming Packets.619. */620.switch(ah->ah_type) {621.622.case AODVTYPE_RREQ:623. recvRequest(p);624.break;625.626.case AODVTYPE_RREP:627. recvReply(p);628.break;629.630.case AODVTYPE_RERR:631. recvError(p);632.break;633.634.case AODVTYPE_HELLO:635. recvHello(p);636.break;637.638.default:639. fprintf(stderr, "Invalid AODV type (%x)\n", ah->ah_type); 640. exit(1);641. }642.643.}644.645.646.void647.AODV::recvRequest(Packet *p) {648.struct hdr_ip *ih = HDR_IP(p);649.struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);650.aodv_rt_entry *rt;651.652./*653. * Drop if:654. * - I'm the source655. * - I recently heard this request.656. */657./*如果此节点就是源节点,出现环路,丢弃路由请求报文*/658.if(rq->rq_src == index) {659.#ifdef DEBUG660. fprintf(stderr, "%s: got my own REQUEST\n", __FUNCTION__); 661.#endif // DEBUG662. Packet::free(p);663.return;664. }665./*如果已经收到了源地址和请求序列号相等的请求报文,丢弃*/666.if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {667.668.#ifdef DEBUG669. fprintf(stderr, "%s: discarding request\n", __FUNCTION__); 670.#endif // DEBUG671.672. Packet::free(p);673.return;674. }675.676./*677. * Cache the broadcast ID678. */679./*缓存此路由请求*/680. id_insert(rq->rq_src, rq->rq_bcast_id);681.682.683.684./*685. * We are either going to forward the REQUEST or generate a 686. * REPLY. Before we do anything, we make sure that the REVERSE 687. * route is in the route table.688. */689.//建立反向路径690. aodv_rt_entry *rt0; // rt0 is the reverse route691.692. rt0 = rtable.rt_lookup(rq->rq_src);693.if(rt0 == 0) { /* if not in the route table */694.// create an entry for the reverse route.695. rt0 = rtable.rt_add(rq->rq_src);696. }697.//更新此路由条目的生存时间698. rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)); 699./*如果请求序列号大于路由序列号或者两者序列号相等但是跳数700.比源路由跳数小,则更新*/701.if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||702. ((rq->rq_src_seqno == rt0->rt_seqno) &&703. (rq->rq_hop_count < rt0->rt_hops)) ) {704.// If we have a fresher seq no. or lesser #hops for the705.// same seq no., update the rt entry. Else don't bother.706.rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(),707. max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) ); 708./*如果此前请求过该路由条目,则更新信息*/709.if (rt0->rt_req_timeout > 0.0) {710.// Reset the soft state and711.// Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT712.// This is because route is used in the forward direction,713.// but only sources get benefited by this change714. rt0->rt_req_cnt = 0;715. rt0->rt_req_timeout = 0.0;716. rt0->rt_req_last_ttl = rq->rq_hop_count;717. rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;718. }719.720./* Find out whether any buffered packet can benefit from the721. * reverse route.722. * May need some change in the following code - Mahesh 09/11/99723. */724./*如果有到反向路径的分组报文,则发送*/725. assert (rt0->rt_flags == RTF_UP);726. Packet *buffered_pkt;727.while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) {728.if (rt0 && (rt0->rt_flags == RTF_UP)) {729. assert(rt0->rt_hops != INFINITY2);730. forward(rt0, buffered_pkt, NO_DELAY);731. }732. }733. }734.// End for putting reverse route in rt table735.736.737./*738. * We have taken care of the reverse route stuff.739. * Now see whether we can send a route reply.740. */741.//寻找到目的节点的路由742. rt = rtable.rt_lookup(rq->rq_dst);743.744.// First check if I am the destination ..745./*如果本节点就是目的节点,直接发送路由应答报文*/746.if(rq->rq_dst == index) {747.748.#ifdef DEBUG749. fprintf(stderr, "%d - %s: destination sending reply\n", 750. index, __FUNCTION__);751.#endif // DEBUG752.753.754.// Just to be safe, I use the max. Somebody may have755.// incremented the dst seqno.756. seqno = max(seqno, rq->rq_dst_seqno)+1;757.if (seqno%2) seqno++;758.759. sendReply(rq->rq_src, // IP Destination760. 1, // Hop Count761. index, // Dest IP Address762. seqno, // Dest Sequence Num763. MY_ROUTE_TIMEOUT, // Lifetime764. rq->rq_timestamp); // timestamp765.766. Packet::free(p);767. }768.769.// I am not the destination, but I may have a fresh enough route. 770./*如果不是目的节点,但是有到目的节点的路径,也发送路由应答报文*/771.else if (rt && (rt->rt_hops != INFINITY2) &&772. (rt->rt_seqno >= rq->rq_dst_seqno) ) {773.774.//assert (rt->rt_flags == RTF_UP);775. assert(rq->rq_dst == rt->rt_dst);776.//assert ((rt->rt_seqno%2) == 0); // is the seqno even?777. sendReply(rq->rq_src,778. rt->rt_hops + 1,779. rq->rq_dst,780. rt->rt_seqno,781. (u_int32_t) (rt->rt_expire - CURRENT_TIME),782.// rt->rt_expire - CURRENT_TIME,783. rq->rq_timestamp);784.// Insert nexthops to RREQ source and RREQ destination in the785.// precursor lists of destination and source respectively786. rt->pc_insert(rt0->rt_nexthop); // 加入前缀列表787. rt0->pc_insert(rt->rt_nexthop); // 加入前缀列表788.789.#ifdef RREQ_GRAT_RREP790.791. sendReply(rq->rq_dst,792. rq->rq_hop_count,793. rq->rq_src,794. rq->rq_src_seqno,795. (u_int32_t) (rt->rt_expire - CURRENT_TIME),796.// rt->rt_expire - CURRENT_TIME,797. rq->rq_timestamp);798.#endif799.800.// TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT801.802.// DONE: Included gratuitous replies to be sent as per IETF aodv draft specification. As of now, G flag has not been dynamically used and is always set or reset in aodv-packet.h --- Anant Utgikar, 09/16/02.803.804. Packet::free(p);805. }806./*807. * Can't reply. So forward the Route Request808. */809.//不能应答此报文,则继续广播810.else {811. ih->saddr() = index;812. ih->daddr() = IP_BROADCAST;813. rq->rq_hop_count += 1;814.// Maximum sequence number seen en route815.if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno); 816. forward((aodv_rt_entry*) 0, p, DELAY);817. }818.819.}820.821.822.void823.AODV::recvReply(Packet *p) {824.//struct hdr_cmn *ch = HDR_CMN(p);825.struct hdr_ip *ih = HDR_IP(p);826.struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);827.aodv_rt_entry *rt;828.char suppress_reply = 0;829.double delay = 0.0;830.831.#ifdef DEBUG832. fprintf(stderr, "%d - %s: received a REPLY\n", index, __FUNCTION__); 833.#endif // DEBUG834.835.836./*837. * Got a reply. So reset the "soft state" maintained for838. * route requests in the request table. We don't really have839. * have a separate request table. It is just a part of the840. * routing table itself.841. */842.// Note that rp_dst is the dest of the data packets, not the843.// the dest of the reply, which is the src of the data packets.844.845. rt = rtable.rt_lookup(rp->rp_dst);//建立反向路径846.847./*848. * If I don't have a rt entry to this host... adding849. */850.if(rt == 0) {851. rt = rtable.rt_add(rp->rp_dst);852. }853.854./*855. * Add a forward route table entry... here I am following856. * Perkins-Royer AODV paper almost literally - SRD 5/99857. */858./*如果应答报文中目的序列号大于路由序列号或者859.两者序列号相等但是跳数较小,则更新路由表*/860.if ( (rt->rt_seqno < rp->rp_dst_seqno) || // newer route861. ((rt->rt_seqno == rp->rp_dst_seqno) &&862. (rt->rt_hops > rp->rp_hop_count)) ) { // shorter or better route 863.864.// Update the rt entry865. rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count,866. rp->rp_src, CURRENT_TIME + rp->rp_lifetime);867.868.// reset the soft state869. rt->rt_req_cnt = 0;//路由请求次数归零870. rt->rt_req_timeout = 0.0; //路由请求剩余时间归零871. rt->rt_req_last_ttl = rp->rp_hop_count;872./*如果此节点是目的节点*/873.if (ih->daddr() == index) { // If I am the original source874.// Update the route discovery latency statistics875.// rp->rp_timestamp is the time of request origination876.877. rt->rt_disc_latency[rt->hist_indx] = (CURRENT_TIME - rp->rp_timestamp) 878. / (double) rp->rp_hop_count; 879.// increment indx for next time880. rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY;881. }882.883./*884. * Send all packets queued in the sendbuffer destined for885. * this destination.886. * XXX - observe the "second" use of p.887. */888./*如果有到反向路径的数据包,则发送*/889. Packet *buf_pkt;890.while((buf_pkt = rqueue.deque(rt->rt_dst))) {891.if(rt->rt_hops != INFINITY2) {892. assert (rt->rt_flags == RTF_UP);893.// Delay them a little to help ARP. Otherwise ARP894.// may drop packets. -SRD 5/23/99895. forward(rt, buf_pkt, delay);896. delay += ARP_DELAY;897. }898. }899. }900.else {901. suppress_reply = 1;//序列号过小且没有更小的跳数902. }903.904./*905. * If reply is for me, discard it.906. */907.908.if(ih->daddr() == index || suppress_reply)909. {//如果此节点是源节点或者应答报文不够新且没有更小的跳数910. Packet::free(p);911. }912./*913. * Otherwise, forward the Route Reply.914. */915.else {916.// Find the rt entry917.aodv_rt_entry *rt0 = rtable.rt_lookup(ih->daddr());918.// If the rt is up, forward919.if(rt0 && (rt0->rt_hops != INFINITY2))920. {921.//如果存在到源节点的路径,则转发应答报文,否则丢弃应答报文922. assert (rt0->rt_flags == RTF_UP);923. rp->rp_hop_count += 1;924. rp->rp_src = index;925. forward(rt0, p, NO_DELAY);926.// Insert the nexthop towards the RREQ source to927.// the precursor list of the RREQ destination928. rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source 929.。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
内容目录1导言 (3)2概述 (4)3AODV术语 (5)4适用性综述 (7)5消息格式 (8)6AODV操作 (13)管理序列号 (13)路由表项和先驱列表 (15)生成路由请求 (16)控制路由请求消息的传播 (17)处理和转发路由请求 (18)生成路由回复 (20)接受和转发路由回复 (22)对单向连接的操作 (23)Hello消息 (24)维护本地连接 (25)路由错误,路由超时和路由删除 (26)本地修复 (28)重启后的操作 (30)接口 (31)7AODV和集群网络 (31)8AODV在其他网络中的应用 (32)9扩展 (34)10参数配置 (35)网络组诺基亚研发中心 C. Perkins RFC:3561加州大学圣芭芭拉分校 E. Belding-Royer类别:试验版辛辛那提大学 S. Das2003年7月Ad hoc网络中基于距离数组的按需(AODV)路由协议本备忘状态本备忘定义的只是一个试验性质的网络社区协议而已,它不是任何一种类型的网络标准。
我们非常需要各种讨论和建议用于改进这个协议。
本备忘录的分发不受任何限制。
版权声明复制权属于整个因特网社区,保留所有权利。
摘要本协议用于特定网络中的可移动节点。
它能在动态变化的点对点网络中确定一条到目的地的路由,并且具有接入速度快,计算量小,内存占用低,网络负荷轻等特点。
它采用目的序列号来确保在任何时候都不会出现回环(甚至在路由控制信息出现异常的时候也是如此),避免了传统的距离数组协议中会出现的很多问题(比如无穷计数问题)。
目录1导言AODV算法旨在多个移动节点中建立和维护一个动态的,自启动的,多跳路由的专属网络。
AODV使得移动节点能快速获得通向新的目的节点的路由,并且节点仅需要维护通向它信号所及范围内的节点的路由,更远的节点的路由信息则不需要维护。
网络中连接的断开和异动会使得网络拓扑结构发生变化,AODV使得移动节点能适时对这种变化做出响应。
AODV的操作是无自环的,并且由于解决了Bellman-Ford“无穷计数”的问题,使得该算法在网络拓扑变化时(比如一个节点在网络中移动)能够快速收敛。
当一个连接断开时,AODV会告知所有受到影响的节点,这些节点会让用到这个连接的路由失效。
AODV的一个显著特点是它在每个路由表项上使用了目的序列号。
目的序列号由目的节点创建,并且被包含在路由信息中,然后这些路由信息将被回发到所有向它发起请求的节点。
目的序列号的使用确保了无回环,并且易于编程。
如果到一个目的有两条路由可供选择,那么收到请求的节点将会选择序列号最大的那一条(由于目的节点每次收到新的请求都会将目的序列号加一,所以序列号最大表明该路由最新)。
2概述路由请求(RREQ),路由回复(RREP)和路由错误(RERR)是AODV定义的三种消息种类。
这些消息通过UDP和通常的IP协议来接收。
举个例子,发起请求的节点需要用它自己的IP地址作为消息中的Originator IP address(发起者IP)。
对于广播,将采用IP协议指定的广播地址(255.255.255.255),这个地址意味着这种消息将不会被盲目转发。
但是,AODV操作确实要求特定的消息(例如RREQ)得到广泛的散布,甚至有可能散布至整个专有网络。
这些RREQ的散布的范围由IP头中的TTL来指定。
作为一个特点,将不会采用IP协议中的分片传输。
只要一条通道连接的两个端点都有通向对方的正确路由,AODV是不工作的。
当某节点需要连接到一个新的目的节点时,它将广播一个RREQ(路由请求消息)来尝试找到一条到目的节点的路由。
如果RREQ消息到达目的节点,这条路由将被找到。
另外一种情况下,路由也可以找到,就是RREQ到达了一个中间节点,该中间节点拥有到目的节点的“足够新鲜”的路由。
“足够新鲜”的路由首先要是一条到目的地的正确路由,该路由还需要拥有一个足够大的序列号,该序列号不得小于RREQ中的序列号(A ‘fresh enough’ route is a valid route entry for the destination whose associated sequence number is at least as great as that contained in the RREQ.)。
当朝发起RREQ的节点单播一个RREP后,这条路由就建立了。
所有接到请求的节点都会缓存一条回到发起节点的路由,所以RREP就可以通过单播从目的节点返回到发起节点,或者从一个能够找到目的节点的中间节点返回到发起节点。
节点将相邻节点(next hops)的连接状态保存在活动路由表里(active routes)。
当活动路由表里有一条连接断开时,一条RERR消息(路由错误消息)将被用来通知其他节点发生了连接断裂。
RERR消息指出了不再能到达的目的节点(甚至是目的子网)。
为了实现这种报告机制,每个节点还要维护一个“先驱表”(precursor list),表中包含了一些邻居的IP,这些邻居可能会将它用作达到目的地的下一跳节点。
先驱表里的信息可以很轻易的从回传RREP的过程中获得,因为按照定义,RREP就该是传往先驱节点的(见6.6节)。
如果RREP有一个非零的前缀长度,那么RREQ的发起者将被包括在先驱表里作为子网的路由。
(不是特定的某个精确目的地)。
RREQ也可以用来请求多播地址。
这篇文档将不细述这种类型消息处理的全过程(比如这种请求的发起者必须要遵循的某种特别的规则)。
但是,使中继节点能正确处理多播操作是非常重要的,特别网络中有没有做过发起节点或目的节点的中继节点,或类似的没有安装任何对多播有特殊操作的节点。
考虑到有这种“对多播不感冒”的节点,处理多播目的IP地址必须要和处理其他任何IP地址是一样的操作才行。
AODV是一个路由协议,它的工作就是管理路由表。
即使是短期的路由,也必须保留它在路由表里的信息。
比如为RREQ临时存储的返回路径。
AODV的每个路由表项将会包含下列的域:- 目的节点IP地址- 目的节点序列号- 目的节点序列号是否正确的标志- 其他状态和路由标志(比如,有效,无效,可修复,正在修复)- 网络接口- 跳数(到达目的节点需要的跳数)- 下一跳- 先驱表(在6.2节里描述)- 生命(路由过期或应当删除的时间)管理序列号对避免路由回环至关重要,即使是当连接断裂,一个节点不再可达而无法提供他自己的序列号信息的时候也是如此。
当一条链路断开或失效,导致一个节点不可达,当这种情况发生时,将通过对序列号的操作和标注路由表项为不正确来使得这条路由失效。
细节请见6.1节。
3AODV术语按照惯例,本协议的说明使用全大写的单词,比如MUST,SHOULD等等来指出对协议各项特性的要求级别(参考文献1)。
参考文献3中没有定义的其他术语,在这一节定义如下:(注,汉语中MUST会翻译为必须,SHOULD翻译为应当)Active route(活跃路由)路由表项里标为“有效”(valid)的通向目的节点的路由。
只有活跃路由能用来转发数据包。
Broadcast (广播)广播的意思是向IP协议规定的广播地址255.255.255.255发送数据。
广播的包不会被盲目的转发。
但是广播在让AODV消息散布到整个专有网络的时候非常有用。
Destination (目的地)数据包需要被送往的一个IP地址。
和“目的节点”是同一个意思。
当一个节点看到它自己的IP地址和数据包IP头特定的字段中的IP地址一样时,它就认为自己是这个数据包的目的节点。
到达目的节点的路由可以从AODV协议得到,AODV协议会在路由发现消息里得到路由信息。
Forwarding node (转发节点)愿意为其他节点转发数据包的节点。
转发节点会将数据包发送到它的下一个节点(就是在到达目的节点的路径上更靠近目的的那个相邻节点,这条路径由路由控制消息来建立)。
Invalid route (无效路由)一个过期的,在路由表项里被标记为无效(invalid)的路由。
当一个有效路由失效时,它会作为无效路由在路由表里再被保存一段时间。
无效路由不能用于转发数据包,但是它能在路由修复和以后的RREQ消息中提供一些有用信息。
Originating node (发起节点)Ad hoc网络内发出AODV路由发现消息的节点。
AODV路由发现消息需要被恰当的处理,然后会被传送到网络内其他节点。
例如,一个RREQ消息的发起节点就是发起一个路由发现过程并且将RREQ消息广播出去的那个节点。
Reverse route (返回路由)用于转发回复包的路由,这个回复包就是从目的节点或能达到目的节点的中间节点返回到发起节点的RREP包。
Sequence number (序列号)一个单调递增的数字,由每个发起节点管理。
在AODV路由协议的消息里,这个序列号被其他节点用于检测发起节点发出的信息的新旧程度。
Valid route (有效路由)见Active route(活跃路由)。
4适用性综述AODV路由协议被设计用于拥有数十个到上千个移动节点的Ad hoc网络。
AODV能应付低速,中等速度,以及相对高速的移动速度,以及各种级别的数据通信。
AODV被设计用于节点间可以互相信任的网络,比如预先定义好密钥的网络,或者是确信不会有恶意入侵节点的网络。
为了提升可测量性和效能,AODV设计成尽力减低控制信息的流量,并且消除数据流量的影响(原文:AODV has been designed to reduce the dissemination of control traffic and eliminate overhead on data traffic, in order to improve scalability and performance)。
5消息格式1.1.路由请求(RREQ)消息格式012301234567890123456789012345678901 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Type(种类)|J|R|G|D|U|Reserved(保留)|Hop Count(跳数)| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |RREQ ID(路由请求消息标识)| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Destination IP Address(目标节点IP地址)| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Destination Sequence Number(目标节点序列号)| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Originator IP Address(发起节点IP地址)| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Originator Sequence Number(发起节点序列号)| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+路由请求消息的格式如上所示,包含下面几个域(或字段):Type(种类)1J Join flag (加入标志):为多播保留R Repair flag (修复标志): 为多播保留G Gratuitous RREP flag (免费路由回复标志): 指示是否该向目标节点IP地址域指定的节点发送一个免费路由回复消息。