00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00037
00038
00039
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
00056
00057 purge();
00058
00059 ch->ts_ = CURRENT_TIME + timeout_;
00060 if (len_ == limit_)
00061 {
00062 Packet *p0 = remove_head();
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
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
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
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
00197
00198
00199
00200
00201
00202
00203
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