|
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 |