[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ns] priqueue.cc bug and fix



Hello, 
If you feed _only_ routing protocols packets to the Interface
Queue implemented in class Priqueue, the  recvHighPriority
function will make it behave like a LIFO queue.
I included thereafter the diffs of the changes I made to fix
that. (I work with ns-2.1b6 on a linux machine)
Cheers, 
 --  
Robin Poss

priqueue.h:
*****************************
64,73c64
<   void recvHighPriorityZRP(Packet *, Handler *);
<   //insert packet at front of queue, 
<   //BUT there might be several routing protocol packets
<   //at the front of the queue already, and inserting 
<   //bluntly this one ahead of them would boil down to
<   //implementing a LIFO queue, which we don't want.
<   //so the packet is inserted at the end of
<   //the routing protocol packet queue which might exist
<   //at the front of the queue.
<   
---
> 
priqueue.cc:
*****************************
93,94d92
< 			recvHighPriority(p, h);
<                         break;
97c95
<                         recvHighPriorityZRP(p, h);
---
>                         recvHighPriority(p, h);
112,115c110,112
< 	// insert packet at front of queue
< {
< 	//robin
< 	//Packet gege;
---
>   // insert packet at front of queue
> {//robin
> Packet gege;
118,202c115,136
< 		{
< 			Packet *to_drop = q_->lookup(q_->length()-1);
< 			q_->remove(to_drop);
< 			//gege=*to_drop;
< 			// stupid debug by robin @@@
< 			//if (sizeof(gege)==0)
< 			//	printf("\nAIE!!!\n");
< 			drop(to_drop);
< 		}
< 	
< 	if (!blocked_) {
< 		/*
< 		 * We're not blocked.  Get a packet and send it on.
< 		 * We perform an extra check because the queue
< 		 * might drop the packet even if it was
< 		 * previously empty!  (e.g., RED can do this.)
< 		 */
< 		p = deque();
< 		if (p != 0) {
< 			blocked_ = 1;
< 			target_->recv(p, &qh_);
< 		}
< 	} 
< }
< 
< void 
< PriQueue::recvHighPriorityZRP(Packet *p, Handler *)
< 	// insert packet at front of queue, with caution (see priqueue.h)
< 	//-Robin
< {
< 	//first get the pointer on the last routing packet
< 	Packet* search_p = q_->head();
< 
< 	if (!search_p)
< 		q_->enqueHead(p);
< 	else {
< 		Packet* last_rt_p = 0;
< 		bool end_of_queue_reached = 0;
< 		struct hdr_cmn *ch = HDR_CMN(search_p);	
< 		
< 		while ((ch->ptype()==PT_ZRP) && (!end_of_queue_reached)) {
< 			if (!search_p->next_)
< 				end_of_queue_reached = 1;
< 			else {
< 				last_rt_p = search_p;
< 				search_p = search_p->next_;
< 			}
< 		}//of the while loop
< 
< 		//2 mutually exclusive possibilities to get out of the previous
< 		//loop:
< 		//-either the end of the queue was reached, the queue was 
< 		//composed of ZRP packets only: Insert packet at the end of it.
< 		//-or(exclusive as I said) last_rt_p is the pointer on the
< 		//last ZRP packet of the queue. Note that if the first packet of 
< 		//the queue was not a ZRP packet, last_rt_p stays NULL and p
< 		//will be conveniently added at the head of the queue by 
< 		//PacketQueue::add(p,last_rt_p) (i.e. PacketQueue::add(p,NULL)).
< 		
< 		if (end_of_queue_reached)
< 			q_->enque(p);
< 		else 
< 			q_->add(p,last_rt_p);
< 	}
< 
< 	if (q_->length() >= qlim_)
< 		{
< 			Packet *to_drop = q_->lookup(q_->length()-1);
< 			q_->remove(to_drop);
< 			drop(to_drop);
< 		}
< 	
< 	if (!blocked_) {
< 		/*
< 		 * We're not blocked.  Get a packet and send it on.
< 		 * We perform an extra check because the queue
< 		 * might drop the packet even if it was
< 		 * previously empty!  (e.g., RED can do this.)
< 		 */
< 		p = deque();
< 		if (p != 0) {
< 			blocked_ = 1;
< 			target_->recv(p, &qh_);
< 		}
< 	} 
---
>     {
>       Packet *to_drop = q_->lookup(q_->length()-1);
>       q_->remove(to_drop);
> gege=*to_drop;
>       if (sizeof(gege)==0)
> 	      printf("\nAIE!!!\n");
>       drop(to_drop);
>     }
>   
>   if (!blocked_) {
>     /*
>      * We're not blocked.  Get a packet and send it on.
>      * We perform an extra check because the queue
>      * might drop the packet even if it was
>      * previously empty!  (e.g., RED can do this.)
>      */
>     p = deque();
>     if (p != 0) {
>       blocked_ = 1;
>       target_->recv(p, &qh_);
>     }
>   } 
203a138
>  

queue.h
************************
77,78d76
< 	/* Adds a packet, located after a given packet. Either could be 0.-ZRP */
< 	void add(Packet *, Packet *);
queue.cc
************************
80,101d79
< /*
<  * Adds packet pkt located after packet prev on the queue.  Either p or prev
<  * could be NULL.  If prev is NULL then pkt must be added at the head of the queue.
<  *-ZRP
<  */
< void PacketQueue::add(Packet* pkt, Packet *prev) //XXX: screwy
< {
< 	if (pkt){
< 		if (!prev)
< 			PacketQueue::enqueHead(pkt) ;/* increments len_ internally */
< 		else {
< 			pkt->next_=prev->next_;
< 			prev->next_ = pkt;
< 			if (!pkt->next_)
< 				tail_ = pkt;
< 			++len_;
< 		}
< 	}
< 	return;
< }
< 
< 
keywords: AORV TORA routing protocol inversed order DSR