21 #define NS_LOG_APPEND_CONTEXT \
22 if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
26 #include "ns3/trace-source-accessor.h"
27 #include "ns3/simulator.h"
28 #include "ns3/abort.h"
35 NS_OBJECT_ENSURE_REGISTERED (TcpReno);
38 TcpReno::GetTypeId (
void)
40 static TypeId tid = TypeId (
"ns3::TcpReno")
42 .AddConstructor<TcpReno> ()
43 .AddAttribute (
"ReTxThreshold",
"Threshold for fast retransmit",
45 MakeUintegerAccessor (&TcpReno::m_retxThresh),
46 MakeUintegerChecker<uint32_t> ())
47 .AddTraceSource (
"CongestionWindow",
48 "The TCP connection's congestion window",
62 m_ssThresh (sock.m_ssThresh),
63 m_initialCWnd (sock.m_initialCWnd),
64 m_retxThresh (sock.m_retxThresh),
71 TcpReno::~TcpReno (
void)
98 return std::min (m_rWnd.Get (), m_cWnd.Get ());
104 return CopyObject<TcpReno> (
this);
112 NS_LOG_LOGIC (
"TcpReno receieved ACK for seq " << seq <<
113 " cwnd " << m_cWnd <<
114 " ssthresh " << m_ssThresh);
126 if (m_cWnd < m_ssThresh)
128 m_cWnd += m_segmentSize;
129 NS_LOG_INFO (
"In SlowStart, updated to cwnd " << m_cWnd <<
" ssthresh " << m_ssThresh);
134 double adder =
static_cast<double> (m_segmentSize * m_segmentSize) / m_cWnd.Get ();
135 adder = std::max (1.0, adder);
136 m_cWnd +=
static_cast<uint32_t
> (adder);
137 NS_LOG_INFO (
"In CongAvoid, updated to cwnd " << m_cWnd <<
" ssthresh " << m_ssThresh);
141 TcpSocketBase::NewAck (seq);
146 TcpReno::DupAck (
const TcpHeader& t, uint32_t count)
149 if (count == m_retxThresh && !m_inFastRec)
151 m_ssThresh = std::max (2 * m_segmentSize, BytesInFlight () / 2);
152 m_cWnd = m_ssThresh + 3 * m_segmentSize;
154 NS_LOG_INFO (
"Triple dupack. Reset cwnd to " << m_cWnd <<
", ssthresh to " << m_ssThresh);
157 else if (m_inFastRec)
159 m_cWnd += m_segmentSize;
166 void TcpReno::Retransmit (
void)
173 if (m_state == CLOSED || m_state == TIME_WAIT)
return;
175 if (m_state <= ESTABLISHED && m_txBuffer.
HeadSequence () >= m_highTxMark)
return;
180 m_ssThresh = std::max (2 * m_segmentSize, BytesInFlight () / 2);
181 m_cWnd = m_segmentSize;
184 ", ssthresh to " << m_ssThresh <<
", restart from seqnum " << m_nextTxSequence);
185 m_rtt->IncreaseMultiplier ();
190 TcpReno::SetSegSize (uint32_t size)
192 NS_ABORT_MSG_UNLESS (m_state == CLOSED,
"TcpReno::SetSegSize() cannot change segment size after connection started.");
193 m_segmentSize = size;
197 TcpReno::SetSSThresh (uint32_t threshold)
199 m_ssThresh = threshold;
203 TcpReno::GetSSThresh (
void)
const
209 TcpReno::SetInitialCwnd (uint32_t cwnd)
211 NS_ABORT_MSG_UNLESS (m_state == CLOSED,
"TcpReno::SetInitialCwnd() cannot change initial cwnd after connection started.");
212 m_initialCWnd = cwnd;
216 TcpReno::GetInitialCwnd (
void)
const
218 return m_initialCWnd;
222 TcpReno::InitializeCwnd (
void)
229 m_cWnd = m_initialCWnd * m_segmentSize;
smart pointer class similar to boost::intrusive_ptr
#define NS_LOG_FUNCTION(parameters)
SequenceNumber32 HeadSequence(void) const
#define NS_LOG_COMPONENT_DEFINE(name)
virtual void NewAck(const SequenceNumber32 &seq)
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if cond is false.
a polymophic address class
An implementation of a stream socket using TCP.
virtual int Connect(const Address &address)
A base class for implementation of a stream socket using TCP.
#define NS_LOG_LOGIC(msg)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
virtual int Connect(const Address &address)
bool SendPendingData(bool withAck=false)
virtual uint32_t Window(void)