|
Lines 172-177
TcpSocketBase::GetTypeId (void)
|
Link Here
|
|---|
|
| 172 |
"TCP slow start threshold (bytes)", |
172 |
"TCP slow start threshold (bytes)", |
| 173 |
MakeTraceSourceAccessor (&TcpSocketBase::m_ssThTrace), |
173 |
MakeTraceSourceAccessor (&TcpSocketBase::m_ssThTrace), |
| 174 |
"ns3::TracedValueCallback::Uint32") |
174 |
"ns3::TracedValueCallback::Uint32") |
|
|
175 |
.AddTraceSource ("NextRxSequence", |
| 176 |
"Next sequence number expected (RCV.NXT)", |
| 177 |
MakeTraceSourceAccessor (&TcpSocketBase::m_rcvNXTTrace), |
| 178 |
"ns3::SequenceNumber32TracedValueCallback") |
| 179 |
.AddTraceSource ("UnackSequence", |
| 180 |
"First unacknowledged sequence number (SND.UNA)", |
| 181 |
MakeTraceSourceAccessor (&TcpSocketBase::m_sndUNATrace), |
| 182 |
"ns3::SequenceNumber32TracedValueCallback") |
| 175 |
.AddTraceSource ("Tx", |
183 |
.AddTraceSource ("Tx", |
| 176 |
"Send tcp packet to IP protocol", |
184 |
"Send tcp packet to IP protocol", |
| 177 |
MakeTraceSourceAccessor (&TcpSocketBase::m_txTrace), |
185 |
MakeTraceSourceAccessor (&TcpSocketBase::m_txTrace), |
|
Lines 308-313
TcpSocketBase::TcpSocketBase (void)
|
Link Here
|
|---|
|
| 308 |
ok = m_tcb->TraceConnectWithoutContext ("CongState", |
316 |
ok = m_tcb->TraceConnectWithoutContext ("CongState", |
| 309 |
MakeCallback (&TcpSocketBase::UpdateCongState, this)); |
317 |
MakeCallback (&TcpSocketBase::UpdateCongState, this)); |
| 310 |
NS_ASSERT (ok == true); |
318 |
NS_ASSERT (ok == true); |
|
|
319 |
|
| 320 |
ok = m_txBuffer->TraceConnectWithoutContext ("UnackSequence", |
| 321 |
MakeCallback (&TcpSocketBase::UpdateSNDUNA, this)); |
| 322 |
NS_ASSERT (ok == true); |
| 323 |
|
| 324 |
ok = m_rxBuffer->TraceConnectWithoutContext("NextRxSequence", |
| 325 |
MakeCallback (&TcpSocketBase::UpdateRCVNXT, this)); |
| 326 |
NS_ASSERT (ok == true); |
| 311 |
} |
327 |
} |
| 312 |
|
328 |
|
| 313 |
TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) |
329 |
TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) |
|
Lines 395-400
TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
|
Link Here
|
|---|
|
| 395 |
ok = m_tcb->TraceConnectWithoutContext ("CongState", |
411 |
ok = m_tcb->TraceConnectWithoutContext ("CongState", |
| 396 |
MakeCallback (&TcpSocketBase::UpdateCongState, this)); |
412 |
MakeCallback (&TcpSocketBase::UpdateCongState, this)); |
| 397 |
NS_ASSERT (ok == true); |
413 |
NS_ASSERT (ok == true); |
|
|
414 |
|
| 415 |
ok = m_txBuffer->TraceConnectWithoutContext ("UnackSequence", |
| 416 |
MakeCallback (&TcpSocketBase::UpdateSNDUNA, this)); |
| 417 |
NS_ASSERT (ok == true); |
| 418 |
|
| 419 |
ok = m_rxBuffer->TraceConnectWithoutContext("NextRxSequence", |
| 420 |
MakeCallback (&TcpSocketBase::UpdateRCVNXT, this)); |
| 421 |
NS_ASSERT (ok == true); |
| 398 |
} |
422 |
} |
| 399 |
|
423 |
|
| 400 |
TcpSocketBase::~TcpSocketBase (void) |
424 |
TcpSocketBase::~TcpSocketBase (void) |
|
Lines 1289-1300
TcpSocketBase::ProcessEstablished (Ptr<Packet> packet, const TcpHeader& tcpHeade
|
Link Here
|
|---|
|
| 1289 |
// Different flags are different events |
1313 |
// Different flags are different events |
| 1290 |
if (tcpflags == TcpHeader::ACK) |
1314 |
if (tcpflags == TcpHeader::ACK) |
| 1291 |
{ |
1315 |
{ |
| 1292 |
if (tcpHeader.GetAckNumber () < m_txBuffer->HeadSequence ()) |
1316 |
if (tcpHeader.GetAckNumber () < GetFirstUnackedSeq ()) |
| 1293 |
{ |
1317 |
{ |
| 1294 |
// Case 1: If the ACK is a duplicate (SEG.ACK < SND.UNA), it can be ignored. |
1318 |
// Case 1: If the ACK is a duplicate (SEG.ACK < SND.UNA), it can be ignored. |
| 1295 |
// Pag. 72 RFC 793 |
1319 |
// Pag. 72 RFC 793 |
| 1296 |
NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber () << |
1320 |
NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber () << |
| 1297 |
" SND.UNA = " << m_txBuffer->HeadSequence ()); |
1321 |
" SND.UNA = " << GetFirstUnackedSeq ()); |
| 1298 |
|
1322 |
|
| 1299 |
// TODO: RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] |
1323 |
// TODO: RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] |
| 1300 |
} |
1324 |
} |
|
Lines 1355-1361
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
|---|
|
| 1355 |
NS_ASSERT (0 != (tcpHeader.GetFlags () & TcpHeader::ACK)); |
1379 |
NS_ASSERT (0 != (tcpHeader.GetFlags () & TcpHeader::ACK)); |
| 1356 |
NS_ASSERT (m_tcb->m_segmentSize > 0); |
1380 |
NS_ASSERT (m_tcb->m_segmentSize > 0); |
| 1357 |
|
1381 |
|
| 1358 |
uint32_t bytesAcked = tcpHeader.GetAckNumber () - m_txBuffer->HeadSequence (); |
1382 |
uint32_t bytesAcked = tcpHeader.GetAckNumber () - GetFirstUnackedSeq (); |
| 1359 |
uint32_t segsAcked = bytesAcked / m_tcb->m_segmentSize; |
1383 |
uint32_t segsAcked = bytesAcked / m_tcb->m_segmentSize; |
| 1360 |
m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize; |
1384 |
m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize; |
| 1361 |
|
1385 |
|
|
Lines 1370-1379
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
|---|
|
| 1370 |
" bytes left: " << m_bytesAckedNotProcessed); |
1394 |
" bytes left: " << m_bytesAckedNotProcessed); |
| 1371 |
|
1395 |
|
| 1372 |
NS_LOG_DEBUG ("ACK of " << tcpHeader.GetAckNumber () << |
1396 |
NS_LOG_DEBUG ("ACK of " << tcpHeader.GetAckNumber () << |
| 1373 |
" SND.UNA=" << m_txBuffer->HeadSequence () << |
1397 |
" SND.UNA=" << GetFirstUnackedSeq () << |
| 1374 |
" SND.NXT=" << m_nextTxSequence); |
1398 |
" SND.NXT=" << m_nextTxSequence); |
| 1375 |
|
1399 |
|
| 1376 |
if (tcpHeader.GetAckNumber () == m_txBuffer->HeadSequence () && |
1400 |
if (tcpHeader.GetAckNumber () == GetFirstUnackedSeq () && |
| 1377 |
tcpHeader.GetAckNumber () < m_nextTxSequence && |
1401 |
tcpHeader.GetAckNumber () < m_nextTxSequence && |
| 1378 |
packet->GetSize () == 0) |
1402 |
packet->GetSize () == 0) |
| 1379 |
{ |
1403 |
{ |
|
Lines 1432-1443
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
|---|
|
| 1432 |
// Artificially call PktsAcked. After all, one segment has been ACKed. |
1456 |
// Artificially call PktsAcked. After all, one segment has been ACKed. |
| 1433 |
m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt); |
1457 |
m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt); |
| 1434 |
} |
1458 |
} |
| 1435 |
else if (tcpHeader.GetAckNumber () == m_txBuffer->HeadSequence () && |
1459 |
else if (tcpHeader.GetAckNumber () == GetFirstUnackedSeq () && |
| 1436 |
tcpHeader.GetAckNumber () == m_nextTxSequence) |
1460 |
tcpHeader.GetAckNumber () == m_nextTxSequence) |
| 1437 |
{ |
1461 |
{ |
| 1438 |
// Dupack, but the ACK is precisely equal to the nextTxSequence |
1462 |
// Dupack, but the ACK is precisely equal to the nextTxSequence |
| 1439 |
} |
1463 |
} |
| 1440 |
else if (tcpHeader.GetAckNumber () > m_txBuffer->HeadSequence ()) |
1464 |
else if (tcpHeader.GetAckNumber () > GetFirstUnackedSeq ()) |
| 1441 |
{ // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer |
1465 |
{ // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer |
| 1442 |
bool callCongestionControl = true; |
1466 |
bool callCongestionControl = true; |
| 1443 |
bool resetRTO = true; |
1467 |
bool resetRTO = true; |
|
Lines 1503-1509
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
|---|
|
| 1503 |
|
1527 |
|
| 1504 |
callCongestionControl = false; // No congestion control on cWnd show be invoked |
1528 |
callCongestionControl = false; // No congestion control on cWnd show be invoked |
| 1505 |
m_dupAckCount -= segsAcked; // Update the dupAckCount |
1529 |
m_dupAckCount -= segsAcked; // Update the dupAckCount |
| 1506 |
m_txBuffer->DiscardUpTo (tcpHeader.GetAckNumber ()); //Bug 1850: retransmit before newack |
1530 |
UpdateTxBuffer (tcpHeader.GetAckNumber ()); //Bug 1850: retransmit before newack |
| 1507 |
DoRetransmit (); // Assume the next seq is lost. Retransmit lost packet |
1531 |
DoRetransmit (); // Assume the next seq is lost. Retransmit lost packet |
| 1508 |
|
1532 |
|
| 1509 |
if (m_isFirstPartialAck) |
1533 |
if (m_isFirstPartialAck) |
|
Lines 2294-2300
TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool with
|
Link Here
|
|---|
|
| 2294 |
NS_LOG_FUNCTION (this << seq << maxSize << withAck); |
2318 |
NS_LOG_FUNCTION (this << seq << maxSize << withAck); |
| 2295 |
|
2319 |
|
| 2296 |
bool isRetransmission = false; |
2320 |
bool isRetransmission = false; |
| 2297 |
if ( seq == m_txBuffer->HeadSequence () ) |
2321 |
if ( seq == GetFirstUnackedSeq () ) |
| 2298 |
{ |
2322 |
{ |
| 2299 |
isRetransmission = true; |
2323 |
isRetransmission = true; |
| 2300 |
} |
2324 |
} |
|
Lines 2478-2484
TcpSocketBase::SendPendingData (bool withAck)
|
Link Here
|
|---|
|
| 2478 |
" rxwin " << m_rWnd << |
2502 |
" rxwin " << m_rWnd << |
| 2479 |
" segsize " << m_tcb->m_segmentSize << |
2503 |
" segsize " << m_tcb->m_segmentSize << |
| 2480 |
" nextTxSeq " << m_nextTxSequence << |
2504 |
" nextTxSeq " << m_nextTxSequence << |
| 2481 |
" highestRxAck " << m_txBuffer->HeadSequence () << |
2505 |
" highestRxAck " << GetFirstUnackedSeq () << |
| 2482 |
" pd->Size " << m_txBuffer->Size () << |
2506 |
" pd->Size " << m_txBuffer->Size () << |
| 2483 |
" pd->SFS " << m_txBuffer->SizeFromSequence (m_nextTxSequence)); |
2507 |
" pd->SFS " << m_txBuffer->SizeFromSequence (m_nextTxSequence)); |
| 2484 |
|
2508 |
|
|
|
| 2502 |
TcpSocketBase::UnAckDataCount () const |
2526 |
TcpSocketBase::UnAckDataCount () const |
| 2503 |
{ |
2527 |
{ |
| 2504 |
NS_LOG_FUNCTION (this); |
2528 |
NS_LOG_FUNCTION (this); |
| 2505 |
return m_nextTxSequence.Get () - m_txBuffer->HeadSequence (); |
2529 |
return m_nextTxSequence.Get () - GetFirstUnackedSeq (); |
| 2506 |
} |
2530 |
} |
| 2507 |
|
2531 |
|
| 2508 |
uint32_t |
2532 |
uint32_t |
| 2509 |
TcpSocketBase::BytesInFlight () const |
2533 |
TcpSocketBase::BytesInFlight () const |
| 2510 |
{ |
2534 |
{ |
| 2511 |
NS_LOG_FUNCTION (this); |
2535 |
NS_LOG_FUNCTION (this); |
| 2512 |
return m_highTxMark.Get () - m_txBuffer->HeadSequence (); |
2536 |
return m_highTxMark.Get () - GetFirstUnackedSeq (); |
| 2513 |
} |
2537 |
} |
| 2514 |
|
2538 |
|
| 2515 |
uint32_t |
2539 |
uint32_t |
|
Lines 2680-2687
TcpSocketBase::NewAck (SequenceNumber32 const& ack, bool resetRTO)
|
Link Here
|
|---|
|
| 2680 |
|
2704 |
|
| 2681 |
// Note the highest ACK and tell app to send more |
2705 |
// Note the highest ACK and tell app to send more |
| 2682 |
NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << |
2706 |
NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << |
| 2683 |
" numberAck " << (ack - m_txBuffer->HeadSequence ())); // Number bytes ack'ed |
2707 |
" numberAck " << (ack - GetFirstUnackedSeq ())); // Number bytes ack'ed |
| 2684 |
m_txBuffer->DiscardUpTo (ack); |
2708 |
UpdateTxBuffer (ack); |
| 2685 |
if (GetTxAvailable () > 0) |
2709 |
if (GetTxAvailable () > 0) |
| 2686 |
{ |
2710 |
{ |
| 2687 |
NotifySend (GetTxAvailable ()); |
2711 |
NotifySend (GetTxAvailable ()); |
|
Lines 2710-2716
TcpSocketBase::ReTxTimeout ()
|
Link Here
|
|---|
|
| 2710 |
return; |
2734 |
return; |
| 2711 |
} |
2735 |
} |
| 2712 |
// If all data are received (non-closing socket and nothing to send), just return |
2736 |
// If all data are received (non-closing socket and nothing to send), just return |
| 2713 |
if (m_state <= ESTABLISHED && m_txBuffer->HeadSequence () >= m_highTxMark) |
2737 |
if (m_state <= ESTABLISHED && GetFirstUnackedSeq () >= m_highTxMark) |
| 2714 |
{ |
2738 |
{ |
| 2715 |
return; |
2739 |
return; |
| 2716 |
} |
2740 |
} |
|
Lines 2791-2797
TcpSocketBase::Retransmit ()
|
Link Here
|
|---|
|
| 2791 |
// If erroneous timeout in closed/timed-wait state, just return |
2815 |
// If erroneous timeout in closed/timed-wait state, just return |
| 2792 |
if (m_state == CLOSED || m_state == TIME_WAIT) return; |
2816 |
if (m_state == CLOSED || m_state == TIME_WAIT) return; |
| 2793 |
// If all data are received (non-closing socket and nothing to send), just return |
2817 |
// If all data are received (non-closing socket and nothing to send), just return |
| 2794 |
if (m_state <= ESTABLISHED && m_txBuffer->HeadSequence () >= m_highTxMark) return; |
2818 |
if (m_state <= ESTABLISHED && GetFirstUnackedSeq () >= m_highTxMark) return; |
| 2795 |
|
2819 |
|
| 2796 |
/* |
2820 |
/* |
| 2797 |
* When a TCP sender detects segment loss using the retransmission timer |
2821 |
* When a TCP sender detects segment loss using the retransmission timer |
|
Lines 2824-2830
TcpSocketBase::Retransmit ()
|
Link Here
|
|---|
|
| 2824 |
* are not able to retransmit anything because of local congestion. |
2848 |
* are not able to retransmit anything because of local congestion. |
| 2825 |
*/ |
2849 |
*/ |
| 2826 |
|
2850 |
|
| 2827 |
m_nextTxSequence = m_txBuffer->HeadSequence (); // Restart from highest Ack |
2851 |
m_nextTxSequence = GetFirstUnackedSeq (); // Restart from highest Ack |
| 2828 |
m_dupAckCount = 0; |
2852 |
m_dupAckCount = 0; |
| 2829 |
|
2853 |
|
| 2830 |
if (m_tcb->m_congState != TcpSocketState::CA_LOSS) |
2854 |
if (m_tcb->m_congState != TcpSocketState::CA_LOSS) |
|
Lines 2880-2890
TcpSocketBase::DoRetransmit ()
|
Link Here
|
|---|
|
| 2880 |
} |
2904 |
} |
| 2881 |
|
2905 |
|
| 2882 |
// Retransmit a data packet: Call SendDataPacket |
2906 |
// Retransmit a data packet: Call SendDataPacket |
| 2883 |
uint32_t sz = SendDataPacket (m_txBuffer->HeadSequence (), m_tcb->m_segmentSize, true); |
2907 |
uint32_t sz = SendDataPacket (GetFirstUnackedSeq (), m_tcb->m_segmentSize, true); |
| 2884 |
// In case of RTO, advance m_nextTxSequence |
2908 |
// In case of RTO, advance m_nextTxSequence |
| 2885 |
m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer->HeadSequence () + sz); |
2909 |
m_nextTxSequence = std::max (m_nextTxSequence.Get (), GetFirstUnackedSeq () + sz); |
| 2886 |
|
2910 |
|
| 2887 |
NS_LOG_DEBUG ("retxing seq " << m_txBuffer->HeadSequence ()); |
2911 |
NS_LOG_DEBUG ("retxing seq " << GetFirstUnackedSeq ()); |
| 2888 |
} |
2912 |
} |
| 2889 |
|
2913 |
|
| 2890 |
void |
2914 |
void |
|
Lines 3310-3321
TcpSocketBase::UpdateCongState (TcpSocketState::TcpCongState_t oldValue,
|
Link Here
|
|---|
|
| 3310 |
} |
3334 |
} |
| 3311 |
|
3335 |
|
| 3312 |
void |
3336 |
void |
|
|
3337 |
TcpSocketBase::UpdateRCVNXT (SequenceNumber32 oldValue, SequenceNumber32 newValue) |
| 3338 |
{ |
| 3339 |
m_rcvNXTTrace (oldValue, newValue); |
| 3340 |
} |
| 3341 |
|
| 3342 |
void |
| 3343 |
TcpSocketBase::UpdateSNDUNA (SequenceNumber32 oldValue, SequenceNumber32 newValue) |
| 3344 |
{ |
| 3345 |
m_sndUNATrace (oldValue, newValue); |
| 3346 |
} |
| 3347 |
|
| 3348 |
void |
| 3313 |
TcpSocketBase::SetCongestionControlAlgorithm (Ptr<TcpCongestionOps> algo) |
3349 |
TcpSocketBase::SetCongestionControlAlgorithm (Ptr<TcpCongestionOps> algo) |
| 3314 |
{ |
3350 |
{ |
| 3315 |
NS_LOG_FUNCTION (this << algo); |
3351 |
NS_LOG_FUNCTION (this << algo); |
| 3316 |
m_congestionControl = algo; |
3352 |
m_congestionControl = algo; |
| 3317 |
} |
3353 |
} |
| 3318 |
|
3354 |
|
|
|
3355 |
void |
| 3356 |
TcpSocketBase::UpdateTxBuffer (SequenceNumber32 seq) |
| 3357 |
{ |
| 3358 |
NS_LOG_FUNCTION (this << seq); |
| 3359 |
m_txBuffer->DiscardUpTo (seq); |
| 3360 |
} |
| 3361 |
|
| 3362 |
SequenceNumber32 |
| 3363 |
TcpSocketBase::GetFirstUnackedSeq () const |
| 3364 |
{ |
| 3365 |
NS_LOG_FUNCTION (this); |
| 3366 |
return m_txBuffer->HeadSequence (); |
| 3367 |
} |
| 3368 |
|
| 3319 |
Ptr<TcpSocketBase> |
3369 |
Ptr<TcpSocketBase> |
| 3320 |
TcpSocketBase::Fork (void) |
3370 |
TcpSocketBase::Fork (void) |
| 3321 |
{ |
3371 |
{ |