A Discrete-Event Network Simulator
API
nsc-tcp-socket-impl.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  * based on tcp-socket-impl.cc, Author: Raj Bhattacharjea <raj.b@gatech.edu>
17  * Author: Florian Westphal <fw@strlen.de>
18  */
19 
20 #define NS_LOG_APPEND_CONTEXT \
21  if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
22 
23 #include "ns3/node.h"
24 #include "ns3/inet-socket-address.h"
25 #include "ns3/log.h"
26 #include "ns3/ipv4.h"
27 #include "ipv4-end-point.h"
28 #include "nsc-tcp-l4-protocol.h"
29 #include "nsc-tcp-socket-impl.h"
30 #include "ns3/simulation-singleton.h"
31 #include "ns3/simulator.h"
32 #include "ns3/packet.h"
33 #include "ns3/uinteger.h"
34 #include "ns3/trace-source-accessor.h"
35 
36 #include <algorithm>
37 
38 // for ntohs().
39 #include <arpa/inet.h>
40 #include <netinet/in.h>
41 #include "sim_interface.h"
42 
43 #include "sim_errno.h"
44 
45 
46 namespace ns3 {
47 
48 NS_LOG_COMPONENT_DEFINE ("NscTcpSocketImpl");
49 
50 NS_OBJECT_ENSURE_REGISTERED (NscTcpSocketImpl);
51 
52 TypeId
54 {
55  static TypeId tid = TypeId ("ns3::NscTcpSocketImpl")
56  .SetParent<TcpSocket> ()
57  .SetGroupName ("Internet")
58  .AddTraceSource ("CongestionWindow",
59  "The TCP connection's congestion window",
61  "ns3::TracedValueCallback::Uint32")
62  .AddTraceSource ("SlowStartThreshold",
63  "TCP slow start threshold (bytes)",
65  "ns3::TracedValueCallback::Uint32")
66  .AddTraceSource ("State",
67  "TCP state",
69  "ns3::TcpStatesTracedValueCallback")
70  ;
71  return tid;
72 }
73 
75  : m_endPoint (0),
76  m_node (0),
77  m_tcp (0),
78  m_localAddress (Ipv4Address::GetZero ()),
79  m_localPort (0),
80  m_peerAddress ("0.0.0.0", 0),
81  m_errno (ERROR_NOTERROR),
82  m_shutdownSend (false),
83  m_shutdownRecv (false),
84  m_connected (false),
85  m_state (CLOSED),
86  m_closeOnEmpty (false),
87  m_txBufferSize (0),
88  m_lastMeasuredRtt (Seconds (0.0))
89 {
90  NS_LOG_FUNCTION (this);
91 }
92 
94  : TcpSocket (sock), //copy the base class callbacks
95  m_delAckMaxCount (sock.m_delAckMaxCount),
96  m_delAckTimeout (sock.m_delAckTimeout),
97  m_noDelay (sock.m_noDelay),
98  m_endPoint (0),
99  m_node (sock.m_node),
100  m_tcp (sock.m_tcp),
101  m_remoteAddress (sock.m_remoteAddress),
102  m_remotePort (sock.m_remotePort),
103  m_localAddress (sock.m_localAddress),
104  m_localPort (sock.m_localPort),
105  m_peerAddress (sock.m_peerAddress),
106  m_errno (sock.m_errno),
107  m_shutdownSend (sock.m_shutdownSend),
108  m_shutdownRecv (sock.m_shutdownRecv),
109  m_connected (sock.m_connected),
110  m_state (sock.m_state),
111  m_closeOnEmpty (sock.m_closeOnEmpty),
112  m_txBufferSize (sock.m_txBufferSize),
113  m_segmentSize (sock.m_segmentSize),
114  m_rxWindowSize (sock.m_rxWindowSize),
115  m_advertisedWindowSize (sock.m_advertisedWindowSize),
116  m_cWnd (sock.m_cWnd),
117  m_ssThresh (sock.m_ssThresh),
118  m_initialCWnd (sock.m_initialCWnd),
119  m_initialSsThresh (sock.m_initialSsThresh),
120  m_lastMeasuredRtt (Seconds (0.0)),
121  m_cnTimeout (sock.m_cnTimeout),
122  m_synRetries (sock.m_synRetries),
123  m_rxAvailable (0),
124  m_nscTcpSocket (0),
125  m_sndBufSize (sock.m_sndBufSize)
126 {
127  NS_LOG_FUNCTION (this);
128  NS_LOG_LOGIC ("Invoked the copy constructor");
129  //copy the pending data if necessary
130  if(!sock.m_txBuffer.empty () )
131  {
132  m_txBuffer = sock.m_txBuffer;
133  }
134  //can't "copy" the endpoint just yes, must do this when we know the peer info
135  //too; this is in SYN_ACK_TX
136 }
137 
139 {
140  NS_LOG_FUNCTION (this);
141  m_node = 0;
142  if (m_endPoint != 0)
143  {
144  NS_ASSERT (m_tcp != 0);
153  NS_ASSERT (m_endPoint != 0);
154  m_tcp->DeAllocate (m_endPoint);
155  NS_ASSERT (m_endPoint == 0);
156  }
157  m_tcp = 0;
158 }
159 
160 void
162 {
163  m_node = node;
164  // Initialize some variables
168 }
169 
170 void
172 {
173  m_nscTcpSocket = tcp->m_nscStack->new_tcp_socket ();
174  m_tcp = tcp;
175 }
176 
177 
180 {
181  NS_LOG_FUNCTION (this);
182  return m_errno;
183 }
184 
187 {
188  return NS3_SOCK_STREAM;
189 }
190 
191 Ptr<Node>
193 {
194  NS_LOG_FUNCTION (this);
195  return m_node;
196 }
197 
198 void
200 {
201  NS_LOG_FUNCTION (this);
202  m_node = 0;
203  m_endPoint = 0;
204  m_tcp = 0;
205 }
206 int
208 {
209  NS_LOG_FUNCTION (this);
210  if (m_endPoint == 0)
211  {
212  return -1;
213  }
218  return 0;
219 }
220 
221 int
223 {
224  NS_LOG_FUNCTION (this);
225  m_endPoint = m_tcp->Allocate ();
226  return FinishBind ();
227 }
228 int
230 {
231  NS_LOG_LOGIC ("NscTcpSocketImpl: ERROR_AFNOSUPPORT - Bind6 not supported");
233  return (-1);
234 }
235 int
237 {
238  NS_LOG_FUNCTION (this<<address);
240  {
241  return ERROR_INVAL;
242  }
244  Ipv4Address ipv4 = transport.GetIpv4 ();
245  uint16_t port = transport.GetPort ();
246  if (ipv4 == Ipv4Address::GetAny () && port == 0)
247  {
248  m_endPoint = m_tcp->Allocate ();
249  NS_LOG_LOGIC ("NscTcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
250  }
251  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
252  {
253  m_endPoint = m_tcp->Allocate (GetBoundNetDevice (), port);
254  NS_LOG_LOGIC ("NscTcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
255  }
256  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
257  {
258  m_endPoint = m_tcp->Allocate (ipv4);
259  NS_LOG_LOGIC ("NscTcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
260  }
261  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
262  {
263  m_endPoint = m_tcp->Allocate (GetBoundNetDevice (), ipv4, port);
264  NS_LOG_LOGIC ("NscTcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
265  }
266 
267  m_localPort = port;
268  return FinishBind ();
269 }
270 
271 /* Inherit from Socket class: Bind this socket to the specified NetDevice */
272 void
274 {
275  NS_LOG_FUNCTION (this << netdevice);
276  Socket::BindToNetDevice (netdevice); // Includes sanity check
277  if (m_endPoint != 0)
278  {
279  m_endPoint->BindToNetDevice (netdevice);
280  }
281  return;
282 }
283 
284 int
286 {
287  NS_LOG_FUNCTION (this);
288  m_shutdownSend = true;
289  return 0;
290 }
291 int
293 {
294  NS_LOG_FUNCTION (this);
295  m_shutdownRecv = true;
296  return 0;
297 }
298 
299 int
301 {
302  NS_LOG_FUNCTION (this << m_state);
303 
304  if (m_state == CLOSED)
305  {
306  return -1;
307  }
308  if (!m_txBuffer.empty ())
309  { // App close with pending data must wait until all data transmitted
310  m_closeOnEmpty = true;
311  NS_LOG_LOGIC ("Socket " << this <<
312  " deferring close, state " << m_state);
313  return 0;
314  }
315 
316  NS_LOG_LOGIC ("NscTcp socket " << this << " calling disconnect(); moving to CLOSED");
318  m_state = CLOSED;
319  ShutdownSend ();
320  return 0;
321 }
322 
323 int
325 {
326  NS_LOG_FUNCTION (this << address);
327  if (m_endPoint == 0)
328  {
329  if (Bind () == -1)
330  {
331  NS_ASSERT (m_endPoint == 0);
332  return -1;
333  }
334  NS_ASSERT (m_endPoint != 0);
335  }
337  m_remoteAddress = transport.GetIpv4 ();
338  m_remotePort = transport.GetPort ();
339 
340  std::ostringstream ss;
341  m_remoteAddress.Print (ss);
342  std::string ipstring = ss.str ();
343 
344  m_nscTcpSocket->connect (ipstring.c_str (), m_remotePort);
345  m_state = SYN_SENT;
346  return 0;
347 }
348 
349 int
350 NscTcpSocketImpl::Send (const Ptr<Packet> p, uint32_t flags)
351 {
352  NS_LOG_FUNCTION (this << p);
353 
354  NS_ASSERT (p->GetSize () > 0);
356  {
357  if (p->GetSize () > GetTxAvailable ())
358  {
360  return -1;
361  }
362 
363  uint32_t sent = p->GetSize ();
364  if (m_state == ESTABLISHED)
365  {
366  m_txBuffer.push (p);
367  m_txBufferSize += sent;
368  SendPendingData ();
369  }
370  else
371  { // SYN_SET -- Queue Data
372  m_txBuffer.push (p);
373  m_txBufferSize += sent;
374  }
375  return sent;
376  }
377  else
378  {
380  return -1;
381  }
382 }
383 
384 int
386 {
387  NS_LOG_FUNCTION (this << address << p);
388  if (!m_connected)
389  {
391  return -1;
392  }
393  else
394  {
395  return Send (p, flags); //drop the address according to BSD manpages
396  }
397 }
398 
399 uint32_t
401 {
402  NS_LOG_FUNCTION (this);
403  if (m_txBufferSize != 0)
404  {
406  return m_sndBufSize - m_txBufferSize;
407  }
408  else
409  {
410  return m_sndBufSize;
411  }
412 }
413 
414 int
416 {
417  NS_LOG_FUNCTION (this);
419  m_state = LISTEN;
420  return 0;
421 }
422 
423 
424 void
426 {
427  NS_LOG_FUNCTION (this);
428  switch (m_state) {
429  case SYN_SENT:
430  if (!m_nscTcpSocket->is_connected ())
431  break;
434  // fall through to schedule read/write events
435  case ESTABLISHED:
436  if (!m_txBuffer.empty ())
437  {
439  }
440  else
441  {
442  if (GetTxAvailable ())
443  {
445  }
446  }
448  break;
449  case LISTEN:
451  break;
452  case CLOSED: break;
453  default:
454  NS_LOG_DEBUG (this << " invalid state: " << m_state);
455  }
456 }
457 
459 NscTcpSocketImpl::Recv (uint32_t maxSize, uint32_tNS_LOG_FUNCTION (this)ON_NOARGS ();
460  if (m_deliveryQueue.empty () )
461  {
462  m_errno = ERROR_AGAIN;
463  return 0;
464  }
465  Ptr<Packet> p = m_deliveryQueue.front ();
466  if (p->GetSize () <= maxSize)
467  {
468  m_deliveryQueue.pop ();
469  m_rxAvailable -= p->GetSize ();
470  }
471  else
472  {
473  m_errno = ERROR_AGAIN;
474  p = 0;
475  }
476  return p;
477 }
478 
479 Ptr<Packet>
480 NscTcpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
481  Address &fromAddress)
482 {
483  NS_LOG_FUNCTION (this << maxSize << flags);
484  Ptr<Packet> packet = Recv (maxSize, flags);
485  GetPeerName (fromAddress);
486  return packet;
487 }
488 
489 int
490 NscTcpSocketImpl::GetSockName (Address &address) const
491 {
492  NS_LOG_FUNCTION (this << address);
493  address = InetSocketAddress (m_localAddress, m_localPort);
494  return 0;
495 }
496 
497 int
498 NscTcpSocketImpl::GetPeerName (Address &address) const
499 {
500  NS_LOG_FUNCTION (this << address);
501 
502  if (!m_endPoint)
503  {
504  m_errno = ERROR_NOTCONN;
505  return -1;
506  }
507  address = InetSocketAddress (m_endPoint->GetPeerAddress (),
508  m_endPoint->GetPeerPort ());
509  return 0;
510 }
511 
512 uint32_t
513 NscTcpSocketImpl::GetRxAvailable (void) const
514 {
515  NS_LOG_FUNCTION (this);
516  // We separately maintain this state to avoid walking the queue
517  // every time this might be called
518  return m_rxAvailable;
519 }
520 
521 void
522 NscTcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port,
523  Ptr<Ipv4Interface> incomingInterface)
524 {
525  NSCWakeup ();
526 }
527 
528 void NscTcpSocketImpl::CompleteFork (void)
529 {
530  // The address pairs (m_localAddress, m_localPort, m_remoteAddress, m_remotePort)
531  // are bogus, but this isn't important at the moment, because
532  // address <-> Socket handling is done by NSC internally.
533  // We only need to add the new ns-3 socket to the list of sockets, so
534  // we use plain Allocate() instead of Allocate(m_localAddress, ... )
535  struct sockaddr_in sin;
536  size_t sin_len = sizeof(sin);
537 
538  if (0 == m_nscTcpSocket->getpeername ((struct sockaddr*) &sin, &sin_len)) {
539  m_remotePort = ntohs (sin.sin_port);
540  m_remoteAddress = Ipv4Address::Deserialize ((const uint8_t*) &sin.sin_addr);
541  m_peerAddress = InetSocketAddress (m_remoteAddress, m_remotePort);
542  }
543 
544  m_endPoint = m_tcp->Allocate ();
545 
546  //the cloned socket with be in listen state, so manually change state
547  NS_ASSERT (m_state == LISTEN);
548  m_state = ESTABLISHED;
549 
550  sin_len = sizeof(sin);
551 
552  if (0 == m_nscTcpSocket->getsockname ((struct sockaddr *) &sin, &sin_len))
553  m_localAddress = Ipv4Address::Deserialize ((const uint8_t*) &sin.sin_addr);
554 
555  NS_LOG_LOGIC ("NscTcpSocketImpl " << this << " accepted connection from "
556  << m_remoteAddress << ":" << m_remotePort
557  << " to " << m_localAddress << ":" << m_localPort);
558  //equivalent to FinishBind
559  m_endPoint->SetRxCallback (MakeCallback (&NscTcpSocketImpl::ForwardUp, Ptr<NscTcpSocketImpl>(this)));
560  m_endPoint->SetDestroyCallback (MakeCallback (&NscTcpSocketImpl::Destroy, Ptr<NscTcpSocketImpl>(this)));
561 
562  NotifyNewConnectionCreated (this, m_peerAddress);
563 }
564 
565 void NscTcpSocketImpl::ConnectionSucceeded ()
566 { // We would preferred to have scheduled an event directly to
567  // NotifyConnectionSucceeded, but (sigh) these are protected
568  // and we can get the address of it :(
569  struct sockaddr_in sin;
570  size_t sin_len = sizeof(sin);
571  if (0 == m_nscTcpSocket->getsockname ((struct sockaddr *) &sin, &sin_len)) {
572  m_localAddress = Ipv4Address::Deserialize ((const uint8_t*)&sin.sin_addr);
573  m_localPort = ntohs (sin.sin_port);
574  }
575 
576  NS_LOG_LOGIC ("NscTcpSocketImpl " << this << " connected to "
577  << m_remoteAddress << ":" << m_remotePort
578  << " from " << m_localAddress << ":" << m_localPort);
579  NotifyConnectionSucceeded ();
580 }
581 
582 
583 bool NscTcpSocketImpl::Accept (void)
584 {
585  if (m_state == CLOSED)
586  { // Happens if application closes listening socket after Accept() was scheduled.
587  return false;
588  }
589  NS_ASSERT (m_state == LISTEN);
590 
591  if (!m_nscTcpSocket->is_listening ())
592  {
593  return false;
594  }
595  INetStreamSocket *newsock;
596  int res = m_nscTcpSocket->accept (&newsock);
597  if (res != 0)
598  {
599  return false;
600  }
601 // We could obtain a fromAddress using getpeername, but we've already
602 // finished the tcp handshake here, i.e. this is a new connection
603 // and not a connection request.
604 // if (!NotifyConnectionRequest(fromAddress))
605 // return true;
606 
607  // Clone the socket
608  Ptr<NscTcpSocketImpl> newSock = Copy ();
609  newSock->m_nscTcpSocket = newsock;
610  NS_LOG_LOGIC ("Cloned a NscTcpSocketImpl " << newSock);
611 
612  Simulator::ScheduleNow (&NscTcpSocketImpl::CompleteFork, newSock);
613  return true;
614 }
615 
616 bool NscTcpSocketImpl::ReadPendingData (void)
617 {
618  if (m_state != ESTABLISHED)
619  {
620  return false;
621  }
622  int len, err;
623  uint8_t buffer[8192];
624  len = sizeof(buffer);
625  m_errno = ERROR_NOTERROR;
626  err = m_nscTcpSocket->read_data (buffer, &len);
627  if (err == 0 && len == 0)
628  {
629  NS_LOG_LOGIC ("ReadPendingData got EOF from socket");
630  m_state = CLOSE_WAIT;
631  return false;
632  }
633  m_errno = GetNativeNs3Errno (err);
634  switch (m_errno)
635  {
636  case ERROR_NOTERROR: break; // some data was sent
637  case ERROR_AGAIN: return false;
638  default:
639  NS_LOG_WARN ("Error (" << err << ") " <<
640  "during read_data, ns-3 errno set to" << m_errno);
641  m_state = CLOSED;
642  return false;
643  }
644 
645  Ptr<Packet> p = Create<Packet> (buffer, len);
646 
647  m_deliveryQueue.push (p);
648  m_rxAvailable += p->GetSize ();
649 
650  NotifyDataRecv ();
651  return true;
652 }
653 
654 bool NscTcpSocketImpl::SendPendingData (void)
655 {
656  NS_LOG_FUNCTION (this);
657  NS_LOG_LOGIC ("ENTERING SendPendingData");
658 
659  if (m_txBuffer.empty ())
660  {
661  return false;
662  }
663 
664  int ret;
665  size_t size, written = 0;
666 
667  do {
668  NS_ASSERT (!m_txBuffer.empty ());
669  Ptr<Packet> &p = m_txBuffer.front ();
670  size = p->GetSize ();
671  NS_ASSERT (size > 0);
672 
673  m_errno = ERROR_NOTERROR;
674 
675  uint8_t *buf = new uint8_t[size];
676  p->CopyData (buf, size);
677  ret = m_nscTcpSocket->send_data ((const char *)buf, size);
678  delete[] buf;
679 
680  if (ret <= 0)
681  {
682  break;
683  }
684  written += ret;
685 
686  NS_ASSERT (m_txBufferSize >= (size_t)ret);
687  m_txBufferSize -= ret;
688 
689  if ((size_t)ret < size)
690  {
691  p->RemoveAtStart (ret);
692  break;
693  }
694 
695  m_txBuffer.pop ();
696 
697  if (m_txBuffer.empty ())
698  {
699  if (m_closeOnEmpty)
700  {
701  m_nscTcpSocket->disconnect ();
702  m_state = CLOSED;
703  }
704  break;
705  }
706  } while ((size_t) ret == size);
707 
708  if (written > 0)
709  {
710  NS_LOG_DEBUG ("Notifying data sent, remaining txbuffer size: " << m_txBufferSize);
711  Simulator::ScheduleNow (&NscTcpSocketImpl::NotifyDataSent, this, ret);
712  return true;
713  }
714  else
715  {
716  NS_LOG_DEBUG ("Not notifying data sent, return value " << ret);
717  }
718  return false;
719 }
720 
722 {
723  return CopyObject<NscTcpSocketImpl> (this);
724 }
725 
726 void
727 NscTcpSocketImpl::SetSndBufSize (uint32_t size)
728 {
729  m_sndBufSize = size;
730 }
731 
732 uint32_t
733 NscTcpSocketImpl::GetSndBufSize (void) const
734 {
735  return m_sndBufSize;
736 }
737 
738 void
739 NscTcpSocketImpl::SetRcvBufSize (uint32_t size)
740 {
741  m_rcvBufSize = size;
742 }
743 
744 uint32_t
745 NscTcpSocketImpl::GetRcvBufSize (void) const
746 {
747  return m_rcvBufSize;
748 }
749 
750 void
751 NscTcpSocketImpl::SetSegSize (uint32_t size)
752 {
753  m_segmentSize = size;
754 }
755 
756 uint32_t
757 NscTcpSocketImpl::GetSegSize (void) const
758 {
759  return m_segmentSize;
760 }
761 
762 void
763 NscTcpSocketImpl::SetAdvWin (uint32_t window)
764 {
765  m_advertisedWindowSize = window;
766 }
767 
768 uint32_t
769 NscTcpSocketImpl::GetAdvWin (void) const
770 {
771  return m_advertisedWindowSize;
772 }
773 
774 void
775 NscTcpSocketImpl::SetInitialSSThresh (uint32_t threshold)
776 {
777  m_initialSsThresh = threshold;
778 }
779 
780 uint32_t
781 NscTcpSocketImpl::GetInitialSSThresh (void) const
782 {
783  return m_initialSsThresh;
784 }
785 
786 void
787 NscTcpSocketImpl::SetInitialCwnd (uint32_t cwnd)
788 {
789  m_initialCWnd = cwnd;
790 }
791 
792 uint32_t
793 NscTcpSocketImpl::GetInitialCwnd (void) const
794 {
795  return m_initialCWnd;
796 }
797 
798 void
799 NscTcpSocketImpl::SetConnTimeout (Time timeout)
800 {
801  m_cnTimeout = timeout;
802 }
803 
804 Time
805 NscTcpSocketImpl::GetConnTimeout (void) const
806 {
807  return m_cnTimeout;
808 }
809 
810 void
811 NscTcpSocketImpl::SetSynRetries (uint32_t count)
812 {
813  m_synRetries = count;
814 }
815 
816 uint32_t
817 NscTcpSocketImpl::GetSynRetries (void) const
818 {
819  return m_synRetries;
820 }
821 
822 void
823 NscTcpSocketImpl::SetDelAckTimeout (Time timeout)
824 {
825  m_delAckTimeout = timeout;
826 }
827 
828 void
829 NscTcpSocketImpl::SetDataRetries (uint32_t retries)
830 {
831  NS_LOG_FUNCTION (this << retries);
832  m_dataRetries = retries;
833 }
834 
835 uint32_t
836 NscTcpSocketImpl::GetDataRetries (void) const
837 {
838  NS_LOG_FUNCTION (this);
839  return m_dataRetries;
840 }
841 
842 Time
843 NscTcpSocketImpl::GetDelAckTimeout (void) const
844 {
845  return m_delAckTimeout;
846 }
847 
848 void
849 NscTcpSocketImpl::SetDelAckMaxCount (uint32_t count)
850 {
851  m_delAckMaxCount = count;
852 }
853 
854 uint32_t
855 NscTcpSocketImpl::GetDelAckMaxCount (void) const
856 {
857  return m_delAckMaxCount;
858 }
859 
860 void
861 NscTcpSocketImpl::SetTcpNoDelay (bool noDelay)
862 {
863  m_noDelay = noDelay;
864 }
865 
866 bool
867 NscTcpSocketImpl::GetTcpNoDelay (void) const
868 {
869  return m_noDelay;
870 }
871 
872 void
873 NscTcpSocketImpl::SetPersistTimeout (Time timeout)
874 {
875  m_persistTimeout = timeout;
876 }
877 
878 Time
879 NscTcpSocketImpl::GetPersistTimeout (void) const
880 {
881  return m_persistTimeout;
882 }
883 
885 NscTcpSocketImpl::GetNativeNs3Errno (int error) const
886 {
887  enum nsc_errno err;
888 
889  if (error >= 0)
890  {
891  return ERROR_NOTERROR;
892  }
893  err = (enum nsc_errno) error;
894  switch (err)
895  {
896  case NSC_EADDRINUSE: // fallthrough
897  case NSC_EADDRNOTAVAIL: return ERROR_AFNOSUPPORT;
898  case NSC_EINPROGRESS: // Although nsc sockets are nonblocking, we pretend they're not.
899  case NSC_EAGAIN: return ERROR_AGAIN;
900  case NSC_EISCONN: // fallthrough
901  case NSC_EALREADY: return ERROR_ISCONN;
902  case NSC_ECONNREFUSED: return ERROR_NOROUTETOHOST;
903  case NSC_ECONNRESET: // for no, all of these fall through
904  case NSC_EHOSTDOWN:
905  case NSC_ENETUNREACH:
906  case NSC_EHOSTUNREACH: return ERROR_NOROUTETOHOST;
907  case NSC_EMSGSIZE: return ERROR_MSGSIZE;
908  case NSC_ENOTCONN: return ERROR_NOTCONN;
909  case NSC_ESHUTDOWN: return ERROR_SHUTDOWN;
910  case NSC_ETIMEDOUT: return ERROR_NOTCONN;
911  case NSC_ENOTDIR: // used by eg. sysctl(2). Shouldn't happen normally,
912  // but is triggered by e.g. show_config().
913  case NSC_EUNKNOWN: return ERROR_INVAL; // Catches stacks that 'return -1' without real mapping
914  }
915  NS_ASSERT_MSG (0, "Unknown NSC error");
916  return ERROR_INVAL;
917 }
918 
919 bool
920 NscTcpSocketImpl::SetAllowBroadcast (bool allowBroadcast)
921 {
922  if (allowBroadcast)
923  {
924  return false;
925  }
926  return true;
927 }
928 
929 bool
930 NscTcpSocketImpl::GetAllowBroadcast () const
931 {
932  return false;
933 }
934 
935 } // namespace ns3
Ipv4EndPoint * m_endPoint
the IPv4 endpoint
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
an Inet address class
static Ipv4Address GetAny(void)
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Connection established.
Definition: tcp-socket.h:71
virtual int ShutdownSend(void)
void Destroy(void)
Kill this socket by zeroing its attributes (IPv4)
(abstract) base class of all TcpSockets
Definition: tcp-socket.h:47
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
bool ReadPendingData(void)
Read all the pending data.
uint32_t m_txBufferSize
transmission buffer size
Ipv4Address m_localAddress
local address
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
NscTcpSocketImpl()
Create an unbound tcp socket.
Ptr< Node > m_node
the associated node
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv4Header, uint16_t, Ptr< Ipv4Interface > > callback)
Set the reception callback.
Ptr< Packet > Recv(void)
Read a single packet from the socket.
Definition: socket.cc:175
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
Ipv4Address m_remoteAddress
peer IP address
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
INetStreamSocket * m_nscTcpSocket
the real NSC TCP socket
TracedValue< TcpStates_t > m_state
state information
virtual int Bind6(void)
Allocate a local IPv6 endpoint for this socket.
uint32_t m_sndBufSize
buffer limit for the outgoing queue
void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
static TypeId GetTypeId(void)
Get the type ID.
nsc_errno
List of network stack errors that may happen in a simulation, and can be handled by the simulator in ...
Definition: sim_errno.h:41
bool m_shutdownSend
Send no longer allowed.
ns3::Time timeout
bool m_closeOnEmpty
true if socket will close when buffer is empty
virtual void connect(const char *, int)=0
Connect to a remote peer.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
virtual enum SocketErrno GetErrno(void) const
Get last error number.
uint16_t port
Definition: dsdv-manet.cc:45
a polymophic address class
Definition: address.h:90
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< NetDevice > GetBoundNetDevice()
Returns socket&#39;s bound NetDevice, if any.
Definition: socket.cc:351
Packet header for IPv4.
Definition: ipv4-header.h:33
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:588
uint32_t m_initialCWnd
Initial cWnd value.
void SetNode(Ptr< Node > node)
Set the associated node.
enum SocketErrno m_errno
last error number
virtual enum SocketType GetSocketType(void) const
uint32_t m_initialSsThresh
Initial Slow Start Threshold.
bool m_connected
Connection established.
Socket logic for the NSC TCP sockets.
bool Accept(void)
Accept an incoming connection.
virtual Ptr< Node > GetNode(void) const
Return the node this socket is associated with.
Ipv4Address GetLocalAddress(void)
Get the local address.
virtual int Send(Ptr< Packet > p, uint32_t flags)
Send data (or dummy data) to the remote host.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
virtual int ShutdownRecv(void)
virtual bool is_connected()=0
Check the connection state.
virtual int Listen(void)
Listen for incoming connections.
virtual int Bind(void)
Allocate a local IPv4 endpoint for this socket.
uint16_t m_remotePort
peer port
virtual uint32_t GetTxAvailable(void) const
Returns the number of bytes which can be sent in a single call to Send.
Ptr< NscTcpL4Protocol > m_tcp
the associated TCP L4 protocol
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
address
Definition: first.py:44
uint16_t GetPort(void) const
TracedValue< uint32_t > m_cWnd
Congestion window.
void ForwardUp(Ptr< Packet > p, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
Called by the L3 protocol when it received a packet to pass on to TCP.
Remote side has shutdown and is waiting for us to finish writing our data and to shutdown (we have to...
Definition: tcp-socket.h:72
Sent a connection request, waiting for ack.
Definition: tcp-socket.h:68
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
Socket is finished.
Definition: tcp-socket.h:66
Listening for a connection.
Definition: tcp-socket.h:67
bool m_shutdownRecv
Receive no longer allowed.
uint32_t m_rxWindowSize
Receive window size.
void SetTcp(Ptr< NscTcpL4Protocol > tcp)
Set the associated TCP L4 protocol.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
bool SendPendingData(void)
Send all the pending data.
int FinishBind(void)
Finish the binding process.
void ConnectionSucceeded()
Called when a connection is in Established state.
uint16_t GetLocalPort(void)
Get the local port.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
virtual int Close(void)
Close a socket.
virtual void listen(int)=0
Put the socket in Listening state on a port.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
Struct interface to NSC Stream (i.e., TCP) Sockets.
virtual void disconnect()=0
Disconnect from a remote peer.
uint16_t m_localPort
local port
void Print(std::ostream &os) const
Print this address to the given output stream.
virtual int accept(INetStreamSocket **handler)=0
Accept an incoming connection.
std::queue< Ptr< Packet > > m_txBuffer
transmission buffer
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)
Send data to a specified peer.
uint32_t m_advertisedWindowSize
Window to advertise.
TracedValue< uint32_t > m_ssThresh
Slow Start Threshold.
SocketType
Enumeration of the possible socket types.
Definition: socket.h:104
a unique identifier for an interface.
Definition: type-id.h:58
void NotifySend(uint32_t spaceAvailable)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:295
uint32_t m_segmentSize
SegmentSize.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
static bool IsMatchingType(const Address &address)
Ptr< T > Copy(Ptr< T > object)
Return a deep copy of a Ptr.
Definition: ptr.h:536
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
virtual int Connect(const Address &address)
Initiate a connection to a remote host.
Ipv4Address GetIpv4(void) const
void NSCWakeup(void)
Called by NscTcpSocketImpl::ForwardUp()