22 #define NS_LOG_APPEND_CONTEXT \
23 if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
25 #include "ns3/abort.h"
27 #include "ns3/inet-socket-address.h"
28 #include "ns3/inet6-socket-address.h"
32 #include "ns3/ipv4-interface-address.h"
33 #include "ns3/ipv4-route.h"
34 #include "ns3/ipv6-route.h"
35 #include "ns3/ipv4-routing-protocol.h"
36 #include "ns3/ipv6-routing-protocol.h"
37 #include "ns3/simulation-singleton.h"
38 #include "ns3/simulator.h"
39 #include "ns3/packet.h"
40 #include "ns3/uinteger.h"
41 #include "ns3/double.h"
42 #include "ns3/trace-source-accessor.h"
43 #include "tcp-socket-base.h"
44 #include "tcp-l4-protocol.h"
45 #include "ipv4-end-point.h"
46 #include "ipv6-end-point.h"
47 #include "ipv6-l3-protocol.h"
48 #include "tcp-header.h"
49 #include "rtt-estimator.h"
57 NS_OBJECT_ENSURE_REGISTERED (TcpSocketBase);
60 TcpSocketBase::GetTypeId (
void)
62 static TypeId tid = TypeId (
"ns3::TcpSocketBase")
63 .SetParent<TcpSocket> ()
69 .AddAttribute (
"MaxSegLifetime",
70 "Maximum segment lifetime in seconds, use for TIME_WAIT state transition to CLOSED state",
72 MakeDoubleAccessor (&TcpSocketBase::m_msl),
73 MakeDoubleChecker<double> (0))
74 .AddAttribute (
"MaxWindowSize",
"Max size of advertised window",
75 UintegerValue (65535),
76 MakeUintegerAccessor (&TcpSocketBase::m_maxWinSize),
77 MakeUintegerChecker<uint16_t> ())
78 .AddAttribute (
"IcmpCallback",
"Callback invoked whenever an icmp error is received on this socket.",
80 MakeCallbackAccessor (&TcpSocketBase::m_icmpCallback),
81 MakeCallbackChecker ())
82 .AddAttribute (
"IcmpCallback6",
"Callback invoked whenever an icmpv6 error is received on this socket.",
84 MakeCallbackAccessor (&TcpSocketBase::m_icmpCallback6),
85 MakeCallbackChecker ())
86 .AddTraceSource (
"RTO",
87 "Retransmission timeout",
89 .AddTraceSource (
"RTT",
92 .AddTraceSource (
"NextTxSequence",
93 "Next sequence number to send (SND.NXT)",
95 .AddTraceSource (
"HighestSequence",
96 "Highest sequence number ever sent in socket's life time",
98 .AddTraceSource (
"State",
101 .AddTraceSource (
"RWND",
102 "Remote side's flow control window",
116 m_nextTxSequence (0),
122 m_errno (ERROR_NOTERROR),
123 m_closeNotified (false),
124 m_closeOnEmpty (false),
125 m_shutdownSend (false),
126 m_shutdownRecv (false),
138 m_dupAckCount (sock.m_dupAckCount),
140 m_delAckMaxCount (sock.m_delAckMaxCount),
141 m_noDelay (sock.m_noDelay),
142 m_cnRetries (sock.m_cnRetries),
143 m_delAckTimeout (sock.m_delAckTimeout),
144 m_persistTimeout (sock.m_persistTimeout),
145 m_cnTimeout (sock.m_cnTimeout),
148 m_node (sock.m_node),
151 m_nextTxSequence (sock.m_nextTxSequence),
152 m_highTxMark (sock.m_highTxMark),
153 m_rxBuffer (sock.m_rxBuffer),
154 m_txBuffer (sock.m_txBuffer),
155 m_state (sock.m_state),
156 m_errno (sock.m_errno),
157 m_closeNotified (sock.m_closeNotified),
158 m_closeOnEmpty (sock.m_closeOnEmpty),
159 m_shutdownSend (sock.m_shutdownSend),
160 m_shutdownRecv (sock.m_shutdownRecv),
161 m_connected (sock.m_connected),
163 m_segmentSize (sock.m_segmentSize),
164 m_maxWinSize (sock.m_maxWinSize),
172 m_rtt = sock.m_rtt->Copy ();
177 Callback<void, Ptr<Socket>, uint32_t> vPSUI = MakeNullCallback<void, Ptr<Socket>, uint32_t> ();
184 TcpSocketBase::~TcpSocketBase (
void)
199 m_tcp->DeAllocate (m_endPoint);
202 if (m_endPoint6 != 0)
206 m_tcp->DeAllocate (m_endPoint6);
235 enum Socket::SocketErrno
242 enum Socket::SocketType
245 return NS3_SOCK_STREAM;
261 m_endPoint = m_tcp->Allocate ();
264 m_errno = ERROR_ADDRNOTAVAIL;
267 m_tcp->m_sockets.push_back (
this);
275 m_endPoint6 = m_tcp->Allocate6 ();
276 if (0 == m_endPoint6)
278 m_errno = ERROR_ADDRNOTAVAIL;
281 m_tcp->m_sockets.push_back (
this);
294 uint16_t port = transport.
GetPort ();
297 m_endPoint = m_tcp->Allocate ();
301 m_endPoint = m_tcp->Allocate (port);
305 m_endPoint = m_tcp->Allocate (ipv4);
309 m_endPoint = m_tcp->Allocate (ipv4, port);
313 m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
321 uint16_t port = transport.
GetPort ();
324 m_endPoint6 = m_tcp->Allocate6 ();
328 m_endPoint6 = m_tcp->Allocate6 (port);
332 m_endPoint6 = m_tcp->Allocate6 (ipv6);
336 m_endPoint6 = m_tcp->Allocate6 (ipv6, port);
338 if (0 == m_endPoint6)
340 m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
346 m_errno = ERROR_INVAL;
349 m_tcp->m_sockets.push_back (
this);
350 NS_LOG_LOGIC (
"TcpSocketBase " <<
this <<
" got an endpoint: " << m_endPoint);
395 if (m_endPoint6 == 0)
408 if (SetupEndpoint6 () != 0)
415 m_errno = ERROR_INVAL;
421 m_cnCount = m_cnRetries;
433 if (m_state != CLOSED)
435 m_errno = ERROR_INVAL;
451 if (m_rxBuffer.Size () != 0)
453 NS_LOG_INFO (
"Socket " <<
this <<
" << unread rx data during close. Sending reset");
460 if (m_closeOnEmpty ==
false)
462 m_closeOnEmpty =
true;
463 NS_LOG_INFO (
"Socket " <<
this <<
" deferring close, state " << TcpStateName[m_state]);
477 m_shutdownSend =
true;
478 m_closeOnEmpty =
true;
481 if (m_txBuffer.
Size () == 0)
483 if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
488 if (m_state == ESTABLISHED)
491 m_state = FIN_WAIT_1;
509 m_shutdownRecv =
true;
519 NS_ABORT_MSG_IF (flags,
"use of flags is not supported in TcpSocketBase::Send()");
520 if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
523 if (!m_txBuffer.
Add (p))
525 m_errno = ERROR_MSGSIZE;
530 m_errno = ERROR_SHUTDOWN;
534 NS_LOG_LOGIC (
"txBufSize=" << m_txBuffer.
Size () <<
" state " << TcpStateName[m_state]);
535 if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
543 m_errno = ERROR_NOTCONN;
552 return Send (p, flags);
561 NS_ABORT_MSG_IF (flags,
"use of flags is not supported in TcpSocketBase::Recv()");
562 if (m_rxBuffer.Size () == 0 && m_state == CLOSE_WAIT)
564 return Create<Packet> ();
567 if (outPacket != 0 && outPacket->
GetSize () != 0)
572 tag.SetAddress (
InetSocketAddress (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ()));
574 else if (m_endPoint6 != 0)
590 if (packet != 0 && packet->
GetSize () != 0)
594 fromAddress =
InetSocketAddress (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ());
596 else if (m_endPoint6 != 0)
621 return m_rxBuffer.Available ();
631 address =
InetSocketAddress (m_endPoint->GetLocalAddress (), m_endPoint->GetLocalPort ());
633 else if (m_endPoint6 != 0)
652 if (m_endPoint == 0 && m_endPoint6 == 0)
656 NS_ASSERT ((m_endPoint == 0 && m_endPoint6 == 0));
659 NS_ASSERT ((m_endPoint != 0 && m_endPoint6 != 0));
664 m_endPoint->BindToNetDevice (netdevice);
676 if (m_endPoint == 0 && m_endPoint6 == 0)
686 if (m_endPoint6 != 0)
703 if (m_state == CLOSED || m_state == LISTEN || m_state == SYN_SENT || m_state == LAST_ACK || m_state == CLOSE_WAIT)
706 NS_LOG_INFO (TcpStateName[m_state] <<
" -> SYN_SENT");
709 else if (m_state != TIME_WAIT)
731 m_state = FIN_WAIT_1;
767 if (!m_closeNotified)
769 NotifyNormalClose ();
771 if (m_state != TIME_WAIT)
775 m_closeNotified =
true;
776 NS_LOG_INFO (TcpStateName[m_state] <<
" -> CLOSED");
787 if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
791 if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
794 return (m_rxBuffer.NextRxSequence () != head);
798 return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
808 DoForwardUp (packet, header, port, incomingInterface);
818 TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
819 uint8_t icmpType, uint8_t icmpCode,
822 NS_LOG_FUNCTION (
this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
823 (uint32_t)icmpCode << icmpInfo);
824 if (!m_icmpCallback.IsNull ())
826 m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
831 TcpSocketBase::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
832 uint8_t icmpType, uint8_t icmpCode,
835 NS_LOG_FUNCTION (
this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
836 (uint32_t)icmpCode << icmpInfo);
837 if (!m_icmpCallback6.IsNull ())
839 m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
851 m_endPoint->GetPeerAddress () <<
852 ":" << m_endPoint->GetPeerPort () <<
853 " to " << m_endPoint->GetLocalAddress () <<
854 ":" << m_endPoint->GetLocalPort ());
861 if (tcpHeader.GetFlags () & TcpHeader::ACK)
868 if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
870 NS_LOG_LOGIC (
this <<
" Leaving zerowindow persist state");
873 m_rWnd = tcpHeader.GetWindowSize ();
877 &&
OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->
GetSize ()))
880 " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
881 ":" << tcpHeader.GetSequenceNumber () + packet->
GetSize () <<
882 ") out of range [" << m_rxBuffer.NextRxSequence () <<
":" <<
883 m_rxBuffer.MaxRxSequence () <<
")");
885 if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
907 if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
956 if (tcpHeader.GetFlags () & TcpHeader::ACK)
963 if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
965 NS_LOG_LOGIC (
this <<
" Leaving zerowindow persist state");
968 m_rWnd = tcpHeader.GetWindowSize ();
972 &&
OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->
GetSize ()))
975 " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
976 ":" << tcpHeader.GetSequenceNumber () + packet->
GetSize () <<
977 ") out of range [" << m_rxBuffer.NextRxSequence () <<
":" <<
978 m_rxBuffer.MaxRxSequence () <<
")");
980 if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
1002 if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
1005 h.SetFlags (TcpHeader::RST);
1006 h.SetSequenceNumber (m_nextTxSequence);
1007 h.SetAckNumber (m_rxBuffer.NextRxSequence ());
1008 h.SetSourcePort (tcpHeader.GetDestinationPort ());
1009 h.SetDestinationPort (tcpHeader.GetSourcePort ());
1010 h.SetWindowSize (AdvertisedWindowSize ());
1045 uint8_t tcpflags = tcpHeader.
GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1048 if (tcpflags == TcpHeader::ACK)
1052 else if (tcpflags == TcpHeader::SYN)
1057 else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1060 else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1064 else if (tcpflags == 0)
1066 ReceivedData (packet, tcpHeader);
1067 if (m_rxBuffer.Finished ())
1074 if (tcpflags != TcpHeader::RST)
1076 NS_LOG_LOGIC (
"Illegal flag " << tcpflags <<
" received. Reset packet is sent.");
1090 if (0 == (tcpHeader.
GetFlags () & TcpHeader::ACK))
1102 DupAck (tcpHeader, ++m_dupAckCount);
1116 ReceivedData (packet, tcpHeader);
1128 uint8_t tcpflags = tcpHeader.
GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1132 if (tcpflags != TcpHeader::SYN)
1139 if (!NotifyConnectionRequest (fromAddress))
1147 packet, tcpHeader, fromAddress, toAddress);
1157 uint8_t tcpflags = tcpHeader.
GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1162 m_state = ESTABLISHED;
1165 m_delAckCount = m_delAckMaxCount;
1166 ReceivedData (packet, tcpHeader);
1169 else if (tcpflags == TcpHeader::ACK)
1172 else if (tcpflags == TcpHeader::SYN)
1176 m_cnCount = m_cnRetries;
1180 else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)
1184 m_state = ESTABLISHED;
1188 m_highTxMark = ++m_nextTxSequence;
1195 m_delAckCount = m_delAckMaxCount;
1199 if (tcpflags != TcpHeader::RST)
1201 NS_LOG_LOGIC (
"Illegal flag " << std::hex << static_cast<uint32_t> (tcpflags) << std::dec <<
" received. Reset packet is sent.");
1216 uint8_t tcpflags = tcpHeader.
GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1219 || (tcpflags == TcpHeader::ACK
1225 m_state = ESTABLISHED;
1228 m_highTxMark = ++m_nextTxSequence;
1235 else if (m_endPoint6)
1242 m_delAckCount = m_delAckMaxCount;
1244 NotifyNewConnectionCreated (
this, fromAddress);
1251 else if (tcpflags == TcpHeader::SYN)
1256 else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1262 m_highTxMark = ++m_nextTxSequence;
1269 else if (m_endPoint6)
1279 if (tcpflags != TcpHeader::RST)
1281 NS_LOG_LOGIC (
"Illegal flag " << tcpflags <<
" received. Reset packet is sent.");
1287 else if (m_endPoint6)
1305 uint8_t tcpflags = tcpHeader.
GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1307 if (packet->
GetSize () > 0 && tcpflags != TcpHeader::ACK)
1309 ReceivedData (packet, tcpHeader);
1311 else if (tcpflags == TcpHeader::ACK)
1314 if (m_state == FIN_WAIT_1 && m_txBuffer.
Size () == 0
1318 m_state = FIN_WAIT_2;
1321 else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1323 if (tcpflags & TcpHeader::ACK)
1329 else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1335 if (tcpflags != TcpHeader::RST)
1337 NS_LOG_LOGIC (
"Illegal flag " << tcpflags <<
" received. Reset packet is sent.");
1345 if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer.Finished ())
1347 if (m_state == FIN_WAIT_1)
1351 if (m_txBuffer.
Size () == 0
1357 else if (m_state == FIN_WAIT_2)
1362 if (!m_shutdownRecv)
1376 uint8_t tcpflags = tcpHeader.
GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1378 if (tcpflags == TcpHeader::ACK)
1388 if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1392 else if (tcpflags != TcpHeader::RST)
1394 NS_LOG_LOGIC (
"Illegal flag " << tcpflags <<
" received. Reset packet is sent.");
1408 uint8_t tcpflags = tcpHeader.
GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1412 ReceivedData (packet, tcpHeader);
1414 else if (tcpflags == TcpHeader::ACK)
1421 else if (tcpflags == TcpHeader::FIN)
1425 else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK) || tcpflags == TcpHeader::RST)
1431 NS_LOG_LOGIC (
"Illegal flag " << tcpflags <<
" received. Reset packet is sent.");
1455 ReceivedData (p, tcpHeader);
1458 if (!m_rxBuffer.Finished ())
1464 if (m_state == FIN_WAIT_1)
1478 NS_ASSERT (m_state == ESTABLISHED || m_state == SYN_RCVD);
1481 NS_LOG_INFO (TcpStateName[m_state] <<
" -> CLOSE_WAIT");
1482 m_state = CLOSE_WAIT;
1484 if (!m_closeNotified)
1492 NS_LOG_LOGIC (
"TCP " <<
this <<
" calling NotifyNormalClose");
1493 NotifyNormalClose ();
1494 m_closeNotified =
true;
1504 if (m_state == LAST_ACK)
1506 NS_LOG_LOGIC (
"TcpSocketBase " <<
this <<
" scheduling LATO1");
1508 &TcpSocketBase::LastAckTimeout,
this);
1521 std::vector<Ptr<TcpSocketBase> >::iterator it
1522 = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (),
this);
1523 if (it != m_tcp->m_sockets.end ())
1525 m_tcp->m_sockets.erase (it);
1528 NS_LOG_LOGIC (
this <<
" Cancelled ReTxTimeout event which was set to expire at " <<
1542 std::vector<Ptr<TcpSocketBase> >::iterator it
1543 = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (),
this);
1544 if (it != m_tcp->m_sockets.end ())
1546 m_tcp->m_sockets.erase (it);
1549 NS_LOG_LOGIC (
this <<
" Cancelled ReTxTimeout event which was set to expire at " <<
1569 if (IsManualIpTos ())
1572 ipTosTag.SetTos (GetIpTos ());
1576 if (IsManualIpv6Tclass ())
1579 ipTclassTag.SetTclass (GetIpv6Tclass ());
1583 if (IsManualIpTtl ())
1586 ipTtlTag.SetTtl (GetIpTtl ());
1590 if (IsManualIpv6HopLimit ())
1593 ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1597 if (m_endPoint == 0 && m_endPoint6 == 0)
1599 NS_LOG_WARN (
"Failed to send empty packet due to null endpoint");
1602 if (flags & TcpHeader::FIN)
1604 flags |= TcpHeader::ACK;
1606 else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING)
1611 header.SetFlags (flags);
1612 header.SetSequenceNumber (s);
1613 header.SetAckNumber (m_rxBuffer.NextRxSequence ());
1614 if (m_endPoint != 0)
1616 header.SetSourcePort (m_endPoint->GetLocalPort ());
1617 header.SetDestinationPort (m_endPoint->GetPeerPort ());
1622 header.SetDestinationPort (m_endPoint6->
GetPeerPort ());
1624 header.SetWindowSize (AdvertisedWindowSize ());
1626 m_rto = m_rtt->RetransmitTimeout ();
1627 bool hasSyn = flags & TcpHeader::SYN;
1628 bool hasFin = flags & TcpHeader::FIN;
1629 bool isAck = flags == TcpHeader::ACK;
1640 int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
1641 m_rto = m_cnTimeout * backoffCount;
1645 if (m_endPoint != 0)
1647 m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1648 m_endPoint->GetPeerAddress (), m_boundnetdevice);
1655 if (flags & TcpHeader::ACK)
1660 if (m_retxEvent.
IsExpired () && (hasSyn || hasFin) && !isAck )
1662 NS_LOG_LOGIC (
"Schedule retransmission timeout at time "
1675 NotifyErrorClose ();
1683 if (m_endPoint != 0)
1685 m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
1686 m_tcp->DeAllocate (m_endPoint);
1688 std::vector<Ptr<TcpSocketBase> >::iterator it
1689 = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (),
this);
1690 if (it != m_tcp->m_sockets.end ())
1692 m_tcp->m_sockets.erase (it);
1696 if (m_endPoint6 != 0)
1699 m_tcp->DeAllocate (m_endPoint6);
1701 std::vector<Ptr<TcpSocketBase> >::iterator it
1702 = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (),
this);
1703 if (it != m_tcp->m_sockets.end ())
1705 m_tcp->m_sockets.erase (it);
1718 if (ipv4->GetRoutingProtocol () == 0)
1726 Socket::SocketErrno errno_;
1729 route = ipv4->GetRoutingProtocol ()->RouteOutput (
Ptr<Packet> (), header, oif, errno_);
1732 NS_LOG_LOGIC (
"Route to " << m_endPoint->GetPeerAddress () <<
" does not exist");
1738 m_endPoint->SetLocalAddress (route->
GetSource ());
1743 TcpSocketBase::SetupEndpoint6 ()
1748 if (ipv6->GetRoutingProtocol () == 0)
1756 Socket::SocketErrno errno_;
1757 Ptr<Ipv6Route> route;
1758 Ptr<NetDevice> oif = m_boundnetdevice;
1759 route = ipv6->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1796 m_tcp->m_sockets.push_back (
this);
1801 m_cnCount = m_cnRetries;
1809 TcpSocketBase::ConnectionSucceeded ()
1812 NotifyConnectionSucceeded ();
1831 uint8_t flags = withAck ? TcpHeader::ACK : 0;
1840 if (IsManualIpTos ())
1843 ipTosTag.SetTos (GetIpTos ());
1847 if (IsManualIpv6Tclass ())
1850 ipTclassTag.SetTclass (GetIpv6Tclass ());
1854 if (IsManualIpTtl ())
1857 ipTtlTag.SetTtl (GetIpTtl ());
1861 if (IsManualIpv6HopLimit ())
1864 ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1868 if (m_closeOnEmpty && (remainingData == 0))
1870 flags |= TcpHeader::FIN;
1871 if (m_state == ESTABLISHED)
1874 m_state = FIN_WAIT_1;
1876 else if (m_state == CLOSE_WAIT)
1900 m_rto = m_rtt->RetransmitTimeout ();
1901 NS_LOG_LOGIC (
this <<
" SendDataPacket Schedule ReTxTimeout at time " <<
1906 NS_LOG_LOGIC (
"Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
1909 m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1910 m_endPoint->GetPeerAddress (), m_boundnetdevice);
1917 m_rtt->SentSeq (seq, sz);
1919 if (seq == m_nextTxSequence)
1924 m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
1935 if (m_txBuffer.
Size () == 0)
1940 if (m_endPoint == 0 && m_endPoint6 == 0)
1942 NS_LOG_INFO (
"TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
1945 uint32_t nPacketsSent = 0;
1948 uint32_t w = AvailableWindow ();
1949 NS_LOG_LOGIC (
"TcpSocketBase " <<
this <<
" SendPendingData" <<
1951 " rxwin " << m_rWnd <<
1952 " segsize " << m_segmentSize <<
1953 " nextTxSeq " << m_nextTxSequence <<
1955 " pd->Size " << m_txBuffer.
Size () <<
1958 if (w < m_segmentSize && m_txBuffer.
SizeFromSequence (m_nextTxSequence) > w)
1964 if (!m_noDelay && UnAckDataCount () > 0
1967 NS_LOG_LOGIC (
"Invoking Nagle's algorithm. Wait to send.");
1970 uint32_t s = std::min (w, m_segmentSize);
1973 m_nextTxSequence += sz;
1975 NS_LOG_LOGIC (
"SendPendingData sent " << nPacketsSent <<
" packets");
1976 return (nPacketsSent > 0);
1980 TcpSocketBase::UnAckDataCount ()
1983 return m_nextTxSequence.Get () - m_txBuffer.
HeadSequence ();
1987 TcpSocketBase::BytesInFlight ()
1990 return m_highTxMark.Get () - m_txBuffer.
HeadSequence ();
1994 TcpSocketBase::Window ()
2001 TcpSocketBase::AvailableWindow ()
2004 uint32_t unack = UnAckDataCount ();
2005 uint32_t win = Window ();
2006 NS_LOG_LOGIC (
"UnAckCount=" << unack <<
", Win=" << win);
2007 return (win < unack) ? 0 : (win - unack);
2011 TcpSocketBase::AdvertisedWindowSize ()
2013 return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), (uint32_t)m_maxWinSize);
2018 TcpSocketBase::ReceivedData (Ptr<Packet> p,
const TcpHeader& tcpHeader)
2021 NS_LOG_LOGIC (
"seq " << tcpHeader.GetSequenceNumber () <<
2022 " ack " << tcpHeader.GetAckNumber () <<
2023 " pkt size " << p->GetSize () );
2026 SequenceNumber32 expectedSeq = m_rxBuffer.NextRxSequence ();
2027 if (!m_rxBuffer.
Add (p, tcpHeader))
2033 if (m_rxBuffer.Size () > m_rxBuffer.Available () || m_rxBuffer.NextRxSequence () > expectedSeq + p->GetSize ())
2039 if (++m_delAckCount >= m_delAckMaxCount)
2048 &TcpSocketBase::DelAckTimeout,
this);
2053 if (expectedSeq < m_rxBuffer.NextRxSequence ())
2055 if (!m_shutdownRecv)
2060 if (m_closeNotified)
2062 NS_LOG_WARN (
"Why TCP " <<
this <<
" got data after close notification?");
2066 if (m_rxBuffer.Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) == 0)
2086 m_lastRtt = nextRtt;
2100 if (m_state != SYN_RCVD)
2102 NS_LOG_LOGIC (
this <<
" Cancelled ReTxTimeout event which was set to expire at " <<
2106 m_rto = m_rtt->RetransmitTimeout ();
2107 NS_LOG_LOGIC (
this <<
" Schedule ReTxTimeout at time " <<
2112 if (m_rWnd.Get () == 0 && m_persistEvent.
IsExpired ())
2114 NS_LOG_LOGIC (
this <<
"Enter zerowindow persist state");
2115 NS_LOG_LOGIC (
this <<
"Cancelled ReTxTimeout event which was set to expire at " <<
2121 m_persistEvent =
Simulator::Schedule (m_persistTimeout, &TcpSocketBase::PersistTimeout,
this);
2132 if (ack > m_nextTxSequence)
2134 m_nextTxSequence = ack;
2136 if (m_txBuffer.
Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING)
2138 NS_LOG_LOGIC (
this <<
" Cancelled ReTxTimeout event which was set to expire at " <<
2148 TcpSocketBase::ReTxTimeout ()
2153 if (m_state == CLOSED || m_state == TIME_WAIT)
2158 if (m_state <= ESTABLISHED && m_txBuffer.
HeadSequence () >= m_highTxMark)
2167 TcpSocketBase::DelAckTimeout (
void)
2174 TcpSocketBase::LastAckTimeout (
void)
2178 m_lastAckEvent.
Cancel ();
2179 if (m_state == LAST_ACK)
2183 if (!m_closeNotified)
2185 m_closeNotified =
true;
2193 TcpSocketBase::PersistTimeout ()
2196 m_persistTimeout = std::min (
Seconds (60), Time (2 * m_persistTimeout));
2198 TcpHeader tcpHeader;
2199 tcpHeader.SetSequenceNumber (m_nextTxSequence);
2200 tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ());
2201 tcpHeader.SetWindowSize (AdvertisedWindowSize ());
2202 if (m_endPoint != 0)
2204 tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
2205 tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
2209 tcpHeader.SetSourcePort (m_endPoint6->
GetLocalPort ());
2210 tcpHeader.SetDestinationPort (m_endPoint6->
GetPeerPort ());
2214 if (m_endPoint != 0)
2216 m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
2217 m_endPoint->GetPeerAddress (), m_boundnetdevice);
2227 m_persistEvent =
Simulator::Schedule (m_persistTimeout, &TcpSocketBase::PersistTimeout,
this);
2231 TcpSocketBase::Retransmit ()
2234 m_rtt->IncreaseMultiplier ();
2240 TcpSocketBase::DoRetransmit ()
2244 if (m_state == SYN_SENT)
2252 NotifyConnectionFailed ();
2257 if (m_txBuffer.
Size () == 0)
2259 if (m_state == FIN_WAIT_1 || m_state == CLOSING)
2269 m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer.
HeadSequence () + sz);
2274 TcpSocketBase::CancelAllTimers ()
2277 m_persistEvent.
Cancel ();
2279 m_lastAckEvent.
Cancel ();
2280 m_timewaitEvent.
Cancel ();
2287 NS_LOG_INFO (TcpStateName[m_state] <<
" -> TIME_WAIT");
2288 m_state = TIME_WAIT;
2305 TcpSocketBase::GetSndBufSize (
void)
const
2311 TcpSocketBase::SetRcvBufSize (uint32_t size)
2313 m_rxBuffer.SetMaxBufferSize (size);
2317 TcpSocketBase::GetRcvBufSize (
void)
const
2319 return m_rxBuffer.MaxBufferSize ();
2323 TcpSocketBase::SetSegSize (uint32_t size)
2325 m_segmentSize = size;
2330 TcpSocketBase::GetSegSize (
void)
const
2332 return m_segmentSize;
2336 TcpSocketBase::SetConnTimeout (Time timeout)
2338 m_cnTimeout = timeout;
2342 TcpSocketBase::GetConnTimeout (
void)
const
2348 TcpSocketBase::SetConnCount (uint32_t count)
2350 m_cnRetries = count;
2354 TcpSocketBase::GetConnCount (
void)
const
2360 TcpSocketBase::SetDelAckTimeout (Time timeout)
2362 m_delAckTimeout = timeout;
2366 TcpSocketBase::GetDelAckTimeout (
void)
const
2368 return m_delAckTimeout;
2372 TcpSocketBase::SetDelAckMaxCount (uint32_t count)
2374 m_delAckMaxCount = count;
2378 TcpSocketBase::GetDelAckMaxCount (
void)
const
2380 return m_delAckMaxCount;
2384 TcpSocketBase::SetTcpNoDelay (
bool noDelay)
2386 m_noDelay = noDelay;
2390 TcpSocketBase::GetTcpNoDelay (
void)
const
2396 TcpSocketBase::SetPersistTimeout (Time timeout)
2398 m_persistTimeout = timeout;
2402 TcpSocketBase::GetPersistTimeout (
void)
const
2404 return m_persistTimeout;
2411 return (!allowBroadcast);
static Time GetDelayLeft(const EventId &id)
Ipv6Address GetLocalAddress()
Get the local address.
uint32_t RemoveHeader(Header &header)
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
virtual int GetSockName(Address &address) const
Ipv4Address GetIpv4(void) const
static Ipv4Address GetAny(void)
uint32_t Size(void) const
virtual void EstimateRtt(const TcpHeader &)
#define NS_LOG_FUNCTION(parameters)
virtual void ReceivedAck(Ptr< Packet >, const TcpHeader &)
bool Add(Ptr< Packet > p, TcpHeader const &tcph)
uint32_t SendDataPacket(SequenceNumber32 seq, uint32_t maxSize, bool withAck)
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer...
void DiscardUpTo(const SequenceNumber32 &seq)
(abstract) base class of all TcpSockets
virtual int ShutdownRecv(void)
uint32_t SizeFromSequence(const SequenceNumber32 &seq) const
void ProcessClosing(Ptr< Packet >, const TcpHeader &)
SequenceNumber32 HeadSequence(void) const
Ptr< Packet > Recv(void)
Read a single packet from the socket.
IPv6 layer implementation.
void PeerClose(Ptr< Packet >, const TcpHeader &)
void AddPacketTag(const Tag &tag) const
virtual int Send(Ptr< Packet > p, uint32_t flags)
virtual bool GetAllowBroadcast(void) const
Query whether broadcast datagram transmissions are allowed.
#define NS_ASSERT(condition)
uint32_t MaxBufferSize(void) const
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
#define NS_LOG_COMPONENT_DEFINE(name)
virtual void AddOptions(TcpHeader &)
uint32_t GetSize(void) const
#define NS_LOG_FUNCTION_NOARGS()
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
void CompleteFork(Ptr< Packet >, const TcpHeader &, const Address &fromAddress, const Address &toAdress)
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer...
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if cond is false.
#define NS_FATAL_ERROR(msg)
fatal error handling
a polymophic address class
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
uint16_t GetPeerPort()
Get the peer port.
void SetLocalAddress(Ipv6Address addr)
Set the local address.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)
void ForwardUp(Ptr< Packet > packet, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
virtual enum SocketType GetSocketType(void) const
uint16_t GetLocalPort()
Get the local port.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
bool OutOfRange(SequenceNumber32 head, SequenceNumber32 tail) const
virtual bool SetAllowBroadcast(bool allowBroadcast)
Configure whether broadcast datagram transmissions are allowed.
This class implements a tag that carries an address of a packet across the socket interface...
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Ipv4Address GetSource(void) const
A base class for implementation of a stream socket using TCP.
#define NS_LOG_LOGIC(msg)
virtual void SetTcp(Ptr< TcpL4Protocol > tcp)
void SetMaxBufferSize(uint32_t n)
virtual int ShutdownSend(void)
uint32_t Available(void) const
void ProcessListen(Ptr< Packet >, const TcpHeader &, const Address &, const Address &)
Access to the Ipv4 forwarding table, interfaces, and configuration.
Ptr< Packet > Extract(uint32_t maxSize)
static InetSocketAddress ConvertFrom(const Address &address)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
void ProcessEstablished(Ptr< Packet >, const TcpHeader &)
virtual void SetNode(Ptr< Node > node)
void SetIcmpCallback(Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
Set the ICMP callback.
bool Add(Ptr< Packet > p)
virtual int Connect(const Address &address)
void ProcessSynRcvd(Ptr< Packet >, const TcpHeader &, const Address &, const Address &)
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
static Ipv4Address GetZero(void)
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv6Header, uint16_t > callback)
Set the reception callback.
void SetSendCallback(Callback< void, Ptr< Socket >, uint32_t > sendCb)
Notify application when space in transmit buffer is added.
virtual void SetRtt(Ptr< RttEstimator > rtt)
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
void SendEmptyPacket(uint8_t flags)
void SetDataSentCallback(Callback< void, Ptr< Socket >, uint32_t > dataSent)
Notify application when a packet has been sent from transport protocol (non-standard socket call) ...
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)
virtual void SetSndBufSize(uint32_t size)
void DeallocateEndPoint(void)
Describes an IPv6 address.
Ipv4 addresses are stored in host order in this class.
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Ipv6Address GetPeerAddress()
Get the peer address.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
static bool IsMatchingType(const Address &addr)
If the address match.
uint16_t GetPort(void) const
Get the port.
void ProcessSynSent(Ptr< Packet >, const TcpHeader &)
virtual enum SocketErrno GetErrno(void) const
void ProcessWait(Ptr< Packet >, const TcpHeader &)
virtual void ReadOptions(const TcpHeader &)
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
#define NS_LOG_ERROR(msg)
uint16_t GetPort(void) const
void ProcessLastAck(Ptr< Packet >, const TcpHeader &)
void SetConnectCallback(Callback< void, Ptr< Socket > > connectionSucceeded, Callback< void, Ptr< Socket > > connectionFailed)
Specify callbacks to allow the caller to determine if the connection succeeds of fails.
void CloseAndNotify(void)
virtual Ptr< Node > GetNode(void) const
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
virtual void DoForwardUp(Ptr< Packet > packet, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
virtual int Bind6(void)
Allocate a local IPv6 endpoint for this socket.
bool IsExpired(void) const
Ptr< T > GetObject(void) const
bool IsIpv4MappedAddress()
If the address is an IPv4-mapped address.
bool SendPendingData(bool withAck=false)
static bool IsMatchingType(const Address &address)
void SetPeer(Ipv6Address addr, uint16_t port)
Set the peer informations (address and port).
void SetHeadSequence(const SequenceNumber32 &seq)
virtual uint32_t GetTxAvailable(void) const
virtual uint32_t GetRxAvailable(void) const
Ptr< Packet > CopyFromSequence(uint32_t numBytes, const SequenceNumber32 &seq)