PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/internet/model/tcp-socket-base.cc

https://github.com/scarletttu/ns-3-codel-dev
C++ | 2293 lines | 1904 code | 157 blank | 232 comment | 491 complexity | 36f750ef4f764a953e53febbbcc2be36 MD5 | raw file
Possible License(s): GPL-2.0
  1. /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
  2. /*
  3. * Copyright (c) 2007 Georgia Tech Research Corporation
  4. * Copyright (c) 2010 Adrian Sai-wah Tam
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation;
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. * Author: Adrian Sai-wah Tam <adrian.sw.tam@gmail.com>
  20. */
  21. #define NS_LOG_APPEND_CONTEXT \
  22. if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
  23. #include <cstdlib>
  24. #include "ns3/abort.h"
  25. #include "ns3/node.h"
  26. #include "ns3/inet-socket-address.h"
  27. #include "ns3/inet6-socket-address.h"
  28. #include "ns3/log.h"
  29. #include "ns3/ipv4.h"
  30. #include "ns3/ipv6.h"
  31. #include "ns3/ipv4-interface-address.h"
  32. #include "ns3/ipv4-route.h"
  33. #include "ns3/ipv6-route.h"
  34. #include "ns3/ipv4-routing-protocol.h"
  35. #include "ns3/ipv6-routing-protocol.h"
  36. #include "ns3/simulation-singleton.h"
  37. #include "ns3/simulator.h"
  38. #include "ns3/packet.h"
  39. #include "ns3/uinteger.h"
  40. #include "ns3/double.h"
  41. #include "ns3/trace-source-accessor.h"
  42. #include "tcp-socket-base.h"
  43. #include "tcp-l4-protocol.h"
  44. #include "ipv4-end-point.h"
  45. #include "ipv6-end-point.h"
  46. #include "ipv6-l3-protocol.h"
  47. #include "tcp-header.h"
  48. #include "rtt-estimator.h"
  49. #include <algorithm>
  50. NS_LOG_COMPONENT_DEFINE ("TcpSocketBase");
  51. namespace ns3 {
  52. NS_OBJECT_ENSURE_REGISTERED (TcpSocketBase);
  53. TypeId
  54. TcpSocketBase::GetTypeId (void)
  55. {
  56. static TypeId tid = TypeId ("ns3::TcpSocketBase")
  57. .SetParent<TcpSocket> ()
  58. // .AddAttribute ("TcpState", "State in TCP state machine",
  59. // TypeId::ATTR_GET,
  60. // EnumValue (CLOSED),
  61. // MakeEnumAccessor (&TcpSocketBase::m_state),
  62. // MakeEnumChecker (CLOSED, "Closed"))
  63. .AddAttribute ("MaxSegLifetime",
  64. "Maximum segment lifetime in seconds, use for TIME_WAIT state transition to CLOSED state",
  65. DoubleValue (120), /* RFC793 says MSL=2 minutes*/
  66. MakeDoubleAccessor (&TcpSocketBase::m_msl),
  67. MakeDoubleChecker<double> (0))
  68. .AddAttribute ("MaxWindowSize", "Max size of advertised window",
  69. UintegerValue (65535),
  70. MakeUintegerAccessor (&TcpSocketBase::m_maxWinSize),
  71. MakeUintegerChecker<uint16_t> ())
  72. .AddTraceSource ("RTO",
  73. "Retransmission timeout",
  74. MakeTraceSourceAccessor (&TcpSocketBase::m_rto))
  75. .AddTraceSource ("RTT",
  76. "Last RTT sample",
  77. MakeTraceSourceAccessor (&TcpSocketBase::m_lastRtt))
  78. .AddTraceSource ("NextTxSequence",
  79. "Next sequence number to send (SND.NXT)",
  80. MakeTraceSourceAccessor (&TcpSocketBase::m_nextTxSequence))
  81. .AddTraceSource ("HighestSequence",
  82. "Highest sequence number ever sent in socket's life time",
  83. MakeTraceSourceAccessor (&TcpSocketBase::m_highTxMark))
  84. .AddTraceSource ("State",
  85. "TCP state",
  86. MakeTraceSourceAccessor (&TcpSocketBase::m_state))
  87. .AddTraceSource ("RWND",
  88. "Remote side's flow control window",
  89. MakeTraceSourceAccessor (&TcpSocketBase::m_rWnd))
  90. ;
  91. return tid;
  92. }
  93. TcpSocketBase::TcpSocketBase (void)
  94. : m_dupAckCount (0),
  95. m_delAckCount (0),
  96. m_endPoint (0),
  97. m_endPoint6 (0),
  98. m_node (0),
  99. m_tcp (0),
  100. m_rtt (0),
  101. m_nextTxSequence (std::rand ()),
  102. // Change this for non-zero initial sequence number
  103. m_highTxMark (0),
  104. m_rxBuffer (0),
  105. m_txBuffer (0),
  106. m_state (CLOSED),
  107. m_errno (ERROR_NOTERROR),
  108. m_closeNotified (false),
  109. m_closeOnEmpty (false),
  110. m_shutdownSend (false),
  111. m_shutdownRecv (false),
  112. m_connected (false),
  113. m_segmentSize (0),
  114. // For attribute initialization consistency (quiet valgrind)
  115. m_rWnd (0)
  116. {
  117. NS_LOG_FUNCTION (this);
  118. }
  119. TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
  120. : TcpSocket (sock),
  121. //copy object::m_tid and socket::callbacks
  122. m_dupAckCount (sock.m_dupAckCount),
  123. m_delAckCount (0),
  124. m_delAckMaxCount (sock.m_delAckMaxCount),
  125. m_noDelay (sock.m_noDelay),
  126. m_cnRetries (sock.m_cnRetries),
  127. m_delAckTimeout (sock.m_delAckTimeout),
  128. m_persistTimeout (sock.m_persistTimeout),
  129. m_cnTimeout (sock.m_cnTimeout),
  130. m_endPoint (0),
  131. m_endPoint6 (0),
  132. m_node (sock.m_node),
  133. m_tcp (sock.m_tcp),
  134. m_rtt (0),
  135. m_nextTxSequence (sock.m_nextTxSequence),
  136. m_highTxMark (sock.m_highTxMark),
  137. m_rxBuffer (sock.m_rxBuffer),
  138. m_txBuffer (sock.m_txBuffer),
  139. m_state (sock.m_state),
  140. m_errno (sock.m_errno),
  141. m_closeNotified (sock.m_closeNotified),
  142. m_closeOnEmpty (sock.m_closeOnEmpty),
  143. m_shutdownSend (sock.m_shutdownSend),
  144. m_shutdownRecv (sock.m_shutdownRecv),
  145. m_connected (sock.m_connected),
  146. m_msl (sock.m_msl),
  147. m_segmentSize (sock.m_segmentSize),
  148. m_maxWinSize (sock.m_maxWinSize),
  149. m_rWnd (sock.m_rWnd)
  150. {
  151. NS_LOG_FUNCTION (this);
  152. NS_LOG_LOGIC ("Invoked the copy constructor");
  153. // Copy the rtt estimator if it is set
  154. if (sock.m_rtt)
  155. {
  156. m_rtt = sock.m_rtt->Copy ();
  157. }
  158. // Reset all callbacks to null
  159. Callback<void, Ptr< Socket > > vPS = MakeNullCallback<void, Ptr<Socket> > ();
  160. Callback<void, Ptr<Socket>, const Address &> vPSA = MakeNullCallback<void, Ptr<Socket>, const Address &> ();
  161. Callback<void, Ptr<Socket>, uint32_t> vPSUI = MakeNullCallback<void, Ptr<Socket>, uint32_t> ();
  162. SetConnectCallback (vPS, vPS);
  163. SetDataSentCallback (vPSUI);
  164. SetSendCallback (vPSUI);
  165. SetRecvCallback (vPS);
  166. }
  167. TcpSocketBase::~TcpSocketBase (void)
  168. {
  169. NS_LOG_FUNCTION (this);
  170. m_node = 0;
  171. if (m_endPoint != 0)
  172. {
  173. NS_ASSERT (m_tcp != 0);
  174. /*
  175. * Upon Bind, an Ipv4Endpoint is allocated and set to m_endPoint, and
  176. * DestroyCallback is set to TcpSocketBase::Destroy. If we called
  177. * m_tcp->DeAllocate, it wil destroy its Ipv4EndpointDemux::DeAllocate,
  178. * which in turn destroys my m_endPoint, and in turn invokes
  179. * TcpSocketBase::Destroy to nullify m_node, m_endPoint, and m_tcp.
  180. */
  181. NS_ASSERT (m_endPoint != 0);
  182. m_tcp->DeAllocate (m_endPoint);
  183. NS_ASSERT (m_endPoint == 0);
  184. }
  185. if (m_endPoint6 != 0)
  186. {
  187. NS_ASSERT (m_tcp != 0);
  188. NS_ASSERT (m_endPoint6 != 0);
  189. m_tcp->DeAllocate (m_endPoint6);
  190. NS_ASSERT (m_endPoint6 == 0);
  191. }
  192. m_tcp = 0;
  193. CancelAllTimers ();
  194. }
  195. /** Associate a node with this TCP socket */
  196. void
  197. TcpSocketBase::SetNode (Ptr<Node> node)
  198. {
  199. m_node = node;
  200. }
  201. /** Associate the L4 protocol (e.g. mux/demux) with this socket */
  202. void
  203. TcpSocketBase::SetTcp (Ptr<TcpL4Protocol> tcp)
  204. {
  205. m_tcp = tcp;
  206. }
  207. /** Set an RTT estimator with this socket */
  208. void
  209. TcpSocketBase::SetRtt (Ptr<RttEstimator> rtt)
  210. {
  211. m_rtt = rtt;
  212. }
  213. /** Inherit from Socket class: Returns error code */
  214. enum Socket::SocketErrno
  215. TcpSocketBase::GetErrno (void) const
  216. {
  217. return m_errno;
  218. }
  219. /** Inherit from Socket class: Returns socket type, NS3_SOCK_STREAM */
  220. enum Socket::SocketType
  221. TcpSocketBase::GetSocketType (void) const
  222. {
  223. return NS3_SOCK_STREAM;
  224. }
  225. /** Inherit from Socket class: Returns associated node */
  226. Ptr<Node>
  227. TcpSocketBase::GetNode (void) const
  228. {
  229. NS_LOG_FUNCTION_NOARGS ();
  230. return m_node;
  231. }
  232. /** Inherit from Socket class: Bind socket to an end-point in TcpL4Protocol */
  233. int
  234. TcpSocketBase::Bind (void)
  235. {
  236. NS_LOG_FUNCTION (this);
  237. m_endPoint = m_tcp->Allocate ();
  238. if (0 == m_endPoint)
  239. {
  240. m_errno = ERROR_ADDRNOTAVAIL;
  241. return -1;
  242. }
  243. m_tcp->m_sockets.push_back (this);
  244. return SetupCallback ();
  245. }
  246. int
  247. TcpSocketBase::Bind6 (void)
  248. {
  249. NS_LOG_FUNCTION (this);
  250. m_endPoint6 = m_tcp->Allocate6 ();
  251. if (0 == m_endPoint6)
  252. {
  253. m_errno = ERROR_ADDRNOTAVAIL;
  254. return -1;
  255. }
  256. m_tcp->m_sockets.push_back (this);
  257. return SetupCallback ();
  258. }
  259. /** Inherit from Socket class: Bind socket (with specific address) to an end-point in TcpL4Protocol */
  260. int
  261. TcpSocketBase::Bind (const Address &address)
  262. {
  263. NS_LOG_FUNCTION (this << address);
  264. if (InetSocketAddress::IsMatchingType (address))
  265. {
  266. InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
  267. Ipv4Address ipv4 = transport.GetIpv4 ();
  268. uint16_t port = transport.GetPort ();
  269. if (ipv4 == Ipv4Address::GetAny () && port == 0)
  270. {
  271. m_endPoint = m_tcp->Allocate ();
  272. }
  273. else if (ipv4 == Ipv4Address::GetAny () && port != 0)
  274. {
  275. m_endPoint = m_tcp->Allocate (port);
  276. }
  277. else if (ipv4 != Ipv4Address::GetAny () && port == 0)
  278. {
  279. m_endPoint = m_tcp->Allocate (ipv4);
  280. }
  281. else if (ipv4 != Ipv4Address::GetAny () && port != 0)
  282. {
  283. m_endPoint = m_tcp->Allocate (ipv4, port);
  284. }
  285. if (0 == m_endPoint)
  286. {
  287. m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
  288. return -1;
  289. }
  290. }
  291. else if (Inet6SocketAddress::IsMatchingType (address))
  292. {
  293. Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
  294. Ipv6Address ipv6 = transport.GetIpv6 ();
  295. uint16_t port = transport.GetPort ();
  296. if (ipv6 == Ipv6Address::GetAny () && port == 0)
  297. {
  298. m_endPoint6 = m_tcp->Allocate6 ();
  299. }
  300. else if (ipv6 == Ipv6Address::GetAny () && port != 0)
  301. {
  302. m_endPoint6 = m_tcp->Allocate6 (port);
  303. }
  304. else if (ipv6 != Ipv6Address::GetAny () && port == 0)
  305. {
  306. m_endPoint6 = m_tcp->Allocate6 (ipv6);
  307. }
  308. else if (ipv6 != Ipv6Address::GetAny () && port != 0)
  309. {
  310. m_endPoint6 = m_tcp->Allocate6 (ipv6, port);
  311. }
  312. if (0 == m_endPoint6)
  313. {
  314. m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
  315. return -1;
  316. }
  317. }
  318. else
  319. {
  320. m_errno = ERROR_INVAL;
  321. return -1;
  322. }
  323. m_tcp->m_sockets.push_back (this);
  324. NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint);
  325. return SetupCallback ();
  326. }
  327. /** Inherit from Socket class: Initiate connection to a remote address:port */
  328. int
  329. TcpSocketBase::Connect (const Address & address)
  330. {
  331. NS_LOG_FUNCTION (this << address);
  332. // If haven't do so, Bind() this socket first
  333. if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0)
  334. {
  335. if (m_endPoint == 0)
  336. {
  337. if (Bind () == -1)
  338. {
  339. NS_ASSERT (m_endPoint == 0);
  340. return -1; // Bind() failed
  341. }
  342. NS_ASSERT (m_endPoint != 0);
  343. }
  344. InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
  345. m_endPoint->SetPeer (transport.GetIpv4 (), transport.GetPort ());
  346. m_endPoint6 = 0;
  347. // Get the appropriate local address and port number from the routing protocol and set up endpoint
  348. if (SetupEndpoint () != 0)
  349. { // Route to destination does not exist
  350. return -1;
  351. }
  352. }
  353. else if (Inet6SocketAddress::IsMatchingType (address) && m_endPoint == 0)
  354. {
  355. // If we are operating on a v4-mapped address, translate the address to
  356. // a v4 address and re-call this function
  357. Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
  358. Ipv6Address v6Addr = transport.GetIpv6 ();
  359. if (v6Addr.IsIpv4MappedAddress () == true)
  360. {
  361. Ipv4Address v4Addr = v6Addr.GetIpv4MappedAddress ();
  362. return Connect (InetSocketAddress (v4Addr, transport.GetPort ()));
  363. }
  364. if (m_endPoint6 == 0)
  365. {
  366. if (Bind6 () == -1)
  367. {
  368. NS_ASSERT (m_endPoint6 == 0);
  369. return -1; // Bind() failed
  370. }
  371. NS_ASSERT (m_endPoint6 != 0);
  372. }
  373. m_endPoint6->SetPeer (v6Addr, transport.GetPort ());
  374. m_endPoint = 0;
  375. // Get the appropriate local address and port number from the routing protocol and set up endpoint
  376. if (SetupEndpoint6 () != 0)
  377. { // Route to destination does not exist
  378. return -1;
  379. }
  380. }
  381. else
  382. {
  383. m_errno = ERROR_INVAL;
  384. return -1;
  385. }
  386. // Re-initialize parameters in case this socket is being reused after CLOSE
  387. m_rtt->Reset ();
  388. m_cnCount = m_cnRetries;
  389. // DoConnect() will do state-checking and send a SYN packet
  390. return DoConnect ();
  391. }
  392. /** Inherit from Socket class: Listen on the endpoint for an incoming connection */
  393. int
  394. TcpSocketBase::Listen (void)
  395. {
  396. NS_LOG_FUNCTION (this);
  397. // Linux quits EINVAL if we're not in CLOSED state, so match what they do
  398. if (m_state != CLOSED)
  399. {
  400. m_errno = ERROR_INVAL;
  401. return -1;
  402. }
  403. // In other cases, set the state to LISTEN and done
  404. NS_LOG_INFO ("CLOSED -> LISTEN");
  405. m_state = LISTEN;
  406. return 0;
  407. }
  408. /** Inherit from Socket class: Kill this socket and signal the peer (if any) */
  409. int
  410. TcpSocketBase::Close (void)
  411. {
  412. NS_LOG_FUNCTION (this);
  413. // First we check to see if there is any unread rx data
  414. // Bug number 426 claims we should send reset in this case.
  415. if (m_rxBuffer.Size () != 0)
  416. {
  417. SendRST ();
  418. return 0;
  419. }
  420. if (m_txBuffer.SizeFromSequence (m_nextTxSequence) > 0)
  421. { // App close with pending data must wait until all data transmitted
  422. if (m_closeOnEmpty == false)
  423. {
  424. m_closeOnEmpty = true;
  425. NS_LOG_INFO ("Socket " << this << " deferring close, state " << TcpStateName[m_state]);
  426. }
  427. return 0;
  428. }
  429. return DoClose ();
  430. }
  431. /** Inherit from Socket class: Signal a termination of send */
  432. int
  433. TcpSocketBase::ShutdownSend (void)
  434. {
  435. NS_LOG_FUNCTION (this);
  436. m_shutdownSend = true;
  437. return 0;
  438. }
  439. /** Inherit from Socket class: Signal a termination of receive */
  440. int
  441. TcpSocketBase::ShutdownRecv (void)
  442. {
  443. NS_LOG_FUNCTION (this);
  444. m_shutdownRecv = true;
  445. return 0;
  446. }
  447. /** Inherit from Socket class: Send a packet. Parameter flags is not used.
  448. Packet has no TCP header. Invoked by upper-layer application */
  449. int
  450. TcpSocketBase::Send (Ptr<Packet> p, uint32_t flags)
  451. {
  452. NS_LOG_FUNCTION (this << p);
  453. NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Send()");
  454. if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
  455. {
  456. // Store the packet into Tx buffer
  457. if (!m_txBuffer.Add (p))
  458. { // TxBuffer overflow, send failed
  459. m_errno = ERROR_MSGSIZE;
  460. return -1;
  461. }
  462. // Submit the data to lower layers
  463. NS_LOG_LOGIC ("txBufSize=" << m_txBuffer.Size () << " state " << TcpStateName[m_state]);
  464. if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
  465. { // Try to send the data out
  466. SendPendingData (m_connected);
  467. }
  468. return p->GetSize ();
  469. }
  470. else
  471. { // Connection not established yet
  472. m_errno = ERROR_NOTCONN;
  473. return -1; // Send failure
  474. }
  475. }
  476. /** Inherit from Socket class: In TcpSocketBase, it is same as Send() call */
  477. int
  478. TcpSocketBase::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
  479. {
  480. return Send (p, flags); // SendTo() and Send() are the same
  481. }
  482. /** Inherit from Socket class: Return data to upper-layer application. Parameter flags
  483. is not used. Data is returned as a packet of size no larger than maxSize */
  484. Ptr<Packet>
  485. TcpSocketBase::Recv (uint32_t maxSize, uint32_t flags)
  486. {
  487. NS_LOG_FUNCTION (this);
  488. NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Recv()");
  489. if (m_rxBuffer.Size () == 0 && m_state == CLOSE_WAIT)
  490. {
  491. return Create<Packet> (); // Send EOF on connection close
  492. }
  493. Ptr<Packet> outPacket = m_rxBuffer.Extract (maxSize);
  494. if (outPacket != 0 && outPacket->GetSize () != 0)
  495. {
  496. SocketAddressTag tag;
  497. if (m_endPoint != 0)
  498. {
  499. tag.SetAddress (InetSocketAddress (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ()));
  500. }
  501. else if (m_endPoint6 != 0)
  502. {
  503. tag.SetAddress (Inet6SocketAddress (m_endPoint6->GetPeerAddress (), m_endPoint6->GetPeerPort ()));
  504. }
  505. outPacket->AddPacketTag (tag);
  506. }
  507. return outPacket;
  508. }
  509. /** Inherit from Socket class: Recv and return the remote's address */
  510. Ptr<Packet>
  511. TcpSocketBase::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
  512. {
  513. NS_LOG_FUNCTION (this << maxSize << flags);
  514. Ptr<Packet> packet = Recv (maxSize, flags);
  515. // Null packet means no data to read, and an empty packet indicates EOF
  516. if (packet != 0 && packet->GetSize () != 0)
  517. {
  518. if (m_endPoint != 0)
  519. {
  520. fromAddress = InetSocketAddress (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ());
  521. }
  522. else if (m_endPoint6 != 0)
  523. {
  524. fromAddress = Inet6SocketAddress (m_endPoint6->GetPeerAddress (), m_endPoint6->GetPeerPort ());
  525. }
  526. else
  527. {
  528. fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
  529. }
  530. }
  531. return packet;
  532. }
  533. /** Inherit from Socket class: Get the max number of bytes an app can send */
  534. uint32_t
  535. TcpSocketBase::GetTxAvailable (void) const
  536. {
  537. NS_LOG_FUNCTION (this);
  538. return m_txBuffer.Available ();
  539. }
  540. /** Inherit from Socket class: Get the max number of bytes an app can read */
  541. uint32_t
  542. TcpSocketBase::GetRxAvailable (void) const
  543. {
  544. NS_LOG_FUNCTION (this);
  545. return m_rxBuffer.Available ();
  546. }
  547. /** Inherit from Socket class: Return local address:port */
  548. int
  549. TcpSocketBase::GetSockName (Address &address) const
  550. {
  551. NS_LOG_FUNCTION (this);
  552. if (m_endPoint != 0)
  553. {
  554. address = InetSocketAddress (m_endPoint->GetLocalAddress (), m_endPoint->GetLocalPort ());
  555. }
  556. else if (m_endPoint6 != 0)
  557. {
  558. address = Inet6SocketAddress (m_endPoint6->GetLocalAddress (), m_endPoint6->GetLocalPort ());
  559. }
  560. else
  561. { // It is possible to call this method on a socket without a name
  562. // in which case, behavior is unspecified
  563. // Should this return an InetSocketAddress or an Inet6SocketAddress?
  564. address = InetSocketAddress (Ipv4Address::GetZero (), 0);
  565. }
  566. return 0;
  567. }
  568. /** Inherit from Socket class: Bind this socket to the specified NetDevice */
  569. void
  570. TcpSocketBase::BindToNetDevice (Ptr<NetDevice> netdevice)
  571. {
  572. NS_LOG_FUNCTION (netdevice);
  573. Socket::BindToNetDevice (netdevice); // Includes sanity check
  574. if (m_endPoint == 0 && m_endPoint6 == 0)
  575. {
  576. if (Bind () == -1)
  577. {
  578. NS_ASSERT ((m_endPoint == 0 && m_endPoint6 == 0));
  579. return;
  580. }
  581. NS_ASSERT ((m_endPoint != 0 && m_endPoint6 != 0));
  582. }
  583. if (m_endPoint != 0)
  584. {
  585. m_endPoint->BindToNetDevice (netdevice);
  586. }
  587. // No BindToNetDevice() for Ipv6EndPoint
  588. return;
  589. }
  590. /** Clean up after Bind. Set up callback functions in the end-point. */
  591. int
  592. TcpSocketBase::SetupCallback (void)
  593. {
  594. NS_LOG_FUNCTION (this);
  595. if (m_endPoint == 0 && m_endPoint6 == 0)
  596. {
  597. return -1;
  598. }
  599. if (m_endPoint != 0)
  600. {
  601. m_endPoint->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp, Ptr<TcpSocketBase> (this)));
  602. m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy, Ptr<TcpSocketBase> (this)));
  603. }
  604. if (m_endPoint6 != 0)
  605. {
  606. m_endPoint6->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp6, Ptr<TcpSocketBase> (this)));
  607. m_endPoint6->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy6, Ptr<TcpSocketBase> (this)));
  608. }
  609. return 0;
  610. }
  611. /** Perform the real connection tasks: Send SYN if allowed, RST if invalid */
  612. int
  613. TcpSocketBase::DoConnect (void)
  614. {
  615. NS_LOG_FUNCTION (this);
  616. // A new connection is allowed only if this socket does not have a connection
  617. if (m_state == CLOSED || m_state == LISTEN || m_state == SYN_SENT || m_state == LAST_ACK || m_state == CLOSE_WAIT)
  618. { // send a SYN packet and change state into SYN_SENT
  619. SendEmptyPacket (TcpHeader::SYN);
  620. NS_LOG_INFO (TcpStateName[m_state] << " -> SYN_SENT");
  621. m_state = SYN_SENT;
  622. }
  623. else if (m_state != TIME_WAIT)
  624. { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, an connection
  625. // exists. We send RST, tear down everything, and close this socket.
  626. SendRST ();
  627. CloseAndNotify ();
  628. }
  629. return 0;
  630. }
  631. /** Do the action to close the socket. Usually send a packet with appropriate
  632. flags depended on the current m_state. */
  633. int
  634. TcpSocketBase::DoClose (void)
  635. {
  636. NS_LOG_FUNCTION (this);
  637. switch (m_state)
  638. {
  639. case SYN_RCVD:
  640. case ESTABLISHED:
  641. // send FIN to close the peer
  642. SendEmptyPacket (TcpHeader::FIN);
  643. NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
  644. m_state = FIN_WAIT_1;
  645. break;
  646. case CLOSE_WAIT:
  647. // send FIN+ACK to close the peer
  648. SendEmptyPacket (TcpHeader::FIN | TcpHeader::ACK);
  649. NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
  650. m_state = LAST_ACK;
  651. break;
  652. case SYN_SENT:
  653. case CLOSING:
  654. // Send RST if application closes in SYN_SENT and CLOSING
  655. SendRST ();
  656. CloseAndNotify ();
  657. break;
  658. case LISTEN:
  659. case LAST_ACK:
  660. // In these three states, move to CLOSED and tear down the end point
  661. CloseAndNotify ();
  662. break;
  663. case CLOSED:
  664. case FIN_WAIT_1:
  665. case FIN_WAIT_2:
  666. case TIME_WAIT:
  667. default: /* mute compiler */
  668. // Do nothing in these four states
  669. break;
  670. }
  671. return 0;
  672. }
  673. /** Peacefully close the socket by notifying the upper layer and deallocate end point */
  674. void
  675. TcpSocketBase::CloseAndNotify (void)
  676. {
  677. NS_LOG_FUNCTION (this);
  678. if (!m_closeNotified)
  679. {
  680. NotifyNormalClose ();
  681. }
  682. if (m_state != TIME_WAIT)
  683. {
  684. DeallocateEndPoint ();
  685. }
  686. m_closeNotified = true;
  687. NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
  688. CancelAllTimers ();
  689. m_state = CLOSED;
  690. }
  691. /** Tell if a sequence number range is out side the range that my rx buffer can
  692. accpet */
  693. bool
  694. TcpSocketBase::OutOfRange (SequenceNumber32 head, SequenceNumber32 tail) const
  695. {
  696. if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
  697. { // Rx buffer in these states are not initialized.
  698. return false;
  699. }
  700. if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
  701. { // In LAST_ACK and CLOSING states, it only wait for an ACK and the
  702. // sequence number must equals to m_rxBuffer.NextRxSequence ()
  703. return (m_rxBuffer.NextRxSequence () != head);
  704. }
  705. // In all other cases, check if the sequence number is in range
  706. return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
  707. }
  708. /** Function called by the L3 protocol when it received a packet to pass on to
  709. the TCP. This function is registered as the "RxCallback" function in
  710. SetupCallback(), which invoked by Bind(), and CompleteFork() */
  711. void
  712. TcpSocketBase::ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port,
  713. Ptr<Ipv4Interface> incomingInterface)
  714. {
  715. DoForwardUp (packet, header, port, incomingInterface);
  716. }
  717. void
  718. TcpSocketBase::ForwardUp6 (Ptr<Packet> packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port)
  719. {
  720. DoForwardUp (packet, saddr, daddr, port);
  721. }
  722. /** The real function to handle the incoming packet from lower layers. This is
  723. wrapped by ForwardUp() so that this function can be overloaded by daughter
  724. classes. */
  725. void
  726. TcpSocketBase::DoForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port,
  727. Ptr<Ipv4Interface> incomingInterface)
  728. {
  729. NS_LOG_LOGIC ("Socket " << this << " forward up " <<
  730. m_endPoint->GetPeerAddress () <<
  731. ":" << m_endPoint->GetPeerPort () <<
  732. " to " << m_endPoint->GetLocalAddress () <<
  733. ":" << m_endPoint->GetLocalPort ());
  734. Address fromAddress = InetSocketAddress (header.GetSource (), port);
  735. Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->GetLocalPort ());
  736. // Peel off TCP header and do validity checking
  737. TcpHeader tcpHeader;
  738. packet->RemoveHeader (tcpHeader);
  739. if (tcpHeader.GetFlags () & TcpHeader::ACK)
  740. {
  741. EstimateRtt (tcpHeader);
  742. }
  743. ReadOptions (tcpHeader);
  744. // Update Rx window size, i.e. the flow control window
  745. if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
  746. { // persist probes end
  747. NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
  748. m_persistEvent.Cancel ();
  749. }
  750. m_rWnd = tcpHeader.GetWindowSize ();
  751. // Discard fully out of range data packets
  752. if (packet->GetSize ()
  753. && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
  754. {
  755. NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
  756. " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
  757. ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
  758. ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
  759. m_rxBuffer.MaxRxSequence () << ")");
  760. // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
  761. if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
  762. {
  763. SendEmptyPacket (TcpHeader::ACK);
  764. }
  765. return;
  766. }
  767. // TCP state machine code in different process functions
  768. // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
  769. switch (m_state)
  770. {
  771. case ESTABLISHED:
  772. ProcessEstablished (packet, tcpHeader);
  773. break;
  774. case LISTEN:
  775. ProcessListen (packet, tcpHeader, fromAddress, toAddress);
  776. break;
  777. case TIME_WAIT:
  778. // Do nothing
  779. break;
  780. case CLOSED:
  781. // Send RST if the incoming packet is not a RST
  782. if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
  783. { // Since m_endPoint is not configured yet, we cannot use SendRST here
  784. TcpHeader h;
  785. h.SetFlags (TcpHeader::RST);
  786. h.SetSequenceNumber (m_nextTxSequence);
  787. h.SetAckNumber (m_rxBuffer.NextRxSequence ());
  788. h.SetSourcePort (tcpHeader.GetDestinationPort ());
  789. h.SetDestinationPort (tcpHeader.GetSourcePort ());
  790. h.SetWindowSize (AdvertisedWindowSize ());
  791. AddOptions (h);
  792. m_tcp->SendPacket (Create<Packet> (), h, header.GetDestination (), header.GetSource (), m_boundnetdevice);
  793. }
  794. break;
  795. case SYN_SENT:
  796. ProcessSynSent (packet, tcpHeader);
  797. break;
  798. case SYN_RCVD:
  799. ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
  800. break;
  801. case FIN_WAIT_1:
  802. case FIN_WAIT_2:
  803. case CLOSE_WAIT:
  804. ProcessWait (packet, tcpHeader);
  805. break;
  806. case CLOSING:
  807. ProcessClosing (packet, tcpHeader);
  808. break;
  809. case LAST_ACK:
  810. ProcessLastAck (packet, tcpHeader);
  811. break;
  812. default: // mute compiler
  813. break;
  814. }
  815. }
  816. void
  817. TcpSocketBase::DoForwardUp (Ptr<Packet> packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port)
  818. {
  819. NS_LOG_LOGIC ("Socket " << this << " forward up " <<
  820. m_endPoint6->GetPeerAddress () <<
  821. ":" << m_endPoint6->GetPeerPort () <<
  822. " to " << m_endPoint6->GetLocalAddress () <<
  823. ":" << m_endPoint6->GetLocalPort ());
  824. Address fromAddress = Inet6SocketAddress (saddr, port);
  825. Address toAddress = Inet6SocketAddress (daddr, m_endPoint6->GetLocalPort ());
  826. // Peel off TCP header and do validity checking
  827. TcpHeader tcpHeader;
  828. packet->RemoveHeader (tcpHeader);
  829. if (tcpHeader.GetFlags () & TcpHeader::ACK)
  830. {
  831. EstimateRtt (tcpHeader);
  832. }
  833. ReadOptions (tcpHeader);
  834. // Update Rx window size, i.e. the flow control window
  835. if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
  836. { // persist probes end
  837. NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
  838. m_persistEvent.Cancel ();
  839. }
  840. m_rWnd = tcpHeader.GetWindowSize ();
  841. // Discard fully out of range packets
  842. if (packet->GetSize ()
  843. && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
  844. {
  845. NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
  846. " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
  847. ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
  848. ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
  849. m_rxBuffer.MaxRxSequence () << ")");
  850. // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
  851. if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
  852. {
  853. SendEmptyPacket (TcpHeader::ACK);
  854. }
  855. return;
  856. }
  857. // TCP state machine code in different process functions
  858. // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
  859. switch (m_state)
  860. {
  861. case ESTABLISHED:
  862. ProcessEstablished (packet, tcpHeader);
  863. break;
  864. case LISTEN:
  865. ProcessListen (packet, tcpHeader, fromAddress, toAddress);
  866. break;
  867. case TIME_WAIT:
  868. // Do nothing
  869. break;
  870. case CLOSED:
  871. // Send RST if the incoming packet is not a RST
  872. if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
  873. { // Since m_endPoint is not configured yet, we cannot use SendRST here
  874. TcpHeader h;
  875. h.SetFlags (TcpHeader::RST);
  876. h.SetSequenceNumber (m_nextTxSequence);
  877. h.SetAckNumber (m_rxBuffer.NextRxSequence ());
  878. h.SetSourcePort (tcpHeader.GetDestinationPort ());
  879. h.SetDestinationPort (tcpHeader.GetSourcePort ());
  880. h.SetWindowSize (AdvertisedWindowSize ());
  881. AddOptions (h);
  882. m_tcp->SendPacket (Create<Packet> (), h, daddr, saddr, m_boundnetdevice);
  883. }
  884. break;
  885. case SYN_SENT:
  886. ProcessSynSent (packet, tcpHeader);
  887. break;
  888. case SYN_RCVD:
  889. ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
  890. break;
  891. case FIN_WAIT_1:
  892. case FIN_WAIT_2:
  893. case CLOSE_WAIT:
  894. ProcessWait (packet, tcpHeader);
  895. break;
  896. case CLOSING:
  897. ProcessClosing (packet, tcpHeader);
  898. break;
  899. case LAST_ACK:
  900. ProcessLastAck (packet, tcpHeader);
  901. break;
  902. default: // mute compiler
  903. break;
  904. }
  905. }
  906. /** Received a packet upon ESTABLISHED state. This function is mimicking the
  907. role of tcp_rcv_established() in tcp_input.c in Linux kernel. */
  908. void
  909. TcpSocketBase::ProcessEstablished (Ptr<Packet> packet, const TcpHeader& tcpHeader)
  910. {
  911. NS_LOG_FUNCTION (this << tcpHeader);
  912. // Extract the flags. PSH and URG are not honoured.
  913. uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
  914. // Different flags are different events
  915. if (tcpflags == TcpHeader::ACK)
  916. {
  917. ReceivedAck (packet, tcpHeader);
  918. }
  919. else if (tcpflags == TcpHeader::SYN)
  920. { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and
  921. // respond with a SYN+ACK. But it is not a legal state transition as of
  922. // RFC793. Thus this is ignored.
  923. }
  924. else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
  925. { // No action for received SYN+ACK, it is probably a duplicated packet
  926. }
  927. else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
  928. { // Received FIN or FIN+ACK, bring down this socket nicely
  929. PeerClose (packet, tcpHeader);
  930. }
  931. else if (tcpflags == 0)
  932. { // No flags means there is only data
  933. ReceivedData (packet, tcpHeader);
  934. if (m_rxBuffer.Finished ())
  935. {
  936. PeerClose (packet, tcpHeader);
  937. }
  938. }
  939. else
  940. { // Received RST or the TCP flags is invalid, in either case, terminate this socket
  941. if (tcpflags != TcpHeader::RST)
  942. { // this must be an invalid flag, send reset
  943. NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
  944. SendRST ();
  945. }
  946. CloseAndNotify ();
  947. }
  948. }
  949. /** Process the newly received ACK */
  950. void
  951. TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
  952. {
  953. NS_LOG_FUNCTION (this << tcpHeader);
  954. // Received ACK. Compare the ACK number against highest unacked seqno
  955. if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
  956. { // Ignore if no ACK flag
  957. }
  958. else if (tcpHeader.GetAckNumber () < m_txBuffer.HeadSequence ())
  959. { // Case 1: Old ACK, ignored.
  960. NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ());
  961. }
  962. else if (tcpHeader.GetAckNumber () == m_txBuffer.HeadSequence ())
  963. { // Case 2: Potentially a duplicated ACK
  964. if (tcpHeader.GetAckNumber () < m_nextTxSequence)
  965. {
  966. NS_LOG_LOGIC ("Dupack of " << tcpHeader.GetAckNumber ());
  967. DupAck (tcpHeader, ++m_dupAckCount);
  968. }
  969. // otherwise, the ACK is precisely equal to the nextTxSequence
  970. NS_ASSERT (tcpHeader.GetAckNumber () <= m_nextTxSequence);
  971. }
  972. else if (tcpHeader.GetAckNumber () > m_txBuffer.HeadSequence ())
  973. { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
  974. NS_LOG_LOGIC ("New ack of " << tcpHeader.GetAckNumber ());
  975. NewAck (tcpHeader.GetAckNumber ());
  976. m_dupAckCount = 0;
  977. }
  978. // If there is any data piggybacked, store it into m_rxBuffer
  979. if (packet->GetSize () > 0)
  980. {
  981. ReceivedData (packet, tcpHeader);
  982. }
  983. }
  984. /** Received a packet upon LISTEN state. */
  985. void
  986. TcpSocketBase::ProcessListen (Ptr<Packet> packet, const TcpHeader& tcpHeader,
  987. const Address& fromAddress, const Address& toAddress)
  988. {
  989. NS_LOG_FUNCTION (this << tcpHeader);
  990. // Extract the flags. PSH and URG are not honoured.
  991. uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
  992. // Fork a socket if received a SYN. Do nothing otherwise.
  993. // C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel
  994. if (tcpflags != TcpHeader::SYN)
  995. {
  996. return;
  997. }
  998. // Call socket's notify function to let the server app know we got a SYN
  999. // If the server app refuses the connection, do nothing
  1000. if (!NotifyConnectionRequest (fromAddress))
  1001. {
  1002. return;
  1003. }
  1004. // Clone the socket, simulate fork
  1005. Ptr<TcpSocketBase> newSock = Fork ();
  1006. NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock);
  1007. Simulator::ScheduleNow (&TcpSocketBase::CompleteFork, newSock,
  1008. packet, tcpHeader, fromAddress, toAddress);
  1009. }
  1010. /** Received a packet upon SYN_SENT */
  1011. void
  1012. TcpSocketBase::ProcessSynSent (Ptr<Packet> packet, const TcpHeader& tcpHeader)
  1013. {
  1014. NS_LOG_FUNCTION (this << tcpHeader);
  1015. // Extract the flags. PSH and URG are not honoured.
  1016. uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
  1017. if (tcpflags == 0)
  1018. { // Bare data, accept it and move to ESTABLISHED state. This is not a normal behaviour. Remove this?
  1019. NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
  1020. m_state = ESTABLISHED;
  1021. m_connected = true;
  1022. m_retxEvent.Cancel ();
  1023. m_delAckCount = m_delAckMaxCount;
  1024. ReceivedData (packet, tcpHeader);
  1025. Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this);
  1026. }
  1027. else if (tcpflags == TcpHeader::ACK)
  1028. { // Ignore ACK in SYN_SENT
  1029. }
  1030. else if (tcpflags == TcpHeader::SYN)
  1031. { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
  1032. NS_LOG_INFO ("SYN_SENT -> SYN_RCVD");
  1033. m_state = SYN_RCVD;
  1034. m_cnCount = m_cnRetries;
  1035. m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
  1036. SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
  1037. }
  1038. else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)
  1039. && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ())
  1040. { // Handshake completed
  1041. NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
  1042. m_state = ESTABLISHED;
  1043. m_connected = true;
  1044. m_retxEvent.Cancel ();
  1045. m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
  1046. m_highTxMark = ++m_nextTxSequence;
  1047. m_txBuffer.SetHeadSequence (m_nextTxSequence);
  1048. SendEmptyPacket (TcpHeader::ACK);
  1049. SendPendingData (m_connected);
  1050. Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this);
  1051. // Always respond to first data packet to speed up the connection.
  1052. // Remove to get the behaviour of old NS-3 code.
  1053. m_delAckCount = m_delAckMaxCount;
  1054. }
  1055. else
  1056. { // Other in-sequence input
  1057. if (tcpflags != TcpHeader::RST)
  1058. { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
  1059. NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t> (tcpflags) << std::dec << " received. Reset packet is sent.");
  1060. SendRST ();
  1061. }
  1062. CloseAndNotify ();
  1063. }
  1064. }
  1065. /** Received a packet upon SYN_RCVD */
  1066. void
  1067. TcpSocketBase::ProcessSynRcvd (Ptr<Packet> packet, const TcpHeader& tcpHeader,
  1068. const Address& fromAddress, const Address& toAddress)
  1069. {
  1070. NS_LOG_FUNCTION (this << tcpHeader);
  1071. // Extract the flags. PSH and URG are not honoured.
  1072. uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
  1073. if (tcpflags == 0
  1074. || (tcpflags == TcpHeader::ACK
  1075. && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()))
  1076. { // If it is bare data, accept it and move to ESTABLISHED state. This is
  1077. // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the
  1078. // handshake is completed nicely.
  1079. NS_LOG_INFO ("SYN_RCVD -> ESTABLISHED");
  1080. m_state = ESTABLISHED;
  1081. m_connected = true;
  1082. m_retxEvent.Cancel ();
  1083. m_highTxMark = ++m_nextTxSequence;
  1084. m_txBuffer.SetHeadSequence (m_nextTxSequence);
  1085. if (m_endPoint)
  1086. {
  1087. m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
  1088. InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
  1089. }
  1090. else if (m_endPoint6)
  1091. {
  1092. m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
  1093. Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
  1094. }
  1095. // Always respond to first data packet to speed up the connection.
  1096. // Remove to get the behaviour of old NS-3 code.
  1097. m_delAckCount = m_delAckMaxCount;
  1098. ReceivedAck (packet, tcpHeader);
  1099. NotifyNewConnectionCreated (this, fromAddress);
  1100. // As this connection is established, the socket is available to send data now
  1101. if (GetTxAvailable () > 0)
  1102. {
  1103. NotifySend (GetTxAvailable ());
  1104. }
  1105. }
  1106. else if (tcpflags == TcpHeader::SYN)
  1107. { // Probably the peer lost my SYN+ACK
  1108. m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
  1109. SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
  1110. }
  1111. else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
  1112. {
  1113. if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
  1114. { // In-sequence FIN before connection complete. Set up connection and close.
  1115. m_connected = true;
  1116. m_retxEvent.Cancel ();
  1117. m_highTxMark = ++m_nextTxSequence;
  1118. m_txBuffer.SetHeadSequence (m_nextTxSequence);
  1119. if (m_endPoint)
  1120. {
  1121. m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
  1122. InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
  1123. }
  1124. else if (m_endPoint6)
  1125. {
  1126. m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
  1127. Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
  1128. }
  1129. PeerClose (packet, tcpHeader);
  1130. }
  1131. }
  1132. else
  1133. { // Other in-sequence input
  1134. if (tcpflags != TcpHeader::RST)
  1135. { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
  1136. NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
  1137. if (m_endPoint)
  1138. {
  1139. m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
  1140. InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
  1141. }
  1142. else if (m_endPoint6)
  1143. {
  1144. m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
  1145. Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
  1146. }
  1147. SendRST ();
  1148. }
  1149. CloseAndNotify ();
  1150. }
  1151. }
  1152. /** Received a packet upon CLOSE_WAIT, FIN_WAIT_1, or FIN_WAIT_2 states */
  1153. void
  1154. TcpSocketBase::ProcessWait (Ptr<Packet> packet, const TcpHeader& tcpHeader)
  1155. {
  1156. NS_LOG_FUNCTION (this << tcpHeader);
  1157. // Extract the flags. PSH and URG are not honoured.
  1158. uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
  1159. if (packet->GetSize () > 0)
  1160. { // Bare data, accept it
  1161. ReceivedData (packet, tcpHeader);
  1162. }
  1163. else if (tcpflags == TcpHeader::ACK)
  1164. { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2
  1165. ReceivedAck (packet, tcpHeader);
  1166. if (m_state == FIN_WAIT_1 && m_txBuffer.Size () == 0
  1167. && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
  1168. { // This ACK corresponds to the FIN sent
  1169. NS_LOG_INFO ("FIN_WAIT_1 -> FIN_WAIT_2");
  1170. m_state = FIN_WAIT_2;
  1171. }
  1172. }
  1173. else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
  1174. { // Got FIN, respond with ACK and move to next state
  1175. if (tcpflags & TcpHeader::ACK)
  1176. { // Process the ACK first
  1177. ReceivedAck (packet, tcpHeader);
  1178. }
  1179. m_rxBuffer.SetFinSequence (tcpHeader.GetSequenceNumber ());
  1180. }
  1181. else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
  1182. { // Duplicated SYN or SYN+ACK, possibly due to spurious retransmission
  1183. return;
  1184. }
  1185. else
  1186. { // This is a RST or bad flags
  1187. if (tcpflags != TcpHeader::RST)
  1188. {
  1189. NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
  1190. SendRST ();
  1191. }
  1192. CloseAndNotify ();
  1193. return;
  1194. }
  1195. // Check if the close responder sent an in-sequence FIN, if so, respond ACK
  1196. if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer.Finished ())
  1197. {
  1198. if (m_state == FIN_WAIT_1)
  1199. {
  1200. NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
  1201. m_state = CLOSING;
  1202. if (m_txBuffer.Size () == 0
  1203. && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
  1204. { // This ACK corresponds to the FIN sent
  1205. TimeWait ();
  1206. }
  1207. }
  1208. else if (m_state == FIN_WAIT_2)
  1209. {
  1210. TimeWait ();
  1211. }
  1212. SendEmptyPacket (TcpHeader::ACK);
  1213. if (!m_shutdownRecv)
  1214. {
  1215. NotifyDataRecv ();
  1216. }
  1217. }
  1218. }
  1219. /** Received a packet upon CLOSING */
  1220. void
  1221. TcpSocketBase::ProcessClosing (Ptr<Packet> packet, const TcpHeader& tcpHeader)
  1222. {
  1223. NS_LOG_FUNCTION (this << tcpHeader);
  1224. // Extract the flags. PSH and URG are not honoured.
  1225. uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
  1226. if (tcpflags == TcpHeader::ACK)
  1227. {
  1228. if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
  1229. { // This ACK corresponds to the FIN sent
  1230. TimeWait ();
  1231. }
  1232. }
  1233. else
  1234. { // CLOSING state means simultaneous close, i.e. no one is sending data to
  1235. // anyone. If anything other than ACK is received, respond with a reset.
  1236. if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
  1237. { // FIN from the peer as well. We can close immediately.
  1238. SendEmptyPacket (TcpHeader::ACK);
  1239. }
  1240. else if (tcpflags != TcpHeader::RST)
  1241. { // Receive of SYN or SYN+ACK or bad flags or pure data
  1242. NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
  1243. SendRST ();
  1244. }
  1245. CloseAndNotify ();
  1246. }
  1247. }
  1248. /** Received a packet upon LAST_ACK */
  1249. void
  1250. TcpSocketBase::ProcessLastAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
  1251. {
  1252. NS_LOG_FUNCTION (this << tcpHeader);
  1253. // Extract the flags. PSH and URG are not honoured.
  1254. uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
  1255. if (tcpflags == 0)
  1256. {
  1257. ReceivedData (packet, tcpHeader);
  1258. }
  1259. else if (tcpflags == TcpHeader::ACK)
  1260. {
  1261. if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
  1262. { // This ACK corresponds to the FIN sent. This socket closed peacefully.
  1263. CloseAndNotify ();
  1264. }
  1265. }
  1266. else if (tcpflags == TcpHeader::FIN)
  1267. { // Received FIN again, the peer probably lost the FIN+ACK
  1268. SendEmptyPacket (TcpHeader::FIN | TcpHeader::ACK);
  1269. }
  1270. else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK) || tcpflags == TcpHeader::RST)
  1271. {
  1272. CloseAndNotify ();
  1273. }
  1274. else
  1275. { // Received a SYN or SYN+ACK or bad flags
  1276. NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
  1277. SendRST ();
  1278. CloseAndNotify ();
  1279. }
  1280. }
  1281. /** Peer sent me a FIN. Remember its sequence in rx buffer. */
  1282. void
  1283. TcpSocketBase::PeerClose (Ptr<Packet> p, const TcpHeader& tcpHeader)
  1284. {
  1285. NS_LOG_FUNCTION (this << tcpHeader);
  1286. // Ignore all out of range packets
  1287. if (tcpHeader.GetSequenceNumber () < m_rxBuffer.NextRxSequence ()
  1288. || tcpHeader.GetSequenceNumber () > m_rxBuffer.MaxRxSequence ())
  1289. {
  1290. return;
  1291. }
  1292. // For any case, remember the FIN position in rx buffer first
  1293. m_rxBuffer.SetFinSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
  1294. NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
  1295. // If there is any piggybacked data, process it
  1296. if (p->GetSize ())
  1297. {
  1298. ReceivedData (p, tcpHeader);
  1299. }
  1300. // Return if FIN is out of sequence, otherwise move to CLOSE_WAIT state by DoPeerClose
  1301. if (!m_rxBuffer.Finished ())
  1302. {
  1303. return;
  1304. }
  1305. // Simultaneous close: Application invoked Close() when we are processing this FIN packet
  1306. if (m_state == FIN_WAIT_1)
  1307. {
  1308. NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
  1309. m_state = CLOSING;
  1310. return;
  1311. }
  1312. DoPeerClose (); // Change state, respond with ACK
  1313. }
  1314. /** Received a in-sequence FIN. Close down this socket. */
  1315. void
  1316. TcpSocketBase::DoPeerClose (void)
  1317. {
  1318. NS_ASSERT (m_state == ESTABLISHED || m_state == SYN_RCVD);
  1319. // Move the state to CLOSE_WAIT
  1320. NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSE_WAIT");
  1321. m_state = CLOSE_WAIT;
  1322. if (!m_closeNotified)
  1323. {
  1324. // The normal behaviour for an application is that, when the peer sent a in-sequence
  1325. // FIN, the app should prepare to close. The app has two choices at this point: either
  1326. // respond with ShutdownSend() call to declare that it has nothing more to send and
  1327. // the socket can be closed immediately; or remember the peer's close request, wait
  1328. // until all its existing data are pushed into the TCP socket, then call Close()
  1329. // explicitly.
  1330. NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose");
  1331. NotifyNormalClose ();
  1332. m_closeNotified = true;
  1333. }
  1334. if (m_shutdownSend)
  1335. { // The application declares that it would not sent any more, close this socket
  1336. Close ();
  1337. }
  1338. else
  1339. { // Need to ack, the application will close later
  1340. SendEmptyPacket (TcpHeader::ACK);
  1341. }
  1342. if (m_state == LAST_ACK)
  1343. {
  1344. NS_LOG_LOGIC ("TcpSocketBase " << this << " scheduling LATO1");
  1345. m_lastAckEvent = Simulator::Schedule (m_rtt->RetransmitTimeout (),
  1346. &TcpSocketBase::LastAckTimeout, this);
  1347. }
  1348. }
  1349. /** Kill this socket. This is a callback function configured to m_endpoint in
  1350. SetupCallback(), invoked when the endpoint is destroyed. */
  1351. void
  1352. TcpSocketBase::Destroy (void)
  1353. {
  1354. NS_LOG_FUNCTION (this);
  1355. m_endPoint = 0;
  1356. if (m_tcp != 0)
  1357. {
  1358. std::vector<Ptr<TcpSocketBase> >::iterator it
  1359. = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
  1360. if (it != m_tcp->m_sockets.end ())
  1361. {
  1362. m_tcp->m_sockets.erase (it);
  1363. }
  1364. }
  1365. NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
  1366. (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
  1367. CancelAllTimers ();
  1368. }
  1369. /** Kill this socket. This is a callback function configured to m_endpoint in
  1370. SetupCallback(), invoked when the endpoint is destroyed. */
  1371. void
  1372. TcpSocketBase::Destroy6 (void)
  1373. {
  1374. NS_LOG_FUNCTION (this);
  1375. m_endPoint6 = 0;
  1376. if (m_tcp != 0)
  1377. {
  1378. std::vector<Ptr<TcpSocketBase> >::iterator it
  1379. = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
  1380. if (it != m_tcp->m_sockets.end ())
  1381. {
  1382. m_tcp->m_sockets.erase (it);
  1383. }
  1384. }
  1385. NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
  1386. (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
  1387. CancelAllTimers ();
  1388. }
  1389. /** Send an empty packet with specified TCP flags */
  1390. void
  1391. TcpSocketBase::SendEmptyPacket (uint8_t flags)
  1392. {
  1393. NS_LOG_FUNCTION (this << (uint32_t)flags);
  1394. Ptr<Packet> p = Create<Packet> ();
  1395. TcpHeader header;
  1396. SequenceNumber32 s = m_nextTxSequence;
  1397. if (m_endPoint == 0 && m_endPoint6 == 0)
  1398. {
  1399. NS_LOG_WARN ("Failed to send empty packet due to null endpoint");
  1400. return;
  1401. }
  1402. if (flags & TcpHeader::FIN)
  1403. {
  1404. flags |= TcpHeader::ACK;
  1405. }
  1406. else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING)
  1407. {
  1408. ++s;
  1409. }
  1410. header.SetFlags (flags);
  1411. header.SetSequenceNumber (s);
  1412. header.SetAckNumber (m_rxBuffer.NextRxSequence ());
  1413. if (m_endPoint != 0)
  1414. {
  1415. header.SetSourcePort (m_endPoint->GetLocalPort ());
  1416. header.SetDestinationPort (m_endPoint->GetPeerPort ());
  1417. }
  1418. else
  1419. {
  1420. header.SetSourcePort (m_endPoint6->GetLocalPort ());
  1421. header.SetDestinationPort (m_endPoint6->GetPeerPort ());
  1422. }
  1423. header.SetWindowSize (AdvertisedWindowSize ());
  1424. AddOptions (header);
  1425. m_rto = m_rtt->RetransmitTimeout ();
  1426. bool hasSyn = flags & TcpHeader::SYN;
  1427. bool hasFin = flags & TcpHeader::FIN;
  1428. bool isAck = flags == TcpHeader::ACK;
  1429. if (hasSyn)
  1430. {
  1431. if (m_cnCount == 0)
  1432. { // No more connection retries, give up
  1433. NS_LOG_LOGIC ("Connection failed.");
  1434. CloseAndNotify ();
  1435. return;
  1436. }
  1437. else
  1438. { // Exponential backoff of connection time out
  1439. int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
  1440. m_rto = m_cnTimeout * backoffCount;
  1441. m_cnCount--;
  1442. }
  1443. }
  1444. if (m_endPoint != 0)
  1445. {
  1446. m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
  1447. m_endPoint->GetPeerAddress (), m_boundnetdevice);
  1448. }
  1449. else
  1450. {
  1451. m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
  1452. m_endPoint6->GetPeerAddress (), m_boundnetdevice);
  1453. }
  1454. if (flags & TcpHeader::ACK)
  1455. { // If sending an ACK, cancel the delay ACK as well
  1456. m_delAckEvent.Cancel ();
  1457. m_delAckCount = 0;
  1458. }
  1459. if (m_retxEvent.IsExpired () && (hasSyn || hasFin) && !isAck )
  1460. { // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost
  1461. NS_LOG_LOGIC ("Schedule retransmission timeout at time "
  1462. << Simulator::Now ().GetSeconds () << " to expire at time "
  1463. << (Simulator::Now () + m_rto.Get ()).GetSeconds ());
  1464. m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::SendEmptyPacket, this, flags);
  1465. }
  1466. }
  1467. /** This function closes the endpoint completely. Called upon RST_TX action. */
  1468. void
  1469. TcpSocketBase::SendRST (void)
  1470. {
  1471. NS_LOG_FUNCTION (this);
  1472. SendEmptyPacket (TcpHeader::RST);
  1473. NotifyErrorClose ();
  1474. DeallocateEndPoint ();
  1475. }
  1476. /** Deallocate the end point and cancel all the timers */
  1477. void
  1478. TcpSocketBase::DeallocateEndPoint (void)
  1479. {
  1480. if (m_endPoint != 0)
  1481. {
  1482. m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
  1483. m_tcp->DeAllocate (m_endPoint);
  1484. m_endPoint = 0;
  1485. std::vector<Ptr<TcpSocketBase> >::iterator it
  1486. = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
  1487. if (it != m_tcp->m_sockets.end ())
  1488. {
  1489. m_tcp->m_sockets.erase (it);
  1490. }
  1491. CancelAllTimers ();
  1492. }
  1493. if (m_endPoint6 != 0)
  1494. {
  1495. m_endPoint6->SetDestroyCallback (MakeNullCallback<void> ());
  1496. m_tcp->DeAllocate (m_endPoint6);
  1497. m_endPoint6 = 0;
  1498. std::vector<Ptr<TcpSocketBase> >::iterator it
  1499. = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
  1500. if (it != m_tcp->m_sockets.end ())
  1501. {
  1502. m_tcp->m_sockets.erase (it);
  1503. }
  1504. CancelAllTimers ();
  1505. }
  1506. }
  1507. /** Configure the endpoint to a local address. Called by Connect() if Bind() didn't specify one. */
  1508. int
  1509. TcpSocketBase::SetupEndpoint ()
  1510. {
  1511. NS_LOG_FUNCTION (this);
  1512. Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
  1513. NS_ASSERT (ipv4 != 0);
  1514. if (ipv4->GetRoutingProtocol () == 0)
  1515. {
  1516. NS_FATAL_ERROR ("No Ipv4RoutingProtocol in the node");
  1517. }
  1518. // Create a dummy packet, then ask the routing function for the best output
  1519. // interface's address
  1520. Ipv4Header header;
  1521. header.SetDestination (m_endPoint->GetPeerAddress ());
  1522. Socket::SocketErrno errno_;
  1523. Ptr<Ipv4Route> route;
  1524. Ptr<NetDevice> oif = m_boundnetdevice;
  1525. route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
  1526. if (route == 0)
  1527. {
  1528. NS_LOG_LOGIC ("Route to " << m_endPoint->GetPeerAddress () << " does not exist");
  1529. NS_LOG_ERROR (errno_);
  1530. m_errno = errno_;
  1531. return -1;
  1532. }
  1533. NS_LOG_LOGIC ("Route exists");
  1534. m_endPoint->SetLocalAddress (route->GetSource ());
  1535. return 0;
  1536. }
  1537. int
  1538. TcpSocketBase::SetupEndpoint6 ()
  1539. {
  1540. NS_LOG_FUNCTION (this);
  1541. Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
  1542. NS_ASSERT (ipv6 != 0);
  1543. if (ipv6->GetRoutingProtocol () == 0)
  1544. {
  1545. NS_FATAL_ERROR ("No Ipv6RoutingProtocol in the node");
  1546. }
  1547. // Create a dummy packet, then ask the routing function for the best output
  1548. // interface's address
  1549. Ipv6Header header;
  1550. header.SetDestinationAddress (m_endPoint6->GetPeerAddress ());
  1551. Socket::SocketErrno errno_;
  1552. Ptr<Ipv6Route> route;
  1553. Ptr<NetDevice> oif = m_boundnetdevice;
  1554. route = ipv6->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
  1555. if (route == 0)
  1556. {
  1557. NS_LOG_LOGIC ("Route to " << m_endPoint6->GetPeerAddress () << " does not exist");
  1558. NS_LOG_ERROR (errno_);
  1559. m_errno = errno_;
  1560. return -1;
  1561. }
  1562. NS_LOG_LOGIC ("Route exists");
  1563. m_endPoint6->SetLocalAddress (route->GetSource ());
  1564. return 0;
  1565. }
  1566. /** This function is called only if a SYN received in LISTEN state. After
  1567. TcpSocketBase cloned, allocate a new end point to handle the incoming
  1568. connection and send a SYN+ACK to complete the handshake. */
  1569. void
  1570. TcpSocketBase::CompleteFork (Ptr<Packet> p, const TcpHeader& h,
  1571. const Address& fromAddress, const Address& toAddress)
  1572. {
  1573. // Get port and address from peer (connecting host)
  1574. if (InetSocketAddress::IsMatchingType (toAddress))
  1575. {
  1576. m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
  1577. InetSocketAddress::ConvertFrom (toAddress).GetPort (),
  1578. InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
  1579. InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
  1580. m_endPoint6 = 0;
  1581. }
  1582. else if (Inet6SocketAddress::IsMatchingType (toAddress))
  1583. {
  1584. m_endPoint6 = m_tcp->Allocate6 (Inet6SocketAddress::ConvertFrom (toAddress).GetIpv6 (),
  1585. Inet6SocketAddress::ConvertFrom (toAddress).GetPort (),
  1586. Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
  1587. Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
  1588. m_endPoint = 0;
  1589. }
  1590. m_tcp->m_sockets.push_back (this);
  1591. // Change the cloned socket from LISTEN state to SYN_RCVD
  1592. NS_LOG_INFO ("LISTEN -> SYN_RCVD");
  1593. m_state = SYN_RCVD;
  1594. m_cnCount = m_cnRetries;
  1595. SetupCallback ();
  1596. // Set the sequence number and send SYN+ACK
  1597. m_rxBuffer.SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1));
  1598. SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
  1599. }
  1600. void
  1601. TcpSocketBase::ConnectionSucceeded ()
  1602. { // Wrapper to protected function NotifyConnectionSucceeded() so that it can
  1603. // be called as a scheduled event
  1604. NotifyConnectionSucceeded ();
  1605. // The if-block below was moved from ProcessSynSent() to here because we need
  1606. // to invoke the NotifySend() only after NotifyConnectionSucceeded() to
  1607. // reflect the behaviour in the real world.
  1608. if (GetTxAvailable () > 0)
  1609. {
  1610. NotifySend (GetTxAvailable ());
  1611. }
  1612. }
  1613. /** Extract at most maxSize bytes from the TxBuffer at sequence seq, add the
  1614. TCP header, and send to TcpL4Protocol */
  1615. uint32_t
  1616. TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck)
  1617. {
  1618. NS_LOG_FUNCTION (this << seq << maxSize << withAck);
  1619. Ptr<Packet> p = m_txBuffer.CopyFromSequence (maxSize, seq);
  1620. uint32_t sz = p->GetSize (); // Size of packet
  1621. uint8_t flags = withAck ? TcpHeader::ACK : 0;
  1622. uint32_t remainingData = m_txBuffer.SizeFromSequence (seq + SequenceNumber32 (sz));
  1623. if (m_closeOnEmpty && (remainingData == 0))
  1624. {
  1625. flags |= TcpHeader::FIN;
  1626. if (m_state == ESTABLISHED)
  1627. { // On active close: I am the first one to send FIN
  1628. NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
  1629. m_state = FIN_WAIT_1;
  1630. }
  1631. else if (m_state == CLOSE_WAIT)
  1632. { // On passive close: Peer sent me FIN already
  1633. NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
  1634. m_state = LAST_ACK;
  1635. }
  1636. }
  1637. TcpHeader header;
  1638. header.SetFlags (flags);
  1639. header.SetSequenceNumber (seq);
  1640. header.SetAckNumber (m_rxBuffer.NextRxSequence ());
  1641. if (m_endPoint)
  1642. {
  1643. header.SetSourcePort (m_endPoint->GetLocalPort ());
  1644. header.SetDestinationPort (m_endPoint->GetPeerPort ());
  1645. }
  1646. else
  1647. {
  1648. header.SetSourcePort (m_endPoint6->GetLocalPort ());
  1649. header.SetDestinationPort (m_endPoint6->GetPeerPort ());
  1650. }
  1651. header.SetWindowSize (AdvertisedWindowSize ());
  1652. AddOptions (header);
  1653. if (m_retxEvent.IsExpired () )
  1654. { // Schedule retransmit
  1655. m_rto = m_rtt->RetransmitTimeout ();
  1656. NS_LOG_LOGIC (this << " SendDataPacket Schedule ReTxTimeout at time " <<
  1657. Simulator::Now ().GetSeconds () << " to expire at time " <<
  1658. (Simulator::Now () + m_rto.Get ()).GetSeconds () );
  1659. m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this);
  1660. }
  1661. NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
  1662. if (m_endPoint)
  1663. {
  1664. m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
  1665. m_endPoint->GetPeerAddress (), m_boundnetdevice);
  1666. }
  1667. else
  1668. {
  1669. m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
  1670. m_endPoint6->GetPeerAddress (), m_boundnetdevice);
  1671. }
  1672. m_rtt->SentSeq (seq, sz); // notify the RTT
  1673. // Notify the application of the data being sent unless this is a retransmit
  1674. if (seq == m_nextTxSequence)
  1675. {
  1676. Simulator::ScheduleNow (&TcpSocketBase::NotifyDataSent, this, sz);
  1677. }
  1678. // Update highTxMark
  1679. m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
  1680. return sz;
  1681. }
  1682. /** Send as much pending data as possible according to the Tx window. Note that
  1683. * this function did not implement the PSH flag
  1684. */
  1685. bool
  1686. TcpSocketBase::SendPendingData (bool withAck)
  1687. {
  1688. NS_LOG_FUNCTION (this << withAck);
  1689. if (m_txBuffer.Size () == 0)
  1690. {
  1691. return false; // Nothing to send
  1692. }
  1693. if (m_endPoint == 0 && m_endPoint6 == 0)
  1694. {
  1695. NS_LOG_INFO ("TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
  1696. return false; // Is this the right way to handle this condition?
  1697. }
  1698. uint32_t nPacketsSent = 0;
  1699. while (m_txBuffer.SizeFromSequence (m_nextTxSequence))
  1700. {
  1701. uint32_t w = AvailableWindow (); // Get available window size
  1702. NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" <<
  1703. " w " << w <<
  1704. " rxwin " << m_rWnd <<
  1705. " segsize " << m_segmentSize <<
  1706. " nextTxSeq " << m_nextTxSequence <<
  1707. " highestRxAck " << m_txBuffer.HeadSequence () <<
  1708. " pd->Size " << m_txBuffer.Size () <<
  1709. " pd->SFS " << m_txBuffer.SizeFromSequence (m_nextTxSequence));
  1710. // Quit if send disallowed
  1711. if (m_shutdownSend)
  1712. {
  1713. m_errno = ERROR_SHUTDOWN;
  1714. return false;
  1715. }
  1716. // Stop sending if we need to wait for a larger Tx window (prevent silly window syndrome)
  1717. if (w < m_segmentSize && m_txBuffer.SizeFromSequence (m_nextTxSequence) > w)
  1718. {
  1719. break; // No more
  1720. }
  1721. // Nagle's algorithm (RFC896): Hold off sending if there is unacked data
  1722. // in the buffer and the amount of data to send is less than one segment
  1723. if (!m_noDelay && UnAckDataCount () > 0
  1724. && m_txBuffer.SizeFromSequence (m_nextTxSequence) < m_segmentSize)
  1725. {
  1726. NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send.");
  1727. break;
  1728. }
  1729. uint32_t s = std::min (w, m_segmentSize); // Send no more than window
  1730. uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck);
  1731. nPacketsSent++; // Count sent this loop
  1732. m_nextTxSequence += sz; // Advance next tx sequence
  1733. }
  1734. NS_LOG_LOGIC ("SendPendingData sent " << nPacketsSent << " packets");
  1735. return (nPacketsSent > 0);
  1736. }
  1737. uint32_t
  1738. TcpSocketBase::UnAckDataCount ()
  1739. {
  1740. NS_LOG_FUNCTION (this);
  1741. return m_nextTxSequence.Get () - m_txBuffer.HeadSequence ();
  1742. }
  1743. uint32_t
  1744. TcpSocketBase::BytesInFlight ()
  1745. {
  1746. NS_LOG_FUNCTION (this);
  1747. return m_highTxMark.Get () - m_txBuffer.HeadSequence ();
  1748. }
  1749. uint32_t
  1750. TcpSocketBase::Window ()
  1751. {
  1752. NS_LOG_FUNCTION (this);
  1753. return m_rWnd;
  1754. }
  1755. uint32_t
  1756. TcpSocketBase::AvailableWindow ()
  1757. {
  1758. NS_LOG_FUNCTION_NOARGS ();
  1759. uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
  1760. uint32_t win = Window (); // Number of bytes allowed to be outstanding
  1761. NS_LOG_LOGIC ("UnAckCount=" << unack << ", Win=" << win);
  1762. return (win < unack) ? 0 : (win - unack);
  1763. }
  1764. uint16_t
  1765. TcpSocketBase::AdvertisedWindowSize ()
  1766. {
  1767. return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), (uint32_t)m_maxWinSize);
  1768. }
  1769. // Receipt of new packet, put into Rx buffer
  1770. void
  1771. TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader)
  1772. {
  1773. NS_LOG_FUNCTION (this << tcpHeader);
  1774. NS_LOG_LOGIC ("seq " << tcpHeader.GetSequenceNumber () <<
  1775. " ack " << tcpHeader.GetAckNumber () <<
  1776. " pkt size " << p->GetSize () );
  1777. // Put into Rx buffer
  1778. SequenceNumber32 expectedSeq = m_rxBuffer.NextRxSequence ();
  1779. if (!m_rxBuffer.Add (p, tcpHeader))
  1780. { // Insert failed: No data or RX buffer full
  1781. SendEmptyPacket (TcpHeader::ACK);
  1782. return;
  1783. }
  1784. // Now send a new ACK packet acknowledging all received and delivered data
  1785. if (m_rxBuffer.Size () > m_rxBuffer.Available () || m_rxBuffer.NextRxSequence () > expectedSeq + p->GetSize ())
  1786. { // A gap exists in the buffer, or we filled a gap: Always ACK
  1787. SendEmptyPacket (TcpHeader::ACK);
  1788. }
  1789. else
  1790. { // In-sequence packet: ACK if delayed ack count allows
  1791. if (++m_delAckCount >= m_delAckMaxCount)
  1792. {
  1793. m_delAckEvent.Cancel ();
  1794. m_delAckCount = 0;
  1795. SendEmptyPacket (TcpHeader::ACK);
  1796. }
  1797. else if (m_delAckEvent.IsExpired ())
  1798. {
  1799. m_delAckEvent = Simulator::Schedule (m_delAckTimeout,
  1800. &TcpSocketBase::DelAckTimeout, this);
  1801. NS_LOG_LOGIC (this << " scheduled delayed ACK at " << (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEvent)).GetSeconds ());
  1802. }
  1803. }
  1804. // Notify app to receive if necessary
  1805. if (expectedSeq < m_rxBuffer.NextRxSequence ())
  1806. { // NextRxSeq advanced, we have something to send to the app
  1807. if (!m_shutdownRecv)
  1808. {
  1809. NotifyDataRecv ();
  1810. }
  1811. // Handle exceptions
  1812. if (m_closeNotified)
  1813. {
  1814. NS_LOG_WARN ("Why TCP " << this << " got data after close notification?");
  1815. }
  1816. // If we received FIN before and now completed all "holes" in rx buffer,
  1817. // invoke peer close procedure
  1818. if (m_rxBuffer.Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) == 0)
  1819. {
  1820. DoPeerClose ();
  1821. }
  1822. }
  1823. }
  1824. /** Called by ForwardUp() to estimate RTT */
  1825. void
  1826. TcpSocketBase::EstimateRtt (const TcpHeader& tcpHeader)
  1827. {
  1828. // Use m_rtt for the estimation. Note, RTT of duplicated acknowledgement
  1829. // (which should be ignored) is handled by m_rtt. Once timestamp option
  1830. // is implemented, this function would be more elaborated.
  1831. m_lastRtt = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
  1832. }
  1833. // Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd()
  1834. // when the three-way handshake completed. This cancels retransmission timer
  1835. // and advances Tx window
  1836. void
  1837. TcpSocketBase::NewAck (SequenceNumber32 const& ack)
  1838. {
  1839. NS_LOG_FUNCTION (this << ack);
  1840. if (m_state != SYN_RCVD)
  1841. { // Set RTO unless the ACK is received in SYN_RCVD state
  1842. NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
  1843. (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
  1844. m_retxEvent.Cancel ();
  1845. // On recieving a "New" ack we restart retransmission timer .. RFC 2988
  1846. m_rto = m_rtt->RetransmitTimeout ();
  1847. NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " <<
  1848. Simulator::Now ().GetSeconds () << " to expire at time " <<
  1849. (Simulator::Now () + m_rto.Get ()).GetSeconds ());
  1850. m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this);
  1851. }
  1852. if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ())
  1853. { // Zero window: Enter persist state to send 1 byte to probe
  1854. NS_LOG_LOGIC (this << "Enter zerowindow persist state");
  1855. NS_LOG_LOGIC (this << "Cancelled ReTxTimeout event which was set to expire at " <<
  1856. (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
  1857. m_retxEvent.Cancel ();
  1858. NS_LOG_LOGIC ("Schedule persist timeout at time " <<
  1859. Simulator::Now ().GetSeconds () << " to expire at time " <<
  1860. (Simulator::Now () + m_persistTimeout).GetSeconds ());
  1861. m_persistEvent = Simulator::Schedule (m_persistTimeout, &TcpSocketBase::PersistTimeout, this);
  1862. NS_ASSERT (m_persistTimeout == Simulator::GetDelayLeft (m_persistEvent));
  1863. }
  1864. // Note the highest ACK and tell app to send more
  1865. NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
  1866. " numberAck " << (ack - m_txBuffer.HeadSequence ())); // Number bytes ack'ed
  1867. m_txBuffer.DiscardUpTo (ack);
  1868. if (GetTxAvailable () > 0)
  1869. {
  1870. NotifySend (GetTxAvailable ());
  1871. }
  1872. if (ack > m_nextTxSequence)
  1873. {
  1874. m_nextTxSequence = ack; // If advanced
  1875. }
  1876. if (m_txBuffer.Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING)
  1877. { // No retransmit timer if no data to retransmit
  1878. NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
  1879. (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
  1880. m_retxEvent.Cancel ();
  1881. }
  1882. // Try to send more data
  1883. SendPendingData (m_connected);
  1884. }
  1885. // Retransmit timeout
  1886. void
  1887. TcpSocketBase::ReTxTimeout ()
  1888. {
  1889. NS_LOG_FUNCTION (this);
  1890. NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
  1891. // If erroneous timeout in closed/timed-wait state, just return
  1892. if (m_state == CLOSED || m_state == TIME_WAIT)
  1893. {
  1894. return;
  1895. }
  1896. // If all data are received (non-closing socket and nothing to send), just return
  1897. if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_highTxMark)
  1898. {
  1899. return;
  1900. }
  1901. Retransmit ();
  1902. }
  1903. void
  1904. TcpSocketBase::DelAckTimeout (void)
  1905. {
  1906. m_delAckCount = 0;
  1907. SendEmptyPacket (TcpHeader::ACK);
  1908. }
  1909. void
  1910. TcpSocketBase::LastAckTimeout (void)
  1911. {
  1912. NS_LOG_FUNCTION (this);
  1913. m_lastAckEvent.Cancel ();
  1914. if (m_state == LAST_ACK)
  1915. {
  1916. CloseAndNotify ();
  1917. }
  1918. if (!m_closeNotified)
  1919. {
  1920. m_closeNotified = true;
  1921. }
  1922. }
  1923. // Send 1-byte data to probe for the window size at the receiver when
  1924. // the local knowledge tells that the receiver has zero window size
  1925. // C.f.: RFC793 p.42, RFC1112 sec.4.2.2.17
  1926. void
  1927. TcpSocketBase::PersistTimeout ()
  1928. {
  1929. NS_LOG_LOGIC ("PersistTimeout expired at " << Simulator::Now ().GetSeconds ());
  1930. m_persistTimeout = std::min (Seconds (60), Time (2 * m_persistTimeout)); // max persist timeout = 60s
  1931. Ptr<Packet> p = m_txBuffer.CopyFromSequence (1, m_nextTxSequence);
  1932. TcpHeader tcpHeader;
  1933. tcpHeader.SetSequenceNumber (m_nextTxSequence);
  1934. tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ());
  1935. tcpHeader.SetWindowSize (AdvertisedWindowSize ());
  1936. if (m_endPoint != 0)
  1937. {
  1938. tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
  1939. tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
  1940. }
  1941. else
  1942. {
  1943. tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ());
  1944. tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ());
  1945. }
  1946. AddOptions (tcpHeader);
  1947. if (m_endPoint != 0)
  1948. {
  1949. m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
  1950. m_endPoint->GetPeerAddress (), m_boundnetdevice);
  1951. }
  1952. else
  1953. {
  1954. m_tcp->SendPacket (p, tcpHeader, m_endPoint6->GetLocalAddress (),
  1955. m_endPoint6->GetPeerAddress (), m_boundnetdevice);
  1956. }
  1957. NS_LOG_LOGIC ("Schedule persist timeout at time "
  1958. << Simulator::Now ().GetSeconds () << " to expire at time "
  1959. << (Simulator::Now () + m_persistTimeout).GetSeconds ());
  1960. m_persistEvent = Simulator::Schedule (m_persistTimeout, &TcpSocketBase::PersistTimeout, this);
  1961. }
  1962. void
  1963. TcpSocketBase::Retransmit ()
  1964. {
  1965. m_nextTxSequence = m_txBuffer.HeadSequence (); // Start from highest Ack
  1966. m_rtt->IncreaseMultiplier (); // Double the timeout value for next retx timer
  1967. m_dupAckCount = 0;
  1968. DoRetransmit (); // Retransmit the packet
  1969. }
  1970. void
  1971. TcpSocketBase::DoRetransmit ()
  1972. {
  1973. NS_LOG_FUNCTION (this);
  1974. // Retransmit SYN packet
  1975. if (m_state == SYN_SENT)
  1976. {
  1977. if (m_cnCount > 0)
  1978. {
  1979. SendEmptyPacket (TcpHeader::SYN);
  1980. }
  1981. else
  1982. {
  1983. NotifyConnectionFailed ();
  1984. }
  1985. return;
  1986. }
  1987. // Retransmit non-data packet: Only if in FIN_WAIT_1 or CLOSING state
  1988. if (m_txBuffer.Size () == 0)
  1989. {
  1990. if (m_state == FIN_WAIT_1 || m_state == CLOSING)
  1991. { // Must have lost FIN, re-send
  1992. SendEmptyPacket (TcpHeader::FIN);
  1993. }
  1994. return;
  1995. }
  1996. // Retransmit a data packet: Call SendDataPacket
  1997. NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer.HeadSequence ());
  1998. uint32_t sz = SendDataPacket (m_txBuffer.HeadSequence (), m_segmentSize, true);
  1999. // In case of RTO, advance m_nextTxSequence
  2000. m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer.HeadSequence () + sz);
  2001. }
  2002. void
  2003. TcpSocketBase::CancelAllTimers ()
  2004. {
  2005. m_retxEvent.Cancel ();
  2006. m_persistEvent.Cancel ();
  2007. m_delAckEvent.Cancel ();
  2008. m_lastAckEvent.Cancel ();
  2009. m_timewaitEvent.Cancel ();
  2010. }
  2011. /** Move TCP to Time_Wait state and schedule a transition to Closed state */
  2012. void
  2013. TcpSocketBase::TimeWait ()
  2014. {
  2015. NS_LOG_INFO (TcpStateName[m_state] << " -> TIME_WAIT");
  2016. m_state = TIME_WAIT;
  2017. CancelAllTimers ();
  2018. // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min
  2019. // according to RFC793, p.28
  2020. m_timewaitEvent = Simulator::Schedule (Seconds (2 * m_msl),
  2021. &TcpSocketBase::CloseAndNotify, this);
  2022. }
  2023. /** Below are the attribute get/set functions */
  2024. void
  2025. TcpSocketBase::SetSndBufSize (uint32_t size)
  2026. {
  2027. m_txBuffer.SetMaxBufferSize (size);
  2028. }
  2029. uint32_t
  2030. TcpSocketBase::GetSndBufSize (void) const
  2031. {
  2032. return m_txBuffer.MaxBufferSize ();
  2033. }
  2034. void
  2035. TcpSocketBase::SetRcvBufSize (uint32_t size)
  2036. {
  2037. m_rxBuffer.SetMaxBufferSize (size);
  2038. }
  2039. uint32_t
  2040. TcpSocketBase::GetRcvBufSize (void) const
  2041. {
  2042. return m_rxBuffer.MaxBufferSize ();
  2043. }
  2044. void
  2045. TcpSocketBase::SetSegSize (uint32_t size)
  2046. {
  2047. m_segmentSize = size;
  2048. NS_ABORT_MSG_UNLESS (m_state == CLOSED, "Cannot change segment size dynamically.");
  2049. }
  2050. uint32_t
  2051. TcpSocketBase::GetSegSize (void) const
  2052. {
  2053. return m_segmentSize;
  2054. }
  2055. void
  2056. TcpSocketBase::SetConnTimeout (Time timeout)
  2057. {
  2058. m_cnTimeout = timeout;
  2059. }
  2060. Time
  2061. TcpSocketBase::GetConnTimeout (void) const
  2062. {
  2063. return m_cnTimeout;
  2064. }
  2065. void
  2066. TcpSocketBase::SetConnCount (uint32_t count)
  2067. {
  2068. m_cnRetries = count;
  2069. }
  2070. uint32_t
  2071. TcpSocketBase::GetConnCount (void) const
  2072. {
  2073. return m_cnRetries;
  2074. }
  2075. void
  2076. TcpSocketBase::SetDelAckTimeout (Time timeout)
  2077. {
  2078. m_delAckTimeout = timeout;
  2079. }
  2080. Time
  2081. TcpSocketBase::GetDelAckTimeout (void) const
  2082. {
  2083. return m_delAckTimeout;
  2084. }
  2085. void
  2086. TcpSocketBase::SetDelAckMaxCount (uint32_t count)
  2087. {
  2088. m_delAckMaxCount = count;
  2089. }
  2090. uint32_t
  2091. TcpSocketBase::GetDelAckMaxCount (void) const
  2092. {
  2093. return m_delAckMaxCount;
  2094. }
  2095. void
  2096. TcpSocketBase::SetTcpNoDelay (bool noDelay)
  2097. {
  2098. m_noDelay = noDelay;
  2099. }
  2100. bool
  2101. TcpSocketBase::GetTcpNoDelay (void) const
  2102. {
  2103. return m_noDelay;
  2104. }
  2105. void
  2106. TcpSocketBase::SetPersistTimeout (Time timeout)
  2107. {
  2108. m_persistTimeout = timeout;
  2109. }
  2110. Time
  2111. TcpSocketBase::GetPersistTimeout (void) const
  2112. {
  2113. return m_persistTimeout;
  2114. }
  2115. bool
  2116. TcpSocketBase::SetAllowBroadcast (bool allowBroadcast)
  2117. {
  2118. // Broadcast is not implemented. Return true only if allowBroadcast==false
  2119. return (!allowBroadcast);
  2120. }
  2121. bool
  2122. TcpSocketBase::GetAllowBroadcast (void) const
  2123. {
  2124. return false;
  2125. }
  2126. /** Placeholder function for future extension that reads more from the TCP header */
  2127. void
  2128. TcpSocketBase::ReadOptions (const TcpHeader&)
  2129. {
  2130. }
  2131. /** Placeholder function for future extension that changes the TCP header */
  2132. void
  2133. TcpSocketBase::AddOptions (TcpHeader&)
  2134. {
  2135. }
  2136. } // namespace ns3