📄 aodv_mcast.cc
字号:
if (index == ih->saddr()){ //printf("******WARNING: %.9f in %s, node %d receive GRPH_U with gh leader %d and ip src %d\n", // CURRENT_TIME, __FUNCTION__, index, gh->gh_grp_leader_addr, ih->saddr()); mt->mt_nexthops.remove(nh); sendMACT(mt->mt_dst, MACT_P, 0, ch->prev_hop_); sendMRQ(mt, RREQ_J); Packet::free(p); return; } mt->mt_grp_leader_addr = gh->gh_grp_leader_addr; mt->mt_seqno = gh->gh_grp_seqno; mt->mt_hops_grp_leader = gh->gh_hop_count; // forward the msg if applicable u_int8_t size = mt->mt_nexthops.size(); if (size > 1){ if (size == 2){ aodv_nh_entry *nh = mt->mt_nexthops.downstream(); ch->next_hop_ = nh->next_hop; ch->addr_type() = NS_AF_INET; } else { ch->next_hop_ = MAC_BROADCAST; ch->addr_type() = NS_AF_NONE; controlNextHello(); } mt_forward(p, DELAY); } else Packet::free(p);}/**************************************************************///receive call back as the data cannot be transmitted//from other node or from upper stack/*************************************************************/static void aodv_mt_failed_callback(Packet *p, void *arg) {#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif ((AODV*) arg)->mt_ll_failed(p);}void AODV::mt_ll_failed(Packet *p){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); if (DATA_PACKET(ch->ptype()) && ch->next_hop_ != MAC_BROADCAST){ aodv_mt_entry *mt = mtable.mt_lookup(ih->daddr()); if (mt && mt->mt_node_status != NOT_ON_TREE){ aodv_nh_entry *nh = mt->mt_nexthops.lookup(ch->next_hop_); if (nh){ if (nh->enabled_flag != NH_ENABLE) mt->mt_nexthops.remove(nh); else { mt_repair(mt, nh); } } } } drop(p, DROP_RTR_MAC_CALLBACK);}/**************************************************************/// on-tree node finding an active link is broke// if the link is upstream, try to repair// if the link is downstream, delete that link// and set prune timer if necessary/**************************************************************/void AODV::mt_repair(aodv_mt_entry *mt, aodv_nh_entry *nh){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif if (nh->link_direction == NH_DOWNSTREAM){ mt->mt_nexthops.remove(nh); setPruneTimer(mt); } else { // link direction is upstream mt->mt_nexthops.remove(nh);#ifdef PREDICTION if (mt->mt_nexthops.upstream()) return; else { mt->mt_flags = MTF_IN_REPAIR; sendMRQ(mt, RREQ_J); }#else mt->mt_flags = MTF_IN_REPAIR; sendMRQ(mt, RREQ_J);#endif }}void AODV::mt_nb_fail(nsaddr_t next_hop){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif aodv_mt_entry *mt; for(mt = mtable.head(); mt; mt = mt->mt_link.le_next){ if (mt->mt_node_status != NOT_ON_TREE){ aodv_nh_entry *nh = mt->mt_nexthops.lookup(next_hop); if (nh){ if (nh->enabled_flag != NH_ENABLE) mt->mt_nexthops.remove(nh); else { mt_repair(mt, nh); } } } }}void AODV::mt_link_purge(){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif aodv_mt_entry *mt; for(mt = mtable.head(); mt; mt = mt->mt_link.le_next){ if (mt->mt_node_status != NOT_ON_TREE){ aodv_nh_entry *nh = mt->mt_nexthops.first(); while (nh != NULL){ aodv_nh_entry *nh_next = nh->next_; if (nh->enabled_flag != NH_ENABLE) mt->mt_nexthops.remove(nh); else { if (nh->link_expire > 0 && nh->link_expire < CURRENT_TIME){ if (nh->link_direction == NH_UPSTREAM){ mt->mt_nexthops.remove(nh); if (mt->mt_nexthops.upstream() == NULL){ mt->mt_flags = MTF_IN_REPAIR; sendMRQ(mt, RREQ_J); break; //must have break } } else { mt->mt_nexthops.remove(nh); //must not be here: mt_prune(mt->mt_dst); } } } nh = nh_next; } if (mt->mt_nexthops.downstream() == NULL) mt_prune(mt->mt_dst); } }}/**************************************************************///receive multicast data packet//from other node or from upper stack/*************************************************************/void AODV::mt_resolve(Packet *p){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); ch->xmit_failure_ = aodv_mt_failed_callback; ch->xmit_failure_data_ = (void*) this; aodv_mt_entry *mt = mtable.mt_lookup(ih->daddr()); // not tree member if (mt == NULL || mt->mt_node_status == NOT_ON_TREE){ if ((ih->saddr() == index && ch->num_forwards() == 0)|| (ch->next_hop_ == index)){ if (pid_lookup(index, ch->uid())) Packet::free(p); else { pid_insert(index, ch->uid()); rt_resolve(p); } } else Packet::free(p); return; } // tree member // once initiated by tree member or is now propagated in tree, the msg is broadcast out // if it comes from out of tree, it must be unicast#ifdef PREDICTION if (ch->num_forwards() != 0 && ch->next_hop_ == MAC_BROADCAST){ double breakTime = 2000.0; Node *currentNode = Node::get_node_by_address(index); breakTime = currentNode->getTime(ch->prev_hop_); aodv_nh_entry *prev_link = mt->mt_nexthops.lookup(ch->prev_hop_); if (prev_link && prev_link->enabled_flag == NH_ENABLE && breakTime < 2000.0 && breakTime > CURRENT_TIME && (breakTime - CURRENT_TIME) < PREDICTION_TIME_FOR_MULTICAST && prev_link->link_expire == 0){ //printf("PREDICTION: %s at %.9f (%.9f) when receiving packet %d from node %d at node %d\n", // __FUNCTION__, CURRENT_TIME, breakTime, ch->uid(), ch->prev_hop_, index); prev_link->link_expire = breakTime; if (prev_link->link_direction == NH_UPSTREAM){ sendMWARN(mt->mt_dst, WARN_U, prev_link->link_expire, ch->prev_hop_); sendMRQ(mt, RREQ_J); } else { sendMWARN(mt->mt_dst, WARN_D, prev_link->link_expire, ch->prev_hop_); } } }#endif u_int8_t size = mt->mt_nexthops.size(); if (size == 0){ if (pid_lookup(index, ch->uid())) Packet::free(p); else { pid_insert(index, ch->uid());#ifdef UPPER_LEVEL_RECEIVE if (mt->mt_node_status == ON_GROUP){ ih->daddr() = index; ch->direction() = hdr_cmn::UP; ih->dport() = UPPER_LEVEL_PORT; Scheduler::instance().schedule(target_, p, 0); } else Packet::free(p);#else Packet::free(p);#endif } return; } if (ih->saddr() == index && ch->num_forwards() == 0){ if (pid_lookup(index, ch->uid())) Packet::free(p); else { pid_insert(index, ch->uid()); ch->next_hop_ = MAC_BROADCAST; ch->addr_type() = NS_AF_ILINK; mt_forward(p, DELAY); } } else if (ch->next_hop_ != MAC_BROADCAST){ if (pid_lookup(index, ch->uid())) Packet::free(p); else { pid_insert(index, ch->uid());#ifdef UPPER_LEVEL_RECEIVE if (mt->mt_node_status == ON_GROUP){ Packet *p_new = p->copy(); struct hdr_cmn *ch_new = HDR_CMN(p_new); struct hdr_ip *ih_new = HDR_IP(p_new); ih_new->daddr() = index; ch_new->direction() = hdr_cmn::UP; ih_new->dport() = UPPER_LEVEL_PORT; Scheduler::instance().schedule(target_, p_new, 0); }#endif ch->next_hop_ = MAC_BROADCAST; ch->addr_type() = NS_AF_ILINK; mt_forward(p, DELAY); } } else { //ch->next_hop_ == MAC_BROADCAST aodv_nh_entry * nh = mt->mt_nexthops.lookup(ch->prev_hop_); if (nh == NULL || nh->enabled_flag != NH_ENABLE){ if (nh) mt->mt_nexthops.remove(nh); Packet::free(p); } else { if (pid_lookup(index, ch->uid())) Packet::free(p); else { pid_insert(index, ch->uid());#ifdef UPPER_LEVEL_RECEIVE if (mt->mt_node_status == ON_GROUP){ Packet *p_new = p->copy(); struct hdr_cmn *ch_new = HDR_CMN(p_new); struct hdr_ip *ih_new = HDR_IP(p_new); ih_new->daddr() = index; ch_new->direction() = hdr_cmn::UP; ih_new->dport() = UPPER_LEVEL_PORT; Scheduler::instance().schedule(target_, p_new, 0); }#endif if (size == 1 && mt->mt_nexthops.hop()->next_hop == ch->prev_hop_) Packet::free(p); else { mt_forward(p, DELAY); } } } }}/***********************************************************************/// forward multicast data packets// unciastly or multicastly/***********************************************************************/void AODV::mt_forward(Packet *p, double delay){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); // check TTL if(ih->ttl_ == 0){ drop(p, DROP_RTR_TTL); return;} ch->prev_hop_ = index; ch->direction() = hdr_cmn::DOWN; if (ch->next_hop_ == MAC_BROADCAST) controlNextHello(); Scheduler::instance().schedule(target_, p, 0.01 * Random::uniform());}/**********************************************************///send request for RREQ_J, RREQ_JR, RREQ_R// Note: RREQ follows the unicast route discovery// RREQ_J: join group (unicastly or broadcastly)// or local repair (broadcastly)// RREQ_JR: tree merge (unicastly)// RREQ_R: ask permission for tree merge (unicastly)/*********************************************************/void AODV::sendMRQ(aodv_mt_entry *mt, u_int8_t flags){#ifdef DEBUG fprintf(stdout,"%s, node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif nsaddr_t addr_type, next_hop, ipdst; u_int8_t ttl; if (flags != RREQ_R && flags!= RREQ_JR && flags != RREQ_J) return; if (flags == RREQ_R){ // before entering this function, // make sure: the node is tree member except group leader // and has valid upstream and valid grp leader // the msg is sent from downstream to upstream aodv_nh_entry *nh = mt->mt_nexthops.upstream(); if (nh == NULL) return; addr_type = NS_AF_INET; next_hop = nh->next_hop; ttl = NETWORK_DIAMETER; ipdst = mt->mt_grp_leader_addr; } else if (flags == RREQ_JR){ // before entering this function, // make sure: 1. the node is tree member // and valid grp leader // and valid upstream if not group leader // 2. glt table has up-to-date info // and the recorded group leader is greater than // that recorded in node's mt table // the msg is sent along the info in glt table aodv_glt_entry *glt = gltable.glt_lookup(mt->mt_dst); if (glt == NULL || glt->glt_grp_leader_addr <= mt->mt_grp_leader_addr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -