A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
red-queue.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright © 2011 Marcos Talau
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation;
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
*
18
* Author: Marcos Talau (talau@users.sourceforge.net)
19
*
20
* Thanks to: Duy Nguyen<duy@soe.ucsc.edu> by RED efforts in NS3
21
*
22
*
23
* This file incorporates work covered by the following copyright and
24
* permission notice:
25
*
26
* Copyright (c) 1990-1997 Regents of the University of California.
27
* All rights reserved.
28
*
29
* Redistribution and use in source and binary forms, with or without
30
* modification, are permitted provided that the following conditions
31
* are met:
32
* 1. Redistributions of source code must retain the above copyright
33
* notice, this list of conditions and the following disclaimer.
34
* 2. Redistributions in binary form must reproduce the above copyright
35
* notice, this list of conditions and the following disclaimer in the
36
* documentation and/or other materials provided with the distribution.
37
* 3. Neither the name of the University nor of the Laboratory may be used
38
* to endorse or promote products derived from this software without
39
* specific prior written permission.
40
*
41
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
42
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
45
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
* SUCH DAMAGE.
52
*/
53
54
/*
55
* PORT NOTE: This code was ported from ns-2 (queue/red.cc). Almost all
56
* comments have also been ported from NS-2
57
*/
58
59
#include "ns3/log.h"
60
#include "ns3/enum.h"
61
#include "ns3/uinteger.h"
62
#include "ns3/double.h"
63
#include "ns3/simulator.h"
64
#include "ns3/abort.h"
65
#include "ns3/random-variable-stream.h"
66
#include "
red-queue.h
"
67
68
NS_LOG_COMPONENT_DEFINE
(
"RedQueue"
);
69
70
namespace
ns3 {
71
72
NS_OBJECT_ENSURE_REGISTERED
(RedQueue);
73
74
TypeId
RedQueue::GetTypeId
(
void
)
75
{
76
static
TypeId
tid =
TypeId
(
"ns3::RedQueue"
)
77
.
SetParent
<
Queue
> ()
78
.AddConstructor<RedQueue> ()
79
.AddAttribute (
"Mode"
,
80
"Determines unit for QueueLimit"
,
81
EnumValue
(
QUEUE_MODE_PACKETS
),
82
MakeEnumAccessor
(&
RedQueue::SetMode
),
83
MakeEnumChecker
(
QUEUE_MODE_BYTES
,
"QUEUE_MODE_BYTES"
,
84
QUEUE_MODE_PACKETS
,
"QUEUE_MODE_PACKETS"
))
85
.AddAttribute (
"MeanPktSize"
,
86
"Average of packet size"
,
87
UintegerValue
(500),
88
MakeUintegerAccessor (&
RedQueue::m_meanPktSize
),
89
MakeUintegerChecker<uint32_t> ())
90
.AddAttribute (
"IdlePktSize"
,
91
"Average packet size used during idle times. Used when m_cautions = 3"
,
92
UintegerValue
(0),
93
MakeUintegerAccessor (&
RedQueue::m_idlePktSize
),
94
MakeUintegerChecker<uint32_t> ())
95
.AddAttribute (
"Wait"
,
96
"True for waiting between dropped packets"
,
97
BooleanValue
(
true
),
98
MakeBooleanAccessor (&
RedQueue::m_isWait
),
99
MakeBooleanChecker ())
100
.AddAttribute (
"Gentle"
,
101
"True to increases dropping probability slowly when average queue exceeds maxthresh"
,
102
BooleanValue
(
true
),
103
MakeBooleanAccessor (&
RedQueue::m_isGentle
),
104
MakeBooleanChecker ())
105
.AddAttribute (
"MinTh"
,
106
"Minimum average length threshold in packets/bytes"
,
107
DoubleValue
(5),
108
MakeDoubleAccessor (&
RedQueue::m_minTh
),
109
MakeDoubleChecker<double> ())
110
.AddAttribute (
"MaxTh"
,
111
"Maximum average length threshold in packets/bytes"
,
112
DoubleValue
(15),
113
MakeDoubleAccessor (&
RedQueue::m_maxTh
),
114
MakeDoubleChecker<double> ())
115
.AddAttribute (
"QueueLimit"
,
116
"Queue limit in bytes/packets"
,
117
UintegerValue
(25),
118
MakeUintegerAccessor (&
RedQueue::m_queueLimit
),
119
MakeUintegerChecker<uint32_t> ())
120
.AddAttribute (
"QW"
,
121
"Queue weight related to the exponential weighted moving average (EWMA)"
,
122
DoubleValue
(0.002),
123
MakeDoubleAccessor (&
RedQueue::m_qW
),
124
MakeDoubleChecker <double> ())
125
.AddAttribute (
"LInterm"
,
126
"The maximum probability of dropping a packet"
,
127
DoubleValue
(50),
128
MakeDoubleAccessor (&
RedQueue::m_lInterm
),
129
MakeDoubleChecker <double> ())
130
.AddAttribute (
"Ns1Compat"
,
131
"NS-1 compatibility"
,
132
BooleanValue
(
false
),
133
MakeBooleanAccessor (&
RedQueue::m_isNs1Compat
),
134
MakeBooleanChecker ())
135
.AddAttribute (
"LinkBandwidth"
,
136
"The RED link bandwidth"
,
137
DataRateValue
(
DataRate
(
"1.5Mbps"
)),
138
MakeDataRateAccessor (&
RedQueue::m_linkBandwidth
),
139
MakeDataRateChecker ())
140
.AddAttribute (
"LinkDelay"
,
141
"The RED link delay"
,
142
TimeValue
(
MilliSeconds
(20)),
143
MakeTimeAccessor (&
RedQueue::m_linkDelay
),
144
MakeTimeChecker ())
145
;
146
147
return
tid;
148
}
149
150
RedQueue::RedQueue
() :
151
Queue
(),
152
m_packets (),
153
m_bytesInQueue (0),
154
m_hasRedStarted (false)
155
{
156
NS_LOG_FUNCTION_NOARGS
();
157
m_uv
= CreateObject<UniformRandomVariable> ();
158
}
159
160
RedQueue::~RedQueue
()
161
{
162
NS_LOG_FUNCTION_NOARGS
();
163
}
164
165
void
166
RedQueue::SetMode
(
RedQueue::QueueMode
mode)
167
{
168
NS_LOG_FUNCTION
(mode);
169
m_mode
= mode;
170
}
171
172
RedQueue::QueueMode
173
RedQueue::GetMode
(
void
)
174
{
175
NS_LOG_FUNCTION_NOARGS
();
176
return
m_mode
;
177
}
178
179
void
180
RedQueue::SetQueueLimit
(uint32_t lim)
181
{
182
NS_LOG_FUNCTION
(lim);
183
m_queueLimit
= lim;
184
}
185
186
void
187
RedQueue::SetTh
(
double
minTh,
double
maxTh)
188
{
189
NS_LOG_FUNCTION
(
this
<< minTh << maxTh);
190
NS_ASSERT
(minTh <= maxTh);
191
m_minTh
= minTh;
192
m_maxTh
= maxTh;
193
}
194
195
RedQueue::Stats
196
RedQueue::GetStats
()
197
{
198
return
m_stats
;
199
}
200
201
int64_t
202
RedQueue::AssignStreams
(int64_t stream)
203
{
204
m_uv
->
SetStream
(stream);
205
return
1;
206
}
207
208
bool
209
RedQueue::DoEnqueue
(
Ptr<Packet>
p)
210
{
211
NS_LOG_FUNCTION
(
this
<< p);
212
213
if
(!
m_hasRedStarted
)
214
{
215
NS_LOG_INFO
(
"Initializing RED params."
);
216
InitializeParams
();
217
m_hasRedStarted
=
true
;
218
}
219
220
uint32_t nQueued = 0;
221
222
if
(
GetMode
() ==
QUEUE_MODE_BYTES
)
223
{
224
NS_LOG_DEBUG
(
"Enqueue in bytes mode"
);
225
nQueued =
m_bytesInQueue
;
226
}
227
else
if
(
GetMode
() ==
QUEUE_MODE_PACKETS
)
228
{
229
NS_LOG_DEBUG
(
"Enqueue in packets mode"
);
230
nQueued =
m_packets
.size ();
231
}
232
233
// simulate number of packets arrival during idle period
234
uint32_t m = 0;
235
236
if
(
m_idle
== 1)
237
{
238
NS_LOG_DEBUG
(
"RED Queue is idle."
);
239
Time
now =
Simulator::Now
();
240
241
if
(
m_cautious
== 3)
242
{
243
double
ptc =
m_ptc
*
m_meanPktSize
/
m_idlePktSize
;
244
m = uint32_t (ptc * (now -
m_idleTime
).GetSeconds ());
245
}
246
else
247
{
248
m = uint32_t (
m_ptc
* (now -
m_idleTime
).GetSeconds ());
249
}
250
251
m_idle
= 0;
252
}
253
254
m_qAvg
=
Estimator
(nQueued, m + 1,
m_qAvg
,
m_qW
);
255
256
NS_LOG_DEBUG
(
"\t bytesInQueue "
<<
m_bytesInQueue
<<
"\tQavg "
<<
m_qAvg
);
257
NS_LOG_DEBUG
(
"\t packetsInQueue "
<<
m_packets
.size () <<
"\tQavg "
<<
m_qAvg
);
258
259
m_count
++;
260
m_countBytes
+= p->
GetSize
();
261
262
uint32_t dropType =
DTYPE_NONE
;
263
if
(
m_qAvg
>=
m_minTh
&& nQueued > 1)
264
{
265
if
((!
m_isGentle
&&
m_qAvg
>=
m_maxTh
) ||
266
(
m_isGentle
&&
m_qAvg
>= 2 *
m_maxTh
))
267
{
268
NS_LOG_DEBUG
(
"adding DROP FORCED MARK"
);
269
dropType =
DTYPE_FORCED
;
270
}
271
else
if
(
m_old
== 0)
272
{
273
/*
274
* The average queue size has just crossed the
275
* threshold from below to above "minthresh", or
276
* from above "minthresh" with an empty queue to
277
* above "minthresh" with a nonempty queue.
278
*/
279
m_count = 1;
280
m_countBytes
= p->
GetSize
();
281
m_old
= 1;
282
}
283
else
if
(
DropEarly
(p, nQueued))
284
{
285
NS_LOG_LOGIC
(
"DropEarly returns 1"
);
286
dropType =
DTYPE_UNFORCED
;
287
}
288
}
289
else
290
{
291
// No packets are being dropped
292
m_vProb
= 0.0;
293
m_old
= 0;
294
}
295
296
if
(nQueued >=
m_queueLimit
)
297
{
298
NS_LOG_DEBUG
(
"\t Dropping due to Queue Full "
<< nQueued);
299
dropType =
DTYPE_FORCED
;
300
m_stats
.
qLimDrop
++;
301
}
302
303
if
(dropType ==
DTYPE_UNFORCED
)
304
{
305
NS_LOG_DEBUG
(
"\t Dropping due to Prob Mark "
<<
m_qAvg
);
306
m_stats
.
unforcedDrop
++;
307
Drop
(p);
308
return
false
;
309
}
310
else
if
(dropType ==
DTYPE_FORCED
)
311
{
312
NS_LOG_DEBUG
(
"\t Dropping due to Hard Mark "
<<
m_qAvg
);
313
m_stats
.
forcedDrop
++;
314
Drop
(p);
315
if
(
m_isNs1Compat
)
316
{
317
m_count = 0;
318
m_countBytes
= 0;
319
}
320
return
false
;
321
}
322
323
m_bytesInQueue
+= p->
GetSize
();
324
m_packets
.push_back (p);
325
326
NS_LOG_LOGIC
(
"Number packets "
<<
m_packets
.size ());
327
NS_LOG_LOGIC
(
"Number bytes "
<<
m_bytesInQueue
);
328
329
return
true
;
330
}
331
332
/*
333
* Note: if the link bandwidth changes in the course of the
334
* simulation, the bandwidth-dependent RED parameters do not change.
335
* This should be fixed, but it would require some extra parameters,
336
* and didn't seem worth the trouble...
337
*/
338
void
339
RedQueue::InitializeParams
(
void
)
340
{
341
NS_LOG_FUNCTION_NOARGS
();
342
343
NS_ASSERT
(
m_minTh
<=
m_maxTh
);
344
m_stats
.
forcedDrop
= 0;
345
m_stats
.
unforcedDrop
= 0;
346
m_stats
.
qLimDrop
= 0;
347
348
m_cautious
= 0;
349
m_ptc
=
m_linkBandwidth
.
GetBitRate
() / (8.0 *
m_meanPktSize
);
350
351
m_qAvg
= 0.0;
352
m_count
= 0;
353
m_countBytes
= 0;
354
m_old
= 0;
355
m_idle
= 1;
356
357
double
th_diff = (
m_maxTh
-
m_minTh
);
358
if
(th_diff == 0)
359
{
360
th_diff = 1.0;
361
}
362
m_vA
= 1.0 / th_diff;
363
m_curMaxP
= 1.0 /
m_lInterm
;
364
m_vB
= -
m_minTh
/ th_diff;
365
366
if
(
m_isGentle
)
367
{
368
m_vC
= (1.0 -
m_curMaxP
) /
m_maxTh
;
369
m_vD
= 2.0 *
m_curMaxP
- 1.0;
370
}
371
m_idleTime
=
NanoSeconds
(0);
372
373
/*
374
* If m_qW=0, set it to a reasonable value of 1-exp(-1/C)
375
* This corresponds to choosing m_qW to be of that value for
376
* which the packet time constant -1/ln(1-m)qW) per default RTT
377
* of 100ms is an order of magnitude more than the link capacity, C.
378
*
379
* If m_qW=-1, then the queue weight is set to be a function of
380
* the bandwidth and the link propagation delay. In particular,
381
* the default RTT is assumed to be three times the link delay and
382
* transmission delay, if this gives a default RTT greater than 100 ms.
383
*
384
* If m_qW=-2, set it to a reasonable value of 1-exp(-10/C).
385
*/
386
if
(
m_qW
== 0.0)
387
{
388
m_qW
= 1.0 - exp (-1.0 /
m_ptc
);
389
}
390
else
if
(
m_qW
== -1.0)
391
{
392
double
rtt = 3.0 * (
m_linkDelay
.
GetSeconds
() + 1.0 /
m_ptc
);
393
394
if
(rtt < 0.1)
395
{
396
rtt = 0.1;
397
}
398
m_qW
= 1.0 - exp (-1.0 / (10 * rtt *
m_ptc
));
399
}
400
else
if
(
m_qW
== -2.0)
401
{
402
m_qW
= 1.0 - exp (-10.0 /
m_ptc
);
403
}
404
405
// TODO: implement adaptive RED
406
407
NS_LOG_DEBUG
(
"\tm_delay "
<<
m_linkDelay
.
GetSeconds
() <<
"; m_isWait "
408
<<
m_isWait
<<
"; m_qW "
<<
m_qW
<<
"; m_ptc "
<<
m_ptc
409
<<
"; m_minTh "
<<
m_minTh
<<
"; m_maxTh "
<<
m_maxTh
410
<<
"; m_isGentle "
<<
m_isGentle
<<
"; th_diff "
<< th_diff
411
<<
"; lInterm "
<<
m_lInterm
<<
"; va "
<<
m_vA
<<
"; cur_max_p "
412
<<
m_curMaxP
<<
"; v_b "
<<
m_vB
<<
"; m_vC "
413
<<
m_vC
<<
"; m_vD "
<<
m_vD
);
414
}
415
416
// Compute the average queue size
417
double
418
RedQueue::Estimator
(uint32_t nQueued, uint32_t m,
double
qAvg,
double
qW)
419
{
420
NS_LOG_FUNCTION
(
this
<< nQueued << m << qAvg << qW);
421
double
newAve;
422
423
newAve = qAvg;
424
while
(--m >= 1)
425
{
426
newAve *= 1.0 - qW;
427
}
428
newAve *= 1.0 - qW;
429
newAve += qW * nQueued;
430
431
// TODO: implement adaptive RED
432
433
return
newAve;
434
}
435
436
// Check if packet p needs to be dropped due to probability mark
437
uint32_t
438
RedQueue::DropEarly
(
Ptr<Packet>
p, uint32_t qSize)
439
{
440
NS_LOG_FUNCTION
(
this
<< p << qSize);
441
m_vProb1
=
CalculatePNew
(
m_qAvg
,
m_maxTh
,
m_isGentle
,
m_vA
,
m_vB
,
m_vC
,
m_vD
,
m_curMaxP
);
442
m_vProb
=
ModifyP
(
m_vProb1
,
m_count
,
m_countBytes
,
m_meanPktSize
,
m_isWait
, p->
GetSize
());
443
444
// Drop probability is computed, pick random number and act
445
if
(
m_cautious
== 1)
446
{
447
/*
448
* Don't drop/mark if the instantaneous queue is much below the average.
449
* For experimental purposes only.
450
* pkts: the number of packets arriving in 50 ms
451
*/
452
double
pkts =
m_ptc
* 0.05;
453
double
fraction = pow ((1 -
m_qW
), pkts);
454
455
if
((
double
) qSize < fraction *
m_qAvg
)
456
{
457
// Queue could have been empty for 0.05 seconds
458
return
0;
459
}
460
}
461
462
double
u =
m_uv
->
GetValue
();
463
464
if
(
m_cautious
== 2)
465
{
466
/*
467
* Decrease the drop probability if the instantaneous
468
* queue is much below the average.
469
* For experimental purposes only.
470
* pkts: the number of packets arriving in 50 ms
471
*/
472
double
pkts =
m_ptc
* 0.05;
473
double
fraction = pow ((1 -
m_qW
), pkts);
474
double
ratio = qSize / (fraction *
m_qAvg
);
475
476
if
(ratio < 1.0)
477
{
478
u *= 1.0 / ratio;
479
}
480
}
481
482
if
(u <=
m_vProb
)
483
{
484
NS_LOG_LOGIC
(
"u <= m_vProb; u "
<< u <<
"; m_vProb "
<<
m_vProb
);
485
486
// DROP or MARK
487
m_count
= 0;
488
m_countBytes
= 0;
489
// TODO: Implement set bit to mark
490
491
return
1;
// drop
492
}
493
494
return
0;
// no drop/mark
495
}
496
497
// Returns a probability using these function parameters for the DropEarly funtion
498
double
499
RedQueue::CalculatePNew
(
double
qAvg,
double
maxTh,
bool
isGentle,
double
vA,
500
double
vB,
double
vC,
double
vD,
double
maxP)
501
{
502
NS_LOG_FUNCTION
(
this
<< qAvg << maxTh << isGentle << vA << vB << vC << vD << maxP);
503
double
p;
504
505
if
(isGentle && qAvg >= maxTh)
506
{
507
// p ranges from maxP to 1 as the average queue
508
// Size ranges from maxTh to twice maxTh
509
p = vC * qAvg + vD;
510
}
511
else
if
(!isGentle && qAvg >= maxTh)
512
{
513
/*
514
* OLD: p continues to range linearly above max_p as
515
* the average queue size ranges above th_max.
516
* NEW: p is set to 1.0
517
*/
518
p = 1.0;
519
}
520
else
521
{
522
/*
523
* p ranges from 0 to max_p as the average queue size ranges from
524
* th_min to th_max
525
*/
526
p = vA * qAvg + vB;
527
p *= maxP;
528
}
529
530
if
(p > 1.0)
531
{
532
p = 1.0;
533
}
534
535
return
p;
536
}
537
538
// Returns a probability using these function parameters for the DropEarly funtion
539
double
540
RedQueue::ModifyP
(
double
p, uint32_t count, uint32_t countBytes,
541
uint32_t meanPktSize,
bool
isWait, uint32_t size)
542
{
543
NS_LOG_FUNCTION
(
this
<< p << count << countBytes << meanPktSize << isWait << size);
544
double
count1 = (double) count;
545
546
if
(
GetMode
() ==
QUEUE_MODE_BYTES
)
547
{
548
count1 = (double) (countBytes / meanPktSize);
549
}
550
551
if
(isWait)
552
{
553
if
(count1 * p < 1.0)
554
{
555
p = 0.0;
556
}
557
else
if
(count1 * p < 2.0)
558
{
559
p /= (2.0 - count1 * p);
560
}
561
else
562
{
563
p = 1.0;
564
}
565
}
566
else
567
{
568
if
(count1 * p < 1.0)
569
{
570
p /= (1.0 - count1 * p);
571
}
572
else
573
{
574
p = 1.0;
575
}
576
}
577
578
if
((
GetMode
() ==
QUEUE_MODE_BYTES
) && (p < 1.0))
579
{
580
p = (p * size) / meanPktSize;
581
}
582
583
if
(p > 1.0)
584
{
585
p = 1.0;
586
}
587
588
return
p;
589
}
590
591
uint32_t
592
RedQueue::GetQueueSize
(
void
)
593
{
594
NS_LOG_FUNCTION_NOARGS
();
595
if
(
GetMode
() ==
QUEUE_MODE_BYTES
)
596
{
597
return
m_bytesInQueue
;
598
}
599
else
if
(
GetMode
() ==
QUEUE_MODE_PACKETS
)
600
{
601
return
m_packets
.size ();
602
}
603
else
604
{
605
NS_ABORT_MSG
(
"Unknown RED mode."
);
606
}
607
}
608
609
Ptr<Packet>
610
RedQueue::DoDequeue
(
void
)
611
{
612
NS_LOG_FUNCTION
(
this
);
613
614
if
(
m_packets
.empty ())
615
{
616
NS_LOG_LOGIC
(
"Queue empty"
);
617
m_idle
= 1;
618
m_idleTime
=
Simulator::Now
();
619
620
return
0;
621
}
622
else
623
{
624
m_idle
= 0;
625
Ptr<Packet>
p =
m_packets
.front ();
626
m_packets
.pop_front ();
627
m_bytesInQueue
-= p->
GetSize
();
628
629
NS_LOG_LOGIC
(
"Popped "
<< p);
630
631
NS_LOG_LOGIC
(
"Number packets "
<<
m_packets
.size ());
632
NS_LOG_LOGIC
(
"Number bytes "
<<
m_bytesInQueue
);
633
634
return
p;
635
}
636
}
637
638
Ptr<const Packet>
639
RedQueue::DoPeek
(
void
)
const
640
{
641
NS_LOG_FUNCTION
(
this
);
642
if
(
m_packets
.empty ())
643
{
644
NS_LOG_LOGIC
(
"Queue empty"
);
645
return
0;
646
}
647
648
Ptr<Packet>
p =
m_packets
.front ();
649
650
NS_LOG_LOGIC
(
"Number packets "
<<
m_packets
.size ());
651
NS_LOG_LOGIC
(
"Number bytes "
<<
m_bytesInQueue
);
652
653
return
p;
654
}
655
656
}
// namespace ns3
src
network
utils
red-queue.cc
Generated on Tue Oct 9 2012 16:45:45 for ns-3 by
1.8.1.2