void
AODV::recvRequest(Packet *p) {//收到RREQ
struct hdr_ip *ih = HDR_IP(p);
struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);
aodv_rt_entry *rt;
/*
* Drop if:
* - I'm the source
* - I recently heard this request.
*/
if(rq->rq_src == index) { //看看这个request是不是自己发出来的。
#ifdef DEBUG
fprintf(stderr, "%s: got my own REQUEST/n", __FUNCTION__);
#endif // DEBUG
Packet::free(p); //如果是的话就将这个包丢弃。
return;
}
if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {//看看是不是曾经收到过的rreq.
//两个判据一个是request source(源节点IP地址) 一个是 广播序列号
#ifdef DEBUG
fprintf(stderr, "%s: discarding request/n", __FUNCTION__);
#endif // DEBUG
Packet::free(p); //如果是的话就丢弃
return;
}
/*
* Cache the broadcast ID
*/
//用于判断是否已经收到过该RREQ
id_insert(rq->rq_src, rq->rq_bcast_id); //刷新自己节点的RREQ的broadcast id(就是RREQ)
/* 在这种情况下我们有两种选择,一种是将RREQ继续传播下去,一种是产生RREP
* 在这之前我们要确定,反向路由已经在路由表中存在。如果存在反向路由,在考虑
是否应该想源节点发送RREP
*/
aodv_rt_entry *rt0; // rt0 is the reverse route
rt0 = rtable.rt_lookup(rq->rq_src); //寻找反向路由
if(rt0 == 0) { /* if not in the route table 如果不在路由表中的话*/
// create an entry for the reverse route.
rt0 = rtable.rt_add(rq->rq_src); //将反向路由写入路由表
}
rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE));
//定义ROUTE的生命期
if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||
((rq->rq_src_seqno == rt0->rt_seqno) &&
(rq->rq_hop_count < rt0->rt_hops)) ) {
//这里就是路由判据,当遇到新的RREQ的时候
//比较在路由表中已经存在的到目的节点的路由,比较目的节点的序列号(用来保证使用最新路由
//防止路由环)在目的节点序列号相同的情况下,采用跳数较小的。在这种情况下
//就更新路由表。
// If we have a fresher seq no. or lesser #hops for the
// same seq no., update the rt entry. Else don't bother.
rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(),
max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) );
//上面两行命令就是如何更新路由表,更新路由表中的哪些项。
if (rt0->rt_req_timeout > 0.0) {
// Reset the soft state and
// Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT
// This is because route is used in the forward direction,
// but only sources get benefited by this change
rt0->rt_req_cnt = 0;
rt0->rt_req_timeout = 0.0;
rt0->rt_req_last_ttl = rq->rq_hop_count;
rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;
}
/* Find out whether any buffered packet can benefit from the
* reverse route.
* May need some change in the following code - Mahesh 09/11/99
*/
//缓存中是否有到源节点的路由,有则删除,无则添加
//缓存中是否有到源节点的数据分组,有则,建立好路由开始发送数据。
//查找是否有到目的节点的有效路由,有则向源节点发送RREP,没有则继续发送RREQ。
//注意转发前要更新RREQ的部分内容;
assert (rt0->rt_flags == RTF_UP);
Packet *buffered_pkt;
while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) {
if (rt0 && (rt0->rt_flags == RTF_UP)) {
assert(rt0->rt_hops != INFINITY2);
forward(rt0, buffered_pkt, NO_DELAY);
}
}
}
// End for putting reverse route in rt table
/*反向路径已经清楚了(搞定了)
* We have taken care of the reverse route stuff.
* Now see whether we can send a route reply.
//现在就看看是否应该在此节点处发送RREP
*/
rt = rtable.rt_lookup(rq->rq_dst);//在路由表中查找目的节点是RREQ_DEST的路由参看aodv_rtable
//.cc文件中的rt_lookup函数。
// First check if I am the destination ..
if(rq->rq_dst == index) {
#ifdef DEBUG
fprintf(stderr, "%d - %s: destination sending reply/n",
index, __FUNCTION__);
#endif // DEBUG
// Just to be safe, I use the max. Somebody may have为了安全起见,使用目的节点序列号最大
//的路由+1
// incremented the dst seqno.
seqno = max(seqno, rq->rq_dst_seqno)+1;
if (seqno%2) seqno++;//如果目的节点序列号是奇数就将其变成偶数,保证目的节点序列号是偶数
sendReply(rq->rq_src, // IP Destination目的节点IP
1, // Hop Count
index, // Dest IP Address
seqno, // Dest Sequence Num目的节点序列号
MY_ROUTE_TIMEOUT, // Lifetime
rq->rq_timestamp); // timestamp没搞清楚什么东西
Packet::free(p); //释放RREQ ,产生RREP(这是后话)
#ifdef DEBUG
fprintf(stderr, "%d - %s: destination sending reply/n",
index, __FUNCTION__);
#endif // DEBUG
// Just to be safe, I use the max. Somebody may have
// incremented the dst seqno.
seqno = max(seqno, rq->rq_dst_seqno)+1;
if (seqno%2) seqno++;
sendReply(rq->rq_src, // IP Destination
1, // Hop Count
index, // Dest IP Address
seqno, // Dest Sequence Num
MY_ROUTE_TIMEOUT, // Lifetime
rq->rq_timestamp); // timestamp
Packet::free(p);
}
// I am not the destination, but I may have a fresh enough route.
//如果不是destination,但是有够新的路由
else if (rt && (rt->rt_hops != INFINITY2) &&
(rt->rt_seqno >= rq->rq_dst_seqno) ) {//保证够新(目的节点序列号)
//assert (rt->rt_flags == RTF_UP);
assert(rq->rq_dst == rt->rt_dst);
//assert ((rt->rt_seqno%2) == 0); // is the seqno even?
sendReply(rq->rq_src,
rt->rt_hops + 1, //如果是目的节点的话就设成一,这里不是目的节点就在
//这个RREQ中的跳数加1;
rq->rq_dst, //如果是目的节点这一项就是目的节点的IP地址(这个节点本身的地址),
//这里是RREQ中的目的节点IP地址
rt->rt_seqno,
(u_int32_t) (rt->rt_expire - CURRENT_TIME),
// rt->rt_expire - CURRENT_TIME,
rq->rq_timestamp);
// Insert nexthops to RREQ source and RREQ destination in the
// precursor lists of destination and source respectively
//将下一跳节点分别加入前向路由,反向路由中;
rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source
rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination
#ifdef RREQ_GRAT_RREP
sendReply(rq->rq_dst,
rq->rq_hop_count,
rq->rq_src,
rq->rq_src_seqno,
(u_int32_t) (rt->rt_expire - CURRENT_TIME),
// rt->rt_expire - CURRENT_TIME,就是剩下的生命周期
rq->rq_timestamp);
#endif
// TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT
//产生RREP发向源节点(RREP的目的节点)RREP中使用RREQ中的rq->rq_src_seqno,rq->rq_hop_count
// 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.
//G flag用来设定或者重设aodv packet.
Packet::free(p);
}
/*
* Can't reply. So forward the Route Request
*/
//
else {
ih->saddr() = index;
ih->daddr() = IP_BROADCAST;
rq->rq_hop_count += 1;
// Maximum sequence number seen en route
if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno);
forward((aodv_rt_entry*) 0, p, DELAY);
}
}