/*
* I am trying to forward a packet for someone else to which
* I don't have a route.
*/
//否则发送错误报文
else {
Packet *rerr = Packet::alloc();
struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);
/*
* For now, drop the packet and send error upstream.
* Now the route errors are broadcast to upstream
* neighbors - Mahesh 09/11/99
*/
assert (rt->rt_flags == RTF_DOWN);
re->DestCount = 0;
re->unreachable_dst[re->DestCount] = rt->rt_dst;
re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;
re->DestCount += 1;
#ifdef DEBUG
fprintf(stderr, "%s: sending RERR...\n", __FUNCTION__);
#endif
sendError(rerr, false);
drop(p, DROP_RTR_NO_ROUTE);
}
}
/*定时查看路由缓存条目*/
void
AODV::rt_purge() {
aodv_rt_entry *rt, *rtn;
double now = CURRENT_TIME;
double delay = 0.0;
Packet *p;
for(rt = rtable.head(); rt; rt = rtn) { // for each rt entry
rtn = rt->rt_link.le_next;
//如果此路由条目标注为有效,但是生存时间为0
//丢弃前往目的分组,并且将此路由条目down掉
if ((rt->rt_flags == RTF_UP) && (rt->rt_expire < now)) {
// if a valid route has expired, purge all packets from
// send buffer and invalidate the route.
assert(rt->rt_hops != INFINITY2);
while((p = rqueue.deque(rt->rt_dst))) {
#ifdef DEBUG
fprintf(stderr, "%s: calling drop()\n",
__FUNCTION__);
#endif // DEBUG
drop(p, DROP_RTR_NO_ROUTE);
}
rt->rt_seqno++;
assert (rt->rt_seqno%2);
rt_down(rt);
}
//如果此路由条目并没有过期,则可以发送分组
else if (rt->rt_flags == RTF_UP) {
// If the route is not expired,
// and there are packets in the sendbuffer waiting,
// forward them. This should not be needed, but this extra
// check does no harm.
assert(rt->rt_hops != INFINITY2);
while((p = rqueue.deque(rt->rt_dst))) {
forward (rt, p, delay);
delay += ARP_DELAY;
}
}
//如果此路由条目已经down掉,但是有前往目的的分组,则发送路由请求
else if (rqueue.find(rt->rt_dst))
// If the route is down and
// if there is a packet for this destination waiting in
// the sendbuffer, then send out route request. sendRequest
// will check whether it is time to really send out request
// or not.
// This may not be crucial to do it here, as each generated
// packet will do a sendRequest anyway.
sendRequest(rt->rt_dst);
}
}
/*
Packet Reception Routines
*/
void
AODV::recv(Packet *p, Handler*) {
struct hdr_cmn *ch = HDR_CMN(p);
struct hdr_ip *ih = HDR_IP(p);
assert(initialized());
//assert(p->incoming == 0);
// XXXXX NOTE: use of incoming flag has been depracated; In order to track direction of pkt flow, direction_ in hdr_cmn is used instead. see packet.h for details.
//如果分组类型是AODV类型,则交给recvAodv函数
if(ch->ptype() == PT_AODV) {
ih->ttl_ -= 1;
recvAODV(p);
return;
}
/*
* Must be a packet I'm originating...
*/
//如果是我发送的报文,加上包头,ch->num_forward()是转发的跳数
if((ih->saddr() == index) && (ch->num_forwards() == 0)) {
/*
* Add the IP Header
*/
ch->size() += IP_HDR_LEN;
// Added by Parag Dadhania && John Novatnack to handle broadcasting
if ( (u_int32_t)ih->daddr() != IP_BROADCAST)
ih->ttl_ = NETWORK_DIAMETER;
}
/*
* I received a packet that I sent. Probably
* a routing loop.
*/
//出现路由环路,丢弃
else if(ih->saddr() == index) {
drop(p, DROP_RTR_ROUTE_LOOP);
return;
}
/*
* Packet I'm forwarding...
*/
else {
/*
* Check the TTL. If it is zero, then discard.
*/
//如果ttl值为零,丢弃
if(--ih->ttl_ == 0) {
drop(p, DROP_RTR_TTL);
return;
}
}
// Added by Parag Dadhania && John Novatnack to handle broadcasting
//如果不是广播报文,交给re_resolve函数处理;如果是广播报文,则转发
if ( (u_int32_t)ih->daddr() != IP_BROADCAST)
rt_resolve(p);
else
forward((aodv_rt_entry*) 0, p, NO_DELAY);
}
void
AODV::recvAODV(Packet *p) {
struct hdr_aodv *ah = HDR_AODV(p);
struct hdr_ip *ih = HDR_IP(p);
assert(ih->sport() == RT_PORT);
assert(ih->dport() == RT_PORT);
/*
* Incoming Packets.
*/
switch(ah->ah_type) {
case AODVTYPE_RREQ:
recvRequest(p);
break;
case AODVTYPE_RREP:
recvReply(p);
break;
case AODVTYPE_RERR:
recvError(p);
break;