routing-queue.cc

00001 /*
00002  * Copyright (c) 2008 Regents of the SIGNET lab, University of Padova.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University of Padova (SIGNET lab) nor the 
00014  *    names of its contributors may be used to endorse or promote products 
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00018  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
00019  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00020  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00021  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00022  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00023  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00024  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00025  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00026  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00027  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <assert.h>
00031 
00032 #include "routing-queue.h"
00033 #include "routing-module.h"
00034 
00035 #define CURRENT_TIME    Scheduler::instance().clock()
00036 // #define QDEBUG
00037 
00038 /*
00039   Packet Queue used by AODV.
00040 */
00041 
00042 RoutingQueue::RoutingQueue(MrclRouting *m) : module_(m)
00043 {
00044         head_.next = &tail_;
00045         tail_.prev = &head_;
00046         len_ = 0;
00047         limit_ = RTR_RTQ_MAX_LEN;
00048         timeout_ = RTR_RTQ_TIMEOUT;
00049 }
00050 
00051 void RoutingQueue::enque(Packet *p) 
00052 {
00053         struct hdr_cmn *ch = HDR_CMN(p);
00054         /*
00055         * Purge any packets that have timed out.
00056         */
00057         purge();
00058  
00059         ch->ts_ = CURRENT_TIME + timeout_;
00060         if (len_ == limit_) 
00061         {
00062                 Packet *p0 = remove_head();     // decrements len_
00063                 assert(p0);
00064                 if(HDR_CMN(p0)->ts_ > CURRENT_TIME) 
00065                 {
00066                         module_->drop(p0, DROP_RTR_QFULL_VERBOSITY, DROP_RTR_QFULL);
00067                 }
00068                 else 
00069                 {
00070                         module_->drop(p0, DROP_RTR_QTIMEOUT_VERBOSITY, DROP_RTR_QTIMEOUT);
00071                 }
00072         }
00073         PktQueue *pq = new PktQueue;
00074         pq->p = p;
00075         pq->prev = tail_.prev;
00076         pq->next = &tail_;
00077         tail_.prev->next = pq;
00078         tail_.prev = pq;
00079 
00080         len_++;
00081 #ifdef QDEBUG
00082         verifyQueue();
00083 #endif // QDEBUG
00084 }
00085                 
00086 
00087 Packet* RoutingQueue::deque() 
00088 {
00089         /*
00090         * Purge any packets that have timed out.
00091         */
00092         purge();
00093         Packet *p = remove_head();
00094 #ifdef QDEBUG
00095         verifyQueue();
00096 #endif // QDEBUG
00097         return p;
00098 }
00099 
00100 
00101 Packet *RoutingQueue::deque(char *dst) {
00102         PktQueue *pq;
00103 
00104         /*
00105         * Purge any packets that have timed out.
00106         */
00107         purge();
00108 
00109         findPacketWithDst(dst, pq);
00110 
00111         if(pq == 0)
00112                 return 0;
00113 
00114         Packet *p = pq->p;
00115         pq->prev->next = pq->next;
00116         pq->next->prev = pq->prev;
00117         delete pq;
00118         len_--;
00119 #ifdef QDEBUG
00120         verifyQueue();
00121 #endif // QDEBUG
00122         return p;
00123 
00124 }
00125 
00126 Packet *RoutingQueue::deque(MrclAddress *dst) 
00127 {
00128         return deque(dst->getAddr());
00129 }
00130 
00131 char RoutingQueue::find(char *dst) 
00132 {
00133         PktQueue *pq;  
00134         
00135         findPacketWithDst(dst, pq);
00136         if(pq)
00137                 return 1;
00138         else
00139                 return 0;
00140 }
00141 
00142 char RoutingQueue::find(MrclAddress *dst) 
00143 {
00144         return find(dst->getAddr());
00145 }
00146         
00147         
00148 
00149 /*
00150   Private Routines
00151 */
00152 
00153 Packet* RoutingQueue::remove_head() 
00154 {
00155         if(len_ == 0)
00156                 return 0;
00157         
00158         
00159         PktQueue *pq = head_.next;
00160         Packet *p = pq->p;
00161         pq->prev->next = pq->next;
00162         pq->next->prev = pq->prev;
00163         len_--;
00164 
00165         return p;
00166 }
00167 
00168 void RoutingQueue::findPacketWithDst(char *dst, PktQueue*& pq) 
00169 {
00170         for(pq = head_.next; pq != &tail_; pq = pq->next) 
00171         {
00172                 RoutingHdr *rhdr = HDR_ROUTING(pq->p);
00173                 if(MrclAddress::areEqual(rhdr->daddr(), dst)) 
00174                 {
00175                         return;
00176                 }
00177         }
00178         pq = 0;
00179 }
00180 
00181 
00182 void RoutingQueue::verifyQueue() 
00183 {
00184         PktQueue *pq;
00185         int cnt = 0;
00186 
00187         for(pq = head_.next; pq != &tail_; pq = pq->next) 
00188         {
00189                 cnt++;
00190         }
00191         assert(cnt == len_);
00192 }
00193 
00194 
00195 /*
00196 void
00197 AodvQueue::purge() {
00198 Packet *p;
00199 
00200  while((p = head_) && HDR_CMN(p)->ts_ < CURRENT_TIME) {
00201    // assert(p == remove_head());     
00202    p = remove_head();     
00203    drop(p, DROP_RTR_QTIMEOUT);
00204  }
00205 
00206 }
00207 */
00208 
00209 int RoutingQueue::findAgedPacket(PktQueue *& pq) {
00210   
00211         for(pq = head_.next; pq != &tail_; pq = pq->next) 
00212         {
00213                 if(HDR_CMN(pq->p)->ts_ < CURRENT_TIME) 
00214                 {
00215                         return 1;
00216                 }
00217         }
00218         return 0;
00219 }
00220 
00221 void RoutingQueue::purge() 
00222 {
00223         PktQueue *pq;
00224 
00225         while (findAgedPacket(pq)) 
00226         {
00227                 if(pq->p == 0) 
00228                         return;
00229                 
00230                 pq->prev->next = pq->next;
00231                 pq->next->prev = pq->prev;
00232                 len_--;
00233                 module_->drop(pq->p, DROP_RTR_QAGED_VERBOSITY, DROP_RTR_QAGED); 
00234 #ifdef QDEBUG
00235                 verifyQueue();
00236 #endif // QDEBUG
00237         }
00238 }
00239 

Generated on Wed Nov 26 15:47:28 2008 for NS-MIRACLE library by  doxygen 1.5.2