📄 aodv_mcast.cc
字号:
/***********************************************************************/// receive Reply_with_J for multicast tree// the request source node must:// be at MTF_IN_REPAIR, having no upstream, not leader// wants to join the group or to reconnect to the tree/***********************************************************************/void AODV::recvMRP_J(Packet *p){#ifdef DEBUG fprintf(stdout,"%s\n", __FUNCTION__);#endif struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_cmn *ch = HDR_CMN(p); struct hdr_aodv_reply_ext *rpe = (struct hdr_aodv_reply_ext*) (rp + rp->size()); // update the msg rp->rp_hop_count ++; rpe->hops_grp_leader ++; aodv_mt_entry *mt = mtable.mt_lookup(rp->rp_dst); if (mt == NULL) mt = mtable.mt_add(rp->rp_dst); // double check if (mt->mt_node_status != NOT_ON_TREE){ if (rpe->grp_leader_addr == index){ Packet::free(p); return; } aodv_nh_entry *nh = mt->mt_nexthops.lookup(rp->rp_src); if (nh && nh->enabled_flag == NH_ENABLE && nh->link_direction == NH_DOWNSTREAM){ Packet::free(p); return; } nh = mt->mt_nexthops.lookup(ch->prev_hop_); if (nh && nh->enabled_flag == NH_ENABLE && nh->link_direction == NH_DOWNSTREAM){ Packet::free(p); return; } nh = mt->mt_nexthops.lookup(rpe->grp_leader_addr); if (nh && nh->enabled_flag == NH_ENABLE && nh->link_direction == NH_DOWNSTREAM){ Packet::free(p); return; } } // the destination is reached if (ih->daddr() == index){ #ifdef PREDICTION aodv_nh_entry *link = mt->mt_nexthops.lookup(ch->prev_hop_); if (link && link->link_expire != 0){ Packet::free(p); return; } if (mt && mt->mt_node_status != NOT_ON_TREE && mt->mt_grp_leader_addr != index){ aodv_nh_entry *nh_up = mt->mt_nexthops.upstream(); if (nh_up == NULL || nh_up->link_expire != 0){ if ((mt->mt_rep_timeout <= CURRENT_TIME) || (mt->mt_rep_grp_leader_addr < rpe->grp_leader_addr) || (mt->mt_rep_grp_leader_addr == rpe->grp_leader_addr && ((mt->mt_rep_seqno < rp->rp_dst_seqno) || (mt->mt_rep_seqno == rp->rp_dst_seqno && ((mt->mt_rep_hops_tree > rp->rp_hop_count) || (mt->mt_rep_hops_tree == rp->rp_hop_count && mt->mt_rep_hops_grp_leader > rpe->hops_grp_leader) ) ) ) ) ) { recordMRpy(mt, p); } } Packet::free(p); return; }#else if (mt && mt->mt_node_status != NOT_ON_TREE && mt->mt_grp_leader_addr != index && mt->mt_nexthops.upstream() == NULL){ if ((mt->mt_rep_timeout <= CURRENT_TIME) || (mt->mt_rep_grp_leader_addr < rpe->grp_leader_addr) || (mt->mt_rep_grp_leader_addr == rpe->grp_leader_addr && ((mt->mt_rep_seqno < rp->rp_dst_seqno) || (mt->mt_rep_seqno == rp->rp_dst_seqno && ((mt->mt_rep_hops_tree > rp->rp_hop_count) || (mt->mt_rep_hops_tree == rp->rp_hop_count && mt->mt_rep_hops_grp_leader > rpe->hops_grp_leader) ) ) ) ) ) { recordMRpy(mt, p); } } Packet::free(p); return;#endif } // an intermediate node is reached // should be not-on-tree // if reach on a tree node, discard it if (mt->mt_node_status != NOT_ON_TREE) { Packet::free(p); return; } // not tree member is reached if ((mt->mt_rep_timeout <= CURRENT_TIME) || (mt->mt_rep_ipdst == ih->daddr() && ((mt->mt_rep_grp_leader_addr < rpe->grp_leader_addr) || (mt->mt_rep_grp_leader_addr == rpe->grp_leader_addr && ((mt->mt_rep_seqno < rp->rp_dst_seqno) || (mt->mt_rep_seqno == rp->rp_dst_seqno && ((mt->mt_rep_hops_tree > rp->rp_hop_count) || (mt->mt_rep_hops_tree == rp->rp_hop_count && mt->mt_rep_hops_grp_leader > rpe->hops_grp_leader) ) ) ) ) ) ) ) { recordMRpy(mt, p); aodv_rt_entry *rt = rtable.rt_lookup(ih->daddr()); if (rt && rt->rt_flags == RTF_UP) forward(rt, p, NO_DELAY); else Packet::free(p); } else Packet::free(p);}/**************************************************************/// the time to check after waiting for RREP// only set the timer when sending out RREQ_J /*************************************************************/void RREPWaitTimer::handle(Event* e){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif Packet *p = (Packet *)e; struct hdr_ip *ih = HDR_IP(p); agent->afterWaitRREP(ih->daddr()); Packet::free(p);}void AODV::afterWaitRREP(nsaddr_t dst){#ifdef DEBUG fprintf(stdout,"%s at node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif aodv_mt_entry *mt = mtable.mt_lookup(dst); if (mt == NULL || mt->mt_node_status == NOT_ON_TREE) return; if (mt->mt_grp_leader_addr == index) return; #ifdef PREDICTION aodv_nh_entry *link = mt->mt_nexthops.upstream(); if (link != NULL && link->link_expire == 0) return;#else if (mt->mt_nexthops.upstream() != NULL) return;#endif // must be tree member, not group leader, has no upstream // if not receiving reply, send request again if (mt->mt_rep_timeout <= CURRENT_TIME){ sendMRQ(mt, RREQ_J); return; } // check the reply // recorded grp leader must not be the node itself, // because we do the check when recording the reply aodv_nh_entry *nh = mt->mt_nexthops.lookup(mt->mt_rep_selected_upstream); #ifdef PREDICTION if (nh && nh->enabled_flag == NH_ENABLE && nh->link_direction == NH_UPSTREAM){ clearMReqState(mt); clearMRpyState(mt); return; }#endif if (nh && nh->enabled_flag == NH_ENABLE){ // as node has no upstream, this link must be downstream //printf("******WARNING: %.9f in %s, node %d cannot activate its existing downstream %d to upstream, need send RREQ_J again\n", // CURRENT_TIME, __FUNCTION__, index, nh->next_hop); clearMReqState(mt); clearMRpyState(mt); sendMRQ(mt, RREQ_J); return; } // now, has valid reply#ifdef PREDICTION if (link) mt->mt_nexthops.remove(link);#endif mt->mt_flags = MTF_UP; nsaddr_t old_leader = mt->mt_grp_leader_addr; mt->mt_grp_leader_addr = mt->mt_rep_grp_leader_addr; mt->mt_seqno = mt->mt_rep_seqno; nsaddr_t old_hops_grp_leader = mt->mt_hops_grp_leader; mt->mt_hops_grp_leader = mt->mt_rep_hops_grp_leader; if (nh) mt->mt_nexthops.remove(nh); nh = new aodv_nh_entry(mt->mt_rep_selected_upstream); mt->mt_nexthops.add(nh); nh->link_direction = NH_UPSTREAM; nh->enabled_flag = NH_ENABLE; if (mt->mt_nexthops.downstream() != NULL && (old_leader != mt->mt_grp_leader_addr || old_hops_grp_leader != mt->mt_hops_grp_leader)) sendMGRPH_U(mt, INFINITY8); clearMReqState(mt); clearMRpyState(mt); sendMACT(mt->mt_dst, MACT_J, mt->mt_hops_grp_leader, nh->next_hop);}void AODV::sendMACT(nsaddr_t dst, u_int8_t flags, u_int8_t hop_count, nsaddr_t next_hop){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif // as there is no MACT_U, next_hop must be a node address // and MACT must be sent out unicastly Packet *p = Packet::alloc(); struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_mact *mact = HDR_AODV_MACT(p); mact->mact_type = AODVTYPE_MACT; mact->mact_flags = flags; mact->mact_hop_count = hop_count; mact->mact_grp_dst = dst; mact->mact_src = index; mact->mact_src_seqno = seqno; ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + mact->size(); ch->iface() = -2; ch->error() = 0; ch->prev_hop_ = index; ch->direction() = hdr_cmn::DOWN; ch->next_hop_ = next_hop; ch->addr_type() = NS_AF_INET; ih->saddr() = index; ih->daddr() = next_hop; ih->sport() = RT_PORT; ih->dport() = RT_PORT; ih->ttl_ = 1; Scheduler::instance().schedule(target_, p, 0.01 * Random::uniform());}void AODV::recvMACT(Packet *p){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif struct hdr_aodv_mact *mact = HDR_AODV_MACT(p); switch (mact->mact_flags){ case MACT_J: recvMACT_J(p); return; case MACT_P: recvMACT_P(p); return; case MACT_GL: recvMACT_GL(p); return; default: Packet::free(p); return; }}/******************************************************************/// receive MACT_P// from upstream: remove that link and select leader// from downstream: remove that link and prune its self if necessary/******************************************************************/void AODV::recvMACT_P(Packet *p){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif struct hdr_aodv_mact *mact = HDR_AODV_MACT(p); nsaddr_t grp_dst = mact->mact_grp_dst; nsaddr_t prev_hop = mact->mact_src; Packet::free(p); // must be on tree and has valid link aodv_mt_entry *mt = mtable.mt_lookup(grp_dst); if (mt==NULL || mt->mt_node_status == NOT_ON_TREE) return; aodv_nh_entry *nh = mt->mt_nexthops.lookup(prev_hop); if (nh == NULL || nh->enabled_flag != NH_ENABLE) { if (nh) mt->mt_nexthops.remove(nh); return; } u_int8_t direction = nh->link_direction; mt->mt_nexthops.remove(nh); if (direction == NH_UPSTREAM) selectLeader(mt, INFINITY8); else mt_prune(mt->mt_dst);}/******************************************************************/// receive MACT_GL// should be only from upstream/******************************************************************/void AODV::recvMACT_GL(Packet *p){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif struct hdr_aodv_mact *mact = HDR_AODV_MACT(p); nsaddr_t grp_dst = mact->mact_grp_dst; nsaddr_t prev_hop = mact->mact_src; Packet::free(p); // must be on tree and has valid link aodv_mt_entry *mt = mtable.mt_lookup(grp_dst); if (mt==NULL || mt->mt_node_status == NOT_ON_TREE){ sendMACT(grp_dst, MACT_P, 0, prev_hop); return; } aodv_nh_entry *nh = mt->mt_nexthops.lookup(prev_hop); if (nh == NULL || nh->enabled_flag != NH_ENABLE){ sendMACT(grp_dst, MACT_P, 0, prev_hop); if (nh) mt->mt_nexthops.remove(nh); return; } if (nh->link_direction == NH_DOWNSTREAM){ //printf("WARNING: at %.9f in %s, node %d receives MACT_GL from donwstream %d\n", // CURRENT_TIME, __FUNCTION__, index, nh->next_hop); sendMGRPH_U(mt, INFINITY8); } else { // change the upstream direction to downstream and // select leader nh->link_direction = NH_DOWNSTREAM; selectLeader(mt, nh->next_hop); }}/******************************************************************/// receive MACT_J// activate a branch to group tree/******************************************************************/void AODV::recvMACT_J(Packet *p){#ifdef DEBUG fprintf(stdout,"%s at node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif struct hdr_aodv_mact *mact = HDR_AODV_MACT(p); aodv_mt_entry *mt = mtable.mt_lookup(mact->mact_grp_dst); if (mt == NULL) mt = mtable.mt_add(mact->mact_grp_dst); nsaddr_t prev_hop = mact->mact_src; u_int8_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -