21 #define NS_LOG_APPEND_CONTEXT \
22 if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
24 #include "tcp-newreno.h"
26 #include "ns3/trace-source-accessor.h"
27 #include "ns3/simulator.h"
28 #include "ns3/abort.h"
35 NS_OBJECT_ENSURE_REGISTERED (TcpNewReno);
38 TcpNewReno::GetTypeId (
void)
40 static TypeId tid = TypeId (
"ns3::TcpNewReno")
42 .AddConstructor<TcpNewReno> ()
43 .AddAttribute (
"ReTxThreshold",
"Threshold for fast retransmit",
45 MakeUintegerAccessor (&TcpNewReno::m_retxThresh),
46 MakeUintegerChecker<uint32_t> ())
47 .AddAttribute (
"LimitedTransmit",
"Enable limited transmit",
49 MakeBooleanAccessor (&TcpNewReno::m_limitedTx),
50 MakeBooleanChecker ())
51 .AddTraceSource (
"CongestionWindow",
52 "The TCP connection's congestion window",
69 m_ssThresh (sock.m_ssThresh),
70 m_initialCWnd (sock.m_initialCWnd),
71 m_retxThresh (sock.m_retxThresh),
73 m_limitedTx (sock.m_limitedTx)
79 TcpNewReno::~TcpNewReno (
void)
106 return std::min (m_rWnd.Get (), m_cWnd.Get ());
110 TcpNewReno::Fork (
void)
112 return CopyObject<TcpNewReno> (
this);
120 NS_LOG_LOGIC (
"TcpNewReno receieved ACK for seq " << seq <<
121 " cwnd " << m_cWnd <<
122 " ssthresh " << m_ssThresh);
125 if (m_inFastRec && seq < m_recover)
128 m_cWnd += m_segmentSize;
129 NS_LOG_INFO (
"Partial ACK in fast recovery: cwnd set to " << m_cWnd);
130 TcpSocketBase::NewAck (seq);
134 else if (m_inFastRec && seq >= m_recover)
136 m_cWnd = std::min (m_ssThresh, BytesInFlight () + m_segmentSize);
138 NS_LOG_INFO (
"Received full ACK. Leaving fast recovery with cwnd set to " << m_cWnd);
142 if (m_cWnd < m_ssThresh)
144 m_cWnd += m_segmentSize;
145 NS_LOG_INFO (
"In SlowStart, updated to cwnd " << m_cWnd <<
" ssthresh " << m_ssThresh);
150 double adder =
static_cast<double> (m_segmentSize * m_segmentSize) / m_cWnd.Get ();
151 adder = std::max (1.0, adder);
152 m_cWnd +=
static_cast<uint32_t
> (adder);
153 NS_LOG_INFO (
"In CongAvoid, updated to cwnd " << m_cWnd <<
" ssthresh " << m_ssThresh);
157 TcpSocketBase::NewAck (seq);
165 if (count == m_retxThresh && !m_inFastRec)
167 m_ssThresh = std::max (2 * m_segmentSize, BytesInFlight () / 2);
168 m_cWnd = m_ssThresh + 3 * m_segmentSize;
169 m_recover = m_highTxMark;
171 NS_LOG_INFO (
"Triple dupack. Enter fast recovery mode. Reset cwnd to " << m_cWnd <<
172 ", ssthresh to " << m_ssThresh <<
" at fast recovery seqnum " << m_recover);
175 else if (m_inFastRec)
177 m_cWnd += m_segmentSize;
178 NS_LOG_INFO (
"Dupack in fast recovery mode. Increase cwnd to " << m_cWnd);
181 else if (!m_inFastRec && m_limitedTx && m_txBuffer.
SizeFromSequence (m_nextTxSequence) > 0)
184 uint32_t sz =
SendDataPacket (m_nextTxSequence, m_segmentSize,
true);
185 m_nextTxSequence += sz;
198 if (m_state == CLOSED || m_state == TIME_WAIT)
return;
200 if (m_state <= ESTABLISHED && m_txBuffer.
HeadSequence () >= m_highTxMark)
return;
205 m_ssThresh = std::max (2 * m_segmentSize, BytesInFlight () / 2);
206 m_cWnd = m_segmentSize;
209 ", ssthresh to " << m_ssThresh <<
", restart from seqnum " << m_nextTxSequence);
210 m_rtt->IncreaseMultiplier ();
215 TcpNewReno::SetSegSize (uint32_t size)
217 NS_ABORT_MSG_UNLESS (m_state == CLOSED,
"TcpNewReno::SetSegSize() cannot change segment size after connection started.");
218 m_segmentSize = size;
222 TcpNewReno::SetSSThresh (uint32_t threshold)
224 m_ssThresh = threshold;
228 TcpNewReno::GetSSThresh (
void)
const
234 TcpNewReno::SetInitialCwnd (uint32_t cwnd)
236 NS_ABORT_MSG_UNLESS (m_state == CLOSED,
"TcpNewReno::SetInitialCwnd() cannot change initial cwnd after connection started.");
237 m_initialCWnd = cwnd;
241 TcpNewReno::GetInitialCwnd (
void)
const
243 return m_initialCWnd;
247 TcpNewReno::InitializeCwnd (
void)
254 m_cWnd = m_initialCWnd * m_segmentSize;
smart pointer class similar to boost::intrusive_ptr
#define NS_LOG_FUNCTION(parameters)
virtual void NewAck(SequenceNumber32 const &seq)
uint32_t SendDataPacket(SequenceNumber32 seq, uint32_t maxSize, bool withAck)
uint32_t SizeFromSequence(const SequenceNumber32 &seq) const
SequenceNumber32 HeadSequence(void) const
#define NS_LOG_COMPONENT_DEFINE(name)
virtual uint32_t Window(void)
An implementation of a stream socket using TCP.
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if cond is false.
a polymophic address class
virtual void DupAck(const TcpHeader &t, uint32_t count)
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)
virtual void Retransmit(void)
bool SendPendingData(bool withAck=false)