21#define NS_LOG_APPEND_CONTEXT \
24 std::clog << " [node " << m_node->GetId() << "] "; \
51#include "ns3/data-rate.h"
52#include "ns3/double.h"
53#include "ns3/inet-socket-address.h"
54#include "ns3/inet6-socket-address.h"
57#include "ns3/object.h"
58#include "ns3/packet.h"
59#include "ns3/pointer.h"
60#include "ns3/simulation-singleton.h"
61#include "ns3/simulator.h"
62#include "ns3/trace-source-accessor.h"
63#include "ns3/uinteger.h"
79 TypeId(
"ns3::TcpSocketBase")
81 .SetGroupName(
"Internet")
88 .AddAttribute(
"MaxSegLifetime",
89 "Maximum segment lifetime in seconds, use for TIME_WAIT state transition "
93 MakeDoubleChecker<double>(0))
94 .AddAttribute(
"MaxWindowSize",
95 "Max size of advertised window",
98 MakeUintegerChecker<uint16_t>())
99 .AddAttribute(
"IcmpCallback",
100 "Callback invoked whenever an icmp error is received on this socket.",
104 .AddAttribute(
"IcmpCallback6",
105 "Callback invoked whenever an icmpv6 error is received on this socket.",
109 .AddAttribute(
"WindowScaling",
110 "Enable or disable Window Scaling option",
114 .AddAttribute(
"Sack",
115 "Enable or disable Sack option",
119 .AddAttribute(
"Timestamp",
120 "Enable or disable Timestamp option",
126 "Minimum retransmit timeout value",
133 "Clock Granularity used in RTO calculations",
138 .AddAttribute(
"TxBuffer",
142 MakePointerChecker<TcpTxBuffer>())
143 .AddAttribute(
"RxBuffer",
147 MakePointerChecker<TcpRxBuffer>())
148 .AddAttribute(
"CongestionOps",
149 "Pointer to TcpCongestionOps object",
152 MakePointerChecker<TcpCongestionOps>())
155 "Threshold for fast retransmit",
158 MakeUintegerChecker<uint32_t>())
159 .AddAttribute(
"LimitedTransmit",
160 "Enable limited transmit",
164 .AddAttribute(
"UseEcn",
165 "Parameter to set ECN functionality",
174 .AddTraceSource(
"RTO",
175 "Retransmission timeout",
177 "ns3::TracedValueCallback::Time")
178 .AddTraceSource(
"RTT",
181 "ns3::TracedValueCallback::Time")
182 .AddTraceSource(
"NextTxSequence",
183 "Next sequence number to send (SND.NXT)",
185 "ns3::SequenceNumber32TracedValueCallback")
186 .AddTraceSource(
"HighestSequence",
187 "Highest sequence number ever sent in socket's life time",
189 "ns3::TracedValueCallback::SequenceNumber32")
190 .AddTraceSource(
"State",
193 "ns3::TcpStatesTracedValueCallback")
194 .AddTraceSource(
"CongState",
195 "TCP Congestion machine state",
197 "ns3::TcpSocketState::TcpCongStatesTracedValueCallback")
198 .AddTraceSource(
"EcnState",
199 "Trace ECN state change of socket",
201 "ns3::TcpSocketState::EcnStatesTracedValueCallback")
202 .AddTraceSource(
"AdvWND",
203 "Advertised Window Size",
205 "ns3::TracedValueCallback::Uint32")
206 .AddTraceSource(
"RWND",
207 "Remote side's flow control window",
209 "ns3::TracedValueCallback::Uint32")
210 .AddTraceSource(
"BytesInFlight",
211 "Socket estimation of bytes in flight",
213 "ns3::TracedValueCallback::Uint32")
214 .AddTraceSource(
"HighestRxSequence",
215 "Highest sequence number received from peer",
217 "ns3::TracedValueCallback::SequenceNumber32")
218 .AddTraceSource(
"HighestRxAck",
219 "Highest ack received from peer",
221 "ns3::TracedValueCallback::SequenceNumber32")
222 .AddTraceSource(
"PacingRate",
223 "The current TCP pacing rate",
225 "ns3::TracedValueCallback::DataRate")
226 .AddTraceSource(
"CongestionWindow",
227 "The TCP connection's congestion window",
229 "ns3::TracedValueCallback::Uint32")
230 .AddTraceSource(
"CongestionWindowInflated",
231 "The TCP connection's congestion window inflates as in older RFC",
233 "ns3::TracedValueCallback::Uint32")
234 .AddTraceSource(
"SlowStartThreshold",
235 "TCP slow start threshold (bytes)",
237 "ns3::TracedValueCallback::Uint32")
238 .AddTraceSource(
"Tx",
239 "Send tcp packet to IP protocol",
241 "ns3::TcpSocketBase::TcpTxRxTracedCallback")
242 .AddTraceSource(
"Rx",
243 "Receive tcp packet from IP protocol",
245 "ns3::TcpSocketBase::TcpTxRxTracedCallback")
246 .AddTraceSource(
"EcnEchoSeq",
247 "Sequence of last received ECN Echo",
249 "ns3::SequenceNumber32TracedValueCallback")
250 .AddTraceSource(
"EcnCeSeq",
251 "Sequence of last received CE",
253 "ns3::SequenceNumber32TracedValueCallback")
254 .AddTraceSource(
"EcnCwrSeq",
255 "Sequence of last received CWR",
257 "ns3::SequenceNumber32TracedValueCallback");
273 m_tcb = CreateObject<TcpSocketState>();
274 m_rateOps = CreateObject<TcpRateLinux>();
330 m_dupAckCount(sock.m_dupAckCount),
332 m_delAckMaxCount(sock.m_delAckMaxCount),
333 m_noDelay(sock.m_noDelay),
334 m_synCount(sock.m_synCount),
335 m_synRetries(sock.m_synRetries),
336 m_dataRetrCount(sock.m_dataRetrCount),
337 m_dataRetries(sock.m_dataRetries),
339 m_minRto(sock.m_minRto),
340 m_clockGranularity(sock.m_clockGranularity),
341 m_delAckTimeout(sock.m_delAckTimeout),
342 m_persistTimeout(sock.m_persistTimeout),
343 m_cnTimeout(sock.m_cnTimeout),
345 m_endPoint6(nullptr),
348 m_state(sock.m_state),
349 m_errno(sock.m_errno),
350 m_closeNotified(sock.m_closeNotified),
351 m_closeOnEmpty(sock.m_closeOnEmpty),
352 m_shutdownSend(sock.m_shutdownSend),
353 m_shutdownRecv(sock.m_shutdownRecv),
354 m_connected(sock.m_connected),
356 m_maxWinSize(sock.m_maxWinSize),
357 m_bytesAckedNotProcessed(sock.m_bytesAckedNotProcessed),
359 m_highRxMark(sock.m_highRxMark),
360 m_highRxAckMark(sock.m_highRxAckMark),
361 m_sackEnabled(sock.m_sackEnabled),
362 m_winScalingEnabled(sock.m_winScalingEnabled),
363 m_rcvWindShift(sock.m_rcvWindShift),
364 m_sndWindShift(sock.m_sndWindShift),
365 m_timestampEnabled(sock.m_timestampEnabled),
366 m_timestampToEcho(sock.m_timestampToEcho),
367 m_recover(sock.m_recover),
368 m_recoverActive(sock.m_recoverActive),
369 m_retxThresh(sock.m_retxThresh),
370 m_limitedTx(sock.m_limitedTx),
371 m_isFirstPartialAck(sock.m_isFirstPartialAck),
372 m_txTrace(sock.m_txTrace),
373 m_rxTrace(sock.m_rxTrace),
374 m_pacingTimer(
Timer::CANCEL_ON_DESTROY),
375 m_ecnEchoSeq(sock.m_ecnEchoSeq),
376 m_ecnCESeq(sock.m_ecnCESeq),
377 m_ecnCWRSeq(sock.m_ecnCWRSeq)
389 MakeNullCallback<void, Ptr<Socket>,
const Address&>();
414 m_rateOps = CreateObject<TcpRateLinux>();
546 m_tcp->AddSocket(
this);
562 m_tcp->AddSocket(
this);
634 m_tcp->AddSocket(
this);
646 "TcpSocketBase::SetSSThresh() cannot change initial ssThresh after connection started.");
662 "TcpSocketBase::SetInitialCwnd() cannot change initial cwnd after connection started.");
779 NS_LOG_WARN(
"Socket " <<
this <<
" << unread rx data during close. Sending reset."
780 <<
"This is probably due to a bad sink application; check its code");
846 NS_ABORT_MSG_IF(flags,
"use of flags is not supported in TcpSocketBase::Send()");
895 return Send(p, flags);
904 NS_ABORT_MSG_IF(flags,
"use of flags is not supported in TcpSocketBase::Recv()");
907 return Create<Packet>();
920 if (packet && packet->GetSize() != 0)
1166 return (tail < m_tcb->m_rxBuffer->NextRxSequence() ||
1187 uint32_t bytesRemoved = packet->PeekHeader(tcpHeader);
1191 packet->GetSize() - bytesRemoved))
1227 uint32_t bytesRemoved = packet->PeekHeader(tcpHeader);
1231 packet->GetSize() - bytesRemoved))
1264 m_icmpCallback(icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
1289 if (tcpHeaderSize == 0 || tcpHeaderSize > 60)
1291 NS_LOG_ERROR(
"Bytes removed: " << tcpHeaderSize <<
" invalid");
1294 else if (tcpPayloadSize > 0 &&
OutOfRange(seq, seq + tcpPayloadSize))
1298 <<
":" << seq + tcpPayloadSize <<
") out of range ["
1313 packet->RemovePacketTag(priorityTag);
1317 packet->RemoveHeader(tcpHeader);
1397 << seq <<
":" << seq + packet->GetSize()
1398 <<
") without TS option. Silently discard it");
1414 NS_LOG_LOGIC(
this <<
" Enter zerowindow persist state");
1416 this <<
" Cancelled ReTxTimeout event which was set to expire at "
1481 NS_LOG_LOGIC(
this <<
" Leaving zerowindow persist state");
1507 <<
" SND.UNA = " <<
m_txBuffer->HeadSequence());
1526 <<
" -> ECN_SENDING_ECE");
1553 else if (tcpflags == 0)
1566 <<
" received. Reset packet is sent.");
1601 switch (option->GetKind())
1686 <<
"Reset cwnd to " <<
m_tcb->
m_cWnd <<
", ssthresh to "
1688 <<
" calculated in flight: " << bytesInFlight);
1726 "From OPEN->DISORDER but with " <<
m_dupAckCount <<
" dup ACKs");
1828 if (ackNumber < oldHeadSequence)
1830 NS_LOG_DEBUG(
"Possibly received a stale ACK (ack number < head sequence)");
1832 if (packet->GetSize() > 0)
1838 if ((ackNumber > oldHeadSequence) && (ackNumber <
m_recover) &&
1842 for (
uint32_t i = 0; i < segAcked; i++)
1847 NS_LOG_DEBUG(
"Ack Number " << ackNumber <<
"is ACK of retransmitted packet.");
1894 NS_LOG_INFO(
"Update bytes in flight before processing the ACK.");
1899 ProcessAck(ackNumber, (bytesSacked > 0), currentDelivered, oldHeadSequence);
1906 (currentLost > previousLost) ? currentLost - previousLost : previousLost - currentLost;
1917 if (packet->GetSize() > 0)
1929 bool scoreboardUpdated,
1937 bool exitedFastRecovery =
false;
1962 NS_LOG_DEBUG(
"ACK of " << ackNumber <<
" SND.UNA=" << oldHeadSequence
1975 DupAck(currentDelivered);
1987 NS_LOG_DEBUG(
"Update nextTxSequence manually to " << ackNumber);
1990 else if (ackNumber == oldHeadSequence)
1995 else if (ackNumber > oldHeadSequence)
1999 bytesAcked = ackNumber - oldHeadSequence;
2040 NS_LOG_INFO(
"Partial ACK. Manually setting head as lost");
2067 <<
" and this is the first (RTO will be reset);"
2077 <<
" and this is NOT the first (RTO will not be reset)"
2098 "Some segment got dup-acked in CA_LOSS state: " <<
m_txBuffer->GetSacked());
2121 if (segsAcked >= oldDupAckCount)
2124 segsAcked - oldDupAckCount,
2134 NS_LOG_DEBUG(segsAcked <<
" segments acked in CA_DISORDER, ack of " << ackNumber
2135 <<
" exiting CA_DISORDER -> CA_OPEN");
2139 NS_LOG_DEBUG(segsAcked <<
" segments acked in CA_DISORDER, ack of " << ackNumber
2140 <<
" but still in CA_DISORDER");
2166 exitedFastRecovery =
true;
2169 NS_LOG_DEBUG(segsAcked <<
" segments acked in CA_RECOVER, ack of " << ackNumber
2170 <<
", exiting CA_RECOVERY -> CA_OPEN");
2185 NS_LOG_DEBUG(segsAcked <<
" segments acked in CA_LOSS, ack of" << ackNumber
2186 <<
", exiting CA_LOSS -> CA_OPEN");
2197 if (exitedFastRecovery)
2202 NS_LOG_DEBUG(
"Leaving Fast Recovery; BytesInFlight() = "
2213 <<
" segsAcked: " << segsAcked);
2354 <<
" received in SYN_SENT. Reset packet is sent.");
2374 if (tcpflags == 0 ||
2459 <<
" received. Reset packet is sent.");
2517 <<
" received. Reset packet is sent.");
2575 <<
" received. Reset packet is sent.");
2613 <<
" received. Reset packet is sent.");
2677 NS_LOG_LOGIC(
"TCP " <<
this <<
" calling NotifyNormalClose");
2692 NS_LOG_LOGIC(
"TcpSocketBase " <<
this <<
" scheduling LATO1");
2707 m_tcp->RemoveSocket(
this);
2709 NS_LOG_LOGIC(
this <<
" Cancelled ReTxTimeout event which was set to expire at "
2723 m_tcp->RemoveSocket(
this);
2725 NS_LOG_LOGIC(
this <<
" Cancelled ReTxTimeout event which was set to expire at "
2738 NS_LOG_WARN(
"Failed to send empty packet due to null endpoint");
2840 m_tcp->SendPacket(p,
2848 m_tcp->SendPacket(p,
2857 NS_LOG_LOGIC(
"Schedule retransmission timeout at time "
2889 m_tcp->RemoveSocket(
this);
2897 m_tcp->RemoveSocket(
this);
2908 if (!ipv4->GetRoutingProtocol())
2919 route = ipv4->GetRoutingProtocol()->RouteOutput(
Ptr<Packet>(), header, oif, errno_);
2938 if (!ipv6->GetRoutingProtocol())
2949 route = ipv6->GetRoutingProtocol()->RouteOutput(
Ptr<Packet>(), header, oif, errno_);
2991 m_tcp->AddSocket(
this);
3054 p->AddPacketTag(ipTosTag);
3063 p->AddPacketTag(ipTosTag);
3079 p->AddPacketTag(ipTclassTag);
3088 p->AddPacketTag(ipTclassTag);
3096 p->AddPacketTag(ipTtlTag);
3103 p->AddPacketTag(ipHopLimitTag);
3111 p->ReplacePacketTag(priorityTag);
3127 bool isRetransmission = outItem->
IsRetrans();
3211 NS_LOG_LOGIC(
this <<
" SendDataPacket Schedule ReTxTimeout at time "
3221 m_tcp->SendPacket(p,
3227 << sz <<
" with remaining data " << remainingData <<
" via TcpL4Protocol to "
3232 m_tcp->SendPacket(p,
3238 << sz <<
" with remaining data " << remainingData <<
" via TcpL4Protocol to "
3252 if (!isRetransmission)
3269 if (!isRetransmission)
3275 for (std::deque<RttHistory>::iterator i =
m_history.begin(); i !=
m_history.end(); ++i)
3299 "TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" <<
m_shutdownSend);
3311 while (availableWindow > 0)
3326 NS_LOG_INFO(
"FIN_WAIT and OPEN state; no data to transmit");
3337 if (!
m_txBuffer->NextSeg(&next, &nextHigh, enableRule3))
3339 NS_LOG_INFO(
"no valid seq to transmit, or no data available");
3349 if (availableData < availableWindow)
3356 if (availableWindow < m_tcb->m_segmentSize && availableData > availableWindow)
3358 NS_LOG_LOGIC(
"Preventing Silly Window Syndrome. Wait to send.");
3366 << next <<
", SFS: " <<
m_txBuffer->SizeFromSequence(next)
3367 <<
". Wait to send.");
3374 s = std::min(s, maxSizeToSend);
3396 <<
" highestRxAck " <<
m_txBuffer->HeadSequence() <<
" pd->Size "
3429 if (nPacketsSent > 0)
3440 NS_LOG_DEBUG(
"SendPendingData sent " << nPacketsSent <<
" segments");
3446 return nPacketsSent;
3463 NS_LOG_DEBUG(
"Returning calculated bytesInFlight: " << bytesInFlight);
3464 return bytesInFlight;
3478 return (inflight > win) ? 0 : win - inflight;
3496 "Unexpected sequence number values");
3515 <<
m_maxWinSize <<
"; possibly to avoid overflow of the 16-bit integer");
3517 NS_LOG_LOGIC(
"Returning AdvertisedWindowSize of " <<
static_cast<uint16_t
>(w));
3518 return static_cast<uint16_t
>(w);
3527 <<
" pkt size=" << p->GetSize());
3547 if (expectedSeq < m_tcb->m_rxBuffer->NextRxSequence())
3556 NS_LOG_WARN(
"Why TCP " <<
this <<
" got data after close notification?");
3596 <<
" -> ECN_SENDING_ECE");
3614 this <<
" scheduled delayed ACK at "
3641 NS_LOG_LOGIC(
"TcpSocketBase::EstimateRtt - RTT calculated from TcpOption::TS "
3642 "is zero, approximating to 1us.");
3666 m_rtt->Measurement(m);
3690 this <<
" Cancelled ReTxTimeout event which was set to expire at "
3699 <<
" to expire at time "
3705 NS_LOG_LOGIC(
"TCP " <<
this <<
" NewAck " << ack <<
" numberAck "
3719 this <<
" Cancelled ReTxTimeout event which was set to expire at "
3763 if (m_state <= ESTABLISHED && m_txBuffer->HeadSequence() >=
m_tcb->
m_highTxMark &&
3773 NS_LOG_INFO(
"No more data retries available. Dropping connection");
3843 <<
", restart from seqnum " <<
m_txBuffer->HeadSequence()
3847 "There are some bytes in flight after an RTO: " <<
BytesInFlight());
3852 "In flight (" <<
BytesInFlight() <<
") there is more than one segment ("
3883 NS_LOG_INFO(
"LAST-ACK: No more data retries available. Dropping connection");
3890 NS_LOG_LOGIC(
"TcpSocketBase " <<
this <<
" rescheduling LATO1");
3927 p->AddPacketTag(ipTosTag);
3931 p->AddPacketTag(ipTclassTag);
3937 m_tcp->SendPacket(p,
3945 m_tcp->SendPacket(p,
3969 res =
m_txBuffer->NextSeg(&seq, &seqHigh,
false);
3981 maxSizeToSend =
static_cast<uint32_t>(seqHigh - seq);
4185 return (!allowBroadcast);
4235 maxSpace = maxSpace >> 1;
4241 NS_LOG_WARN(
"Possible error; scale exceeds 14: " << scale);
4246 <<
static_cast<int>(scale) <<
" for buffer size "