⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hgpsrouter.cc

📁 在Linux下做的QuadTree的程序
💻 CC
📖 第 1 页 / 共 2 页
字号:
			}			rt_1[i].next_hop = new_pt;			new_pt->prev = NULL;		    }else {			assert(nexthop_pt->next == NULL);			//insert at the end of list			nexthop_pt->next = new_pt;			new_pt->prev = nexthop_pt;			new_pt->next = NULL;		    }		}	    }	    return;	}else if ((freeslot ==-1) && ((now - rt_1[i].lastupdate_time)>NEIGHBOR_TIMEOUT_INTEVAL)) {	    //remove all the outdated next hop nodes	    nexthop_pt = rt_1[i].next_hop;	    while(nexthop_pt) {		nexthop_pt = nexthop_pt->next;		if (nexthop_pt) {		    delete nexthop_pt->prev;		}	    }	    rt_1[i].next_hop = NULL;	    freeslot = i;	}    }    assert(freeslot >= 0);    new_pt = new nexthop_entry;    new_pt->lastupdate_time = now;    new_pt->speed = speed;    new_pt->next_node = next_hop;    new_pt->x = x;    new_pt->y = y;    new_pt->dist = distance;    new_pt->prev = NULL;    new_pt->next = NULL;    rt_1[freeslot].next_hop = new_pt;    rt_1[freeslot].loc = loc;    rt_1[freeslot].lastupdate_time = now;}nsaddr_tHGPSRouter::getBestNextHopNode(route_entry &rnt){    nexthop_entry *pt;    pt = getNextHopNode(rnt.next_hop);    if (!pt) {	assert(rnt.next_hop == NULL);	rnt.dst = 0;	rnt.lastupdate_time = -3 * NEIGHBOR_TIMEOUT_INTEVAL;	return 0;    }    int dstdst_x,dstdst_y;    loctodistance(dstdst_x,dstdst_y,rnt.loc);    dstdst_x = dstdst_x*125;    dstdst_y = dstdst_y*125;    double best_dist = 5*RADIO_PROPAGATION*RADIO_PROPAGATION;    double dist;    nsaddr_t best_node = pt->next_node;    while (pt) {	dist = (pt->x-dstdst_x)*(pt->x-dstdst_x)+(pt->y-dstdst_y)*(pt->y-dstdst_y);	if (dist<best_dist) {	    best_node = pt->next_node;	    best_dist = dist;	}	pt = getNextHopNode(pt->next);    }    return best_node;}boolHGPSRouter::outdatedNeighbor(nexthop_entry *next_hop, double now){    if ((now - next_hop->lastupdate_time) < NEIGHBOR_TIMEOUT_INTEVAL) {	return false;    }else {	return true;    }	    /*    double x, y, dist;    locserver->getPos(x,y);    dist = (x - next_hop->x)*(x - next_hop->x) + (y-next_hop->y)*(y-next_hop->y);    dist = sqrt(dist);    dist += next_hop->speed*(now-next_hop->lastupdate_time);    if (dist < (0.97*RADIO_PROPAGATION)) {	return false;    }else {	return true;    }    */}nsaddr_tHGPSRouter::getNextHopNode(route_entry &rnt){    nexthop_entry *pt;    pt = getNextHopNode(rnt.next_hop);    if (!pt) {	assert(rnt.next_hop == NULL);	rnt.dst = 0;	rnt.lastupdate_time = -3*NEIGHBOR_TIMEOUT_INTEVAL;	return 0;    }    return pt->next_node;}nexthop_entry *HGPSRouter::getNextHopNode(nexthop_entry *&next_hop){    nexthop_entry *nexthop_pt;    nexthop_entry *tmp_pt;    double now = Scheduler::instance().clock();    nexthop_pt = next_hop;    while(nexthop_pt && outdatedNeighbor(nexthop_pt, now)) {	//delete one entry	if (nexthop_pt->prev){	    nexthop_pt->prev->next = nexthop_pt->next;	    if (nexthop_pt->next) {	       nexthop_pt->next->prev = nexthop_pt->prev;	    }	}else{	    next_hop = nexthop_pt->next;	    if (nexthop_pt->next) {		nexthop_pt->next->prev = NULL;	    }	}	tmp_pt = nexthop_pt;	nexthop_pt = nexthop_pt->next;	delete tmp_pt;    }    if (nexthop_pt) {	assert(next_hop !=NULL);	return nexthop_pt;    }else{	return NULL;    }}nsaddr_t HGPSRouter::getNextHopFromNT(nsaddr_t dst, location & hisloc){    int i;    for (int j=0;j<MAX_RT_ENTRIES;j++) {	i = (j+dst) % MAX_RT_ENTRIES;//some simple hash functions	if (dst == nt[i].dst) {	    //if (hisloc.loc != 0) {		hisloc = nt[i].loc;	    //}	    //return getBestNextHopNode(nt[i]);	    return getNextHopNode(nt[i]);	}    }    return 0;}/* this function implements the simplest greedy geographic forwarding   it sends the packet towards its destination location grid by   searching in its 1 and 2 hop neighbor table, to prevent from routing   loop, prev_hop of this route is avoided.  It turns out in the simulation,   recording only the prev_hop is enough to prevent routing loop for geographic   forwarding.  More investigation on this issue needs to be done*/nsaddr_tHGPSRouter::getNextHop(location hisloc, nsaddr_t prev_hop){    location myloc;    int dist,min_dist;    double now = Scheduler::instance().clock();    nexthop_entry *next_hop_node = NULL;    int srcdst_x,srcdst_y,dstdst_x,dstdst_y;        myloc = locserver->myloc;           if ((hisloc.mask == BIGGEST_MASK) && (inSameGrid(myloc, hisloc))) {	//I should be able to reach the destination via my neighbor table	return parent->myaddr_;    }    loctodistance(dstdst_x,dstdst_y,hisloc);    loctodistance(srcdst_x,srcdst_y,myloc);    min_dist = (srcdst_x-dstdst_x)*(srcdst_x-dstdst_x)+ (srcdst_y-dstdst_y)*(srcdst_y-dstdst_y);        for (int i=0;i<MAX_ADJ_GRID;i++) {	if ((now - rt_1[i].lastupdate_time) < NEIGHBOR_TIMEOUT_INTEVAL) {	    loctodistance(srcdst_x,srcdst_y,rt_1[i].loc);	    dist = (srcdst_x-dstdst_x)*(srcdst_x-dstdst_x)+ (srcdst_y-dstdst_y)*(srcdst_y-dstdst_y);	    if (dist < min_dist) {		if ((next_hop_node = getNextHopNode(rt_1[i].next_hop))) {		    min_dist = dist;		}	    }	}    }        if (!next_hop_node) {	return 0;    }else {	//select one that makes the most progress among a set of valid next hops	nsaddr_t best_next_hop = next_hop_node->next_node;	double best_dist = (next_hop_node->x-dstdst_x*125)*(next_hop_node->x-dstdst_x*125)+(next_hop_node->y-dstdst_y*125)*(next_hop_node->y-dstdst_y*125);	double new_dist;	while (next_hop_node->next) {	    next_hop_node = getNextHopNode(next_hop_node->next);	    if (!next_hop_node) return best_next_hop;	    new_dist = (next_hop_node->x-dstdst_x*125)*(next_hop_node->x-dstdst_x*125)+(next_hop_node->y-dstdst_y*125)*(next_hop_node->y-dstdst_y*125);	    if ((new_dist < best_dist) && (next_hop_node->next_node!= prev_hop)){		best_next_hop = next_hop_node->next_node;		best_dist = new_dist;	    }	}	return best_next_hop;    }}voidHGPSRouter::sendOutPktWithLocation(Packet *&packet, double delay, bool checkNT){    hdr_hgps *hgpsh =  (hdr_hgps*)packet->access(parent->off_hgps_);    assert(hgpsh->type_ != LOC_QUERY);    this->sendOutPktWithLocation(packet,delay,checkNT,false);}/* invoked by the location server or data packets to send out a packet with its destination grid known.*/voidHGPSRouter::sendOutPktWithLocation(Packet *&packet,double delay,bool checkNT, bool invoke_loc_server){    hdr_hgps *hgpsh =  (hdr_hgps*)packet->access(parent->off_hgps_);    hdr_ip *iph =  (hdr_ip*)packet->access(parent->off_ip_);    hdr_cmn *cmnh =  (hdr_cmn*)packet->access(parent->off_cmn_);    Scheduler & s = Scheduler::instance();    //insert failure handler to the packet    cmnh->xmit_failure_ = HGPS_XmitFailureCallback;    cmnh->xmit_failure_data_ = (void *) this;    //check first if there's short-cut    bool i_have_sent_before = false;    if (checkNT) {	for (int i = 0; i<hgpsh->prev_hop_num_; i++) {	    deleteEntry(hgpsh->prev_hop_[i], iph->dst());	    if (hgpsh->prev_hop_[i] == parent->myaddr_) {		i_have_sent_before = true;	    }	}		if ((iph->dst_!=0) && (cmnh->next_hop_ = getNextHopFromNT(iph->dst_,hgpsh->dst_loc_))) {	    if (cmnh->next_hop_!=iph->dst()) {		if (hgpsh->prev_hop_num_ >= 4) {		    parent->drop(packet, DROP_RTR_ROUTE_LOOP);		    return;		}else{		    if (hgpsh->prev_hop_[hgpsh->prev_hop_num_-1]!=parent->myaddr_) {		    	hgpsh->prev_hop_[hgpsh->prev_hop_num_] = parent->myaddr_;		    	hgpsh->prev_hop_num_++;		    }		}	    }    	    s.schedule(parent->ll,packet,0);	    packet = NULL;    	    return;	}    }    assert((hgpsh->dst_loc_).mask != 0);#ifdef IDEAL_ROUTE     //this part has not been tested!    if (hgpsh->curr_addr_ == 0) {	//i'll ask god to give me a perfect route!	if (God::instance()->getRouteToLoc(parent->myaddr_,hgpsh->dst_loc_,hgpsh->addrs_,MAX_ADDR_LEN)) {	    parent->drop(packet,DROP_RTR_NO_ROUTE);	}else {	    hgpsh->curr_addr_++;	    cmnh->next_hop() = hgpsh->addrs_[hgpsh->curr_addr_];	    s.schedule(parent->ll,packet,delay);	}    }else {	//just forward the pkt along the source route       hgpsh->curr_addr_++;       cmnh->next_hop() = hgpsh->addrs_[hgpsh->curr_addr_];       s.schedule(parent->ll,packet,delay);    }    packet = NULL;    return;#endif        cmnh->next_hop_ = getNextHop(hgpsh->dst_loc_, (hgpsh->prev_hop_num_)? hgpsh->prev_hop_[0]:0);    /* an location update might not have the idea of who to forward the pkt to*/    /* i have to set iph->dst(), otherwise the link layer will complain*/    if (!iph->dst()) {	iph->dst() = cmnh->next_hop();     }        if (cmnh->next_hop() && (cmnh->next_hop() != parent->myaddr_)) {	hgpsh->prev_hop_[0] = parent->myaddr_;	hgpsh->prev_hop_num_ = 1;	s.schedule(parent->ll,packet,delay);    }else if (cmnh->next_hop() == parent->myaddr_) {	//I should be the next hop to destination. i.e. destination has moved away	//send out an ERR packet to information the source about this invalid dst_loc_#ifdef HGPS_DEBUG	printf("_%d_ %.2f location (%d) error dst %d\n",parent->myaddr_,s.clock(),hgpsh->dst_loc_.loc,iph->dst());#endif	if (hgpsh->type_ == DATA) {    	    Packet *p = parent->allocpkt();	    hdr_hgps *new_hgpsh =  (hdr_hgps*)p->access(parent->off_hgps_);	    hdr_ip *new_iph =  (hdr_ip*)p->access(parent->off_ip_);	    hdr_cmn *new_cmnh =  (hdr_cmn*)p->access(parent->off_cmn_);       	    new_iph->src() = parent->myaddr_;	    new_iph->dst() = iph->src();	    new_hgpsh->init();	    new_hgpsh->dst_loc_ = hgpsh->src_loc_;	    new_hgpsh->src_loc_ = locserver->getGrid();	    new_hgpsh->type_ = ERR;	    new_hgpsh->id_ = iph->dst();	    new_hgpsh->loc_ = hgpsh->dst_loc_;	    new_cmnh->num_forwards() = 0;	    new_cmnh->ptype() = PT_HGPS;	    new_cmnh->size() = hgpsh->size();	    sendOutPktWithLocation(p,0.0,true);    	    parent->trace("HGPS DROP: _%d_ %.2f outdated location %d->%d(%d)",parent->myaddr_,s.clock(),iph->src(),iph->dst(),(hgpsh->dst_loc_).loc);	}else if ((hgpsh->type_ == LOC_QUERY)) {	    if (parent->verbose_) {		parent->trace("HGPS dst %d loc %d error",iph->dst(),hgpsh->dst_loc_.loc);	    }	    if (invoke_loc_server) {		locserver->recvQuery(packet,true);		return;	    }else{		parent->trace("HGPS %.5f _%d_ loc-query-failure-1(%d %d)%d->%d",s.clock(),parent->myaddr_,parent->myaddr_,hgpsh->id_,iph->src(),iph->dst());	    }	}else if (hgpsh->type_ == LOC_UPDATE) {	    printf("_%d_ update dst %d location(%d) error\n", parent->myaddr_,iph->dst(),hgpsh->dst_loc_.loc);	}	//i classify location error as no route temporarily	parent->drop(packet,DROP_RTR_NO_ROUTE);    }else{	double x, y, z;	locserver->mynode->getLoc(&x,&y,&z);#ifdef HGPS_DEBUG	printf("_%d_ (%d, %.2f, %.2f) %.5f no route to dst %d (%d,%d)\n",parent->myaddr_,		(locserver->getGrid()).loc,x,y,s.clock(),iph->dst(),(hgpsh->dst_loc_).loc,(hgpsh->dst_loc_).mask);#endif	parent->drop(packet,DROP_RTR_NO_ROUTE);	packet = NULL;	return;    }    packet = NULL;}voidHGPS_XmitFailureCallback(Packet *pkt, void *data){    HGPSRouter *router = (HGPSRouter *)data; // cast of trust    router->xmitFailed(pkt);}voidHGPSRouter::xmitFailed(Packet *pkt){    hdr_hgps *hgpsh =  (hdr_hgps*)pkt->access(parent->off_hgps_);    hdr_ip *iph =  (hdr_ip*)pkt->access(parent->off_ip_);    hdr_cmn *cmnh =  (hdr_cmn*)pkt->access(parent->off_cmn_);        double now = Scheduler::instance().clock();    //delete incorrect neighbor entry whatever    deleteEntry(cmnh->next_hop());        if (parent->verbose_) {	parent->trace("HGPS: error from %d->%d %d",parent->myaddr_,cmnh->next_hop(),cmnh->uid());    }    nsaddr_t prev_cmnh_next_hop = cmnh->next_hop();    cmnh->next_hop() = 0; //i have to reset next hop/*    if (hgpsh->prev_hop_num_ && (hgpsh->prev_hop_[hgpsh->prev_hop_num_-1] == parent->myaddr_)) {	    hgpsh->prev_hop_num_ --;	}*/    if (hgpsh->type_ == LOC_UPDATE) {	//because my neighbor table has been changed, therefore iph->dst() might be different from recvUpdate()        locserver->recvUpdate(pkt);         }else if (hgpsh->type_ == LOC_QUERY) {        locserver->recvQuery(pkt,false);    }else {        sendOutPktWithLocation(pkt,0.0,true);    }    /* now kill all the other packets in the output queue that would    use the same next hop.  This is reasonable, since 802.11 has    already retried the xmission multiple times => a persistent failure.     from dmaltz*/    Packet *r, *nr, *head = NULL;		// pkts to be recycled    while ((r = (parent->ifq)->prq_get_nexthop(prev_cmnh_next_hop))) {	r->next_ = head;	head = r;     }    // the packets are now in the reverse order of how they appeared in the IFQ    // so reverse them again    for (r = head, head = NULL; r; r = r->next_) {  	r->next_ = head;	head = r;     }    // now process them in order    for (r = head; r; r = nr) {  	nr = r->next_;	//depending on packet type, rescue differently	hgpsh =  (hdr_hgps*)r->access(parent->off_hgps_);	cmnh = (hdr_cmn*)r->access(parent->off_cmn_);	cmnh->next_hop() = 0;	/*	if (hgpsh->prev_hop_num_ && (hgpsh->prev_hop_[hgpsh->prev_hop_num_-1] == parent->myaddr_)) {	    hgpsh->prev_hop_num_ --;	}	*/	if (hgpsh->type_ == LOC_UPDATE) {	    locserver->recvUpdate(r);	}else if (hgpsh->type_ == LOC_QUERY) {	    locserver->recvQuery(r,false);	}else {	    sendOutPktWithLocation(r,jitter(0.2,1),true);	}    } }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -