|
|
|
|
@@ -23,7 +23,7 @@
|
|
|
|
|
#include "ns3/inet-socket-address.h"
|
|
|
|
|
#include "ns3/log.h"
|
|
|
|
|
#include "ns3/ipv4.h"
|
|
|
|
|
#include "tcp-socket.h"
|
|
|
|
|
#include "tcp-socket-impl.h"
|
|
|
|
|
#include "tcp-l4-protocol.h"
|
|
|
|
|
#include "ipv4-end-point.h"
|
|
|
|
|
#include "ipv4-l4-demux.h"
|
|
|
|
|
@@ -36,27 +36,27 @@
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
|
|
NS_LOG_COMPONENT_DEFINE ("TcpSocket");
|
|
|
|
|
NS_LOG_COMPONENT_DEFINE ("TcpSocketImpl");
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
namespace ns3 {
|
|
|
|
|
|
|
|
|
|
NS_OBJECT_ENSURE_REGISTERED (TcpSocket);
|
|
|
|
|
NS_OBJECT_ENSURE_REGISTERED (TcpSocketImpl);
|
|
|
|
|
|
|
|
|
|
TypeId
|
|
|
|
|
TcpSocket::GetTypeId ()
|
|
|
|
|
TcpSocketImpl::GetTypeId ()
|
|
|
|
|
{
|
|
|
|
|
static TypeId tid = TypeId("ns3::TcpSocket")
|
|
|
|
|
static TypeId tid = TypeId("ns3::TcpSocketImpl")
|
|
|
|
|
.SetParent<Socket> ()
|
|
|
|
|
.AddTraceSource ("CongestionWindow",
|
|
|
|
|
"The TCP connection's congestion window",
|
|
|
|
|
MakeTraceSourceAccessor (&TcpSocket::m_cWnd))
|
|
|
|
|
MakeTraceSourceAccessor (&TcpSocketImpl::m_cWnd))
|
|
|
|
|
;
|
|
|
|
|
return tid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TcpSocket::TcpSocket ()
|
|
|
|
|
TcpSocketImpl::TcpSocketImpl ()
|
|
|
|
|
: m_skipRetxResched (false),
|
|
|
|
|
m_dupAckCount (0),
|
|
|
|
|
m_delAckCount (0),
|
|
|
|
|
@@ -89,7 +89,7 @@ TcpSocket::GetTypeId ()
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TcpSocket::TcpSocket(const TcpSocket& sock)
|
|
|
|
|
TcpSocketImpl::TcpSocketImpl(const TcpSocketImpl& sock)
|
|
|
|
|
: Socket(sock), //copy the base class callbacks
|
|
|
|
|
m_skipRetxResched (sock.m_skipRetxResched),
|
|
|
|
|
m_dupAckCount (sock.m_dupAckCount),
|
|
|
|
|
@@ -148,7 +148,7 @@ TcpSocket::TcpSocket(const TcpSocket& sock)
|
|
|
|
|
//too; this is in SYN_ACK_TX
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TcpSocket::~TcpSocket ()
|
|
|
|
|
TcpSocketImpl::~TcpSocketImpl ()
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION(this);
|
|
|
|
|
m_node = 0;
|
|
|
|
|
@@ -173,7 +173,7 @@ TcpSocket::~TcpSocket ()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TcpSocket::SetNode (Ptr<Node> node)
|
|
|
|
|
TcpSocketImpl::SetNode (Ptr<Node> node)
|
|
|
|
|
{
|
|
|
|
|
m_node = node;
|
|
|
|
|
Ptr<Tcp> t = node->GetObject<Tcp> ();
|
|
|
|
|
@@ -190,33 +190,33 @@ TcpSocket::SetNode (Ptr<Node> node)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TcpSocket::SetTcp (Ptr<TcpL4Protocol> tcp)
|
|
|
|
|
TcpSocketImpl::SetTcp (Ptr<TcpL4Protocol> tcp)
|
|
|
|
|
{
|
|
|
|
|
m_tcp = tcp;
|
|
|
|
|
}
|
|
|
|
|
void
|
|
|
|
|
TcpSocket::SetRtt (Ptr<RttEstimator> rtt)
|
|
|
|
|
TcpSocketImpl::SetRtt (Ptr<RttEstimator> rtt)
|
|
|
|
|
{
|
|
|
|
|
m_rtt = rtt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum Socket::SocketErrno
|
|
|
|
|
TcpSocket::GetErrno (void) const
|
|
|
|
|
TcpSocketImpl::GetErrno (void) const
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
return m_errno;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ptr<Node>
|
|
|
|
|
TcpSocket::GetNode (void) const
|
|
|
|
|
TcpSocketImpl::GetNode (void) const
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
return m_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TcpSocket::Destroy (void)
|
|
|
|
|
TcpSocketImpl::Destroy (void)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
m_node = 0;
|
|
|
|
|
@@ -225,29 +225,29 @@ TcpSocket::Destroy (void)
|
|
|
|
|
m_retxEvent.Cancel ();
|
|
|
|
|
}
|
|
|
|
|
int
|
|
|
|
|
TcpSocket::FinishBind (void)
|
|
|
|
|
TcpSocketImpl::FinishBind (void)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
if (m_endPoint == 0)
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
m_endPoint->SetRxCallback (MakeCallback (&TcpSocket::ForwardUp, Ptr<TcpSocket>(this)));
|
|
|
|
|
m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocket::Destroy, Ptr<TcpSocket>(this)));
|
|
|
|
|
m_endPoint->SetRxCallback (MakeCallback (&TcpSocketImpl::ForwardUp, Ptr<TcpSocketImpl>(this)));
|
|
|
|
|
m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketImpl::Destroy, Ptr<TcpSocketImpl>(this)));
|
|
|
|
|
m_localAddress = m_endPoint->GetLocalAddress ();
|
|
|
|
|
m_localPort = m_endPoint->GetLocalPort ();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TcpSocket::Bind (void)
|
|
|
|
|
TcpSocketImpl::Bind (void)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
m_endPoint = m_tcp->Allocate ();
|
|
|
|
|
return FinishBind ();
|
|
|
|
|
}
|
|
|
|
|
int
|
|
|
|
|
TcpSocket::Bind (const Address &address)
|
|
|
|
|
TcpSocketImpl::Bind (const Address &address)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this<<address);
|
|
|
|
|
if (!InetSocketAddress::IsMatchingType (address))
|
|
|
|
|
@@ -260,36 +260,36 @@ TcpSocket::Bind (const Address &address)
|
|
|
|
|
if (ipv4 == Ipv4Address::GetAny () && port == 0)
|
|
|
|
|
{
|
|
|
|
|
m_endPoint = m_tcp->Allocate ();
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
|
|
|
|
|
}
|
|
|
|
|
else if (ipv4 == Ipv4Address::GetAny () && port != 0)
|
|
|
|
|
{
|
|
|
|
|
m_endPoint = m_tcp->Allocate (port);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
|
|
|
|
|
}
|
|
|
|
|
else if (ipv4 != Ipv4Address::GetAny () && port == 0)
|
|
|
|
|
{
|
|
|
|
|
m_endPoint = m_tcp->Allocate (ipv4);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
|
|
|
|
|
}
|
|
|
|
|
else if (ipv4 != Ipv4Address::GetAny () && port != 0)
|
|
|
|
|
{
|
|
|
|
|
m_endPoint = m_tcp->Allocate (ipv4, port);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FinishBind ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TcpSocket::ShutdownSend (void)
|
|
|
|
|
TcpSocketImpl::ShutdownSend (void)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
m_shutdownSend = true;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int
|
|
|
|
|
TcpSocket::ShutdownRecv (void)
|
|
|
|
|
TcpSocketImpl::ShutdownRecv (void)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
m_shutdownRecv = false;
|
|
|
|
|
@@ -297,7 +297,7 @@ TcpSocket::ShutdownRecv (void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TcpSocket::Close (void)
|
|
|
|
|
TcpSocketImpl::Close (void)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
if (m_state == CLOSED)
|
|
|
|
|
@@ -319,7 +319,7 @@ TcpSocket::Close (void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TcpSocket::Connect (const Address & address)
|
|
|
|
|
TcpSocketImpl::Connect (const Address & address)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this << address);
|
|
|
|
|
if (m_endPoint == 0)
|
|
|
|
|
@@ -357,12 +357,12 @@ TcpSocket::Connect (const Address & address)
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
int
|
|
|
|
|
TcpSocket::Send (const Ptr<Packet> p) //p here is just data, no headers
|
|
|
|
|
TcpSocketImpl::Send (const Ptr<Packet> p) //p here is just data, no headers
|
|
|
|
|
{ // TCP Does not deal with packets from app, just data
|
|
|
|
|
return Send(p->PeekData(), p->GetSize());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TcpSocket::Send (const uint8_t* buf, uint32_t size)
|
|
|
|
|
int TcpSocketImpl::Send (const uint8_t* buf, uint32_t size)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this << buf << size);
|
|
|
|
|
if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
|
|
|
|
|
@@ -397,7 +397,7 @@ int TcpSocket::Send (const uint8_t* buf, uint32_t size)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TcpSocket::DoSendTo (Ptr<Packet> p, const Address &address)
|
|
|
|
|
int TcpSocketImpl::DoSendTo (Ptr<Packet> p, const Address &address)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this << p << address);
|
|
|
|
|
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
|
|
|
|
|
@@ -406,7 +406,7 @@ int TcpSocket::DoSendTo (Ptr<Packet> p, const Address &address)
|
|
|
|
|
return DoSendTo (p, ipv4, port);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TcpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port)
|
|
|
|
|
int TcpSocketImpl::DoSendTo (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this << p << ipv4 << port);
|
|
|
|
|
if (m_endPoint == 0)
|
|
|
|
|
@@ -430,7 +430,7 @@ int TcpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TcpSocket::SendTo (Ptr<Packet> p, const Address &address)
|
|
|
|
|
TcpSocketImpl::SendTo (Ptr<Packet> p, const Address &address)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this << address << p);
|
|
|
|
|
if (!m_connected)
|
|
|
|
|
@@ -445,7 +445,7 @@ TcpSocket::SendTo (Ptr<Packet> p, const Address &address)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
|
TcpSocket::GetTxAvailable (void) const
|
|
|
|
|
TcpSocketImpl::GetTxAvailable (void) const
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
if (m_pendingData != 0)
|
|
|
|
|
@@ -462,7 +462,7 @@ TcpSocket::GetTxAvailable (void) const
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TcpSocket::Listen (uint32_t q)
|
|
|
|
|
TcpSocketImpl::Listen (uint32_t q)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this << q);
|
|
|
|
|
Actions_t action = ProcessEvent (APP_LISTEN);
|
|
|
|
|
@@ -471,7 +471,7 @@ TcpSocket::Listen (uint32_t q)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ptr<Packet>
|
|
|
|
|
TcpSocket::Recv (uint32_t maxSize, uint32_t flags)
|
|
|
|
|
TcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
if (m_deliveryQueue.empty() )
|
|
|
|
|
@@ -492,7 +492,7 @@ TcpSocket::Recv (uint32_t maxSize, uint32_t flags)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
|
TcpSocket::GetRxAvailable (void) const
|
|
|
|
|
TcpSocketImpl::GetRxAvailable (void) const
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
// We separately maintain this state to avoid walking the queue
|
|
|
|
|
@@ -501,35 +501,35 @@ TcpSocket::GetRxAvailable (void) const
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TcpSocket::SetSndBuf (uint32_t size)
|
|
|
|
|
TcpSocketImpl::SetSndBuf (uint32_t size)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
m_sndBufLimit = size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
|
TcpSocket::GetSndBuf (void) const
|
|
|
|
|
TcpSocketImpl::GetSndBuf (void) const
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
return m_sndBufLimit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TcpSocket::SetRcvBuf (uint32_t size)
|
|
|
|
|
TcpSocketImpl::SetRcvBuf (uint32_t size)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
m_rcvBufLimit = size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
|
TcpSocket::GetRcvBuf (void) const
|
|
|
|
|
TcpSocketImpl::GetRcvBuf (void) const
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
return m_rcvBufLimit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TcpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
|
|
|
|
|
TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_DEBUG("Socket " << this << " got forward up" <<
|
|
|
|
|
" dport " << m_endPoint->GetLocalPort() <<
|
|
|
|
|
@@ -563,26 +563,26 @@ TcpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
|
|
|
|
|
ProcessPacketAction (action, packet, tcpHeader, address);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Actions_t TcpSocket::ProcessEvent (Events_t e)
|
|
|
|
|
Actions_t TcpSocketImpl::ProcessEvent (Events_t e)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this << e);
|
|
|
|
|
States_t saveState = m_state;
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " processing event " << e);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " processing event " << e);
|
|
|
|
|
// simulation singleton is a way to get a single global static instance of a
|
|
|
|
|
// class intended to be a singleton; see simulation-singleton.h
|
|
|
|
|
SA stateAction = SimulationSingleton<TcpStateMachine>::Get ()->Lookup (m_state,e);
|
|
|
|
|
// debug
|
|
|
|
|
if (stateAction.action == RST_TX)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " sending RST from state "
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " sending RST from state "
|
|
|
|
|
<< saveState << " event " << e);
|
|
|
|
|
}
|
|
|
|
|
bool needCloseNotify = (stateAction.state == CLOSED && m_state != CLOSED
|
|
|
|
|
&& e != TIMEOUT);
|
|
|
|
|
m_state = stateAction.state;
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " moved from state " << saveState
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " moved from state " << saveState
|
|
|
|
|
<< " to state " <<m_state);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " pendingData " << m_pendingData);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " pendingData " << m_pendingData);
|
|
|
|
|
|
|
|
|
|
//extra event logic is here for RX events
|
|
|
|
|
//e = SYN_ACK_RX
|
|
|
|
|
@@ -590,31 +590,31 @@ Actions_t TcpSocket::ProcessEvent (Events_t e)
|
|
|
|
|
// this means the application side has completed its portion of
|
|
|
|
|
// the handshaking
|
|
|
|
|
{
|
|
|
|
|
Simulator::ScheduleNow(&TcpSocket::ConnectionSucceeded, this);
|
|
|
|
|
Simulator::ScheduleNow(&TcpSocketImpl::ConnectionSucceeded, this);
|
|
|
|
|
//NotifyConnectionSucceeded ();
|
|
|
|
|
m_connected = true;
|
|
|
|
|
m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " Connected!");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (needCloseNotify && !m_closeNotified)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " transition to CLOSED from "
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " transition to CLOSED from "
|
|
|
|
|
<< m_state << " event " << e << " closeNot " << m_closeNotified
|
|
|
|
|
<< " action " << stateAction.action);
|
|
|
|
|
NotifyCloseCompleted ();
|
|
|
|
|
m_closeNotified = true;
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " calling Closed from PE"
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " calling Closed from PE"
|
|
|
|
|
<< " origState " << saveState
|
|
|
|
|
<< " event " << e);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " transition to CLOSED from "
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " transition to CLOSED from "
|
|
|
|
|
<< m_state << " event " << e
|
|
|
|
|
<< " set CloseNotif ");
|
|
|
|
|
}
|
|
|
|
|
return stateAction.action;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TcpSocket::SendEmptyPacket (uint8_t flags)
|
|
|
|
|
void TcpSocketImpl::SendEmptyPacket (uint8_t flags)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this << flags);
|
|
|
|
|
Ptr<Packet> p = Create<Packet> ();
|
|
|
|
|
@@ -640,17 +640,17 @@ void TcpSocket::SendEmptyPacket (uint8_t flags)
|
|
|
|
|
NS_LOG_LOGIC ("Schedule retransmission timeout at time "
|
|
|
|
|
<< Simulator::Now ().GetSeconds () << " to expire at time "
|
|
|
|
|
<< (Simulator::Now () + rto).GetSeconds ());
|
|
|
|
|
m_retxEvent = Simulator::Schedule (rto, &TcpSocket::ReTxTimeout, this);
|
|
|
|
|
m_retxEvent = Simulator::Schedule (rto, &TcpSocketImpl::ReTxTimeout, this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TcpSocket::ProcessAction (Actions_t a)
|
|
|
|
|
bool TcpSocketImpl::ProcessAction (Actions_t a)
|
|
|
|
|
{ // These actions do not require a packet or any TCP Headers
|
|
|
|
|
NS_LOG_FUNCTION (this << a);
|
|
|
|
|
switch (a)
|
|
|
|
|
{
|
|
|
|
|
case NO_ACT:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action: NO_ACT");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action: NO_ACT");
|
|
|
|
|
break;
|
|
|
|
|
case ACK_TX:
|
|
|
|
|
SendEmptyPacket (TcpHeader::ACK);
|
|
|
|
|
@@ -659,11 +659,11 @@ bool TcpSocket::ProcessAction (Actions_t a)
|
|
|
|
|
NS_ASSERT (false); // This should be processed in ProcessPacketAction
|
|
|
|
|
break;
|
|
|
|
|
case RST_TX:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action RST_TX");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action RST_TX");
|
|
|
|
|
SendEmptyPacket (TcpHeader::RST);
|
|
|
|
|
break;
|
|
|
|
|
case SYN_TX:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action SYN_TX");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SYN_TX");
|
|
|
|
|
// TCP SYN Flag consumes one byte
|
|
|
|
|
// is the above correct? we're SENDING a syn, not acking back -- Raj
|
|
|
|
|
// commented out for now
|
|
|
|
|
@@ -671,17 +671,17 @@ bool TcpSocket::ProcessAction (Actions_t a)
|
|
|
|
|
SendEmptyPacket (TcpHeader::SYN);
|
|
|
|
|
break;
|
|
|
|
|
case SYN_ACK_TX:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action SYN_ACK_TX");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SYN_ACK_TX");
|
|
|
|
|
// TCP SYN Flag consumes one byte
|
|
|
|
|
++m_nextRxSequence;
|
|
|
|
|
SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
|
|
|
|
|
break;
|
|
|
|
|
case FIN_TX:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action FIN_TX");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action FIN_TX");
|
|
|
|
|
SendEmptyPacket (TcpHeader::FIN);
|
|
|
|
|
break;
|
|
|
|
|
case FIN_ACK_TX:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action FIN_ACK_TX");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action FIN_ACK_TX");
|
|
|
|
|
SendEmptyPacket (TcpHeader::FIN | TcpHeader::ACK);
|
|
|
|
|
break;
|
|
|
|
|
case NEW_ACK:
|
|
|
|
|
@@ -691,36 +691,36 @@ bool TcpSocket::ProcessAction (Actions_t a)
|
|
|
|
|
NS_ASSERT (false); // This should be processed in ProcessPacketAction
|
|
|
|
|
break;
|
|
|
|
|
case RETX:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action RETX");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action RETX");
|
|
|
|
|
break;
|
|
|
|
|
case TX_DATA:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action TX_DATA");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action TX_DATA");
|
|
|
|
|
SendPendingData ();
|
|
|
|
|
break;
|
|
|
|
|
case PEER_CLOSE:
|
|
|
|
|
NS_ASSERT (false); // This should be processed in ProcessPacketAction
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action PEER_CLOSE");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action PEER_CLOSE");
|
|
|
|
|
break;
|
|
|
|
|
case APP_CLOSED:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action APP_CLOSED");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action APP_CLOSED");
|
|
|
|
|
break;
|
|
|
|
|
case CANCEL_TM:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action CANCEL_TM");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action CANCEL_TM");
|
|
|
|
|
break;
|
|
|
|
|
case APP_NOTIFY:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action APP_NOTIFY");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action APP_NOTIFY");
|
|
|
|
|
break;
|
|
|
|
|
case SERV_NOTIFY:
|
|
|
|
|
NS_ASSERT (false); // This should be processed in ProcessPacketAction
|
|
|
|
|
break;
|
|
|
|
|
case LAST_ACTION:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action LAST_ACTION");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action LAST_ACTION");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
|
|
|
|
bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
|
|
|
|
const TcpHeader& tcpHeader,
|
|
|
|
|
const Address& fromAddress)
|
|
|
|
|
{
|
|
|
|
|
@@ -730,24 +730,24 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
|
|
|
|
switch (a)
|
|
|
|
|
{
|
|
|
|
|
case SYN_ACK_TX:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action SYN_ACK_TX");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SYN_ACK_TX");
|
|
|
|
|
// m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
|
|
|
|
|
// m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
|
|
|
|
|
// if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
|
|
|
|
|
// {
|
|
|
|
|
// m_localAddress = ipv4->GetAddress (localIfIndex);
|
|
|
|
|
// }
|
|
|
|
|
if (m_state == LISTEN) //this means we should fork a new TcpSocket
|
|
|
|
|
if (m_state == LISTEN) //this means we should fork a new TcpSocketImpl
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_DEBUG("In SYN_ACK_TX, m_state is LISTEN, this " << this);
|
|
|
|
|
//notify the server that we got a SYN
|
|
|
|
|
// If server refuses connection do nothing
|
|
|
|
|
if (!NotifyConnectionRequest(fromAddress)) return true;
|
|
|
|
|
// Clone the socket
|
|
|
|
|
Ptr<TcpSocket> newSock = Copy ();
|
|
|
|
|
NS_LOG_LOGIC ("Cloned a TcpSocket " << newSock);
|
|
|
|
|
Ptr<TcpSocketImpl> newSock = Copy ();
|
|
|
|
|
NS_LOG_LOGIC ("Cloned a TcpSocketImpl " << newSock);
|
|
|
|
|
//this listening socket should do nothing more
|
|
|
|
|
Simulator::ScheduleNow (&TcpSocket::CompleteFork, newSock,
|
|
|
|
|
Simulator::ScheduleNow (&TcpSocketImpl::CompleteFork, newSock,
|
|
|
|
|
p, tcpHeader,fromAddress);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
@@ -766,12 +766,12 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
|
|
|
|
SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
|
|
|
|
|
break;
|
|
|
|
|
case ACK_TX_1:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action ACK_TX_1");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action ACK_TX_1");
|
|
|
|
|
// TCP SYN consumes one byte
|
|
|
|
|
m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
|
|
|
|
|
m_nextTxSequence = tcpHeader.GetAckNumber ();
|
|
|
|
|
m_firstPendingSequence = m_nextTxSequence; //bug 166
|
|
|
|
|
NS_LOG_DEBUG ("TcpSocket " << this << " ACK_TX_1" <<
|
|
|
|
|
NS_LOG_DEBUG ("TcpSocketImpl " << this << " ACK_TX_1" <<
|
|
|
|
|
" nextRxSeq " << m_nextRxSequence);
|
|
|
|
|
SendEmptyPacket (TcpHeader::ACK);
|
|
|
|
|
m_rxWindowSize = tcpHeader.GetWindowSize ();
|
|
|
|
|
@@ -788,7 +788,7 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
|
|
|
|
SendPendingData ();
|
|
|
|
|
break;
|
|
|
|
|
case NEW_ACK:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action NEW_ACK_TX");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action NEW_ACK_TX");
|
|
|
|
|
if (tcpHeader.GetAckNumber () < m_highestRxAck) //old ack, do nothing
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
@@ -806,7 +806,7 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
|
|
|
|
NewAck (tcpHeader.GetAckNumber ());
|
|
|
|
|
break;
|
|
|
|
|
case NEW_SEQ_RX:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action NEW_SEQ_RX");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action NEW_SEQ_RX");
|
|
|
|
|
NewRx (p, tcpHeader, fromAddress); // Process new data received
|
|
|
|
|
break;
|
|
|
|
|
case PEER_CLOSE:
|
|
|
|
|
@@ -817,7 +817,7 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
|
|
|
|
if (tcpHeader.GetSequenceNumber () != m_nextRxSequence)
|
|
|
|
|
{ // process close later
|
|
|
|
|
m_pendingClose = true;
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " setting pendingClose"
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " setting pendingClose"
|
|
|
|
|
<< " rxseq " << tcpHeader.GetSequenceNumber ()
|
|
|
|
|
<< " nextRxSeq " << m_nextRxSequence);
|
|
|
|
|
NewRx (p, tcpHeader, fromAddress);
|
|
|
|
|
@@ -830,7 +830,7 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
|
|
|
|
NewRx (p, tcpHeader, fromAddress);
|
|
|
|
|
}
|
|
|
|
|
States_t saveState = m_state; // Used to see if app responds
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this
|
|
|
|
|
<< " peer close, state " << m_state);
|
|
|
|
|
if (!m_closeRequestNotified)
|
|
|
|
|
{
|
|
|
|
|
@@ -839,7 +839,7 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
|
|
|
|
NotifyCloseRequested();
|
|
|
|
|
m_closeRequestNotified = true;
|
|
|
|
|
}
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this
|
|
|
|
|
<< " peer close, state after " << m_state);
|
|
|
|
|
if (m_state == saveState)
|
|
|
|
|
{ // Need to ack, the application will close later
|
|
|
|
|
@@ -848,15 +848,15 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
|
|
|
|
}
|
|
|
|
|
if (m_state == LAST_ACK)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " scheduling LATO1");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " scheduling LATO1");
|
|
|
|
|
m_lastAckEvent = Simulator::Schedule (m_rtt->RetransmitTimeout (),
|
|
|
|
|
&TcpSocket::LastAckTimeout,this);
|
|
|
|
|
&TcpSocketImpl::LastAckTimeout,this);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SERV_NOTIFY:
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this <<" Action SERV_NOTIFY");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " Connected!");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SERV_NOTIFY");
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
|
|
|
|
|
NotifyNewConnectionCreated (this, fromAddress);
|
|
|
|
|
m_connected = true; // ! This is bogus; fix when we clone the tcp
|
|
|
|
|
m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
|
|
|
|
|
@@ -869,7 +869,7 @@ bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TcpSocket::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& fromAddress)
|
|
|
|
|
void TcpSocketImpl::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& fromAddress)
|
|
|
|
|
{
|
|
|
|
|
// Get port and address from peer (connecting host)
|
|
|
|
|
m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
|
|
|
|
|
@@ -881,19 +881,19 @@ void TcpSocket::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& f
|
|
|
|
|
//the cloned socket with be in listen state, so manually change state
|
|
|
|
|
m_state = SYN_RCVD;
|
|
|
|
|
//equivalent to FinishBind
|
|
|
|
|
m_endPoint->SetRxCallback (MakeCallback (&TcpSocket::ForwardUp, Ptr<TcpSocket>(this)));
|
|
|
|
|
m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocket::Destroy, Ptr<TcpSocket>(this)));
|
|
|
|
|
m_endPoint->SetRxCallback (MakeCallback (&TcpSocketImpl::ForwardUp, Ptr<TcpSocketImpl>(this)));
|
|
|
|
|
m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketImpl::Destroy, Ptr<TcpSocketImpl>(this)));
|
|
|
|
|
ProcessPacketAction(SYN_ACK_TX, p, h, fromAddress);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TcpSocket::ConnectionSucceeded()
|
|
|
|
|
void TcpSocketImpl::ConnectionSucceeded()
|
|
|
|
|
{ // We would preferred to have scheduled an event directly to
|
|
|
|
|
// NotifyConnectionSucceeded, but (sigh) these are protected
|
|
|
|
|
// and we can get the address of it :(
|
|
|
|
|
NotifyConnectionSucceeded();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TcpSocket::SendPendingData (bool withAck)
|
|
|
|
|
bool TcpSocketImpl::SendPendingData (bool withAck)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this << withAck);
|
|
|
|
|
NS_LOG_LOGIC ("ENTERING SendPendingData");
|
|
|
|
|
@@ -905,7 +905,7 @@ bool TcpSocket::SendPendingData (bool withAck)
|
|
|
|
|
while (m_pendingData->SizeFromSeq (m_firstPendingSequence, m_nextTxSequence))
|
|
|
|
|
{
|
|
|
|
|
uint32_t w = AvailableWindow ();// Get available window size
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " SendPendingData"
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " SendPendingData"
|
|
|
|
|
<< " w " << w
|
|
|
|
|
<< " rxwin " << m_rxWindowSize
|
|
|
|
|
<< " cWnd " << m_cWnd
|
|
|
|
|
@@ -922,7 +922,7 @@ bool TcpSocket::SendPendingData (bool withAck)
|
|
|
|
|
uint32_t s = std::min (w, m_segmentSize); // Send no more than window
|
|
|
|
|
Ptr<Packet> p = m_pendingData->CopyFromSeq (s, m_firstPendingSequence,
|
|
|
|
|
m_nextTxSequence);
|
|
|
|
|
NS_LOG_LOGIC("TcpSocket " << this << " sendPendingData"
|
|
|
|
|
NS_LOG_LOGIC("TcpSocketImpl " << this << " sendPendingData"
|
|
|
|
|
<< " txseq " << m_nextTxSequence
|
|
|
|
|
<< " s " << s
|
|
|
|
|
<< " datasize " << p->GetSize() );
|
|
|
|
|
@@ -960,7 +960,7 @@ bool TcpSocket::SendPendingData (bool withAck)
|
|
|
|
|
NS_LOG_LOGIC ("Schedule retransmission timeout at time " <<
|
|
|
|
|
Simulator::Now ().GetSeconds () << " to expire at time " <<
|
|
|
|
|
(Simulator::Now () + rto).GetSeconds () );
|
|
|
|
|
m_retxEvent = Simulator::Schedule (rto,&TcpSocket::ReTxTimeout,this);
|
|
|
|
|
m_retxEvent = Simulator::Schedule (rto,&TcpSocketImpl::ReTxTimeout,this);
|
|
|
|
|
}
|
|
|
|
|
NS_LOG_LOGIC ("About to send a packet with flags: " << flags);
|
|
|
|
|
m_tcp->SendPacket (p, header,
|
|
|
|
|
@@ -968,7 +968,7 @@ bool TcpSocket::SendPendingData (bool withAck)
|
|
|
|
|
m_remoteAddress);
|
|
|
|
|
m_rtt->SentSeq(m_nextTxSequence, sz); // notify the RTT
|
|
|
|
|
// Notify the application
|
|
|
|
|
Simulator::ScheduleNow(&TcpSocket::NotifyDataSent, this, p->GetSize ());
|
|
|
|
|
Simulator::ScheduleNow(&TcpSocketImpl::NotifyDataSent, this, p->GetSize ());
|
|
|
|
|
nPacketsSent++; // Count sent this loop
|
|
|
|
|
m_nextTxSequence += sz; // Advance next tx sequence
|
|
|
|
|
// Note the high water mark
|
|
|
|
|
@@ -979,26 +979,26 @@ bool TcpSocket::SendPendingData (bool withAck)
|
|
|
|
|
return (nPacketsSent>0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t TcpSocket::UnAckDataCount ()
|
|
|
|
|
uint32_t TcpSocketImpl::UnAckDataCount ()
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
return m_nextTxSequence - m_highestRxAck;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t TcpSocket::BytesInFlight ()
|
|
|
|
|
uint32_t TcpSocketImpl::BytesInFlight ()
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
return m_highTxMark - m_highestRxAck;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t TcpSocket::Window ()
|
|
|
|
|
uint32_t TcpSocketImpl::Window ()
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket::Window() "<<this);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl::Window() "<<this);
|
|
|
|
|
return std::min (m_rxWindowSize, m_cWnd.Get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t TcpSocket::AvailableWindow ()
|
|
|
|
|
uint32_t TcpSocketImpl::AvailableWindow ()
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION_NOARGS ();
|
|
|
|
|
uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
|
|
|
|
|
@@ -1010,16 +1010,16 @@ uint32_t TcpSocket::AvailableWindow ()
|
|
|
|
|
return (win - unack); // Amount of window space available
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TcpSocket::NewRx (Ptr<Packet> p,
|
|
|
|
|
void TcpSocketImpl::NewRx (Ptr<Packet> p,
|
|
|
|
|
const TcpHeader& tcpHeader,
|
|
|
|
|
const Address& fromAddress)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this << p << "tcpHeader " << fromAddress);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " NewRx,"
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewRx,"
|
|
|
|
|
<< " seq " << tcpHeader.GetSequenceNumber()
|
|
|
|
|
<< " ack " << tcpHeader.GetAckNumber()
|
|
|
|
|
<< " p.size is " << p->GetSize () );
|
|
|
|
|
NS_LOG_DEBUG ("TcpSocket " << this <<
|
|
|
|
|
NS_LOG_DEBUG ("TcpSocketImpl " << this <<
|
|
|
|
|
" NewRx," <<
|
|
|
|
|
" seq " << tcpHeader.GetSequenceNumber() <<
|
|
|
|
|
" ack " << tcpHeader.GetAckNumber() <<
|
|
|
|
|
@@ -1055,7 +1055,7 @@ void TcpSocket::NewRx (Ptr<Packet> p,
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_LOGIC ("Tcp " << this << " HuH? Got data after closeNotif");
|
|
|
|
|
}
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " adv rxseq by " << s);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " adv rxseq by " << s);
|
|
|
|
|
// Look for buffered data
|
|
|
|
|
UnAckData_t::iterator i;
|
|
|
|
|
// Note that the bufferedData list DOES contain the tcp header
|
|
|
|
|
@@ -1109,11 +1109,11 @@ void TcpSocket::NewRx (Ptr<Packet> p,
|
|
|
|
|
m_rxAvailable += p->GetSize ();
|
|
|
|
|
NotifyDataRecv ();
|
|
|
|
|
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " adv rxseq1 by " << s1 );
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " adv rxseq1 by " << s1 );
|
|
|
|
|
m_nextRxSequence += s1; // Note data received
|
|
|
|
|
m_bufferedData.erase (i); // Remove from list
|
|
|
|
|
if (flags & TcpHeader::FIN)
|
|
|
|
|
NS_LOG_LOGIC("TcpSocket " << this
|
|
|
|
|
NS_LOG_LOGIC("TcpSocketImpl " << this
|
|
|
|
|
<< " found FIN in buffered");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1153,17 +1153,17 @@ void TcpSocket::NewRx (Ptr<Packet> p,
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_delAckEvent = Simulator::Schedule (m_delAckTimout, &TcpSocket::DelAckTimeout, this);
|
|
|
|
|
m_delAckEvent = Simulator::Schedule (m_delAckTimout, &TcpSocketImpl::DelAckTimeout, this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TcpSocket::DelAckTimeout ()
|
|
|
|
|
void TcpSocketImpl::DelAckTimeout ()
|
|
|
|
|
{
|
|
|
|
|
m_delAckCount = 0;
|
|
|
|
|
SendEmptyPacket (TcpHeader::ACK);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TcpSocket::CommonNewAck (SequenceNumber ack, bool skipTimer)
|
|
|
|
|
void TcpSocketImpl::CommonNewAck (SequenceNumber ack, bool skipTimer)
|
|
|
|
|
{ // CommonNewAck is called only for "New" (non-duplicate) acks
|
|
|
|
|
// and MUST be called by any subclass, from the NewAck function
|
|
|
|
|
// Always cancel any pending re-tx timer on new acknowledgement
|
|
|
|
|
@@ -1177,7 +1177,7 @@ void TcpSocket::CommonNewAck (SequenceNumber ack, bool skipTimer)
|
|
|
|
|
NS_LOG_LOGIC ("Schedule retransmission timeout at time "
|
|
|
|
|
<< Simulator::Now ().GetSeconds () << " to expire at time "
|
|
|
|
|
<< (Simulator::Now () + rto).GetSeconds ());
|
|
|
|
|
m_retxEvent = Simulator::Schedule (rto, &TcpSocket::ReTxTimeout, this);
|
|
|
|
|
m_retxEvent = Simulator::Schedule (rto, &TcpSocketImpl::ReTxTimeout, this);
|
|
|
|
|
}
|
|
|
|
|
NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack
|
|
|
|
|
<< " numberAck " << (ack - m_highestRxAck)); // Number bytes ack'ed
|
|
|
|
|
@@ -1209,23 +1209,23 @@ void TcpSocket::CommonNewAck (SequenceNumber ack, bool skipTimer)
|
|
|
|
|
SendPendingData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ptr<TcpSocket> TcpSocket::Copy ()
|
|
|
|
|
Ptr<TcpSocketImpl> TcpSocketImpl::Copy ()
|
|
|
|
|
{
|
|
|
|
|
return CopyObject<TcpSocket> (this);
|
|
|
|
|
return CopyObject<TcpSocketImpl> (this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TcpSocket::NewAck (SequenceNumber seq)
|
|
|
|
|
void TcpSocketImpl::NewAck (SequenceNumber seq)
|
|
|
|
|
{ // New acknowledgement up to sequence number "seq"
|
|
|
|
|
// Adjust congestion window in response to new ack's received
|
|
|
|
|
NS_LOG_FUNCTION (this << seq);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " NewAck "
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewAck "
|
|
|
|
|
<< " seq " << seq
|
|
|
|
|
<< " cWnd " << m_cWnd
|
|
|
|
|
<< " ssThresh " << m_ssThresh);
|
|
|
|
|
if (m_cWnd < m_ssThresh)
|
|
|
|
|
{ // Slow start mode, add one segSize to cWnd
|
|
|
|
|
m_cWnd += m_segmentSize;
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " NewCWnd SlowStart, cWnd " << m_cWnd
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewCWnd SlowStart, cWnd " << m_cWnd
|
|
|
|
|
<< " sst " << m_ssThresh);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
@@ -1242,17 +1242,17 @@ void TcpSocket::NewAck (SequenceNumber seq)
|
|
|
|
|
CommonNewAck (seq, false); // Complete newAck processing
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TcpSocket::DupAck (const TcpHeader& t, uint32_t count)
|
|
|
|
|
void TcpSocketImpl::DupAck (const TcpHeader& t, uint32_t count)
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this << "t " << count);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " DupAck " << t.GetAckNumber ()
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " DupAck " << t.GetAckNumber ()
|
|
|
|
|
<< ", count " << count
|
|
|
|
|
<< ", time " << Simulator::Now ());
|
|
|
|
|
if (count == 3)
|
|
|
|
|
{ // Count of three indicates triple duplicate ack
|
|
|
|
|
m_ssThresh = Window () / 2; // Per RFC2581
|
|
|
|
|
m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);
|
|
|
|
|
NS_LOG_LOGIC("TcpSocket " << this << "Tahoe TDA, time " << Simulator::Now ()
|
|
|
|
|
NS_LOG_LOGIC("TcpSocketImpl " << this << "Tahoe TDA, time " << Simulator::Now ()
|
|
|
|
|
<< " seq " << t.GetAckNumber ()
|
|
|
|
|
<< " in flight " << BytesInFlight ()
|
|
|
|
|
<< " new ssthresh " << m_ssThresh);
|
|
|
|
|
@@ -1264,7 +1264,7 @@ void TcpSocket::DupAck (const TcpHeader& t, uint32_t count)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TcpSocket::ReTxTimeout ()
|
|
|
|
|
void TcpSocketImpl::ReTxTimeout ()
|
|
|
|
|
{ // Retransmit timeout
|
|
|
|
|
NS_LOG_FUNCTION (this);
|
|
|
|
|
m_ssThresh = Window () / 2; // Per RFC2581
|
|
|
|
|
@@ -1277,7 +1277,7 @@ void TcpSocket::ReTxTimeout ()
|
|
|
|
|
Retransmit (); // Retransmit the packet
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TcpSocket::LastAckTimeout ()
|
|
|
|
|
void TcpSocketImpl::LastAckTimeout ()
|
|
|
|
|
{
|
|
|
|
|
m_lastAckEvent.Cancel ();
|
|
|
|
|
if (m_state == LAST_ACK)
|
|
|
|
|
@@ -1291,7 +1291,7 @@ void TcpSocket::LastAckTimeout ()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TcpSocket::Retransmit ()
|
|
|
|
|
void TcpSocketImpl::Retransmit ()
|
|
|
|
|
{
|
|
|
|
|
NS_LOG_FUNCTION (this);
|
|
|
|
|
uint8_t flags = TcpHeader::NONE;
|
|
|
|
|
@@ -1328,14 +1328,14 @@ void TcpSocket::Retransmit ()
|
|
|
|
|
flags = flags | TcpHeader::FIN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocket " << this << " retxing seq " << m_highestRxAck);
|
|
|
|
|
NS_LOG_LOGIC ("TcpSocketImpl " << this << " retxing seq " << m_highestRxAck);
|
|
|
|
|
if (m_retxEvent.IsExpired () )
|
|
|
|
|
{
|
|
|
|
|
Time rto = m_rtt->RetransmitTimeout ();
|
|
|
|
|
NS_LOG_LOGIC ("Schedule retransmission timeout at time "
|
|
|
|
|
<< Simulator::Now ().GetSeconds () << " to expire at time "
|
|
|
|
|
<< (Simulator::Now () + rto).GetSeconds ());
|
|
|
|
|
m_retxEvent = Simulator::Schedule (rto,&TcpSocket::ReTxTimeout,this);
|
|
|
|
|
m_retxEvent = Simulator::Schedule (rto,&TcpSocketImpl::ReTxTimeout,this);
|
|
|
|
|
}
|
|
|
|
|
m_rtt->SentSeq (m_highestRxAck,p->GetSize ());
|
|
|
|
|
// And send the packet
|