void
AODV::recvReply(Packet *p) {
//struct hdr_cmn *ch = HDR_CMN(p);
struct hdr_ip *ih = HDR_IP(p);
struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);
aodv_rt_entry *rt;
char suppress_reply = 0;
double delay = 0.0;
#ifdef DEBUG
fprintf(stderr, "%d - %s: received a REPLY\n", index, __FUNCTION__);
#endif // DEBUG
/*
* Got a reply. So reset the "soft state" maintained for
* route requests in the request table. We don't really have
* have a separate request table. It is just a part of the
* routing table itself.
*/
// Note that rp_dst is the dest of the data packets, not the
// the dest of the reply, which is the src of the data packets.
rt = rtable.rt_lookup(rp->rp_dst);//建立反向路径
/*
* If I don't have a rt entry to this host... adding
*/
if(rt == 0) {
rt = rtable.rt_add(rp->rp_dst);
}
/*
* Add a forward route table entry... here I am following
* Perkins-Royer AODV paper almost literally - SRD 5/99
*/
/*如果应答报文中目的序列号大于路由序列号或者
两者序列号相等但是跳数较小,则更新路由表*/
if ( (rt->rt_seqno < rp->rp_dst_seqno) || // newer route
((rt->rt_seqno == rp->rp_dst_seqno) &&
(rt->rt_hops > rp->rp_hop_count)) ) { // shorter or better route
// Update the rt entry
rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count,
rp->rp_src, CURRENT_TIME + rp->rp_lifetime);
// reset the soft state
rt->rt_req_cnt = 0;//路由请求次数归零
rt->rt_req_timeout = 0.0; //路由请求剩余时间归零
rt->rt_req_last_ttl = rp->rp_hop_count;
/*如果此节点是目的节点*/
if (ih->daddr() == index) { // If I am the original source
// Update the route discovery latency statistics
// rp->rp_timestamp is the time of request origination
rt->rt_disc_latency[rt->hist_indx] = (CURRENT_TIME - rp->rp_timestamp)
/ (double) rp->rp_hop_count;
// increment indx for next time
rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY;
}
/*
* Send all packets queued in the sendbuffer destined for
* this destination.
* XXX - observe the "second" use of p.
*/
/*如果有到反向路径的数据包,则发送*/
Packet *buf_pkt;
while((buf_pkt = rqueue.deque(rt->rt_dst))) {
if(rt->rt_hops != INFINITY2) {
assert (rt->rt_flags == RTF_UP);
// Delay them a little to help ARP. Otherwise ARP
// may drop packets. -SRD 5/23/99
forward(rt, buf_pkt, delay);
delay += ARP_DELAY;
}
}
}
else {
suppress_reply = 1;//序列号过小且没有更小的跳数
}
/*
* If reply is for me, discard it.
*/
if(ih->daddr() == index || suppress_reply)
{//如果此节点是源节点或者应答报文不够新且没有更小的跳数
Packet::free(p);
}
/*
* Otherwise, forward the Route Reply.
*/
else {
// Find the rt entry
aodv_rt_entry *rt0 = rtable.rt_lookup(ih->daddr());
// If the rt is up, forward
if(rt0 && (rt0->rt_hops != INFINITY2))
{
//如果存在到源节点的路径,则转发应答报文,否则丢弃应答报文
assert (rt0->rt_flags == RTF_UP);
rp->rp_hop_count += 1;
rp->rp_src = index;
forward(rt0, p, NO_DELAY);
// Insert the nexthop towards the RREQ source to
// the precursor list of the RREQ destination
rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source
}
else {//
// I don't know how to forward .. drop the reply.
#ifdef DEBUG
fprintf(stderr, "%s: dropping Route Reply\n", __FUNCTION__);
#endif // DEBUG
drop(p, DROP_RTR_NO_ROUTE);
}
}
}
/*从邻居那里收到错误分组,检查自己路由表是否有通过此邻居到达目的地的
路由条目,如果有,则将此路由删除,并继续向邻居广播错误分组*/
void
AODV::recvError(Packet *p) {
struct hdr_ip *ih = HDR_IP(p);
struct hdr_aodv_error *re = HDR_AODV_ERROR(p);
aodv_rt_entry *rt;
u_int8_t i;
Packet *rerr = Packet::alloc();
struct hdr_aodv_error *nre = HDR_AODV_ERROR(rerr);