节点首先清除所有受到影响的路由项,丢弃所有受影响的分组。然后,如果前驱节点中存在会受该路由错误影响的分组,则调用sendError(Packet*, bool)函数转发该分组。

sendError函数创建并填充分组,然后调用Scheduler::instance().schedule()函数来发送该分组。

(4)如果接收到的是Hello消息分组,则调用recvHello(Packet*)函数进行处理。

节点会将该邻居的信息添加到邻居列表中(或更新该邻居的信息)。

2、如果是数据分组,则节点丢弃已经发送过或者ttl为0的分组,并结束处理。如果分组是由上层协议产生的,则节点添加IP报头。随后,节点根据目的路由进行不同处理。

(1)如果目的节点路由未知,则调用rt_resolve(Packet*)函数进行路由解析和转发。

如果目的节点路由在路由表中存在,则直接调用forward函数进行转发。如果分组是由节点自身产生的,则将分组保存到缓冲队列中,并调用 sendRequest(nsaddr_t)函数查询目的路由。如果目的路由已知,但正在进行本地修复,则将分组保存到缓冲队列中。否则,丢弃该分组,并调用sendError函数报错。

(2)如果目的节点路由已知,则调用forward进行转发。

节点丢弃ttl为0的分组,并根据分组类型决定下一步操作。

如果接收到的是数据分组,且自身为目的节点,则通过调用PortClassifier对象的recv(Packet*, Handle*)函数将分组交递给高层协议,并结束处理。否则,节点设置分组属性,并调用Scheduler::instance().schedule (Handler*, Event*, double)函数来发送分组。其中,Handler为基类中的属性target_(会根据脚本中的设置指向相应的协议实体),Event为要发送的分组即可。

以上就是AODV路由协议在节点收到分组后的一个处理过程。接下来看看各个定时器所做的工作。

1、广播定时器BroadcastTimer在到时后调用id_purge()函数删除广播项中已超时的项目,并通过调用Scheduler:: instance().schedule()函数来设置下次被调用的时间(Handler为this指针,Event为类属性intr)。

2、周期Hello报文广播定时器HelloTimer在到时后调用sendHello()函数向邻居创建并发送Hello消息,并调用schedule()函数来设置下次被调用的时间。

3、邻居管理定时器NeighborTimer在到时后调用nb_purge()函数来清除邻居列表中已超时的邻居项,并调用schedule()来设置下次被调用的时间。nb_purge会调用nt_delete(nsaddr_t)函数来清除超时的邻居项,其又会调用 handle_link_failure(nsaddr_t)函数来处理由于邻居节点被删除而引起的路由变化。

4、路由缓存定时器RouteCacheTimer在到时后调用rt_purge()函数来清除路由表中已超时的路由项,并丢弃相关的分组,再调用schedule()来设置下次被调用的时间。

5、本地修复定时器LocalRepairTimer在调用后根据传递的分组的目的地址关闭相应的路由项。

6、缓存广播ID定时器BroadcastID用来保存广播分组的ID。

此外,AODV路由协议的路由表、日志记录和队列三个类就相对比较简单了,都只实现了一些非常基本的功能,在此就不做介绍了


相关内容