NS2下AODV协议aodv.cc注释(8)

nre->DestCount = 0;
/*遍历错误分组中每一个不可达路由*/
 for (i=0; i<re->DestCount; i++) {
 // For each unreachable destination
  rt = rtable.rt_lookup(re->unreachable_dst[i]);
 /*是否存在经过发送错误分组的邻居的路由*/
  if ( rt && (rt->rt_hops != INFINITY2) &&
 (rt->rt_nexthop == ih->saddr()) &&
     (rt->rt_seqno <= re->unreachable_dst_seqno[i]) ) {
 assert(rt->rt_flags == RTF_UP);
 assert((rt->rt_seqno%2) == 0); // 奇数代表无穷大,无效的意思
#ifdef DEBUG
    fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\t(%d\t%u\t%d)\n", __FUNCTION__,CURRENT_TIME,
      index, rt->rt_dst, rt->rt_seqno, rt->rt_nexthop,
      re->unreachable_dst[i],re->unreachable_dst_seqno[i],
              ih->saddr());
#endif // DEBUG
     rt->rt_seqno = re->unreachable_dst_seqno[i];
     rt_down(rt);//将此路由down掉

// Not sure whether this is the right thing to do
  /*查看队列中是否有下一跳是此邻居的分组
  若有的话,直接丢包;具体请看queue/priqueue.cc的filter函数*/
  Packet *pkt;
 while((pkt = ifqueue->filter(ih->saddr()))) {
         drop(pkt, DROP_RTR_MAC_CALLBACK);
     }

// if precursor list non-empty add to RERR and delete the precursor list
    /*如果此路由的前缀列表非空,将此节点不可达的目的地记录在新的路由分组中
  并且删除此路由的前缀列表*/
     if (!rt->pc_empty()) {
      nre->unreachable_dst[nre->DestCount] = rt->rt_dst;
      nre->unreachable_dst_seqno[nre->DestCount] = rt->rt_seqno;
      nre->DestCount += 1;
  rt->pc_delete();
     }
  }
 }
/*如果此节点有不可达路由,则继续广播错误分组*/
 if (nre->DestCount > 0) {
#ifdef DEBUG
  fprintf(stderr, "%s(%f): %d\t sending RERR...\n", __FUNCTION__, CURRENT_TIME, index);
#endif // DEBUG
  sendError(rerr);
 }
 else {
  Packet::free(rerr);
 }

Packet::free(p);
}


/*
  Packet Transmission Routines
*/

void
AODV::forward(aodv_rt_entry *rt, Packet *p, double delay) {
struct hdr_cmn *ch = HDR_CMN(p);
struct hdr_ip *ih = HDR_IP(p);
/*如果跳数为零,直接丢弃*/
 if(ih->ttl_ == 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.);
  }
 }

}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/ab5562fd35bafa4ee10b3188dd4834ce.html