tl_ == 0) {
#ifdef DEBUG
fprintf(stderr, "%s: calling drop()\n", __PRETTY_FUNCTION__);
#endif // DEBUG
drop(p, DROP_RTR_TTL);
return;
}
/*如果不是AODV数据包并且链路方向是上行并且是广播包或者此节点就是目的地址*/
if (ch->ptype() != PT_AODV && ch->direction() == hdr_cmn::UP &&
((u_int32_t)ih->daddr() == IP_BROADCAST)
|| ((u_int32_t)ih->daddr() == here_.addr_)) {
dmux_->recv(p,0);//交给分类器
return;
}
if (rt) {//如果存在去往目的的路由,设置一系列参数
assert(rt->rt_flags == RTF_UP);
rt->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;
ch->next_hop_ = rt->rt_nexthop;
ch->addr_type() = NS_AF_INET;
ch->direction() = hdr_cmn::DOWN; //important: change the packet's direction
}
else { // if it is a broadcast packet
// assert(ch->ptype() == PT_AODV); // maybe a diff pkt type like gaf
assert(ih->daddr() == (nsaddr_t) IP_BROADCAST);//如果这是一个广播报文
ch->addr_type() = NS_AF_NONE;
ch->direction() = hdr_cmn::DOWN; //important: change the packet's direction
}
if (ih->daddr() == (nsaddr_t) IP_BROADCAST) {//广播报文
// If it is a broadcast packet
assert(rt == 0);
/*
* Jitter the sending of broadcast packets by 10ms
*/
Scheduler::instance().schedule(target_, p,
0.01 * Random::uniform());//加入定时器
}
else { // 非广播报文
if(delay > 0.0) {
Scheduler::instance().schedule(target_, p, delay);
}
else {
// Not a broadcast packet, no delay, send immediately
Scheduler::instance().schedule(target_, p, 0.);
}
}
}
void
AODV::sendRequest(nsaddr_t dst) {
// Allocate a RREQ packet
Packet *p = Packet::alloc();
struct hdr_cmn *ch = HDR_CMN(p);
struct hdr_ip *ih = HDR_IP(p);
struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);
aodv_rt_entry *rt = rtable.rt_lookup(dst);
assert(rt);
/*
* Rate limit sending of Route Requests. We are very conservative
* about sending out route requests.
*/
//如果有到目的节点的路由,则终止请求
if (rt->rt_flags == RTF_UP) {
assert(rt->rt_hops != INFINITY2);
Packet::free((Packet *)p);
return;
}
//如果请求时间还有到,则不发送
if (rt->rt_req_timeout > CURRENT_TIME) {
Packet::free((Packet *)p);
return;
}
// rt_req_cnt is the no. of times we did network-wide broadcast
// RREQ_RETRIES is the maximum number we will allow before
// going to a long timeout.
//如果请求次数大于最大的发送请求次数,则丢掉分组,不发送请求
if (rt->rt_req_cnt > RREQ_RETRIES) {
rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;
rt->rt_req_cnt = 0;
Packet *buf_pkt;
while ((buf_pkt = rqueue.deque(rt->rt_dst))) {
drop(buf_pkt, DROP_RTR_NO_ROUTE);
}
Packet::free((Packet *)p);
return;
}
#ifdef DEBUG
fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d\n",
++route_request, index, rt->rt_dst);
#endif // DEBUG
// Determine the TTL to be used this time.
// Dynamic TTL eva luation - SRD
rt->rt_req_last_ttl = max(rt->rt_req_last_ttl,rt->rt_last_hop_count);
//路由请求的环搜索
//第一次广播请求,选择初始跳数;随后逐渐扩大
if (0 == rt->rt_req_last_ttl) {
// first time query broadcast
ih->ttl_ = TTL_START;
}
else {
// Expanding ring search.
if (rt->rt_req_last_ttl < TTL_THRESHOLD)
ih->ttl_ = rt->rt_req_last_ttl + TTL_INCREMENT;
else {
// network-wide broadcast
ih->ttl_ = NETWORK_DIAMETER;
rt->rt_req_cnt += 1;
}
}
// remember the TTL used for the next time
rt->rt_req_last_ttl = ih->ttl_;//为下次使用做记录
// PerHopTime is the roundtrip time per hop for route requests.
// The factor 2.0 is just to be safe .. SRD 5/22/99
// Also note that we are making timeouts to be larger if we have
// done network wide broadcast before.
rt->rt_req_timeout = 2.0 * (double) ih->ttl_ * PerHopTime(rt);