📄 aodv_mcast.cc
字号:
return; addr_type = NS_AF_INET; next_hop = glt->glt_next_hop; ttl = NETWORK_DIAMETER; ipdst = glt->glt_grp_leader_addr; } else { // flags == RREQ_J, tree member except leader, has no upstream // double checking if (mt->mt_node_status == NOT_ON_TREE) return; if (mt->mt_grp_leader_addr == index) return;#ifdef PREDICTION aodv_nh_entry *nh_up = mt->mt_nexthops.upstream(); if (nh_up && nh_up->link_expire == 0) return; if (nh_up) mt->mt_flags = MTF_UP; else mt->mt_flags = MTF_IN_REPAIR;#else if (mt->mt_nexthops.upstream()) return; mt->mt_flags = MTF_IN_REPAIR;#endif if (mt->mt_req_cnt > RREQ_RETRIES){#ifdef PREDICTION if (mt->mt_nexthops.upstream() != NULL) return;#endif selectLeader(mt, INFINITY8); return; } // finding ttl and recording corresponding info in mt if (mt->mt_hops_grp_leader != INFINITY2) mt->mt_req_last_ttl = max( mt->mt_req_last_ttl, mt->mt_hops_grp_leader); if (mt->mt_req_last_ttl == 0) ttl = TTL_START; else { if (mt->mt_req_last_ttl < TTL_THRESHOLD) ttl = mt->mt_req_last_ttl + TTL_INCREMENT; else { ttl = NETWORK_DIAMETER; mt->mt_req_cnt ++; } } mt->mt_req_last_ttl = ttl; mt->mt_req_times ++; // deciding if it can be unicastly sent to group leader aodv_glt_entry * glt = gltable.glt_lookup(mt->mt_dst); if ((mt->mt_grp_leader_addr == INFINITY8 && mt->mt_node_status == ON_GROUP) && (mt->mt_req_times == 1) && (glt && glt->glt_expire > CURRENT_TIME)){ addr_type = NS_AF_INET; next_hop = glt->glt_next_hop; ipdst = glt->glt_grp_leader_addr; } else { addr_type = NS_AF_NONE; next_hop = MAC_BROADCAST; ipdst = IP_BROADCAST; } Packet *p_store = Packet::alloc(); struct hdr_ip *ih = HDR_IP(p_store); ih->daddr() = mt->mt_dst; Scheduler::instance().schedule(&rtetimer, (Event *)p_store, RREP_WAIT_TIME); } Packet *p = Packet::alloc(); struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p); // fill up the request fields rq->rq_type = AODVTYPE_RREQ; rq->rq_flags = flags; rq->rq_hop_count = 0; bid++; rq->rq_bcast_id = bid; rq->rq_dst = mt->mt_dst; if (flags == RREQ_J && mt->mt_grp_leader_addr == INFINITY8 && mt->mt_node_status == ON_GROUP) rq->rq_dst_seqno = 0; else rq->rq_dst_seqno= mt->mt_seqno; rq->rq_src = index; seqno+=2; rq->rq_src_seqno = seqno; rq->rq_timestamp = CURRENT_TIME; // fill up the common header part ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + rq->size(); ch->iface() = -2; ch->error() = 0; ch->addr_type() = addr_type; ch->prev_hop_ = index; ch->next_hop_ = next_hop; ch->direction() = hdr_cmn::DOWN; // fill up the ip header part ih->saddr() = index; ih->daddr() = ipdst; ih->sport() = RT_PORT; ih->dport() = RT_PORT; ih->ttl_ = ttl; if (flags == RREQ_J && mt->mt_grp_leader_addr != INFINITY8){ struct hdr_aodv_request_ext *rqe = (struct hdr_aodv_request_ext *)(HDR_AODV_REQUEST(p) + rq->size()); rqe->type = AODVTYPE_RREQ_EXT; rqe->length = AODVTYPE_RREQ_EXT_LEN; rqe->hop_count= mt->mt_hops_grp_leader; ch->size() += rqe->size(); if (mt->mt_nexthops.downstream()) sendMGRPH_U(mt, INFINITY8); } // insert bcast_id in cache id_insert(rq->rq_src, rq->rq_bcast_id); if (ch->next_hop_ == MAC_BROADCAST) controlNextHello(); // send out the request immidiately Scheduler::instance().schedule(target_, p, 0.01*Random::uniform());}/***********************************************************************/// receive Request_with_no_flag for multicast tree// the request source node must:// be not_on_tree and has no route to the tree/***********************************************************************/void AODV::recvMRQ_NOFLAG(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_request *rq = HDR_AODV_REQUEST(p); struct hdr_ip *ih = HDR_IP(p); // update the msg ih->saddr() = index; rq->rq_hop_count ++; aodv_mt_entry *mt = mtable.mt_lookup(rq->rq_dst); // a tree member is reached if (mt && mt->mt_node_status != NOT_ON_TREE){ if (mt->mt_grp_leader_addr == index || (mt->mt_grp_leader_addr != INFINITY8 && mt->mt_seqno >= rq->rq_dst_seqno)){ sendReply(rq->rq_src, // ipdst RREP_NO_FLAG, // flags 0, // hop count to tree mt->mt_dst, // rpdst = multicast group addr mt->mt_seqno, // multicast group seqno MY_ROUTE_TIMEOUT, // lifetime rq->rq_timestamp, // timestamp = the timestamp of request 0, // hop count to group leader ( no use for RREP_NO_FLAG) 0); // grp leader addr (no use for RREP_NO_FLAG) } Packet::free(p); return; } // not tree member is reached aodv_rt_entry *rt = rtable.rt_lookup(rq->rq_dst); if (rt && rt->rt_flags == RTF_UP && rt->rt_seqno >= rq->rq_dst_seqno){ sendReply(rq->rq_src, RREP_NO_FLAG, rt->rt_hops, rq->rq_dst, rt->rt_seqno, (u_int32_t) (rt->rt_expire - CURRENT_TIME), rq->rq_timestamp, 0, 0); aodv_rt_entry *rt0 = rtable.rt_lookup(rq->rq_src); rt->pc_insert(rt0->rt_nexthop); rt0->pc_insert(rt->rt_nexthop); Packet::free(p); return; } if (ih->daddr() == index){ Packet::free(p); return;} if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno); if (ih->daddr() == IP_BROADCAST) mt_forward(p, DELAY); else { // follow the glt table entry aodv_glt_entry *glt = gltable.glt_lookup(rq->rq_dst); if (glt && glt->glt_expire > CURRENT_TIME && glt->glt_grp_leader_addr == ih->daddr()){ hdr_cmn *ch = HDR_CMN(p); ch->next_hop_ = glt->glt_next_hop; mt_forward(p, NO_DELAY); } else drop(p, DROP_RTR_NO_ROUTE); }}/***********************************************************************/// receive Request_with_J_flag 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::recvMRQ_J(Packet *p){#ifdef DEBUG fprintf(stdout,"%s at node %i at %.9f\n", __FUNCTION__, index, CURRENT_TIME);#endif struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_cmn *ch = HDR_CMN(p); u_int16_t hop_count = INFINITY4; if (ch->size() > rq->size()){ struct hdr_aodv_request_ext *rqe = (struct hdr_aodv_request_ext *)(HDR_AODV_REQUEST(p) + rq->size()); hop_count = rqe->hop_count; } // update the msg ih->saddr() = index; rq->rq_hop_count ++; aodv_mt_entry *mt = mtable.mt_lookup(rq->rq_dst); // a tree member is reached if (mt && mt->mt_node_status != NOT_ON_TREE){ #ifdef PREDICTION aodv_nh_entry *link = mt->mt_nexthops.lookup(ch->prev_hop_); if (link && link->link_expire != 0){ Packet::free(p); return; } link = mt->mt_nexthops.upstream(); if (mt->mt_grp_leader_addr != index && (link == NULL || link->link_expire != 0)){ Packet::free(p); return; }#endif aodv_nh_entry *nh = mt->mt_nexthops.upstream(); if ((mt->mt_grp_leader_addr == index) || (mt->mt_grp_leader_addr != INFINITY8 && nh != NULL && ((mt->mt_seqno > rq->rq_dst_seqno) || (mt->mt_seqno == rq->rq_dst_seqno && mt->mt_hops_grp_leader <= hop_count) || (mt->mt_seqno == rq->rq_dst_seqno && hop_count == 1 && mt->mt_hops_grp_leader == 2 && nh->next_hop != rq->rq_src)))){ aodv_rt_entry *rt = rtable.rt_lookup(rq->rq_src); if (mt->mt_grp_leader_addr == index || (mt->mt_grp_leader_addr != rq->rq_src && mt->mt_grp_leader_addr != rt->rt_nexthop && nh->next_hop!= rq->rq_src && nh->next_hop!= rt->rt_nexthop)){ sendReply(rq->rq_src, //ipdst RREP_J, //flags 0, //hop_count to tree mt->mt_dst, //rpdst = multicast group addr mt->mt_seqno, //multicast grp seqno MY_ROUTE_TIMEOUT, //lifetime rq->rq_timestamp, //timestamp = the timestamp in reqeust mt->mt_hops_grp_leader, //hop_count to grp leader mt->mt_grp_leader_addr); //grp leader addr mt->mt_keep_on_tree_timeout = CURRENT_TIME + 1.5*RREP_WAIT_TIME; } } Packet::free(p); return; } // destination but not tree member is reached if (ih->daddr() == index){ Packet::free(p); return; } // intermediate node but not tree member is reached if (ih->daddr() ==IP_BROADCAST) mt_forward(p, DELAY); else { // follow the glt table entry aodv_glt_entry *glt = gltable.glt_lookup(rq->rq_dst); if (glt && glt->glt_expire > CURRENT_TIME && ih->daddr() == glt->glt_grp_leader_addr){ ch->next_hop_ = glt->glt_next_hop; mt_forward(p, NO_DELAY); } else drop(p, DROP_RTR_NO_ROUTE); }}/***********************************************************************/// receive Request_with_R_flag for multicast tree// the request source node must:// be on_tree and // wants to get permission from its group leader for requesting tree merge// along upstream towards its own leader// NOT ADD ANY NEXT HOP in MT TABLE, NOT UPDATE GRP INFO in MT TABLE/***********************************************************************/void AODV::recvMRQ_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_request *rq = HDR_AODV_REQUEST(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_cmn *ch = HDR_CMN(p); // update the msg ih->saddr() = index; rq->rq_hop_count ++; // check the node // must be tree member, should has valid upstream if not grp leader // the msg must be came from its downstream aodv_mt_entry *mt = mtable.mt_lookup(rq->rq_dst); if (mt == NULL || mt->mt_node_status == NOT_ON_TREE) { Packet::free(p); return; } if (mt->mt_grp_leader_addr != index && mt->mt_nexthops.upstream() == NULL) { Packet::free(p); return; } 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 && nh->enabled_flag != NH_ENABLE) mt->mt_nexthops.remove(nh); Packet::free(p); return; } // destination and also group leader is reached // send reply, if it has not permitted other node to request tree merge if (mt->mt_grp_leader_addr == index && ih->daddr() == index){ if (mt->mt_grp_merge_timeout < CURRENT_TIME){ mt->mt_grp_merge_permission = rq->rq_src; mt->mt_grp_merge_timeout = CURRENT_TIME + GROUP_HELLO_INTERVAL; sendReply(rq->rq_src, // ipdst RREP_R, // flags 0, // for RREP_R, used as hop count to grp 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_R) 0); // grp leader addr (no use for RREP_R) } Packet::free(p); return; } // destination is reached but not group leader if (ih->daddr() == index){ sendMGRPH_U(mt, ch->prev_hop_); Packet::free(p); return; } // group leader but not its destination if (mt->mt_grp_leader_addr == index){ sendMGRPH_U(mt, ch->prev_hop_); Packet::free(p); return; } // intermediate node is reached and not group leader // along upstream to forward the msg if (mt->mt_grp_leader_addr == ih->daddr()) { nh = mt->mt_nexthops.upstream(); ch->next_hop_ = nh->next_hop; mt_forward(p, NO_DELAY); } else { sendMGRPH_U(mt, ch->prev_hop_); Packet::free(p); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -