20 #define NS_LOG_APPEND_CONTEXT \
21 if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
24 #include "ns3/inet-socket-address.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"
39 #include <arpa/inet.h>
40 #include <netinet/in.h>
41 #include "sim_interface.h"
43 #include "sim_errno.h"
50 NS_OBJECT_ENSURE_REGISTERED (NscTcpSocketImpl);
53 NscTcpSocketImpl::GetTypeId ()
55 static TypeId tid = TypeId (
"ns3::NscTcpSocketImpl")
56 .SetParent<TcpSocket> ()
57 .AddTraceSource (
"CongestionWindow",
58 "The TCP connection's congestion window",
70 m_peerAddress (
"0.0.0.0", 0),
71 m_errno (ERROR_NOTERROR),
72 m_shutdownSend (false),
73 m_shutdownRecv (false),
76 m_closeOnEmpty (false),
78 m_lastMeasuredRtt (
Seconds (0.0))
85 m_delAckMaxCount (sock.m_delAckMaxCount),
86 m_delAckTimeout (sock.m_delAckTimeout),
87 m_noDelay (sock.m_noDelay),
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),
114 m_sndBufSize (sock.m_sndBufSize)
119 if(!sock.m_txBuffer.empty () )
121 m_txBuffer = sock.m_txBuffer;
143 m_tcp->DeAllocate (m_endPoint);
150 NscTcpSocketImpl::SetNode (
Ptr<Node> node)
154 m_cWnd = m_initialCWnd * m_segmentSize;
155 m_rxWindowSize = m_advertisedWindowSize;
159 NscTcpSocketImpl::SetTcp (Ptr<NscTcpL4Protocol> tcp)
161 m_nscTcpSocket = tcp->m_nscStack->new_tcp_socket ();
166 enum Socket::SocketErrno
173 enum Socket::SocketType
176 return NS3_SOCK_STREAM;
187 NscTcpSocketImpl::Destroy (
void)
195 NscTcpSocketImpl::FinishBind (
void)
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 ();
213 m_endPoint = m_tcp->Allocate ();
214 return FinishBind ();
219 NS_LOG_LOGIC (
"NscTcpSocketImpl: ERROR_AFNOSUPPORT - Bind6 not supported");
220 m_errno = ERROR_AFNOSUPPORT;
233 uint16_t port = transport.
GetPort ();
236 m_endPoint = m_tcp->Allocate ();
237 NS_LOG_LOGIC (
"NscTcpSocketImpl "<<
this<<
" got an endpoint: "<<m_endPoint);
241 m_endPoint = m_tcp->Allocate (port);
242 NS_LOG_LOGIC (
"NscTcpSocketImpl "<<
this<<
" got an endpoint: "<<m_endPoint);
246 m_endPoint = m_tcp->Allocate (ipv4);
247 NS_LOG_LOGIC (
"NscTcpSocketImpl "<<
this<<
" got an endpoint: "<<m_endPoint);
251 m_endPoint = m_tcp->Allocate (ipv4, port);
252 NS_LOG_LOGIC (
"NscTcpSocketImpl "<<
this<<
" got an endpoint: "<<m_endPoint);
256 return FinishBind ();
263 m_shutdownSend =
true;
270 m_shutdownRecv =
true;
279 if (m_state == CLOSED)
283 if (!m_txBuffer.empty ())
285 m_closeOnEmpty =
true;
287 " deferring close, state " << m_state);
291 NS_LOG_LOGIC (
"NscTcp socket " <<
this <<
" calling disconnect(); moving to CLOSED");
292 m_nscTcpSocket->disconnect ();
312 m_remoteAddress = transport.
GetIpv4 ();
313 m_remotePort = transport.
GetPort ();
315 std::ostringstream ss;
316 m_remoteAddress.
Print (ss);
317 std::string ipstring = ss.str ();
319 m_nscTcpSocket->connect (ipstring.c_str (), m_remotePort);
330 if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
334 m_errno = ERROR_MSGSIZE;
339 if (m_state == ESTABLISHED)
342 m_txBufferSize += sent;
348 m_txBufferSize += sent;
354 m_errno = ERROR_NOTCONN;
365 m_errno = ERROR_NOTCONN;
370 return Send (p, flags);
378 if (m_txBufferSize != 0)
380 NS_ASSERT (m_txBufferSize <= m_sndBufSize);
381 return m_sndBufSize - m_txBufferSize;
393 m_nscTcpSocket->listen (m_localPort);
400 NscTcpSocketImpl::NSCWakeup ()
404 if (!m_nscTcpSocket->is_connected ())
406 m_state = ESTABLISHED;
410 if (!m_txBuffer.empty ())
427 if (m_deliveryQueue.empty () )
429 m_errno = ERROR_AGAIN;
435 m_deliveryQueue.pop ();
436 m_rxAvailable -= p->
GetSize ();
440 m_errno = ERROR_AGAIN;
458 fromAddress = tag.GetAddress ();
477 return m_rxAvailable;
487 void NscTcpSocketImpl::CompleteFork (
void)
494 struct sockaddr_in sin;
495 size_t sin_len =
sizeof(sin);
497 if (0 == m_nscTcpSocket->getpeername ((
struct sockaddr*) &sin, &sin_len)) {
498 m_remotePort = ntohs (sin.sin_port);
500 m_peerAddress = InetSocketAddress (m_remoteAddress, m_remotePort);
503 m_endPoint = m_tcp->Allocate ();
507 m_state = ESTABLISHED;
509 sin_len =
sizeof(sin);
511 if (0 == m_nscTcpSocket->getsockname ((
struct sockaddr *) &sin, &sin_len))
514 NS_LOG_LOGIC (
"NscTcpSocketImpl " <<
this <<
" accepted connection from "
515 << m_remoteAddress <<
":" << m_remotePort
516 <<
" to " << m_localAddress <<
":" << m_localPort);
518 m_endPoint->SetRxCallback (
MakeCallback (&NscTcpSocketImpl::ForwardUp, Ptr<NscTcpSocketImpl>(
this)));
519 m_endPoint->SetDestroyCallback (
MakeCallback (&NscTcpSocketImpl::Destroy, Ptr<NscTcpSocketImpl>(
this)));
521 NotifyNewConnectionCreated (
this, m_peerAddress);
524 void NscTcpSocketImpl::ConnectionSucceeded ()
528 struct sockaddr_in sin;
529 size_t sin_len =
sizeof(sin);
530 if (0 == m_nscTcpSocket->getsockname ((
struct sockaddr *) &sin, &sin_len)) {
532 m_localPort = ntohs (sin.sin_port);
535 NS_LOG_LOGIC (
"NscTcpSocketImpl " <<
this <<
" connected to "
536 << m_remoteAddress <<
":" << m_remotePort
537 <<
" from " << m_localAddress <<
":" << m_localPort);
538 NotifyConnectionSucceeded ();
542 bool NscTcpSocketImpl::Accept (
void)
544 if (m_state == CLOSED)
550 if (!m_nscTcpSocket->is_listening ())
555 int res = m_nscTcpSocket->accept (&newsock);
567 Ptr<NscTcpSocketImpl> newSock = Copy ();
568 newSock->m_nscTcpSocket = newsock;
575 bool NscTcpSocketImpl::ReadPendingData (
void)
577 if (m_state != ESTABLISHED)
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)
589 m_state = CLOSE_WAIT;
592 m_errno = GetNativeNs3Errno (err);
595 case ERROR_NOTERROR:
break;
596 case ERROR_AGAIN:
return false;
599 "during read_data, ns-3 errno set to" << m_errno);
604 Ptr<Packet> p = Create<Packet> (buffer, len);
606 SocketAddressTag tag;
608 tag.SetAddress (m_peerAddress);
609 p->AddPacketTag (tag);
610 m_deliveryQueue.push (p);
611 m_rxAvailable += p->GetSize ();
617 bool NscTcpSocketImpl::SendPendingData (
void)
622 if (m_txBuffer.empty ())
628 size_t size, written = 0;
632 Ptr<Packet> &p = m_txBuffer.front ();
633 size = p->GetSize ();
636 m_errno = ERROR_NOTERROR;
638 uint8_t *buf =
new uint8_t[size];
639 p->CopyData (buf, size);
640 ret = m_nscTcpSocket->send_data ((
const char *)buf, size);
649 NS_ASSERT (m_txBufferSize >= (
size_t)ret);
650 m_txBufferSize -= ret;
652 if ((
size_t)ret < size)
654 p->RemoveAtStart (ret);
660 if (m_txBuffer.empty ())
664 m_nscTcpSocket->disconnect ();
669 }
while ((
size_t) ret == size);
679 Ptr<NscTcpSocketImpl> NscTcpSocketImpl::Copy ()
681 return CopyObject<NscTcpSocketImpl> (
this);
685 NscTcpSocketImpl::SetSndBufSize (uint32_t size)
691 NscTcpSocketImpl::GetSndBufSize (
void)
const
697 NscTcpSocketImpl::SetRcvBufSize (uint32_t size)
703 NscTcpSocketImpl::GetRcvBufSize (
void)
const
709 NscTcpSocketImpl::SetSegSize (uint32_t size)
711 m_segmentSize = size;
715 NscTcpSocketImpl::GetSegSize (
void)
const
717 return m_segmentSize;
721 NscTcpSocketImpl::SetAdvWin (uint32_t window)
723 m_advertisedWindowSize = window;
727 NscTcpSocketImpl::GetAdvWin (
void)
const
729 return m_advertisedWindowSize;
733 NscTcpSocketImpl::SetSSThresh (uint32_t threshold)
735 m_ssThresh = threshold;
739 NscTcpSocketImpl::GetSSThresh (
void)
const
745 NscTcpSocketImpl::SetInitialCwnd (uint32_t cwnd)
747 m_initialCWnd = cwnd;
751 NscTcpSocketImpl::GetInitialCwnd (
void)
const
753 return m_initialCWnd;
757 NscTcpSocketImpl::SetConnTimeout (Time timeout)
759 m_cnTimeout = timeout;
763 NscTcpSocketImpl::GetConnTimeout (
void)
const
769 NscTcpSocketImpl::SetConnCount (uint32_t count)
775 NscTcpSocketImpl::GetConnCount (
void)
const
781 NscTcpSocketImpl::SetDelAckTimeout (Time timeout)
783 m_delAckTimeout = timeout;
787 NscTcpSocketImpl::GetDelAckTimeout (
void)
const
789 return m_delAckTimeout;
793 NscTcpSocketImpl::SetDelAckMaxCount (uint32_t count)
795 m_delAckMaxCount = count;
799 NscTcpSocketImpl::GetDelAckMaxCount (
void)
const
801 return m_delAckMaxCount;
805 NscTcpSocketImpl::SetTcpNoDelay (
bool noDelay)
811 NscTcpSocketImpl::GetTcpNoDelay (
void)
const
817 NscTcpSocketImpl::SetPersistTimeout (Time timeout)
819 m_persistTimeout = timeout;
823 NscTcpSocketImpl::GetPersistTimeout (
void)
const
825 return m_persistTimeout;
828 enum Socket::SocketErrno
829 NscTcpSocketImpl::GetNativeNs3Errno (
int error)
const
835 return ERROR_NOTERROR;
837 err = (
enum nsc_errno) error;
841 case NSC_EADDRNOTAVAIL:
return ERROR_AFNOSUPPORT;
842 case NSC_EINPROGRESS:
843 case NSC_EAGAIN:
return ERROR_AGAIN;
845 case NSC_EALREADY:
return ERROR_ISCONN;
846 case NSC_ECONNREFUSED:
return ERROR_NOROUTETOHOST;
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;
857 case NSC_EUNKNOWN:
return ERROR_INVAL;
virtual Ptr< Node > GetNode(void) const
static Ipv4Address Deserialize(const uint8_t buf[4])
Ipv4Address GetIpv4(void) const
static Ipv4Address GetAny(void)
#define NS_LOG_FUNCTION(parameters)
virtual int ShutdownSend(void)
(abstract) base class of all TcpSockets
virtual int GetSockName(Address &address) const
virtual enum SocketType GetSocketType(void) const
Ptr< Packet > Recv(void)
Read a single packet from the socket.
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
uint32_t GetSize(void) const
virtual int Bind6(void)
Allocate a local IPv6 endpoint for this socket.
#define NS_LOG_FUNCTION_NOARGS()
a polymophic address class
virtual uint32_t GetTxAvailable(void) const
Returns the number of bytes which can be sent in a single call to Send.
bool PeekPacketTag(Tag &tag) const
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...
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
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)
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)
#define NS_ASSERT_MSG(condition, message)
virtual uint32_t GetRxAvailable(void) const
Ipv4 addresses are stored in host order in this class.
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
virtual int Close(void)
Close a socket.
#define NS_LOG_DEBUG(msg)
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.
virtual ~NscTcpSocketImpl()