NS-3 based Named Data Networking (NDN) simulator
ndnSIM: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
ndn-rtt-estimator.cc
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 // THIS IS A COPY OF rtt-estimator.cc from internet module with minor modifications
22 
23 // Ported from:
24 // Georgia Tech Network Simulator - Round Trip Time Estimation Class
25 // George F. Riley. Georgia Tech, Spring 2002
26 
27 // Implements several variations of round trip time estimators
28 
29 #include <iostream>
30 
31 #include "ndn-rtt-estimator.h"
32 #include "ns3/simulator.h"
33 #include "ns3/double.h"
34 #include "ns3/integer.h"
35 #include "ns3/uinteger.h"
36 #include "ns3/log.h"
37 
38 NS_LOG_COMPONENT_DEFINE ("ndn.RttEstimator");
39 
40 namespace ns3 {
41 
42 namespace ndn {
43 
44 NS_OBJECT_ENSURE_REGISTERED (RttEstimator);
45 
46 TypeId
47 RttEstimator::GetTypeId (void)
48 {
49  static TypeId tid = TypeId ("ns3::ndn::RttEstimator")
50  .SetParent<Object> ()
51  .AddAttribute ("MaxMultiplier",
52  "Maximum RTO Multiplier",
53  UintegerValue (64),
54  MakeUintegerAccessor (&RttEstimator::m_maxMultiplier),
55  MakeUintegerChecker<uint16_t> ())
56  .AddAttribute ("InitialEstimation",
57  "Initial RTT estimation",
58  TimeValue (Seconds (1.0)),
59  MakeTimeAccessor (&RttEstimator::m_initialEstimatedRtt),
60  MakeTimeChecker ())
61  .AddAttribute ("MinRTO",
62  "Minimum retransmit timeout value",
63  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
64  MakeTimeAccessor (&RttEstimator::SetMinRto,
66  MakeTimeChecker ())
67  .AddAttribute ("MaxRTO",
68  "Maximum retransmit timeout value",
69  TimeValue (Seconds (200.0)),
70  MakeTimeAccessor (&RttEstimator::SetMaxRto,
72  MakeTimeChecker ())
73  ;
74  return tid;
75 }
76 
77 void
79 {
80  NS_LOG_FUNCTION (this << minRto);
81  m_minRto = minRto;
82 }
83 Time
85 {
86  return m_minRto;
87 }
88 
89 void
91 {
92  NS_LOG_FUNCTION (this << maxRto);
93  m_maxRto = maxRto;
94 }
95 Time
97 {
98  return m_maxRto;
99 }
100 
101 void
103 {
104  NS_LOG_FUNCTION (this << estimate);
105  m_currentEstimatedRtt = estimate;
106 }
107 Time
109 {
110  return m_currentEstimatedRtt;
111 }
112 
113 
114 //RttHistory methods
115 RttHistory::RttHistory (SequenceNumber32 s, uint32_t c, Time t)
116  : seq (s), count (c), time (t), retx (false)
117 {
118  NS_LOG_FUNCTION (this);
119 }
120 
121 RttHistory::RttHistory (const RttHistory& h)
122  : seq (h.seq), count (h.count), time (h.time), retx (h.retx)
123 {
124  NS_LOG_FUNCTION (this);
125 }
126 
127 // Base class methods
128 
129 RttEstimator::RttEstimator ()
130  : m_next (1),
131  m_nSamples (0),
132  m_multiplier (1),
133  m_history ()
134 {
135  NS_LOG_FUNCTION (this);
136  //note next=1 everywhere since first segment will have sequence 1
137 
138  // We need attributes initialized here, not later, so use the
139  // ConstructSelf() technique documented in the manual
140  ObjectBase::ConstructSelf (AttributeConstructionList ());
141  m_currentEstimatedRtt = m_initialEstimatedRtt;
142  NS_LOG_DEBUG ("Initialize m_currentEstimatedRtt to " << m_currentEstimatedRtt.GetSeconds () << " sec.");
143 }
144 
145 RttEstimator::RttEstimator (const RttEstimator& c)
146  : Object (c), m_next (c.m_next),
147  m_maxMultiplier (c.m_maxMultiplier),
148  m_initialEstimatedRtt (c.m_initialEstimatedRtt),
149  m_currentEstimatedRtt (c.m_currentEstimatedRtt), m_minRto (c.m_minRto), m_maxRto (c.m_maxRto),
150  m_nSamples (c.m_nSamples), m_multiplier (c.m_multiplier),
151  m_history (c.m_history)
152 {
153  NS_LOG_FUNCTION (this);
154 }
155 
156 RttEstimator::~RttEstimator ()
157 {
158  NS_LOG_FUNCTION (this);
159 }
160 
161 TypeId
162 RttEstimator::GetInstanceTypeId (void) const
163 {
164  return GetTypeId ();
165 }
166 
167 void RttEstimator::SentSeq (SequenceNumber32 seq, uint32_t size)
168 {
169  NS_LOG_FUNCTION (this << seq << size);
170  // Note that a particular sequence has been sent
171  if (seq == m_next)
172  { // This is the next expected one, just log at end
173  m_history.push_back (RttHistory (seq, size, Simulator::Now () ));
174  m_next = seq + SequenceNumber32 (size); // Update next expected
175  }
176  else
177  { // This is a retransmit, find in list and mark as re-tx
178  for (RttHistory_t::iterator i = m_history.begin (); i != m_history.end (); ++i)
179  {
180  if ((seq >= i->seq) && (seq < (i->seq + SequenceNumber32 (i->count))))
181  { // Found it
182  i->retx = true;
183  // One final test..be sure this re-tx does not extend "next"
184  if ((seq + SequenceNumber32 (size)) > m_next)
185  {
186  m_next = seq + SequenceNumber32 (size);
187  i->count = ((seq + SequenceNumber32 (size)) - i->seq); // And update count in hist
188  }
189  break;
190  }
191  }
192  }
193 }
194 
195 Time RttEstimator::AckSeq (SequenceNumber32 ackSeq)
196 {
197  NS_LOG_FUNCTION (this << ackSeq);
198  // An ack has been received, calculate rtt and log this measurement
199  // Note we use a linear search (O(n)) for this since for the common
200  // case the ack'ed packet will be at the head of the list
201  Time m = Seconds (0.0);
202  if (m_history.size () == 0) return (m); // No pending history, just exit
203  RttHistory& h = m_history.front ();
204  if (!h.retx && ackSeq >= (h.seq + SequenceNumber32 (h.count)))
205  { // Ok to use this sample
206  m = Simulator::Now () - h.time; // Elapsed time
207  Measurement (m); // Log the measurement
208  ResetMultiplier (); // Reset multiplier on valid measurement
209  }
210  // Now delete all ack history with seq <= ack
211  while(m_history.size () > 0)
212  {
213  RttHistory& h = m_history.front ();
214  if ((h.seq + SequenceNumber32 (h.count)) > ackSeq) break; // Done removing
215  m_history.pop_front (); // Remove
216  }
217  return m;
218 }
219 
221 {
222  NS_LOG_FUNCTION (this);
223  // Clear all history entries
224  m_next = 1;
225  m_history.clear ();
226 }
227 
229 {
230  NS_LOG_FUNCTION (this);
231  m_multiplier = (m_multiplier*2 < m_maxMultiplier) ? m_multiplier*2 : m_maxMultiplier;
232  NS_LOG_DEBUG ("Multiplier increased to " << m_multiplier);
233 }
234 
236 {
237  NS_LOG_FUNCTION (this);
238  m_multiplier = 1;
239 }
240 
242 {
243  NS_LOG_FUNCTION (this);
244  // Reset to initial state
245  m_next = 1;
246  m_currentEstimatedRtt = m_initialEstimatedRtt;
247  m_history.clear (); // Remove all info from the history
248  m_nSamples = 0;
249  ResetMultiplier ();
250 }
251 
252 
253 } // namespace ndn
254 } // namespace ns3
void SetCurrentEstimate(Time estimate)
Sets the current RTT estimate (forcefully).
virtual void SentSeq(SequenceNumber32 seq, uint32_t size)
Note that a particular sequence has been sent.
virtual void ClearSent()
Clear all history entries.
Time GetMaxRto(void) const
Get the Maximum RTO.
Helper class to store RTT measurements.
Time GetCurrentEstimate(void) const
gets the current RTT estimate.
void SetMinRto(Time minRto)
Sets the Minimum RTO.
virtual void Reset()
Resets the estimation to its initial state.
virtual void Measurement(Time t)=0
Add a new measurement to the estimator.
virtual Time AckSeq(SequenceNumber32 ackSeq)
Note that a particular ack sequence has been received.
virtual void IncreaseMultiplier()
Increase the estimation multiplier up to MaxMultiplier.
void SetMaxRto(Time maxRto)
Sets the Maximum RTO.
virtual void ResetMultiplier()
Resets the estimation multiplier to 1.
Time GetMinRto(void) const
Get the Minimum RTO.