A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
nsc-tcp-socket-impl.cc
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 NS_LOG_COMPONENT_DEFINE ("NscTcpSocketImpl");
47 
48 namespace ns3 {
49 
50 NS_OBJECT_ENSURE_REGISTERED (NscTcpSocketImpl);
51 
52 TypeId
53 NscTcpSocketImpl::GetTypeId ()
54 {
55  static TypeId tid = TypeId ("ns3::NscTcpSocketImpl")
56  .SetParent<TcpSocket> ()
57  .AddTraceSource ("CongestionWindow",
58  "The TCP connection's congestion window",
59  MakeTraceSourceAccessor (&NscTcpSocketImpl::m_cWnd))
60  ;
61  return tid;
62 }
63 
65  : m_endPoint (0),
66  m_node (0),
67  m_tcp (0),
68  m_localAddress (Ipv4Address::GetZero ()),
69  m_localPort (0),
70  m_peerAddress ("0.0.0.0", 0),
71  m_errno (ERROR_NOTERROR),
72  m_shutdownSend (false),
73  m_shutdownRecv (false),
74  m_connected (false),
75  m_state (CLOSED),
76  m_closeOnEmpty (false),
77  m_txBufferSize (0),
78  m_lastMeasuredRtt (Seconds (0.0))
79 {
80  NS_LOG_FUNCTION (this);
81 }
82 
84  : TcpSocket (sock), //copy the base class callbacks
85  m_delAckMaxCount (sock.m_delAckMaxCount),
86  m_delAckTimeout (sock.m_delAckTimeout),
87  m_noDelay (sock.m_noDelay),
88  m_endPoint (0),
89  m_node (sock.m_node),
90  m_tcp (sock.m_tcp),
91  m_remoteAddress (sock.m_remoteAddress),
92  m_remotePort (sock.m_remotePort),
93  m_localAddress (sock.m_localAddress),
94  m_localPort (sock.m_localPort),
95  m_peerAddress (sock.m_peerAddress),
96  m_errno (sock.m_errno),
97  m_shutdownSend (sock.m_shutdownSend),
98  m_shutdownRecv (sock.m_shutdownRecv),
99  m_connected (sock.m_connected),
100  m_state (sock.m_state),
101  m_closeOnEmpty (sock.m_closeOnEmpty),
102  m_txBufferSize (sock.m_txBufferSize),
103  m_segmentSize (sock.m_segmentSize),
104  m_rxWindowSize (sock.m_rxWindowSize),
105  m_advertisedWindowSize (sock.m_advertisedWindowSize),
106  m_cWnd (sock.m_cWnd),
107  m_ssThresh (sock.m_ssThresh),
108  m_initialCWnd (sock.m_initialCWnd),
109  m_lastMeasuredRtt (Seconds (0.0)),
110  m_cnTimeout (sock.m_cnTimeout),
111  m_cnCount (sock.m_cnCount),
112  m_rxAvailable (0),
113  m_nscTcpSocket (0),
114  m_sndBufSize (sock.m_sndBufSize)
115 {
117  NS_LOG_LOGIC ("Invoked the copy constructor");
118  //copy the pending data if necessary
119  if(!sock.m_txBuffer.empty () )
120  {
121  m_txBuffer = sock.m_txBuffer;
122  }
123  //can't "copy" the endpoint just yes, must do this when we know the peer info
124  //too; this is in SYN_ACK_TX
125 }
126 
128 {
129  NS_LOG_FUNCTION (this);
130  m_node = 0;
131  if (m_endPoint != 0)
132  {
133  NS_ASSERT (m_tcp != 0);
142  NS_ASSERT (m_endPoint != 0);
143  m_tcp->DeAllocate (m_endPoint);
144  NS_ASSERT (m_endPoint == 0);
145  }
146  m_tcp = 0;
147 }
148 
149 void
150 NscTcpSocketImpl::SetNode (Ptr<Node> node)
151 {
152  m_node = node;
153  // Initialize some variables
154  m_cWnd = m_initialCWnd * m_segmentSize;
155  m_rxWindowSize = m_advertisedWindowSize;
156 }
157 
158 void
159 NscTcpSocketImpl::SetTcp (Ptr<NscTcpL4Protocol> tcp)
160 {
161  m_nscTcpSocket = tcp->m_nscStack->new_tcp_socket ();
162  m_tcp = tcp;
163 }
164 
165 
166 enum Socket::SocketErrno
168 {
170  return m_errno;
171 }
172 
173 enum Socket::SocketType
175 {
176  return NS3_SOCK_STREAM;
177 }
178 
179 Ptr<Node>
181 {
183  return m_node;
184 }
185 
186 void
187 NscTcpSocketImpl::Destroy (void)
188 {
190  m_node = 0;
191  m_endPoint = 0;
192  m_tcp = 0;
193 }
194 int
195 NscTcpSocketImpl::FinishBind (void)
196 {
198  if (m_endPoint == 0)
199  {
200  return -1;
201  }
202  m_endPoint->SetRxCallback (MakeCallback (&NscTcpSocketImpl::ForwardUp, Ptr<NscTcpSocketImpl>(this)));
203  m_endPoint->SetDestroyCallback (MakeCallback (&NscTcpSocketImpl::Destroy, Ptr<NscTcpSocketImpl>(this)));
204  m_localAddress = m_endPoint->GetLocalAddress ();
205  m_localPort = m_endPoint->GetLocalPort ();
206  return 0;
207 }
208 
209 int
211 {
213  m_endPoint = m_tcp->Allocate ();
214  return FinishBind ();
215 }
216 int
218 {
219  NS_LOG_LOGIC ("NscTcpSocketImpl: ERROR_AFNOSUPPORT - Bind6 not supported");
220  m_errno = ERROR_AFNOSUPPORT;
221  return (-1);
222 }
223 int
225 {
226  NS_LOG_FUNCTION (this<<address);
227  if (!InetSocketAddress::IsMatchingType (address))
228  {
229  return ERROR_INVAL;
230  }
232  Ipv4Address ipv4 = transport.GetIpv4 ();
233  uint16_t port = transport.GetPort ();
234  if (ipv4 == Ipv4Address::GetAny () && port == 0)
235  {
236  m_endPoint = m_tcp->Allocate ();
237  NS_LOG_LOGIC ("NscTcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
238  }
239  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
240  {
241  m_endPoint = m_tcp->Allocate (port);
242  NS_LOG_LOGIC ("NscTcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
243  }
244  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
245  {
246  m_endPoint = m_tcp->Allocate (ipv4);
247  NS_LOG_LOGIC ("NscTcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
248  }
249  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
250  {
251  m_endPoint = m_tcp->Allocate (ipv4, port);
252  NS_LOG_LOGIC ("NscTcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
253  }
254 
255  m_localPort = port;
256  return FinishBind ();
257 }
258 
259 int
261 {
263  m_shutdownSend = true;
264  return 0;
265 }
266 int
268 {
270  m_shutdownRecv = true;
271  return 0;
272 }
273 
274 int
276 {
277  NS_LOG_FUNCTION (this << m_state);
278 
279  if (m_state == CLOSED)
280  {
281  return -1;
282  }
283  if (!m_txBuffer.empty ())
284  { // App close with pending data must wait until all data transmitted
285  m_closeOnEmpty = true;
286  NS_LOG_LOGIC ("Socket " << this <<
287  " deferring close, state " << m_state);
288  return 0;
289  }
290 
291  NS_LOG_LOGIC ("NscTcp socket " << this << " calling disconnect(); moving to CLOSED");
292  m_nscTcpSocket->disconnect ();
293  m_state = CLOSED;
294  ShutdownSend ();
295  return 0;
296 }
297 
298 int
300 {
301  NS_LOG_FUNCTION (this << address);
302  if (m_endPoint == 0)
303  {
304  if (Bind () == -1)
305  {
306  NS_ASSERT (m_endPoint == 0);
307  return -1;
308  }
309  NS_ASSERT (m_endPoint != 0);
310  }
312  m_remoteAddress = transport.GetIpv4 ();
313  m_remotePort = transport.GetPort ();
314 
315  std::ostringstream ss;
316  m_remoteAddress.Print (ss);
317  std::string ipstring = ss.str ();
318 
319  m_nscTcpSocket->connect (ipstring.c_str (), m_remotePort);
320  m_state = SYN_SENT;
321  return 0;
322 }
323 
324 int
325 NscTcpSocketImpl::Send (const Ptr<Packet> p, uint32_t flags)
326 {
327  NS_LOG_FUNCTION (this << p);
328 
329  NS_ASSERT (p->GetSize () > 0);
330  if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
331  {
332  if (p->GetSize () > GetTxAvailable ())
333  {
334  m_errno = ERROR_MSGSIZE;
335  return -1;
336  }
337 
338  uint32_t sent = p->GetSize ();
339  if (m_state == ESTABLISHED)
340  {
341  m_txBuffer.push (p);
342  m_txBufferSize += sent;
343  SendPendingData ();
344  }
345  else
346  { // SYN_SET -- Queue Data
347  m_txBuffer.push (p);
348  m_txBufferSize += sent;
349  }
350  return sent;
351  }
352  else
353  {
354  m_errno = ERROR_NOTCONN;
355  return -1;
356  }
357 }
358 
359 int
360 NscTcpSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
361 {
362  NS_LOG_FUNCTION (this << address << p);
363  if (!m_connected)
364  {
365  m_errno = ERROR_NOTCONN;
366  return -1;
367  }
368  else
369  {
370  return Send (p, flags); //drop the address according to BSD manpages
371  }
372 }
373 
374 uint32_t
376 {
378  if (m_txBufferSize != 0)
379  {
380  NS_ASSERT (m_txBufferSize <= m_sndBufSize);
381  return m_sndBufSize - m_txBufferSize;
382  }
383  else
384  {
385  return m_sndBufSize;
386  }
387 }
388 
389 int
391 {
392  NS_LOG_FUNCTION (this);
393  m_nscTcpSocket->listen (m_localPort);
394  m_state = LISTEN;
395  return 0;
396 }
397 
398 
399 void
400 NscTcpSocketImpl::NSCWakeup ()
401 {
402  switch (m_state) {
403  case SYN_SENT:
404  if (!m_nscTcpSocket->is_connected ())
405  break;
406  m_state = ESTABLISHED;
407  Simulator::ScheduleNow (&NscTcpSocketImpl::ConnectionSucceeded, this);
408  // fall through to schedule read/write events
409  case ESTABLISHED:
410  if (!m_txBuffer.empty ())
411  Simulator::ScheduleNow (&NscTcpSocketImpl::SendPendingData, this);
412  Simulator::ScheduleNow (&NscTcpSocketImpl::ReadPendingData, this);
413  break;
414  case LISTEN:
415  Simulator::ScheduleNow (&NscTcpSocketImpl::Accept, this);
416  break;
417  case CLOSED: break;
418  default:
419  NS_LOG_DEBUG (this << " invalid state: " << m_state);
420  }
421 }
422 
423 Ptr<Packet>
424 NscTcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
425 {
427  if (m_deliveryQueue.empty () )
428  {
429  m_errno = ERROR_AGAIN;
430  return 0;
431  }
432  Ptr<Packet> p = m_deliveryQueue.front ();
433  if (p->GetSize () <= maxSize)
434  {
435  m_deliveryQueue.pop ();
436  m_rxAvailable -= p->GetSize ();
437  }
438  else
439  {
440  m_errno = ERROR_AGAIN;
441  p = 0;
442  }
443  return p;
444 }
445 
447 NscTcpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
448  Address &fromAddress)
449 {
450  NS_LOG_FUNCTION (this << maxSize << flags);
451  Ptr<Packet> packet = Recv (maxSize, flags);
452  if (packet != 0)
453  {
454  SocketAddressTag tag;
455  bool found;
456  found = packet->PeekPacketTag (tag);
457  NS_ASSERT (found);
458  fromAddress = tag.GetAddress ();
459  }
460  return packet;
461 }
462 
463 int
465 {
467  address = InetSocketAddress (m_localAddress, m_localPort);
468  return 0;
469 }
470 
471 uint32_t
473 {
475  // We separately maintain this state to avoid walking the queue
476  // every time this might be called
477  return m_rxAvailable;
478 }
479 
480 void
481 NscTcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port,
482  Ptr<Ipv4Interface> incomingInterface)
483 {
484  NSCWakeup ();
485 }
486 
487 void NscTcpSocketImpl::CompleteFork (void)
488 {
489  // The address pairs (m_localAddress, m_localPort, m_remoteAddress, m_remotePort)
490  // are bogus, but this isn't important at the moment, because
491  // address <-> Socket handling is done by NSC internally.
492  // We only need to add the new ns-3 socket to the list of sockets, so
493  // we use plain Allocate() instead of Allocate(m_localAddress, ... )
494  struct sockaddr_in sin;
495  size_t sin_len = sizeof(sin);
496 
497  if (0 == m_nscTcpSocket->getpeername ((struct sockaddr*) &sin, &sin_len)) {
498  m_remotePort = ntohs (sin.sin_port);
499  m_remoteAddress = Ipv4Address::Deserialize ((const uint8_t*) &sin.sin_addr);
500  m_peerAddress = InetSocketAddress (m_remoteAddress, m_remotePort);
501  }
502 
503  m_endPoint = m_tcp->Allocate ();
504 
505  //the cloned socket with be in listen state, so manually change state
506  NS_ASSERT (m_state == LISTEN);
507  m_state = ESTABLISHED;
508 
509  sin_len = sizeof(sin);
510 
511  if (0 == m_nscTcpSocket->getsockname ((struct sockaddr *) &sin, &sin_len))
512  m_localAddress = Ipv4Address::Deserialize ((const uint8_t*) &sin.sin_addr);
513 
514  NS_LOG_LOGIC ("NscTcpSocketImpl " << this << " accepted connection from "
515  << m_remoteAddress << ":" << m_remotePort
516  << " to " << m_localAddress << ":" << m_localPort);
517  //equivalent to FinishBind
518  m_endPoint->SetRxCallback (MakeCallback (&NscTcpSocketImpl::ForwardUp, Ptr<NscTcpSocketImpl>(this)));
519  m_endPoint->SetDestroyCallback (MakeCallback (&NscTcpSocketImpl::Destroy, Ptr<NscTcpSocketImpl>(this)));
520 
521  NotifyNewConnectionCreated (this, m_peerAddress);
522 }
523 
524 void NscTcpSocketImpl::ConnectionSucceeded ()
525 { // We would preferred to have scheduled an event directly to
526  // NotifyConnectionSucceeded, but (sigh) these are protected
527  // and we can get the address of it :(
528  struct sockaddr_in sin;
529  size_t sin_len = sizeof(sin);
530  if (0 == m_nscTcpSocket->getsockname ((struct sockaddr *) &sin, &sin_len)) {
531  m_localAddress = Ipv4Address::Deserialize ((const uint8_t*)&sin.sin_addr);
532  m_localPort = ntohs (sin.sin_port);
533  }
534 
535  NS_LOG_LOGIC ("NscTcpSocketImpl " << this << " connected to "
536  << m_remoteAddress << ":" << m_remotePort
537  << " from " << m_localAddress << ":" << m_localPort);
538  NotifyConnectionSucceeded ();
539 }
540 
541 
542 bool NscTcpSocketImpl::Accept (void)
543 {
544  if (m_state == CLOSED)
545  { // Happens if application closes listening socket after Accept() was scheduled.
546  return false;
547  }
548  NS_ASSERT (m_state == LISTEN);
549 
550  if (!m_nscTcpSocket->is_listening ())
551  {
552  return false;
553  }
554  INetStreamSocket *newsock;
555  int res = m_nscTcpSocket->accept (&newsock);
556  if (res != 0)
557  {
558  return false;
559  }
560 // We could obtain a fromAddress using getpeername, but we've already
561 // finished the tcp handshake here, i.e. this is a new connection
562 // and not a connection request.
563 // if (!NotifyConnectionRequest(fromAddress))
564 // return true;
565 
566  // Clone the socket
567  Ptr<NscTcpSocketImpl> newSock = Copy ();
568  newSock->m_nscTcpSocket = newsock;
569  NS_LOG_LOGIC ("Cloned a NscTcpSocketImpl " << newSock);
570 
571  Simulator::ScheduleNow (&NscTcpSocketImpl::CompleteFork, newSock);
572  return true;
573 }
574 
575 bool NscTcpSocketImpl::ReadPendingData (void)
576 {
577  if (m_state != ESTABLISHED)
578  {
579  return false;
580  }
581  int len, err;
582  uint8_t buffer[8192];
583  len = sizeof(buffer);
584  m_errno = ERROR_NOTERROR;
585  err = m_nscTcpSocket->read_data (buffer, &len);
586  if (err == 0 && len == 0)
587  {
588  NS_LOG_LOGIC ("ReadPendingData got EOF from socket");
589  m_state = CLOSE_WAIT;
590  return false;
591  }
592  m_errno = GetNativeNs3Errno (err);
593  switch (m_errno)
594  {
595  case ERROR_NOTERROR: break; // some data was sent
596  case ERROR_AGAIN: return false;
597  default:
598  NS_LOG_WARN ("Error (" << err << ") " <<
599  "during read_data, ns-3 errno set to" << m_errno);
600  m_state = CLOSED;
601  return false;
602  }
603 
604  Ptr<Packet> p = Create<Packet> (buffer, len);
605 
606  SocketAddressTag tag;
607 
608  tag.SetAddress (m_peerAddress);
609  p->AddPacketTag (tag);
610  m_deliveryQueue.push (p);
611  m_rxAvailable += p->GetSize ();
612 
613  NotifyDataRecv ();
614  return true;
615 }
616 
617 bool NscTcpSocketImpl::SendPendingData (void)
618 {
619  NS_LOG_FUNCTION (this);
620  NS_LOG_LOGIC ("ENTERING SendPendingData");
621 
622  if (m_txBuffer.empty ())
623  {
624  return false;
625  }
626 
627  int ret;
628  size_t size, written = 0;
629 
630  do {
631  NS_ASSERT (!m_txBuffer.empty ());
632  Ptr<Packet> &p = m_txBuffer.front ();
633  size = p->GetSize ();
634  NS_ASSERT (size > 0);
635 
636  m_errno = ERROR_NOTERROR;
637 
638  uint8_t *buf = new uint8_t[size];
639  p->CopyData (buf, size);
640  ret = m_nscTcpSocket->send_data ((const char *)buf, size);
641  delete[] buf;
642 
643  if (ret <= 0)
644  {
645  break;
646  }
647  written += ret;
648 
649  NS_ASSERT (m_txBufferSize >= (size_t)ret);
650  m_txBufferSize -= ret;
651 
652  if ((size_t)ret < size)
653  {
654  p->RemoveAtStart (ret);
655  break;
656  }
657 
658  m_txBuffer.pop ();
659 
660  if (m_txBuffer.empty ())
661  {
662  if (m_closeOnEmpty)
663  {
664  m_nscTcpSocket->disconnect ();
665  m_state = CLOSED;
666  }
667  break;
668  }
669  } while ((size_t) ret == size);
670 
671  if (written > 0)
672  {
673  Simulator::ScheduleNow (&NscTcpSocketImpl::NotifyDataSent, this, ret);
674  return true;
675  }
676  return false;
677 }
678 
679 Ptr<NscTcpSocketImpl> NscTcpSocketImpl::Copy ()
680 {
681  return CopyObject<NscTcpSocketImpl> (this);
682 }
683 
684 void
685 NscTcpSocketImpl::SetSndBufSize (uint32_t size)
686 {
687  m_sndBufSize = size;
688 }
689 
690 uint32_t
691 NscTcpSocketImpl::GetSndBufSize (void) const
692 {
693  return m_sndBufSize;
694 }
695 
696 void
697 NscTcpSocketImpl::SetRcvBufSize (uint32_t size)
698 {
699  m_rcvBufSize = size;
700 }
701 
702 uint32_t
703 NscTcpSocketImpl::GetRcvBufSize (void) const
704 {
705  return m_rcvBufSize;
706 }
707 
708 void
709 NscTcpSocketImpl::SetSegSize (uint32_t size)
710 {
711  m_segmentSize = size;
712 }
713 
714 uint32_t
715 NscTcpSocketImpl::GetSegSize (void) const
716 {
717  return m_segmentSize;
718 }
719 
720 void
721 NscTcpSocketImpl::SetAdvWin (uint32_t window)
722 {
723  m_advertisedWindowSize = window;
724 }
725 
726 uint32_t
727 NscTcpSocketImpl::GetAdvWin (void) const
728 {
729  return m_advertisedWindowSize;
730 }
731 
732 void
733 NscTcpSocketImpl::SetSSThresh (uint32_t threshold)
734 {
735  m_ssThresh = threshold;
736 }
737 
738 uint32_t
739 NscTcpSocketImpl::GetSSThresh (void) const
740 {
741  return m_ssThresh;
742 }
743 
744 void
745 NscTcpSocketImpl::SetInitialCwnd (uint32_t cwnd)
746 {
747  m_initialCWnd = cwnd;
748 }
749 
750 uint32_t
751 NscTcpSocketImpl::GetInitialCwnd (void) const
752 {
753  return m_initialCWnd;
754 }
755 
756 void
757 NscTcpSocketImpl::SetConnTimeout (Time timeout)
758 {
759  m_cnTimeout = timeout;
760 }
761 
762 Time
763 NscTcpSocketImpl::GetConnTimeout (void) const
764 {
765  return m_cnTimeout;
766 }
767 
768 void
769 NscTcpSocketImpl::SetConnCount (uint32_t count)
770 {
771  m_cnCount = count;
772 }
773 
774 uint32_t
775 NscTcpSocketImpl::GetConnCount (void) const
776 {
777  return m_cnCount;
778 }
779 
780 void
781 NscTcpSocketImpl::SetDelAckTimeout (Time timeout)
782 {
783  m_delAckTimeout = timeout;
784 }
785 
786 Time
787 NscTcpSocketImpl::GetDelAckTimeout (void) const
788 {
789  return m_delAckTimeout;
790 }
791 
792 void
793 NscTcpSocketImpl::SetDelAckMaxCount (uint32_t count)
794 {
795  m_delAckMaxCount = count;
796 }
797 
798 uint32_t
799 NscTcpSocketImpl::GetDelAckMaxCount (void) const
800 {
801  return m_delAckMaxCount;
802 }
803 
804 void
805 NscTcpSocketImpl::SetTcpNoDelay (bool noDelay)
806 {
807  m_noDelay = noDelay;
808 }
809 
810 bool
811 NscTcpSocketImpl::GetTcpNoDelay (void) const
812 {
813  return m_noDelay;
814 }
815 
816 void
817 NscTcpSocketImpl::SetPersistTimeout (Time timeout)
818 {
819  m_persistTimeout = timeout;
820 }
821 
822 Time
823 NscTcpSocketImpl::GetPersistTimeout (void) const
824 {
825  return m_persistTimeout;
826 }
827 
828 enum Socket::SocketErrno
829 NscTcpSocketImpl::GetNativeNs3Errno (int error) const
830 {
831  enum nsc_errno err;
832 
833  if (error >= 0)
834  {
835  return ERROR_NOTERROR;
836  }
837  err = (enum nsc_errno) error;
838  switch (err)
839  {
840  case NSC_EADDRINUSE: // fallthrough
841  case NSC_EADDRNOTAVAIL: return ERROR_AFNOSUPPORT;
842  case NSC_EINPROGRESS: // Altough nsc sockets are nonblocking, we pretend they're not.
843  case NSC_EAGAIN: return ERROR_AGAIN;
844  case NSC_EISCONN: // fallthrough
845  case NSC_EALREADY: return ERROR_ISCONN;
846  case NSC_ECONNREFUSED: return ERROR_NOROUTETOHOST; // XXX, better mapping?
847  case NSC_ECONNRESET: // for no, all of these fall through
848  case NSC_EHOSTDOWN:
849  case NSC_ENETUNREACH:
850  case NSC_EHOSTUNREACH: return ERROR_NOROUTETOHOST;
851  case NSC_EMSGSIZE: return ERROR_MSGSIZE;
852  case NSC_ENOTCONN: return ERROR_NOTCONN;
853  case NSC_ESHUTDOWN: return ERROR_SHUTDOWN;
854  case NSC_ETIMEDOUT: return ERROR_NOTCONN; // XXX - this mapping isn't correct
855  case NSC_ENOTDIR: // used by eg. sysctl(2). Shouldn't happen normally,
856  // but is triggered by e.g. show_config().
857  case NSC_EUNKNOWN: return ERROR_INVAL; // Catches stacks that 'return -1' without real mapping
858  }
859  NS_ASSERT_MSG (0, "Unknown NSC error");
860  return ERROR_INVAL;
861 }
862 
863 bool
865 {
866  if (allowBroadcast)
867  {
868  return false;
869  }
870  return true;
871 }
872 
873 bool
875 {
876  return false;
877 }
878 
879 } // namespace ns3
virtual Ptr< Node > GetNode(void) const
static Ipv4Address Deserialize(const uint8_t buf[4])
an Inet address class
Ipv4Address GetIpv4(void) const
static Ipv4Address GetAny(void)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
virtual int ShutdownSend(void)
(abstract) base class of all TcpSockets
Definition: tcp-socket.h:62
virtual int GetSockName(Address &address) const
virtual enum SocketType GetSocketType(void) const
Ptr< Packet > Recv(void)
Read a single packet from the socket.
Definition: socket.cc:174
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
uint32_t GetSize(void) const
Definition: packet.h:620
virtual int Bind6(void)
Allocate a local IPv6 endpoint for this socket.
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
a polymophic address class
Definition: address.h:86
virtual uint32_t GetTxAvailable(void) const
Returns the number of bytes which can be sent in a single call to Send.
Packet header for IPv4.
Definition: ipv4-header.h:31
bool PeekPacketTag(Tag &tag) const
Definition: packet.cc:881
Socket logic for the NSC TCP sockets.
virtual bool SetAllowBroadcast(bool allowBroadcast)
Configure whether broadcast datagram transmissions are allowed.
virtual int Send(Ptr< Packet > p, uint32_t flags)
Send data (or dummy data) to the remote host.
This class implements a tag that carries an address of a packet across the socket interface...
Definition: socket.h:847
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
virtual int ShutdownRecv(void)
virtual bool GetAllowBroadcast() const
Query whether broadcast datagram transmissions are allowed.
void Print(std::ostream &os) const
Print this address to the given output stream.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)
Read a single packet from the socket and retrieve the sender address.
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
virtual int Listen(void)
Listen for incoming connections.
virtual int Bind(void)
Allocate a local IPv4 endpoint for this socket.
static InetSocketAddress ConvertFrom(const Address &address)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Definition: simulator.h:981
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
virtual uint32_t GetRxAvailable(void) const
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
#define NS_LOG_WARN(msg)
Definition: log.h:246
virtual int Close(void)
Close a socket.
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
virtual enum SocketErrno GetErrno(void) const
uint16_t GetPort(void) const
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)
Send data to a specified peer.
static bool IsMatchingType(const Address &address)
virtual int Connect(const Address &address)
Initiate a connection to a remote host.