📄 aodv_mcast.cc
字号:
/***********************************************************************/// receive Reply_with_R_flag for multicast tree// the msg must be from leader to downstream on tree// NOT ADD ANY NEXT HOP in MT TABLE, BUT UPDATE GRP INFO in MT TABLE/***********************************************************************/void AODV::recvMRP_R(Packet * p){#ifdef DEBUG fprintf(stdout,"%s at node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif // the msg has no extension struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_cmn *ch = HDR_CMN(p); aodv_mt_entry *mt; aodv_nh_entry *nh; // for RREP_R, rp_hop_count is used as hop count to grp leader rp->rp_hop_count ++; // must be on tree node and receive msg from its upstream mt = mtable.mt_lookup(rp->rp_dst); if (mt == NULL || mt->mt_node_status == NOT_ON_TREE) { Packet::free(p); return; } nh = mt->mt_nexthops.lookup(ch->prev_hop_); if (nh == NULL || nh->enabled_flag != NH_ENABLE || nh->link_direction != NH_UPSTREAM){ if (nh && nh->enabled_flag != NH_ENABLE) mt->mt_nexthops.remove(nh); Packet::free(p); return; } if (index == mt->mt_grp_leader_addr){ printf("******ERROR: at %.9f in %s, node %i is group leader for group %d, BUT IT HAS UPSTREAM!\n", CURRENT_TIME, __FUNCTION__, index, mt->mt_dst); Packet::free(p); exit(1); } if (index == rp->rp_src){ printf("******ERROR: at %.9f in %s, node %d is group leader for group %d, BUT IT RECEIVE RREP_R FROM ITSELF!\n", CURRENT_TIME, __FUNCTION__, index, mt->mt_dst); Packet::free(p); exit(1); } // update the grp info mt->mt_grp_leader_addr = rp->rp_src; mt->mt_seqno = rp->rp_dst_seqno; mt->mt_hops_grp_leader = rp->rp_hop_count; // destination node is reached if (index == ih->daddr()){ sendMRQ(mt, RREQ_JR); Packet::free(p); return; } // intermediate node is reached // must forward to its downstream aodv_rt_entry *rt = rtable.rt_lookup(ih->daddr()); if (rt == NULL || rt->rt_flags != RTF_UP) { //printf("******WARNING: at %.9f in %s, node %d cannot find route to node %d\n", // CURRENT_TIME, __FUNCTION__, index, ih->daddr()); Packet::free(p); return; } nh = mt->mt_nexthops.lookup(rt->rt_nexthop); if (nh == NULL || nh->enabled_flag != NH_ENABLE || nh->link_direction != NH_DOWNSTREAM){ //printf("******WARNING: at %.9f in %s, node %d cannot follow downstream to node %d, because node %d is not its downstream\n", // CURRENT_TIME, __FUNCTION__, index, ih->daddr(), rt->rt_nexthop); if (nh && nh->enabled_flag != NH_ENABLE) mt->mt_nexthops.remove(nh); Packet::free(p); return; } ch->next_hop_ = nh->next_hop; mt_forward(p, NO_DELAY);}/***********************************************************************/// receive Request_with_JR_flag for multicast tree// the request source node must be on tree and requests tree merge// if the node receiving this msg is not-on-tree node, follow the glt entry// if the node receiving this msg is a tree member, follow to upstream till group leader// ONLY ADD NEXT HOP and UPDATE GRP Seqno in MT TABLE when GRP LEADER reached/***********************************************************************/void AODV::recvMRQ_JR(Packet *p){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif // the msg has no extension struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_cmn *ch = HDR_CMN(p); aodv_mt_entry *mt = mtable.mt_lookup(rq->rq_dst); // update request msg ih->saddr() = index; rq->rq_hop_count++; // group leader is reached if (mt && mt->mt_grp_leader_addr == index){ aodv_nh_entry *nh = mt->mt_nexthops.lookup(ch->prev_hop_); if (nh && nh->enabled_flag == NH_ENABLE && nh->link_direction == NH_UPSTREAM){ printf("******ERROR: %.9f in %s, node %i is group leader for group %d, BUT IT HAS UPSTEAM!\n", CURRENT_TIME, __FUNCTION__, index, mt->mt_dst); exit(1); } // add the new downstream link if (nh) mt->mt_nexthops.remove(nh); nh = new aodv_nh_entry(ch->prev_hop_); mt->mt_nexthops.add(nh); nh->enabled_flag = NH_ENABLE; nh->link_direction = NH_DOWNSTREAM; // get new seqno mt->mt_seqno = max(mt->mt_seqno, rq->rq_dst_seqno) + 1; sendReply(rq->rq_src, //ipdst: should be another group leader RREP_JR, //flags 0, // used as hop count to the new group leader mt->mt_dst, // rpdst = multicast group addr mt->mt_seqno, // multicast grp seqno MY_ROUTE_TIMEOUT, // lifetime rq->rq_timestamp, // timestamp = the timestamp in request 0, // hop count to grp leader (no use for RREP_JR) 0); // grp leader addr (no use for RREP_JR) Packet::free(p); return; } // destination is reached but not group leader if (ih->daddr() == index) { Packet::free(p); return; } // intermediate node is reached but not group leader aodv_glt_entry *glt = gltable.glt_lookup(rq->rq_dst); // 1. not on tree node, forward msg along glt info if (mt == NULL || mt->mt_node_status == NOT_ON_TREE){ if (glt && glt->glt_grp_leader_addr == ih->daddr() && glt->glt_expire > CURRENT_TIME){ ch->next_hop_ = glt->glt_next_hop; mt_forward(p, NO_DELAY); } else Packet::free(p); return; } // 2. on tree node but not group leader // it must has upstream, forward msg to upstream // also, if it has any downstream, this msg should be received from its downstream aodv_nh_entry *nh = mt->mt_nexthops.upstream(); if (nh == NULL) { Packet::free(p); return; } ch->next_hop_ = nh->next_hop; mt_forward(p, NO_DELAY);}/***********************************************************************/// receive Reply_with_JR_flag for multicast tree// ADD NEXT HOP and UPDATE GRP INFO in MT TABLE/***********************************************************************/void AODV::recvMRP_JR(Packet *p){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif // the msg has no extension struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_cmn *ch = HDR_CMN(p); aodv_mt_entry *mt = mtable.mt_lookup(rp->rp_dst); if (mt == NULL) mt = mtable.mt_add(rp->rp_dst); // hop count to group leader +1 rp->rp_hop_count ++; // grp leader is reached if (mt->mt_grp_leader_addr == index){ // check the new grp leader is not itself if (rp->rp_src == index){ printf("******ERROR: %.9f in %s, node %i is group leader for group %d, BUT IT RECEIVE RREP_JR FROM ITS SELF!\n", CURRENT_TIME, __FUNCTION__, index, mt->mt_dst); Packet::free(p); exit(1); } // before entering, make sure that grp leader must not have any upstream aodv_nh_entry *nh = mt->mt_nexthops.lookup(ch->prev_hop_); if (nh) mt->mt_nexthops.remove(nh); nh = new aodv_nh_entry(ch->prev_hop_); mt->mt_nexthops.add(nh); nh->enabled_flag = NH_ENABLE; nh->link_direction = NH_UPSTREAM; // update the grp info mt->mt_flags = MTF_UP; mt->mt_grp_leader_addr = rp->rp_src; mt->mt_seqno = rp->rp_dst_seqno; mt->mt_hops_grp_leader = rp->rp_hop_count; if (mt->mt_nexthops.size()>1) sendMGRPH_U(mt, INFINITY8); Packet::free(p); return; } // destination or intermediate node is reached, but not group leader // not tree member if (mt->mt_node_status == NOT_ON_TREE){ if (ih->daddr() == index){ sendMACT(mt->mt_dst, MACT_P, 0, ch->prev_hop_); Packet::free(p); return; } aodv_rt_entry *rt = rtable.rt_lookup(ih->daddr()); if (rt == NULL || rt->rt_flags != RTF_UP || rt->rt_nexthop == ch->prev_hop_){ sendMACT(mt->mt_dst, MACT_P, 0, ch->prev_hop_); Packet::free(p); return; } aodv_nh_entry *nh = new aodv_nh_entry(ch->prev_hop_); mt->mt_nexthops.add(nh); nh->link_direction = NH_UPSTREAM; nh->enabled_flag = NH_ENABLE; nh = new aodv_nh_entry(rt->rt_nexthop); mt->mt_nexthops.add(nh); nh->link_direction = NH_DOWNSTREAM; nh->enabled_flag = NH_ENABLE; mt->mt_flags = MTF_UP; mt->mt_node_status = ON_TREE; mt->mt_grp_leader_addr = rp->rp_src; mt->mt_seqno = rp->rp_dst_seqno; mt->mt_hops_grp_leader = rp->rp_hop_count; clearMReqState(mt); clearMRpyState(mt); ch->next_hop_ = rt->rt_nexthop; mt_forward(p, NO_DELAY); return; } // tree member with the same group leader, but not grp leader if (mt->mt_grp_leader_addr == rp->rp_src){ aodv_nh_entry *nh = mt->mt_nexthops.lookup(ch->prev_hop_); if (nh == NULL || nh->enabled_flag != NH_ENABLE || nh->link_direction == NH_DOWNSTREAM){ if (nh){ if (nh->enabled_flag != NH_ENABLE) mt->mt_nexthops.remove(nh); else { mt->mt_nexthops.remove(nh); mt_prune(mt->mt_dst); } } sendMACT(mt->mt_dst, MACT_P, 0, ch->prev_hop_); Packet::free(p); return; } //from its own upstream, update grp info u_int16_t old_hop_count = mt->mt_hops_grp_leader; mt->mt_seqno = rp->rp_dst_seqno; mt->mt_hops_grp_leader = rp->rp_hop_count; // check its next hop aodv_rt_entry *rt = rtable.rt_lookup(ih->daddr()); if (rt==NULL || rt->rt_flags != RTF_UP || rt->rt_nexthop == nh->next_hop){ if (old_hop_count != mt->mt_hops_grp_leader && mt->mt_nexthops.size() > 1) sendMGRPH_U(mt, INFINITY8); Packet::free(p); return; } aodv_nh_entry *nh_d = mt->mt_nexthops.lookup(rt->rt_nexthop); //if already enabled, must be downstream if (nh_d) mt->mt_nexthops.remove(nh_d); nh_d = new aodv_nh_entry(rt->rt_nexthop); mt->mt_nexthops.add(nh_d); nh_d->link_direction = NH_DOWNSTREAM; nh_d->enabled_flag = NH_ENABLE; ch->next_hop_ = rt->rt_nexthop; if (old_hop_count != mt->mt_hops_grp_leader && mt->mt_nexthops.size() > 2) sendMGRPH_U(mt, INFINITY8); mt_forward(p, NO_DELAY); return; } // tree member with different group leader, but this node is not group leader if (index == rp->rp_src){ printf("******ERROR: at %.9f in %s, node %i is not group leader for group %d, BUT IT RECEIVE RREP_JR FROM ITS SELF!\n", CURRENT_TIME, __FUNCTION__, index, mt->mt_dst); Packet::free(p); exit(1); } if (mt->mt_grp_leader_addr > rp->rp_src){ aodv_nh_entry *nh = mt->mt_nexthops.lookup(ch->prev_hop_); if (nh == NULL || nh->enabled_flag != NH_ENABLE || nh->link_direction == NH_DOWNSTREAM){ if (nh) mt->mt_nexthops.remove(nh); sendMACT(mt->mt_dst, MACT_P, 0, ch->prev_hop_); Packet::free(p); return; } else{ // from its own upstream, update the grp info mt->mt_grp_leader_addr = rp->rp_src; mt->mt_seqno = rp->rp_dst_seqno; mt->mt_hops_grp_leader = rp->rp_hop_count; if (mt->mt_nexthops.size() > 1) sendMGRPH_U(mt, INFINITY8); Packet::free(p); return; } } // mt->mt_grp_leader < rp->rp_src aodv_nh_entry *nh = mt->mt_nexthops.lookup(ch->prev_hop_); if (nh == NULL || nh->enabled_flag != NH_ENABLE || nh->link_direction == NH_DOWNSTREAM){ nsaddr_t old_grp_leader = mt->mt_grp_leader_addr; // update the grp info mt->mt_flags = MTF_UP; mt->mt_grp_leader_addr = rp->rp_src; mt->mt_seqno = rp->rp_dst_seqno; mt->mt_hops_grp_leader = rp->rp_hop_count; // upstream node if it has, must not be nh link aodv_nh_entry *nh_u = mt->mt_nexthops.upstream(); if (nh_u) nh_u->link_direction = NH_DOWNSTREAM; if (nh) mt->mt_nexthops.remove(nh); nh = new aodv_nh_entry(ch->prev_hop_); mt->mt_nexthops.add(nh); nh->enabled_flag = NH_ENABLE; nh->link_direction = NH_UPSTREAM; if ((nh_u && mt->mt_nexthops.size()>2)|| (nh_u == NULL && mt->mt_nexthops.size()>1)) sendMGRPH_U(mt, INFINITY8); if (nh_u){ if (ih->daddr() == index) ih->daddr() = old_grp_leader; ch->next_hop_ = nh_u->next_hop; mt_forward(p, NO_DELAY); } else Packet::free(p); return; } // from its own upstream, update the grp info mt->mt_grp_leader_addr = rp->rp_src; mt->mt_seqno = rp->rp_dst_seqno; mt->mt_hops_grp_leader = rp->rp_hop_count; if (mt->mt_nexthops.size() > 1) sendMGRPH_U(mt, INFINITY8); Packet::free(p); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -