Lines 180-190
TcpSocketBase::GetTypeId (void)
|
Link Here
|
---|
|
180 |
"Receive tcp packet from IP protocol", |
180 |
"Receive tcp packet from IP protocol", |
181 |
MakeTraceSourceAccessor (&TcpSocketBase::m_rxTrace), |
181 |
MakeTraceSourceAccessor (&TcpSocketBase::m_rxTrace), |
182 |
"ns3::TcpSocketBase::TcpTxRxTracedCallback") |
182 |
"ns3::TcpSocketBase::TcpTxRxTracedCallback") |
|
|
183 |
.AddTraceSource("UnackSequence", |
184 |
"First unacknowledged sequence number (SND.UNA)", |
185 |
MakeTraceSourceAccessor(&TcpSocketBase::m_firstTxUnack), |
186 |
"ns3::SequenceNumber32TracedValueCallback") |
187 |
|
183 |
; |
188 |
; |
184 |
return tid; |
189 |
return tid; |
185 |
} |
190 |
} |
186 |
|
191 |
|
187 |
// TcpSocketState |
192 |
TypeId |
|
|
193 |
TcpSocketBase::GetInstanceTypeId () const |
194 |
{ |
195 |
return TcpSocketBase::GetTypeId(); |
196 |
} |
197 |
|
198 |
|
188 |
TypeId |
199 |
TypeId |
189 |
TcpSocketState::GetTypeId (void) |
200 |
TcpSocketState::GetTypeId (void) |
190 |
{ |
201 |
{ |
Lines 332-337
TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
|
Link Here
|
---|
|
332 |
m_endPoint6 (0), |
343 |
m_endPoint6 (0), |
333 |
m_node (sock.m_node), |
344 |
m_node (sock.m_node), |
334 |
m_tcp (sock.m_tcp), |
345 |
m_tcp (sock.m_tcp), |
|
|
346 |
m_rtt (0), |
347 |
m_firstTxUnack (sock.m_firstTxUnack), |
335 |
m_nextTxSequence (sock.m_nextTxSequence), |
348 |
m_nextTxSequence (sock.m_nextTxSequence), |
336 |
m_highTxMark (sock.m_highTxMark), |
349 |
m_highTxMark (sock.m_highTxMark), |
337 |
m_state (sock.m_state), |
350 |
m_state (sock.m_state), |
Lines 469-474
TcpSocketBase::GetNode (void) const
|
Link Here
|
---|
|
469 |
return m_node; |
482 |
return m_node; |
470 |
} |
483 |
} |
471 |
|
484 |
|
|
|
485 |
SequenceNumber32 |
486 |
TcpSocketBase::FirstUnackedSeq () const |
487 |
{ |
488 |
return m_firstTxUnack.Get(); |
489 |
} |
490 |
|
472 |
/* Inherit from Socket class: Bind socket to an end-point in TcpL4Protocol */ |
491 |
/* Inherit from Socket class: Bind socket to an end-point in TcpL4Protocol */ |
473 |
int |
492 |
int |
474 |
TcpSocketBase::Bind (void) |
493 |
TcpSocketBase::Bind (void) |
Lines 577-590
TcpSocketBase::Bind (const Address &address)
|
Link Here
|
---|
|
577 |
void |
596 |
void |
578 |
TcpSocketBase::InitializeCwnd (void) |
597 |
TcpSocketBase::InitializeCwnd (void) |
579 |
{ |
598 |
{ |
580 |
m_tcb->m_cWnd = m_tcb->m_initialCWnd * m_tcb->m_segmentSize; |
599 |
m_tcb->m_cWnd = GetInitialCwnd() * GetSegSize(); |
581 |
m_tcb->m_ssThresh = m_tcb->m_initialSsThresh; |
600 |
m_tcb->m_ssThresh = GetInitialSSThresh(); |
582 |
} |
601 |
} |
583 |
|
602 |
|
584 |
void |
603 |
void |
585 |
TcpSocketBase::SetInitialSSThresh (uint32_t threshold) |
604 |
TcpSocketBase::SetInitialSSThresh (uint32_t threshold) |
586 |
{ |
605 |
{ |
587 |
NS_ABORT_MSG_UNLESS (m_state == CLOSED, |
606 |
NS_ABORT_MSG_UNLESS ( (m_state == CLOSED) || threshold == m_tcb->m_initialSsThresh, |
588 |
"TcpSocketBase::SetSSThresh() cannot change initial ssThresh after connection started."); |
607 |
"TcpSocketBase::SetSSThresh() cannot change initial ssThresh after connection started."); |
589 |
|
608 |
|
590 |
m_tcb->m_initialSsThresh = threshold; |
609 |
m_tcb->m_initialSsThresh = threshold; |
Lines 599-605
TcpSocketBase::GetInitialSSThresh (void) const
|
Link Here
|
---|
|
599 |
void |
618 |
void |
600 |
TcpSocketBase::SetInitialCwnd (uint32_t cwnd) |
619 |
TcpSocketBase::SetInitialCwnd (uint32_t cwnd) |
601 |
{ |
620 |
{ |
602 |
NS_ABORT_MSG_UNLESS (m_state == CLOSED, |
621 |
NS_ABORT_MSG_UNLESS ( (m_state == CLOSED) || cwnd == m_tcb->m_initialCWnd, |
603 |
"TcpSocketBase::SetInitialCwnd() cannot change initial cwnd after connection started."); |
622 |
"TcpSocketBase::SetInitialCwnd() cannot change initial cwnd after connection started."); |
604 |
|
623 |
|
605 |
m_tcb->m_initialCWnd = cwnd; |
624 |
m_tcb->m_initialCWnd = cwnd; |
Lines 643-649
TcpSocketBase::Connect (const Address & address)
|
Link Here
|
---|
|
643 |
|
662 |
|
644 |
// Get the appropriate local address and port number from the routing protocol and set up endpoint |
663 |
// Get the appropriate local address and port number from the routing protocol and set up endpoint |
645 |
if (SetupEndpoint () != 0) |
664 |
if (SetupEndpoint () != 0) |
646 |
{ // Route to destination does not exist |
665 |
{ |
|
|
666 |
NS_LOG_ERROR("Route to destination does not exist ?!"); |
647 |
return -1; |
667 |
return -1; |
648 |
} |
668 |
} |
649 |
} |
669 |
} |
Lines 1289-1300
TcpSocketBase::ProcessEstablished (Ptr<Packet> packet, const TcpHeader& tcpHeade
|
Link Here
|
---|
|
1289 |
// Different flags are different events |
1309 |
// Different flags are different events |
1290 |
if (tcpflags == TcpHeader::ACK) |
1310 |
if (tcpflags == TcpHeader::ACK) |
1291 |
{ |
1311 |
{ |
1292 |
if (tcpHeader.GetAckNumber () < m_txBuffer->HeadSequence ()) |
1312 |
if (tcpHeader.GetAckNumber () < FirstUnackedSeq ()) |
1293 |
{ |
1313 |
{ |
1294 |
// Case 1: If the ACK is a duplicate (SEG.ACK < SND.UNA), it can be ignored. |
1314 |
// Case 1: If the ACK is a duplicate (SEG.ACK < SND.UNA), it can be ignored. |
1295 |
// Pag. 72 RFC 793 |
1315 |
// Pag. 72 RFC 793 |
1296 |
NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber () << |
1316 |
NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber () << |
1297 |
" SND.UNA = " << m_txBuffer->HeadSequence ()); |
1317 |
" SND.UNA = " << FirstUnackedSeq ()); |
1298 |
|
1318 |
|
1299 |
// TODO: RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] |
1319 |
// TODO: RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] |
1300 |
} |
1320 |
} |
Lines 1346-1361
TcpSocketBase::ProcessEstablished (Ptr<Packet> packet, const TcpHeader& tcpHeade
|
Link Here
|
---|
|
1346 |
} |
1366 |
} |
1347 |
} |
1367 |
} |
1348 |
|
1368 |
|
|
|
1369 |
void |
1370 |
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, |
1371 |
const TcpHeader& tcpHeader |
1372 |
) |
1373 |
{ |
1374 |
// If there is any data piggybacked, store it into m_rxBuffer |
1375 |
NS_LOG_FUNCTION(this << packet << tcpHeader); |
1376 |
NS_ASSERT (0 != (tcpHeader.GetFlags () & TcpHeader::ACK)); |
1377 |
ReceivedAck(packet, tcpHeader.GetAckNumber()); |
1378 |
if (packet->GetSize () > 0) |
1379 |
{ |
1380 |
ReceivedData (packet, tcpHeader); |
1381 |
} |
1382 |
} |
1383 |
|
1349 |
/* Process the newly received ACK */ |
1384 |
/* Process the newly received ACK */ |
1350 |
void |
1385 |
void |
1351 |
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader) |
1386 |
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, SequenceNumber32 ack) |
1352 |
{ |
1387 |
{ |
1353 |
NS_LOG_FUNCTION (this << tcpHeader); |
1388 |
NS_LOG_FUNCTION (this << ack); |
1354 |
|
1389 |
|
1355 |
NS_ASSERT (0 != (tcpHeader.GetFlags () & TcpHeader::ACK)); |
|
|
1356 |
NS_ASSERT (m_tcb->m_segmentSize > 0); |
1390 |
NS_ASSERT (m_tcb->m_segmentSize > 0); |
1357 |
|
1391 |
|
1358 |
uint32_t bytesAcked = tcpHeader.GetAckNumber () - m_txBuffer->HeadSequence (); |
1392 |
uint32_t bytesAcked = ack - FirstUnackedSeq (); |
1359 |
uint32_t segsAcked = bytesAcked / m_tcb->m_segmentSize; |
1393 |
uint32_t segsAcked = bytesAcked / m_tcb->m_segmentSize; |
1360 |
m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize; |
1394 |
m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize; |
1361 |
|
1395 |
|
Lines 1369-1380
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
---|
|
1369 |
" Segments acked: " << segsAcked << |
1403 |
" Segments acked: " << segsAcked << |
1370 |
" bytes left: " << m_bytesAckedNotProcessed); |
1404 |
" bytes left: " << m_bytesAckedNotProcessed); |
1371 |
|
1405 |
|
1372 |
NS_LOG_DEBUG ("ACK of " << tcpHeader.GetAckNumber () << |
1406 |
NS_LOG_DEBUG ("ACK of " << ack << |
1373 |
" SND.UNA=" << m_txBuffer->HeadSequence () << |
1407 |
" SND.UNA=" << FirstUnackedSeq() << |
1374 |
" SND.NXT=" << m_nextTxSequence); |
1408 |
" SND.NXT=" << m_nextTxSequence); |
1375 |
|
1409 |
|
1376 |
if (tcpHeader.GetAckNumber () == m_txBuffer->HeadSequence () && |
1410 |
if (ack == FirstUnackedSeq() && |
1377 |
tcpHeader.GetAckNumber () < m_nextTxSequence && |
1411 |
ack < m_nextTxSequence && |
1378 |
packet->GetSize () == 0) |
1412 |
packet->GetSize () == 0) |
1379 |
{ |
1413 |
{ |
1380 |
// There is a DupAck |
1414 |
// There is a DupAck |
Lines 1432-1443
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
---|
|
1432 |
// Artificially call PktsAcked. After all, one segment has been ACKed. |
1466 |
// Artificially call PktsAcked. After all, one segment has been ACKed. |
1433 |
m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt); |
1467 |
m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt); |
1434 |
} |
1468 |
} |
1435 |
else if (tcpHeader.GetAckNumber () == m_txBuffer->HeadSequence () && |
1469 |
else if (ack == FirstUnackedSeq () && |
1436 |
tcpHeader.GetAckNumber () == m_nextTxSequence) |
1470 |
ack == m_nextTxSequence) |
1437 |
{ |
1471 |
{ |
1438 |
// Dupack, but the ACK is precisely equal to the nextTxSequence |
1472 |
// Dupack, but the ACK is precisely equal to the nextTxSequence |
1439 |
} |
1473 |
} |
1440 |
else if (tcpHeader.GetAckNumber () > m_txBuffer->HeadSequence ()) |
1474 |
else if (ack > FirstUnackedSeq ()) |
1441 |
{ // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer |
1475 |
{ // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer |
1442 |
bool callCongestionControl = true; |
1476 |
bool callCongestionControl = true; |
1443 |
bool resetRTO = true; |
1477 |
bool resetRTO = true; |
Lines 1475-1481
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
---|
|
1475 |
} |
1509 |
} |
1476 |
else if (m_tcb->m_congState == TcpSocketState::CA_RECOVERY) |
1510 |
else if (m_tcb->m_congState == TcpSocketState::CA_RECOVERY) |
1477 |
{ |
1511 |
{ |
1478 |
if (tcpHeader.GetAckNumber () < m_recover) |
1512 |
if (ack < m_recover) |
1479 |
{ |
1513 |
{ |
1480 |
/* Partial ACK. |
1514 |
/* Partial ACK. |
1481 |
* In case of partial ACK, retransmit the first unacknowledged |
1515 |
* In case of partial ACK, retransmit the first unacknowledged |
Lines 1503-1509
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
---|
|
1503 |
|
1537 |
|
1504 |
callCongestionControl = false; // No congestion control on cWnd show be invoked |
1538 |
callCongestionControl = false; // No congestion control on cWnd show be invoked |
1505 |
m_dupAckCount -= segsAcked; // Update the dupAckCount |
1539 |
m_dupAckCount -= segsAcked; // Update the dupAckCount |
1506 |
m_txBuffer->DiscardUpTo (tcpHeader.GetAckNumber ()); //Bug 1850: retransmit before newack |
1540 |
m_firstTxUnack = ack; |
|
|
1541 |
UpdateTxBuffer (); //Bug 1850: retransmit before newack |
1507 |
DoRetransmit (); // Assume the next seq is lost. Retransmit lost packet |
1542 |
DoRetransmit (); // Assume the next seq is lost. Retransmit lost packet |
1508 |
|
1543 |
|
1509 |
if (m_isFirstPartialAck) |
1544 |
if (m_isFirstPartialAck) |
Lines 1521-1532
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
---|
|
1521 |
*/ |
1556 |
*/ |
1522 |
m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt); |
1557 |
m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt); |
1523 |
|
1558 |
|
1524 |
NS_LOG_INFO ("Partial ACK for seq " << tcpHeader.GetAckNumber () << |
1559 |
NS_LOG_INFO ("Partial ACK for seq " << ack << |
1525 |
" in fast recovery: cwnd set to " << m_tcb->m_cWnd << |
1560 |
" in fast recovery: cwnd set to " << m_tcb->m_cWnd << |
1526 |
" recover seq: " << m_recover << |
1561 |
" recover seq: " << m_recover << |
1527 |
" dupAck count: " << m_dupAckCount); |
1562 |
" dupAck count: " << m_dupAckCount); |
1528 |
} |
1563 |
} |
1529 |
else if (tcpHeader.GetAckNumber () >= m_recover) |
1564 |
else if (ack >= m_recover) |
1530 |
{// Full ACK (RFC2582 sec.3 bullet #5 paragraph 2, option 1) |
1565 |
{// Full ACK (RFC2582 sec.3 bullet #5 paragraph 2, option 1) |
1531 |
m_tcb->m_cWnd = std::min (m_tcb->m_ssThresh.Get (), |
1566 |
m_tcb->m_cWnd = std::min (m_tcb->m_ssThresh.Get (), |
1532 |
BytesInFlight () + m_tcb->m_segmentSize); |
1567 |
BytesInFlight () + m_tcb->m_segmentSize); |
Lines 1539-1548
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
---|
|
1539 |
* except the (maybe) new ACKs which come from a new window |
1574 |
* except the (maybe) new ACKs which come from a new window |
1540 |
*/ |
1575 |
*/ |
1541 |
m_congestionControl->PktsAcked (m_tcb, segsAcked, m_lastRtt); |
1576 |
m_congestionControl->PktsAcked (m_tcb, segsAcked, m_lastRtt); |
1542 |
newSegsAcked = (tcpHeader.GetAckNumber () - m_recover) / m_tcb->m_segmentSize; |
1577 |
newSegsAcked = (ack - m_recover) / m_tcb->m_segmentSize; |
1543 |
m_tcb->m_congState = TcpSocketState::CA_OPEN; |
1578 |
m_tcb->m_congState = TcpSocketState::CA_OPEN; |
1544 |
|
1579 |
|
1545 |
NS_LOG_INFO ("Received full ACK for seq " << tcpHeader.GetAckNumber () << |
1580 |
NS_LOG_INFO ("Received full ACK for seq " << ack << |
1546 |
". Leaving fast recovery with cwnd set to " << m_tcb->m_cWnd); |
1581 |
". Leaving fast recovery with cwnd set to " << m_tcb->m_cWnd); |
1547 |
NS_LOG_DEBUG ("RECOVERY -> OPEN"); |
1582 |
NS_LOG_DEBUG ("RECOVERY -> OPEN"); |
1548 |
} |
1583 |
} |
Lines 1574-1580
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
---|
|
1574 |
NS_ASSERT (m_tcb->m_congState == TcpSocketState::CA_RECOVERY); |
1609 |
NS_ASSERT (m_tcb->m_congState == TcpSocketState::CA_RECOVERY); |
1575 |
} |
1610 |
} |
1576 |
|
1611 |
|
1577 |
NewAck (tcpHeader.GetAckNumber (), resetRTO); |
1612 |
NewAck (ack, resetRTO); |
1578 |
|
1613 |
|
1579 |
// Try to send more data |
1614 |
// Try to send more data |
1580 |
if (!m_sendPendingDataEvent.IsRunning ()) |
1615 |
if (!m_sendPendingDataEvent.IsRunning ()) |
Lines 1584-1595
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
---|
|
1584 |
this, m_connected); |
1619 |
this, m_connected); |
1585 |
} |
1620 |
} |
1586 |
} |
1621 |
} |
1587 |
|
|
|
1588 |
// If there is any data piggybacked, store it into m_rxBuffer |
1589 |
if (packet->GetSize () > 0) |
1590 |
{ |
1591 |
ReceivedData (packet, tcpHeader); |
1592 |
} |
1593 |
} |
1622 |
} |
1594 |
|
1623 |
|
1595 |
/* Received a packet upon LISTEN state. */ |
1624 |
/* Received a packet upon LISTEN state. */ |
Lines 1662-1667
TcpSocketBase::ProcessSynSent (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
---|
|
1662 |
m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1)); |
1691 |
m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1)); |
1663 |
m_highTxMark = ++m_nextTxSequence; |
1692 |
m_highTxMark = ++m_nextTxSequence; |
1664 |
m_txBuffer->SetHeadSequence (m_nextTxSequence); |
1693 |
m_txBuffer->SetHeadSequence (m_nextTxSequence); |
|
|
1694 |
m_firstTxUnack = m_nextTxSequence; |
1665 |
SendEmptyPacket (TcpHeader::ACK); |
1695 |
SendEmptyPacket (TcpHeader::ACK); |
1666 |
SendPendingData (m_connected); |
1696 |
SendPendingData (m_connected); |
1667 |
Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); |
1697 |
Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this); |
Lines 1703-1708
TcpSocketBase::ProcessSynRcvd (Ptr<Packet> packet, const TcpHeader& tcpHeader,
|
Link Here
|
---|
|
1703 |
m_retxEvent.Cancel (); |
1733 |
m_retxEvent.Cancel (); |
1704 |
m_highTxMark = ++m_nextTxSequence; |
1734 |
m_highTxMark = ++m_nextTxSequence; |
1705 |
m_txBuffer->SetHeadSequence (m_nextTxSequence); |
1735 |
m_txBuffer->SetHeadSequence (m_nextTxSequence); |
|
|
1736 |
m_firstTxUnack = m_nextTxSequence; |
1737 |
|
1738 |
|
1706 |
if (m_endPoint) |
1739 |
if (m_endPoint) |
1707 |
{ |
1740 |
{ |
1708 |
m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (), |
1741 |
m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (), |
Lines 1737-1742
TcpSocketBase::ProcessSynRcvd (Ptr<Packet> packet, const TcpHeader& tcpHeader,
|
Link Here
|
---|
|
1737 |
m_retxEvent.Cancel (); |
1770 |
m_retxEvent.Cancel (); |
1738 |
m_highTxMark = ++m_nextTxSequence; |
1771 |
m_highTxMark = ++m_nextTxSequence; |
1739 |
m_txBuffer->SetHeadSequence (m_nextTxSequence); |
1772 |
m_txBuffer->SetHeadSequence (m_nextTxSequence); |
|
|
1773 |
m_firstTxUnack = m_nextTxSequence; |
1740 |
if (m_endPoint) |
1774 |
if (m_endPoint) |
1741 |
{ |
1775 |
{ |
1742 |
m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (), |
1776 |
m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (), |
Lines 2294-2300
TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool with
|
Link Here
|
---|
|
2294 |
NS_LOG_FUNCTION (this << seq << maxSize << withAck); |
2328 |
NS_LOG_FUNCTION (this << seq << maxSize << withAck); |
2295 |
|
2329 |
|
2296 |
bool isRetransmission = false; |
2330 |
bool isRetransmission = false; |
2297 |
if ( seq == m_txBuffer->HeadSequence () ) |
2331 |
if ( seq == FirstUnackedSeq() ) |
2298 |
{ |
2332 |
{ |
2299 |
isRetransmission = true; |
2333 |
isRetransmission = true; |
2300 |
} |
2334 |
} |
Lines 2478-2491
TcpSocketBase::SendPendingData (bool withAck)
|
Link Here
|
---|
|
2478 |
" rxwin " << m_rWnd << |
2512 |
" rxwin " << m_rWnd << |
2479 |
" segsize " << m_tcb->m_segmentSize << |
2513 |
" segsize " << m_tcb->m_segmentSize << |
2480 |
" nextTxSeq " << m_nextTxSequence << |
2514 |
" nextTxSeq " << m_nextTxSequence << |
2481 |
" highestRxAck " << m_txBuffer->HeadSequence () << |
2515 |
" highestRxAck " << FirstUnackedSeq() << |
2482 |
" pd->Size " << m_txBuffer->Size () << |
2516 |
" TxBufferSize=" << m_txBuffer->Size () << |
2483 |
" pd->SFS " << m_txBuffer->SizeFromSequence (m_nextTxSequence)); |
2517 |
" pd->SizeFromSequence( " << m_nextTxSequence << ")=" |
2484 |
|
2518 |
<< m_txBuffer->SizeFromSequence (m_nextTxSequence)); |
2485 |
NS_LOG_DEBUG ("Window: " << w << |
|
|
2486 |
" cWnd: " << m_tcb->m_cWnd << |
2487 |
" unAck: " << UnAckDataCount ()); |
2488 |
|
2489 |
uint32_t s = std::min (w, m_tcb->m_segmentSize); // Send no more than window |
2519 |
uint32_t s = std::min (w, m_tcb->m_segmentSize); // Send no more than window |
2490 |
uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck); |
2520 |
uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck); |
2491 |
nPacketsSent++; // Count sent this loop |
2521 |
nPacketsSent++; // Count sent this loop |
|
2502 |
TcpSocketBase::UnAckDataCount () const |
2532 |
TcpSocketBase::UnAckDataCount () const |
2503 |
{ |
2533 |
{ |
2504 |
NS_LOG_FUNCTION (this); |
2534 |
NS_LOG_FUNCTION (this); |
2505 |
return m_nextTxSequence.Get () - m_txBuffer->HeadSequence (); |
2535 |
return m_nextTxSequence.Get () - FirstUnackedSeq(); |
2506 |
} |
2536 |
} |
2507 |
|
2537 |
|
2508 |
uint32_t |
2538 |
uint32_t |
2509 |
TcpSocketBase::BytesInFlight () const |
2539 |
TcpSocketBase::BytesInFlight () const |
2510 |
{ |
2540 |
{ |
2511 |
NS_LOG_FUNCTION (this); |
2541 |
NS_LOG_FUNCTION (this); |
2512 |
return m_highTxMark.Get () - m_txBuffer->HeadSequence (); |
2542 |
return m_highTxMark.Get () - FirstUnackedSeq(); |
2513 |
} |
2543 |
} |
2514 |
|
2544 |
|
2515 |
uint32_t |
2545 |
uint32_t |
Lines 2556-2562
TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader)
|
Link Here
|
---|
|
2556 |
|
2586 |
|
2557 |
// Put into Rx buffer |
2587 |
// Put into Rx buffer |
2558 |
SequenceNumber32 expectedSeq = m_rxBuffer->NextRxSequence (); |
2588 |
SequenceNumber32 expectedSeq = m_rxBuffer->NextRxSequence (); |
2559 |
if (!m_rxBuffer->Add (p, tcpHeader)) |
2589 |
if (!m_rxBuffer->Add (p, tcpHeader.GetSequenceNumber ())) |
2560 |
{ // Insert failed: No data or RX buffer full |
2590 |
{ // Insert failed: No data or RX buffer full |
2561 |
SendEmptyPacket (TcpHeader::ACK); |
2591 |
SendEmptyPacket (TcpHeader::ACK); |
2562 |
return; |
2592 |
return; |
Lines 2680-2694
TcpSocketBase::NewAck (SequenceNumber32 const& ack, bool resetRTO)
|
Link Here
|
---|
|
2680 |
|
2710 |
|
2681 |
// Note the highest ACK and tell app to send more |
2711 |
// Note the highest ACK and tell app to send more |
2682 |
NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << |
2712 |
NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << |
2683 |
" numberAck " << (ack - m_txBuffer->HeadSequence ())); // Number bytes ack'ed |
2713 |
" numberAck " << (ack - FirstUnackedSeq())); // Number bytes ack'ed |
2684 |
m_txBuffer->DiscardUpTo (ack); |
2714 |
|
|
|
2715 |
m_firstTxUnack = ack; |
2716 |
UpdateTxBuffer(); |
2717 |
|
2685 |
if (GetTxAvailable () > 0) |
2718 |
if (GetTxAvailable () > 0) |
2686 |
{ |
2719 |
{ |
2687 |
NotifySend (GetTxAvailable ()); |
2720 |
NotifySend (GetTxAvailable ()); |
2688 |
} |
2721 |
} |
2689 |
if (ack > m_nextTxSequence) |
2722 |
if (ack > m_nextTxSequence) |
2690 |
{ |
2723 |
{ |
2691 |
m_nextTxSequence = ack; // If advanced |
2724 |
m_nextTxSequence = m_firstTxUnack; // If advanced |
2692 |
} |
2725 |
} |
2693 |
if (m_txBuffer->Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING) |
2726 |
if (m_txBuffer->Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING) |
2694 |
{ // No retransmit timer if no data to retransmit |
2727 |
{ // No retransmit timer if no data to retransmit |
Lines 2698-2703
TcpSocketBase::NewAck (SequenceNumber32 const& ack, bool resetRTO)
|
Link Here
|
---|
|
2698 |
} |
2731 |
} |
2699 |
} |
2732 |
} |
2700 |
|
2733 |
|
|
|
2734 |
void |
2735 |
TcpSocketBase::UpdateTxBuffer() |
2736 |
{ |
2737 |
NS_LOG_FUNCTION(this); |
2738 |
m_txBuffer->DiscardUpTo (m_firstTxUnack); |
2739 |
} |
2740 |
|
2701 |
// Retransmit timeout |
2741 |
// Retransmit timeout |
2702 |
void |
2742 |
void |
2703 |
TcpSocketBase::ReTxTimeout () |
2743 |
TcpSocketBase::ReTxTimeout () |
Lines 2710-2716
TcpSocketBase::ReTxTimeout ()
|
Link Here
|
---|
|
2710 |
return; |
2750 |
return; |
2711 |
} |
2751 |
} |
2712 |
// If all data are received (non-closing socket and nothing to send), just return |
2752 |
// If all data are received (non-closing socket and nothing to send), just return |
2713 |
if (m_state <= ESTABLISHED && m_txBuffer->HeadSequence () >= m_highTxMark) |
2753 |
if (m_state <= ESTABLISHED && FirstUnackedSeq() >= m_highTxMark) |
2714 |
{ |
2754 |
{ |
2715 |
return; |
2755 |
return; |
2716 |
} |
2756 |
} |
Lines 2791-2797
TcpSocketBase::Retransmit ()
|
Link Here
|
---|
|
2791 |
// If erroneous timeout in closed/timed-wait state, just return |
2831 |
// If erroneous timeout in closed/timed-wait state, just return |
2792 |
if (m_state == CLOSED || m_state == TIME_WAIT) return; |
2832 |
if (m_state == CLOSED || m_state == TIME_WAIT) return; |
2793 |
// If all data are received (non-closing socket and nothing to send), just return |
2833 |
// 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; |
2834 |
if (m_state <= ESTABLISHED && FirstUnackedSeq() >= m_highTxMark) return; |
2795 |
|
2835 |
|
2796 |
/* |
2836 |
/* |
2797 |
* When a TCP sender detects segment loss using the retransmission timer |
2837 |
* 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. |
2864 |
* are not able to retransmit anything because of local congestion. |
2825 |
*/ |
2865 |
*/ |
2826 |
|
2866 |
|
2827 |
m_nextTxSequence = m_txBuffer->HeadSequence (); // Restart from highest Ack |
2867 |
m_nextTxSequence = FirstUnackedSeq (); // Restart from highest Ack |
2828 |
m_dupAckCount = 0; |
2868 |
m_dupAckCount = 0; |
2829 |
|
2869 |
|
2830 |
if (m_tcb->m_congState != TcpSocketState::CA_LOSS) |
2870 |
if (m_tcb->m_congState != TcpSocketState::CA_LOSS) |
Lines 2880-2890
TcpSocketBase::DoRetransmit ()
|
Link Here
|
---|
|
2880 |
} |
2920 |
} |
2881 |
|
2921 |
|
2882 |
// Retransmit a data packet: Call SendDataPacket |
2922 |
// Retransmit a data packet: Call SendDataPacket |
2883 |
uint32_t sz = SendDataPacket (m_txBuffer->HeadSequence (), m_tcb->m_segmentSize, true); |
2923 |
NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << FirstUnackedSeq ()); |
|
|
2924 |
uint32_t sz = SendDataPacket (FirstUnackedSeq(), GetSegSize(), true); |
2884 |
// In case of RTO, advance m_nextTxSequence |
2925 |
// In case of RTO, advance m_nextTxSequence |
2885 |
m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer->HeadSequence () + sz); |
2926 |
m_nextTxSequence = std::max (FirstUnackedSeq (), FirstUnackedSeq () + sz); |
2886 |
|
2927 |
// m_firstTxUnack = m_nextTxSequence; |
2887 |
NS_LOG_DEBUG ("retxing seq " << m_txBuffer->HeadSequence ()); |
2928 |
|
|
|
2929 |
NS_LOG_DEBUG ("retxing seq " << FirstUnackedSeq ()); |
2888 |
} |
2930 |
} |
2889 |
|
2931 |
|
2890 |
void |
2932 |
void |
Lines 2952-2961
TcpSocketBase::GetRcvBufSize (void) const
|
Link Here
|
---|
|
2952 |
void |
2994 |
void |
2953 |
TcpSocketBase::SetSegSize (uint32_t size) |
2995 |
TcpSocketBase::SetSegSize (uint32_t size) |
2954 |
{ |
2996 |
{ |
2955 |
NS_LOG_FUNCTION (this << size); |
2997 |
NS_ABORT_MSG_UNLESS ( (m_state == CLOSED) || (m_tcb->m_segmentSize == size), "Cannot change segment size dynamically."); |
2956 |
m_tcb->m_segmentSize = size; |
2998 |
m_tcb->m_segmentSize = size; |
2957 |
|
2999 |
|
2958 |
NS_ABORT_MSG_UNLESS (m_state == CLOSED, "Cannot change segment size dynamically."); |
|
|
2959 |
} |
3000 |
} |
2960 |
|
3001 |
|
2961 |
uint32_t |
3002 |
uint32_t |
Lines 3208-3214
TcpSocketBase::AddOptionTimestamp (TcpHeader& header)
|
Link Here
|
---|
|
3208 |
option->GetTimestamp () << " echo=" << m_timestampToEcho); |
3249 |
option->GetTimestamp () << " echo=" << m_timestampToEcho); |
3209 |
} |
3250 |
} |
3210 |
|
3251 |
|
3211 |
void TcpSocketBase::UpdateWindowSize (const TcpHeader &header) |
3252 |
bool |
|
|
3253 |
TcpSocketBase::UpdateWindowSize (const TcpHeader &header) |
3212 |
{ |
3254 |
{ |
3213 |
NS_LOG_FUNCTION (this << header); |
3255 |
NS_LOG_FUNCTION (this << header); |
3214 |
// If the connection is not established, the window size is always |
3256 |
// If the connection is not established, the window size is always |
Lines 3220-3226
void TcpSocketBase::UpdateWindowSize (const TcpHeader &header)
|
Link Here
|
---|
|
3220 |
{ |
3262 |
{ |
3221 |
m_rWnd = receivedWindow; |
3263 |
m_rWnd = receivedWindow; |
3222 |
NS_LOG_LOGIC ("State less than ESTABLISHED; updating rWnd to " << m_rWnd); |
3264 |
NS_LOG_LOGIC ("State less than ESTABLISHED; updating rWnd to " << m_rWnd); |
3223 |
return; |
3265 |
return true; |
3224 |
} |
3266 |
} |
3225 |
|
3267 |
|
3226 |
// Test for conditions that allow updating of the window |
3268 |
// Test for conditions that allow updating of the window |
Lines 3250-3255
void TcpSocketBase::UpdateWindowSize (const TcpHeader &header)
|
Link Here
|
---|
|
3250 |
m_rWnd = receivedWindow; |
3292 |
m_rWnd = receivedWindow; |
3251 |
NS_LOG_LOGIC ("updating rWnd to " << m_rWnd); |
3293 |
NS_LOG_LOGIC ("updating rWnd to " << m_rWnd); |
3252 |
} |
3294 |
} |
|
|
3295 |
return update; |
3253 |
} |
3296 |
} |
3254 |
|
3297 |
|
3255 |
void |
3298 |
void |