A Discrete-Event Network Simulator
API
 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 
44 TypeId
46 {
47  static TypeId tid = TypeId ("ns3::RttEstimator")
48  .SetParent<Object> ()
49  .AddAttribute ("MaxMultiplier",
50  "Maximum RTO Multiplier",
51  UintegerValue (64),
52  MakeUintegerAccessor (&RttEstimator::m_maxMultiplier),
53  MakeUintegerChecker<uint16_t> ())
54  .AddAttribute ("InitialEstimation",
55  "Initial RTT estimation",
56  TimeValue (Seconds (1.0)),
57  MakeTimeAccessor (&RttEstimator::m_initialEstimatedRtt),
58  MakeTimeChecker ())
59  .AddAttribute ("MinRTO",
60  "Minimum retransmit timeout value",
61  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
62  MakeTimeAccessor (&RttEstimator::SetMinRto,
64  MakeTimeChecker ())
65  ;
66  return tid;
67 }
68 
69 void
71 {
72  NS_LOG_FUNCTION (this << minRto);
73  m_minRto = minRto;
74 }
75 Time
77 {
78  return m_minRto;
79 }
80 void
82 {
83  NS_LOG_FUNCTION (this << estimate);
84  m_currentEstimatedRtt = estimate;
85 }
86 Time
88 {
89  return m_currentEstimatedRtt;
90 }
91 
92 
93 //RttHistory methods
95  : seq (s), count (c), time (t), retx (false)
96 {
97  NS_LOG_FUNCTION (this);
98 }
99 
101  : seq (h.seq), count (h.count), time (h.time), retx (h.retx)
102 {
103  NS_LOG_FUNCTION (this);
104 }
105 
106 // Base class methods
107 
109  : m_next (1), m_history (),
110  m_nSamples (0),
111  m_multiplier (1)
112 {
113  NS_LOG_FUNCTION (this);
114  //note next=1 everywhere since first segment will have sequence 1
115 
116  // We need attributes initialized here, not later, so use the
117  // ConstructSelf() technique documented in the manual
120  NS_LOG_DEBUG ("Initialize m_currentEstimatedRtt to " << m_currentEstimatedRtt.GetSeconds () << " sec.");
121 }
122 
124  : Object (c), m_next (c.m_next), m_history (c.m_history),
125  m_maxMultiplier (c.m_maxMultiplier),
126  m_initialEstimatedRtt (c.m_initialEstimatedRtt),
127  m_currentEstimatedRtt (c.m_currentEstimatedRtt), m_minRto (c.m_minRto),
128  m_nSamples (c.m_nSamples), m_multiplier (c.m_multiplier)
129 {
130  NS_LOG_FUNCTION (this);
131 }
132 
134 {
135  NS_LOG_FUNCTION (this);
136 }
137 
138 TypeId
140 {
141  return GetTypeId ();
142 }
143 
144 void RttEstimator::SentSeq (SequenceNumber32 seq, uint32_t size)
145 {
146  NS_LOG_FUNCTION (this << seq << size);
147  // Note that a particular sequence has been sent
148  if (seq == m_next)
149  { // This is the next expected one, just log at end
150  m_history.push_back (RttHistory (seq, size, Simulator::Now () ));
151  m_next = seq + SequenceNumber32 (size); // Update next expected
152  }
153  else
154  { // This is a retransmit, find in list and mark as re-tx
155  for (RttHistory_t::iterator i = m_history.begin (); i != m_history.end (); ++i)
156  {
157  if ((seq >= i->seq) && (seq < (i->seq + SequenceNumber32 (i->count))))
158  { // Found it
159  i->retx = true;
160  // One final test..be sure this re-tx does not extend "next"
161  if ((seq + SequenceNumber32 (size)) > m_next)
162  {
163  m_next = seq + SequenceNumber32 (size);
164  i->count = ((seq + SequenceNumber32 (size)) - i->seq); // And update count in hist
165  }
166  break;
167  }
168  }
169  }
170 }
171 
173 {
174  NS_LOG_FUNCTION (this << ackSeq);
175  // An ack has been received, calculate rtt and log this measurement
176  // Note we use a linear search (O(n)) for this since for the common
177  // case the ack'ed packet will be at the head of the list
178  Time m = Seconds (0.0);
179  if (m_history.size () == 0) return (m); // No pending history, just exit
180  RttHistory& h = m_history.front ();
181  if (!h.retx && ackSeq >= (h.seq + SequenceNumber32 (h.count)))
182  { // Ok to use this sample
183  m = Simulator::Now () - h.time; // Elapsed time
184  Measurement (m); // Log the measurement
185  ResetMultiplier (); // Reset multiplier on valid measurement
186  }
187  // Now delete all ack history with seq <= ack
188  while(m_history.size () > 0)
189  {
190  RttHistory& h = m_history.front ();
191  if ((h.seq + SequenceNumber32 (h.count)) > ackSeq) break; // Done removing
192  m_history.pop_front (); // Remove
193  }
194  return m;
195 }
196 
198 {
199  NS_LOG_FUNCTION (this);
200  // Clear all history entries
201  m_next = 1;
202  m_history.clear ();
203 }
204 
206 {
207  NS_LOG_FUNCTION (this);
209  NS_LOG_DEBUG ("Multiplier increased to " << m_multiplier);
210 }
211 
213 {
214  NS_LOG_FUNCTION (this);
215  m_multiplier = 1;
216 }
217 
219 {
220  NS_LOG_FUNCTION (this);
221  // Reset to initial state
222  m_next = 1;
224  m_history.clear (); // Remove all info from the history
225  m_nSamples = 0;
226  ResetMultiplier ();
227 }
228 
229 
230 
231 //-----------------------------------------------------------------------------
232 //-----------------------------------------------------------------------------
233 // Mean-Deviation Estimator
234 
236  ;
237 
238 TypeId
240 {
241  static TypeId tid = TypeId ("ns3::RttMeanDeviation")
243  .AddConstructor<RttMeanDeviation> ()
244  .AddAttribute ("Gain",
245  "Gain used in estimating the RTT, must be 0 < Gain < 1",
246  DoubleValue (0.1),
247  MakeDoubleAccessor (&RttMeanDeviation::m_gain),
248  MakeDoubleChecker<double> ())
249  ;
250  return tid;
251 }
252 
254  m_variance (0)
255 {
256  NS_LOG_FUNCTION (this);
257 }
258 
260  : RttEstimator (c), m_gain (c.m_gain), m_variance (c.m_variance)
261 {
262  NS_LOG_FUNCTION (this);
263 }
264 
265 TypeId
267 {
268  return GetTypeId ();
269 }
270 
272 {
273  NS_LOG_FUNCTION (this << m);
274  if (m_nSamples)
275  { // Not first
276  Time err (m - m_currentEstimatedRtt);
277  double gErr = err.ToDouble (Time::S) * m_gain;
279  Time difference = Abs (err) - m_variance;
280  NS_LOG_DEBUG ("m_variance += " << Time::FromDouble (difference.ToDouble (Time::S) * m_gain, Time::S));
282  }
283  else
284  { // First sample
285  m_currentEstimatedRtt = m; // Set estimate to current
286  //variance = sample / 2; // And variance to current / 2
287  m_variance = m; // try this
288  NS_LOG_DEBUG ("(first sample) m_variance += " << m);
289  }
290  m_nSamples++;
291 }
292 
294 {
295  NS_LOG_FUNCTION (this);
296  NS_LOG_DEBUG ("RetransmitTimeout: var " << m_variance.GetSeconds () << " est " << m_currentEstimatedRtt.GetSeconds () << " multiplier " << m_multiplier);
297  // RTO = srtt + 4* rttvar
299  if (temp < m_minRto.ToInteger (Time::MS))
300  {
301  temp = m_minRto.ToInteger (Time::MS);
302  }
303  temp = temp * m_multiplier; // Apply backoff
304  Time retval = Time::FromInteger (temp, Time::MS);
305  NS_LOG_DEBUG ("RetransmitTimeout: return " << retval.GetSeconds ());
306  return (retval);
307 }
308 
310 {
311  NS_LOG_FUNCTION (this);
312  return CopyObject<RttMeanDeviation> (this);
313 }
314 
316 {
317  NS_LOG_FUNCTION (this);
318  // Reset to initial state
319  m_variance = Seconds (0);
321 }
322 void RttMeanDeviation::Gain (double g)
323 {
324  NS_LOG_FUNCTION (this);
325  NS_ASSERT_MSG( (g > 0) && (g < 1), "RttMeanDeviation: Gain must be less than 1 and greater than 0" );
326  m_gain = g;
327 }
328 
329 } //namespace ns3
Time m_currentEstimatedRtt
Current estimate.
Time m_variance
Current variance.
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
int64x64_t Abs(const int64x64_t &value)
Definition: int64x64.h:85
NS_LOG_COMPONENT_DEFINE("RttEstimator")
double ToDouble(enum Unit timeUnit) const
Definition: nstime.h:444
static TypeId GetTypeId(void)
Get the type ID.
RttHistory_t m_history
List of sent packet.
double m_gain
Filter gain.
int64_t ToInteger(enum Unit timeUnit) const
Definition: nstime.h:412
The "Mean--Deviation" RTT estimator, as discussed by Van Jacobson.
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
bool retx
True if this has been retransmitted.
Definition: rtt-estimator.h:58
uint32_t count
Number of bytes sent.
Definition: rtt-estimator.h:56
static TypeId GetTypeId(void)
Get the type ID.
Time m_initialEstimatedRtt
Initial RTT estimation.
virtual TypeId GetInstanceTypeId(void) const
static Time FromDouble(double value, enum Unit timeUnit)
Definition: nstime.h:433
virtual ~RttEstimator()
SequenceNumber< uint32_t, int32_t > SequenceNumber32
uint16_t m_multiplier
RTO Multiplier.
double GetSeconds(void) const
Definition: nstime.h:274
uint16_t m_maxMultiplier
Maximum RTO Multiplier.
Time time
Time this one was sent.
Definition: rtt-estimator.h:57
virtual void ResetMultiplier()
Resets the estimation multiplier to 1.
hold objects of type ns3::Time
Definition: nstime.h:961
Time GetCurrentEstimate(void) const
gets the current RTT estimate.
Hold an unsigned integer type.
Definition: uinteger.h:46
Ptr< SampleEmitter > s
Base class for all RTT Estimators.
Definition: rtt-estimator.h:69
RttHistory(SequenceNumber32 s, uint32_t c, Time t)
Constructor - builds an RttHistory with the given parameters.
virtual void Measurement(Time t)=0
Add a new measurement to the estimator.
virtual void SentSeq(SequenceNumber32 seq, uint32_t size)
Note that a particular sequence has been sent.
void ConstructSelf(const AttributeConstructionList &attributes)
Definition: object-base.cc:66
Time GetMinRto(void) const
Get the Minimum RTO.
uint32_t m_nSamples
Number of samples.
Time RetransmitTimeout()
Returns the estimated RTO.
void SetMinRto(Time minRto)
Sets the Minimum RTO.
Time m_minRto
minimum value of the timeout
virtual void Reset()
Resets the estimation to its initial state.
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
void Reset()
Resets the estimator.
virtual void IncreaseMultiplier()
Increase the estimation multiplier up to MaxMultiplier.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Ptr< RttEstimator > Copy() const
Copy object.
static Time FromInteger(uint64_t value, enum Unit timeUnit)
Definition: nstime.h:392
void Measurement(Time measure)
Add a new measurement to the estimator.
virtual TypeId GetInstanceTypeId(void) const
SequenceNumber32 m_next
Next expected sequence to be sent.
Helper class to store RTT measurements.
Definition: rtt-estimator.h:40
SequenceNumber32 seq
First sequence number in packet sent.
Definition: rtt-estimator.h:55
void SetCurrentEstimate(Time estimate)
Sets the current RTT estimate (forcefully).
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
virtual void ClearSent()
Clear all history entries.
void Gain(double g)
Sets the estimator Gain.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:452
second
Definition: nstime.h:93
a base class which provides memory management and object aggregation
Definition: object.h:63
millisecond
Definition: nstime.h:94
Hold a floating point type.
Definition: double.h:41
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
virtual Time AckSeq(SequenceNumber32 ackSeq)
Note that a particular ack sequence has been received.