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
rtt-estimator.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
//
3
// Copyright (c) 2006 Georgia Tech Research Corporation
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: Rajib Bhattacharjea<raj.b@gatech.edu>
19
//
20
21
22
// Ported from:
23
// Georgia Tech Network Simulator - Round Trip Time Estimation Class
24
// George F. Riley. Georgia Tech, Spring 2002
25
26
// Implements several variations of round trip time estimators
27
28
#include <iostream>
29
30
#include "
rtt-estimator.h
"
31
#include "ns3/simulator.h"
32
#include "ns3/double.h"
33
#include "ns3/integer.h"
34
#include "ns3/uinteger.h"
35
#include "ns3/log.h"
36
37
NS_LOG_COMPONENT_DEFINE
(
"RttEstimator"
);
38
39
namespace
ns3 {
40
41
NS_OBJECT_ENSURE_REGISTERED
(RttEstimator);
42
43
TypeId
44
RttEstimator::GetTypeId
(
void
)
45
{
46
static
TypeId
tid =
TypeId
(
"ns3::RttEstimator"
)
47
.
SetParent
<
Object
> ()
48
.AddAttribute (
"MaxMultiplier"
,
49
"Maximum RTO Multiplier"
,
50
UintegerValue
(64),
51
MakeUintegerAccessor (&
RttEstimator::m_maxMultiplier
),
52
MakeUintegerChecker<uint16_t> ())
53
.AddAttribute (
"InitialEstimation"
,
54
"Initial RTT estimation"
,
55
TimeValue
(
Seconds
(1.0)),
56
MakeTimeAccessor (&
RttEstimator::m_initialEstimatedRtt
),
57
MakeTimeChecker ())
58
.AddAttribute (
"MinRTO"
,
59
"Minimum retransmit timeout value"
,
60
TimeValue
(
Seconds
(0.2)),
// RFC2988 says min RTO=1 sec, but Linux uses 200ms. See http://www.postel.org/pipermail/end2end-interest/2004-November/004402.html
61
MakeTimeAccessor (&
RttEstimator::SetMinRto
,
62
&
RttEstimator::GetMinRto
),
63
MakeTimeChecker ())
64
;
65
return
tid;
66
}
67
68
void
69
RttEstimator::SetMinRto
(
Time
minRto)
70
{
71
NS_LOG_FUNCTION
(
this
<< minRto);
72
m_minRto
= minRto;
73
}
74
Time
75
RttEstimator::GetMinRto
(
void
)
const
76
{
77
return
m_minRto
;
78
}
79
void
80
RttEstimator::SetCurrentEstimate
(
Time
estimate)
81
{
82
NS_LOG_FUNCTION
(
this
<< estimate);
83
m_currentEstimatedRtt
= estimate;
84
}
85
Time
86
RttEstimator::GetCurrentEstimate
(
void
)
const
87
{
88
return
m_currentEstimatedRtt
;
89
}
90
91
92
//RttHistory methods
93
RttHistory::RttHistory
(
SequenceNumber32
s, uint32_t c,
Time
t)
94
: seq (s), count (c), time (t), retx (false)
95
{
96
NS_LOG_FUNCTION
(
this
);
97
}
98
99
RttHistory::RttHistory
(
const
RttHistory
& h)
100
: seq (h.seq), count (h.count), time (h.time), retx (h.retx)
101
{
102
NS_LOG_FUNCTION
(
this
);
103
}
104
105
// Base class methods
106
107
RttEstimator::RttEstimator
()
108
: m_next (1), m_history (),
109
m_nSamples (0),
110
m_multiplier (1)
111
{
112
NS_LOG_FUNCTION
(
this
);
113
//note next=1 everywhere since first segment will have sequence 1
114
115
// We need attributes initialized here, not later, so use the
116
// ConstructSelf() technique documented in the manual
117
ObjectBase::ConstructSelf
(
AttributeConstructionList
());
118
m_currentEstimatedRtt
=
m_initialEstimatedRtt
;
119
NS_LOG_DEBUG
(
"Initialize m_currentEstimatedRtt to "
<<
m_currentEstimatedRtt
.
GetSeconds
() <<
" sec."
);
120
}
121
122
RttEstimator::RttEstimator
(
const
RttEstimator
& c)
123
:
Object
(c), m_next (c.m_next), m_history (c.m_history),
124
m_maxMultiplier (c.m_maxMultiplier),
125
m_initialEstimatedRtt (c.m_initialEstimatedRtt),
126
m_currentEstimatedRtt (c.m_currentEstimatedRtt), m_minRto (c.m_minRto),
127
m_nSamples (c.m_nSamples), m_multiplier (c.m_multiplier)
128
{
129
NS_LOG_FUNCTION
(
this
);
130
}
131
132
RttEstimator::~RttEstimator
()
133
{
134
NS_LOG_FUNCTION
(
this
);
135
}
136
137
void
RttEstimator::SentSeq
(
SequenceNumber32
seq, uint32_t size)
138
{
139
NS_LOG_FUNCTION
(
this
<< seq << size);
140
// Note that a particular sequence has been sent
141
if
(seq ==
m_next
)
142
{
// This is the next expected one, just log at end
143
m_history
.push_back (
RttHistory
(seq, size,
Simulator::Now
() ));
144
m_next
= seq +
SequenceNumber32
(size);
// Update next expected
145
}
146
else
147
{
// This is a retransmit, find in list and mark as re-tx
148
for
(RttHistory_t::iterator i =
m_history
.begin (); i !=
m_history
.end (); ++i)
149
{
150
if
((seq >= i->seq) && (seq < (i->seq +
SequenceNumber32
(i->count))))
151
{
// Found it
152
i->retx =
true
;
153
// One final test..be sure this re-tx does not extend "next"
154
if
((seq +
SequenceNumber32
(size)) >
m_next
)
155
{
156
m_next
= seq +
SequenceNumber32
(size);
157
i->count = ((seq +
SequenceNumber32
(size)) - i->seq);
// And update count in hist
158
}
159
break
;
160
}
161
}
162
}
163
}
164
165
Time
RttEstimator::AckSeq
(
SequenceNumber32
ackSeq)
166
{
167
NS_LOG_FUNCTION
(
this
<< ackSeq);
168
// An ack has been received, calculate rtt and log this measurement
169
// Note we use a linear search (O(n)) for this since for the common
170
// case the ack'ed packet will be at the head of the list
171
Time
m =
Seconds
(0.0);
172
if
(
m_history
.size () == 0)
return
(m);
// No pending history, just exit
173
RttHistory
& h =
m_history
.front ();
174
if
(!h.
retx
&& ackSeq >= (h.
seq
+
SequenceNumber32
(h.
count
)))
175
{
// Ok to use this sample
176
m =
Simulator::Now
() - h.
time
;
// Elapsed time
177
Measurement
(m);
// Log the measurement
178
ResetMultiplier
();
// Reset multiplier on valid measurement
179
}
180
// Now delete all ack history with seq <= ack
181
while
(
m_history
.size () > 0)
182
{
183
RttHistory
& h =
m_history
.front ();
184
if
((h.
seq
+
SequenceNumber32
(h.
count
)) > ackSeq)
break
;
// Done removing
185
m_history
.pop_front ();
// Remove
186
}
187
return
m;
188
}
189
190
void
RttEstimator::ClearSent
()
191
{
192
NS_LOG_FUNCTION
(
this
);
193
// Clear all history entries
194
m_next
= 1;
195
m_history
.clear ();
196
}
197
198
void
RttEstimator::IncreaseMultiplier
()
199
{
200
NS_LOG_FUNCTION
(
this
);
201
m_multiplier
= (
m_multiplier
*2 <
m_maxMultiplier
) ?
m_multiplier
*2 :
m_maxMultiplier
;
202
NS_LOG_DEBUG
(
"Multiplier increased to "
<<
m_multiplier
);
203
}
204
205
void
RttEstimator::ResetMultiplier
()
206
{
207
NS_LOG_FUNCTION
(
this
);
208
m_multiplier
= 1;
209
}
210
211
void
RttEstimator::Reset
()
212
{
213
NS_LOG_FUNCTION
(
this
);
214
// Reset to initial state
215
m_next
= 1;
216
m_currentEstimatedRtt
=
m_initialEstimatedRtt
;
217
m_history
.clear ();
// Remove all info from the history
218
m_nSamples
= 0;
219
ResetMultiplier
();
220
}
221
222
223
224
//-----------------------------------------------------------------------------
225
//-----------------------------------------------------------------------------
226
// Mean-Deviation Estimator
227
228
NS_OBJECT_ENSURE_REGISTERED
(
RttMeanDeviation
);
229
230
TypeId
231
RttMeanDeviation::GetTypeId
(
void
)
232
{
233
static
TypeId
tid =
TypeId
(
"ns3::RttMeanDeviation"
)
234
.
SetParent
<
RttEstimator
> ()
235
.AddConstructor<RttMeanDeviation> ()
236
.AddAttribute (
"Gain"
,
237
"Gain used in estimating the RTT, must be 0 < Gain < 1"
,
238
DoubleValue
(0.1),
239
MakeDoubleAccessor (&
RttMeanDeviation::m_gain
),
240
MakeDoubleChecker<double> ())
241
;
242
return
tid;
243
}
244
245
RttMeanDeviation::RttMeanDeviation
() :
246
m_variance (0)
247
{
248
NS_LOG_FUNCTION
(
this
);
249
}
250
251
RttMeanDeviation::RttMeanDeviation
(
const
RttMeanDeviation
& c)
252
:
RttEstimator
(c), m_gain (c.m_gain), m_variance (c.m_variance)
253
{
254
NS_LOG_FUNCTION
(
this
);
255
}
256
257
void
RttMeanDeviation::Measurement
(
Time
m)
258
{
259
NS_LOG_FUNCTION
(
this
<< m);
260
if
(
m_nSamples
)
261
{
// Not first
262
Time
err (m -
m_currentEstimatedRtt
);
263
double
gErr = err.
ToDouble
(
Time::S
) *
m_gain
;
264
m_currentEstimatedRtt
+=
Time::FromDouble
(gErr,
Time::S
);
265
Time
difference =
Abs
(err) -
m_variance
;
266
NS_LOG_DEBUG
(
"m_variance += "
<<
Time::FromDouble
(difference.
ToDouble
(
Time::S
) *
m_gain
,
Time::S
));
267
m_variance
+=
Time::FromDouble
(difference.
ToDouble
(
Time::S
) *
m_gain
,
Time::S
);
268
}
269
else
270
{
// First sample
271
m_currentEstimatedRtt
= m;
// Set estimate to current
272
//variance = sample / 2; // And variance to current / 2
273
m_variance
= m;
// try this
274
NS_LOG_DEBUG
(
"(first sample) m_variance += "
<< m);
275
}
276
m_nSamples
++;
277
}
278
279
Time
RttMeanDeviation::RetransmitTimeout
()
280
{
281
NS_LOG_FUNCTION
(
this
);
282
NS_LOG_DEBUG
(
"RetransmitTimeout: var "
<<
m_variance
.
GetSeconds
() <<
" est "
<<
m_currentEstimatedRtt
.
GetSeconds
() <<
" multiplier "
<<
m_multiplier
);
283
// RTO = srtt + 4* rttvar
284
int64_t temp =
m_currentEstimatedRtt
.
ToInteger
(
Time::MS
) + 4 *
m_variance
.
ToInteger
(
Time::MS
);
285
if
(temp <
m_minRto
.
ToInteger
(
Time::MS
))
286
{
287
temp =
m_minRto
.
ToInteger
(
Time::MS
);
288
}
289
temp = temp *
m_multiplier
;
// Apply backoff
290
Time
retval =
Time::FromInteger
(temp,
Time::MS
);
291
NS_LOG_DEBUG
(
"RetransmitTimeout: return "
<< retval.
GetSeconds
());
292
return
(retval);
293
}
294
295
Ptr<RttEstimator>
RttMeanDeviation::Copy
()
const
296
{
297
NS_LOG_FUNCTION
(
this
);
298
return
CopyObject<RttMeanDeviation> (
this
);
299
}
300
301
void
RttMeanDeviation::Reset
()
302
{
303
NS_LOG_FUNCTION
(
this
);
304
// Reset to initial state
305
m_variance
=
Seconds
(0);
306
RttEstimator::Reset
();
307
}
308
void
RttMeanDeviation::Gain
(
double
g)
309
{
310
NS_LOG_FUNCTION
(
this
);
311
NS_ASSERT_MSG
( (g > 0) && (g < 1),
"RttMeanDeviation: Gain must be less than 1 and greater than 0"
);
312
m_gain
= g;
313
}
314
315
}
//namespace ns3
src
internet
model
rtt-estimator.cc
Generated on Tue Oct 9 2012 16:45:39 for ns-3 by
1.8.1.2